refactor: pass argv via proxyquire for cli tests
				
					
				
			This commit is contained in:
		
							parent
							
								
									264472c998
								
							
						
					
					
						commit
						12e4155cd3
					
				@ -37,6 +37,10 @@ execa
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
// Node 8+ from this point on
 | 
			
		||||
require('../cli')().catch(() => {
 | 
			
		||||
  process.exitCode = 1;
 | 
			
		||||
});
 | 
			
		||||
require('../cli')()
 | 
			
		||||
  .then(exitCode => {
 | 
			
		||||
    process.exitCode = exitCode;
 | 
			
		||||
  })
 | 
			
		||||
  .catch(() => {
 | 
			
		||||
    process.exitCode = 1;
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										12
									
								
								cli.js
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								cli.js
									
									
									
									
									
								
							@ -1,3 +1,5 @@
 | 
			
		||||
const {argv} = require('process');
 | 
			
		||||
 | 
			
		||||
const stringList = {
 | 
			
		||||
  type: 'string',
 | 
			
		||||
  array: true,
 | 
			
		||||
@ -36,11 +38,10 @@ Usage:
 | 
			
		||||
    .exitProcess(false);
 | 
			
		||||
 | 
			
		||||
  try {
 | 
			
		||||
    const {help, version, ...opts} = cli.argv;
 | 
			
		||||
    const {help, version, ...opts} = cli.parse(argv.slice(2));
 | 
			
		||||
 | 
			
		||||
    if (Boolean(help) || Boolean(version)) {
 | 
			
		||||
      process.exitCode = 0;
 | 
			
		||||
      return;
 | 
			
		||||
      return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Set the `noCi` options as yargs sets the `ci` options instead (because arg starts with `--no`)
 | 
			
		||||
@ -52,13 +53,12 @@ Usage:
 | 
			
		||||
      // Debug must be enabled before other requires in order to work
 | 
			
		||||
      require('debug').enable('semantic-release:*');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    await require('.')(opts);
 | 
			
		||||
    process.exitCode = 0;
 | 
			
		||||
    return 0;
 | 
			
		||||
  } catch (err) {
 | 
			
		||||
    if (err.name !== 'YError') {
 | 
			
		||||
      console.error(err);
 | 
			
		||||
    }
 | 
			
		||||
    process.exitCode = 1;
 | 
			
		||||
    return 1;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										117
									
								
								test/cli.test.js
									
									
									
									
									
								
							
							
						
						
									
										117
									
								
								test/cli.test.js
									
									
									
									
									
								
							@ -1,14 +1,10 @@
 | 
			
		||||
import test from 'ava';
 | 
			
		||||
import proxyquire from 'proxyquire';
 | 
			
		||||
import clearModule from 'clear-module';
 | 
			
		||||
import {stub} from 'sinon';
 | 
			
		||||
 | 
			
		||||
// Save the current process.env and process.argv
 | 
			
		||||
const envBackup = Object.assign({}, process.env);
 | 
			
		||||
const argvBackup = Object.assign({}, process.argv);
 | 
			
		||||
const requireNoCache = proxyquire.noPreserveCache();
 | 
			
		||||
 | 
			
		||||
test.beforeEach(t => {
 | 
			
		||||
  clearModule('yargs');
 | 
			
		||||
  t.context.logs = '';
 | 
			
		||||
  t.context.errors = '';
 | 
			
		||||
  t.context.stdout = stub(process.stdout, 'write').callsFake(val => {
 | 
			
		||||
@ -20,18 +16,13 @@ test.beforeEach(t => {
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
test.afterEach.always(t => {
 | 
			
		||||
  process.env = envBackup;
 | 
			
		||||
  process.argv = argvBackup;
 | 
			
		||||
  t.context.stdout.restore();
 | 
			
		||||
  t.context.stderr.restore();
 | 
			
		||||
  delete process.exitCode;
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
test.serial('Pass options to semantic-release API', async t => {
 | 
			
		||||
  const run = stub().resolves(true);
 | 
			
		||||
  const cli = proxyquire('../cli', {'.': run});
 | 
			
		||||
 | 
			
		||||
  process.argv = [
 | 
			
		||||
  const argv = [
 | 
			
		||||
    '',
 | 
			
		||||
    '',
 | 
			
		||||
    '-b',
 | 
			
		||||
@ -68,8 +59,9 @@ test.serial('Pass options to semantic-release API', async t => {
 | 
			
		||||
    '--debug',
 | 
			
		||||
    '-d',
 | 
			
		||||
  ];
 | 
			
		||||
  const cli = requireNoCache('../cli', {'.': run, process: {...process, argv}});
 | 
			
		||||
 | 
			
		||||
  await cli();
 | 
			
		||||
  const exitCode = await cli();
 | 
			
		||||
 | 
			
		||||
  t.is(run.args[0][0].branch, 'master');
 | 
			
		||||
  t.is(run.args[0][0].repositoryUrl, 'https://github/com/owner/repo.git');
 | 
			
		||||
@ -86,14 +78,12 @@ test.serial('Pass options to semantic-release API', async t => {
 | 
			
		||||
  t.is(run.args[0][0].debug, true);
 | 
			
		||||
  t.is(run.args[0][0].dryRun, true);
 | 
			
		||||
 | 
			
		||||
  t.is(process.exitCode, 0);
 | 
			
		||||
  t.is(exitCode, 0);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
test.serial('Pass options to semantic-release API with alias arguments', async t => {
 | 
			
		||||
  const run = stub().resolves(true);
 | 
			
		||||
  const cli = proxyquire('../cli', {'.': run});
 | 
			
		||||
 | 
			
		||||
  process.argv = [
 | 
			
		||||
  const argv = [
 | 
			
		||||
    '',
 | 
			
		||||
    '',
 | 
			
		||||
    '--branch',
 | 
			
		||||
@ -107,8 +97,9 @@ test.serial('Pass options to semantic-release API with alias arguments', async t
 | 
			
		||||
    'config2',
 | 
			
		||||
    '--dry-run',
 | 
			
		||||
  ];
 | 
			
		||||
  const cli = requireNoCache('../cli', {'.': run, process: {...process, argv}});
 | 
			
		||||
 | 
			
		||||
  await cli();
 | 
			
		||||
  const exitCode = await cli();
 | 
			
		||||
 | 
			
		||||
  t.is(run.args[0][0].branch, 'master');
 | 
			
		||||
  t.is(run.args[0][0].repositoryUrl, 'https://github/com/owner/repo.git');
 | 
			
		||||
@ -116,122 +107,104 @@ test.serial('Pass options to semantic-release API with alias arguments', async t
 | 
			
		||||
  t.deepEqual(run.args[0][0].extends, ['config1', 'config2']);
 | 
			
		||||
  t.is(run.args[0][0].dryRun, true);
 | 
			
		||||
 | 
			
		||||
  t.is(process.exitCode, 0);
 | 
			
		||||
  t.is(exitCode, 0);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
test.serial('Pass unknown options to semantic-release API', async t => {
 | 
			
		||||
  const run = stub().resolves(true);
 | 
			
		||||
  const cli = proxyquire('../cli', {'.': run});
 | 
			
		||||
  const argv = ['', '', '--bool', '--first-option', 'value1', '--second-option', 'value2', '--second-option', 'value3'];
 | 
			
		||||
  const cli = requireNoCache('../cli', {'.': run, process: {...process, argv}});
 | 
			
		||||
 | 
			
		||||
  process.argv = [
 | 
			
		||||
    '',
 | 
			
		||||
    '',
 | 
			
		||||
    '--bool',
 | 
			
		||||
    '--first-option',
 | 
			
		||||
    'value1',
 | 
			
		||||
    '--second-option',
 | 
			
		||||
    'value2',
 | 
			
		||||
    '--second-option',
 | 
			
		||||
    'value3',
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  await cli();
 | 
			
		||||
  const exitCode = await cli();
 | 
			
		||||
 | 
			
		||||
  t.is(run.args[0][0].bool, true);
 | 
			
		||||
  t.is(run.args[0][0].firstOption, 'value1');
 | 
			
		||||
  t.deepEqual(run.args[0][0].secondOption, ['value2', 'value3']);
 | 
			
		||||
 | 
			
		||||
  t.is(process.exitCode, 0);
 | 
			
		||||
  t.is(exitCode, 0);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
test.serial('Pass empty Array to semantic-release API for list option set to "false"', async t => {
 | 
			
		||||
  const run = stub().resolves(true);
 | 
			
		||||
  const cli = proxyquire('../cli', {'.': run});
 | 
			
		||||
  const argv = ['', '', '--publish', 'false'];
 | 
			
		||||
  const cli = requireNoCache('../cli', {'.': run, process: {...process, argv}});
 | 
			
		||||
 | 
			
		||||
  process.argv = ['', '', '--publish', 'false'];
 | 
			
		||||
 | 
			
		||||
  await cli();
 | 
			
		||||
  const exitCode = await cli();
 | 
			
		||||
 | 
			
		||||
  t.deepEqual(run.args[0][0].publish, []);
 | 
			
		||||
 | 
			
		||||
  t.is(process.exitCode, 0);
 | 
			
		||||
  t.is(exitCode, 0);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
test.serial('Do not set properties in option for which arg is not in command line', async t => {
 | 
			
		||||
  const run = stub().resolves(true);
 | 
			
		||||
  const cli = proxyquire('../cli', {'.': run});
 | 
			
		||||
 | 
			
		||||
  process.argv = ['', '', '-b', 'master'];
 | 
			
		||||
  const argv = ['', '', '-b', 'master'];
 | 
			
		||||
  const cli = requireNoCache('../cli', {'.': run, process: {...process, argv}});
 | 
			
		||||
 | 
			
		||||
  await cli();
 | 
			
		||||
 | 
			
		||||
  t.false(Reflect.apply(Object.prototype.hasOwnProperty, run.args[0][0], ['ci']));
 | 
			
		||||
  t.false(Reflect.apply(Object.prototype.hasOwnProperty, run.args[0][0], ['d']));
 | 
			
		||||
  t.false(Reflect.apply(Object.prototype.hasOwnProperty, run.args[0][0], ['dry-run']));
 | 
			
		||||
  t.false(Reflect.apply(Object.prototype.hasOwnProperty, run.args[0][0], ['debug']));
 | 
			
		||||
  t.false(Reflect.apply(Object.prototype.hasOwnProperty, run.args[0][0], ['r']));
 | 
			
		||||
  t.false(Reflect.apply(Object.prototype.hasOwnProperty, run.args[0][0], ['t']));
 | 
			
		||||
  t.false('ci' in run.args[0][0]);
 | 
			
		||||
  t.false('d' in run.args[0][0]);
 | 
			
		||||
  t.false('dry-run' in run.args[0][0]);
 | 
			
		||||
  t.false('debug' in run.args[0][0]);
 | 
			
		||||
  t.false('r' in run.args[0][0]);
 | 
			
		||||
  t.false('t' in run.args[0][0]);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
test.serial('Set "noCi" options to "true" with "--no-ci"', async t => {
 | 
			
		||||
  const run = stub().resolves(true);
 | 
			
		||||
  const cli = proxyquire('../cli', {'.': run});
 | 
			
		||||
  const argv = ['', '', '--no-ci'];
 | 
			
		||||
  const cli = requireNoCache('../cli', {'.': run, process: {...process, argv}});
 | 
			
		||||
 | 
			
		||||
  process.argv = ['', '', '--no-ci'];
 | 
			
		||||
 | 
			
		||||
  await cli();
 | 
			
		||||
  const exitCode = await cli();
 | 
			
		||||
 | 
			
		||||
  t.is(run.args[0][0].noCi, true);
 | 
			
		||||
 | 
			
		||||
  t.is(process.exitCode, 0);
 | 
			
		||||
  t.is(exitCode, 0);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
test.serial('Display help', async t => {
 | 
			
		||||
  const run = stub().resolves(true);
 | 
			
		||||
  const cli = proxyquire('../cli', {'.': run});
 | 
			
		||||
  const argv = ['', '', '--help'];
 | 
			
		||||
  const cli = requireNoCache('../cli', {'.': run, process: {...process, argv}});
 | 
			
		||||
 | 
			
		||||
  process.argv = ['', '', '--help'];
 | 
			
		||||
 | 
			
		||||
  await cli();
 | 
			
		||||
  const exitCode = await cli();
 | 
			
		||||
 | 
			
		||||
  t.regex(t.context.logs, /Run automated package publishing/);
 | 
			
		||||
  t.is(process.exitCode, 0);
 | 
			
		||||
  t.is(exitCode, 0);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
test.serial('Returns error code and prints help if called with a command', async t => {
 | 
			
		||||
  const run = stub().resolves(true);
 | 
			
		||||
  const cli = proxyquire('../cli', {'.': run});
 | 
			
		||||
  const argv = ['', '', 'pre'];
 | 
			
		||||
  const cli = requireNoCache('../cli', {'.': run, process: {...process, argv}});
 | 
			
		||||
 | 
			
		||||
  process.argv = ['', '', 'pre'];
 | 
			
		||||
 | 
			
		||||
  await cli();
 | 
			
		||||
  const exitCode = await cli();
 | 
			
		||||
 | 
			
		||||
  t.regex(t.context.errors, /Run automated package publishing/);
 | 
			
		||||
  t.regex(t.context.errors, /Too many non-option arguments/);
 | 
			
		||||
  t.is(process.exitCode, 1);
 | 
			
		||||
  t.is(exitCode, 1);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
test.serial('Return error code if multiple plugin are set for single plugin', async t => {
 | 
			
		||||
  const run = stub().resolves(true);
 | 
			
		||||
  const cli = proxyquire('../cli', {'.': run});
 | 
			
		||||
  const argv = ['', '', '--analyze-commits', 'analyze1', 'analyze2'];
 | 
			
		||||
  const cli = requireNoCache('../cli', {'.': run, process: {...process, argv}});
 | 
			
		||||
 | 
			
		||||
  process.argv = ['', '', '--analyze-commits', 'analyze1', 'analyze2'];
 | 
			
		||||
 | 
			
		||||
  await cli();
 | 
			
		||||
  const exitCode = await cli();
 | 
			
		||||
 | 
			
		||||
  t.regex(t.context.errors, /Run automated package publishing/);
 | 
			
		||||
  t.regex(t.context.errors, /Too many non-option arguments/);
 | 
			
		||||
  t.is(process.exitCode, 1);
 | 
			
		||||
  t.is(exitCode, 1);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
test.serial('Return error code if semantic-release throw error', async t => {
 | 
			
		||||
  const run = stub().rejects(new Error('semantic-release error'));
 | 
			
		||||
  const cli = proxyquire('../cli', {'.': run});
 | 
			
		||||
  const argv = ['', ''];
 | 
			
		||||
  const cli = requireNoCache('../cli', {'.': run, process: {...process, argv}});
 | 
			
		||||
 | 
			
		||||
  process.argv = ['', ''];
 | 
			
		||||
 | 
			
		||||
  await cli();
 | 
			
		||||
  const exitCode = await cli();
 | 
			
		||||
 | 
			
		||||
  t.regex(t.context.errors, /semantic-release error/);
 | 
			
		||||
  t.is(process.exitCode, 1);
 | 
			
		||||
  t.is(exitCode, 1);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user