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