Skip to content

Commit

Permalink
labrc.js can override all cli options (#613)
Browse files Browse the repository at this point in the history
* Support rc overrides for all cli options

* test for more labrc overrides
  • Loading branch information
geek authored Jun 29, 2016
1 parent 1fafc20 commit bbbc2b0
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 51 deletions.
148 changes: 98 additions & 50 deletions lib/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ internals.options = function () {
assert: {
alias: 'a',
type: 'string',
description: 'specify an assertion library module path to require and make available under Lab.assertions'
description: 'specify an assertion library module path to require and make available under Lab.assertions',
default: null
},
colors: {
alias: 'C',
Expand All @@ -154,7 +155,8 @@ internals.options = function () {
'context-timeout': {
alias: 'M',
type: 'number',
description: 'timeout for before, after, beforeEach, afterEach in milliseconds'
description: 'timeout for before, after, beforeEach, afterEach in milliseconds',
default: null
},
coverage: {
alias: 'c',
Expand All @@ -164,12 +166,14 @@ internals.options = function () {
},
'coverage-path': {
type: 'string',
description: 'set code coverage path'
description: 'set code coverage path',
default: null
},
'coverage-exclude': {
type: 'string',
description: 'set code coverage excludes',
multiple: true
multiple: true,
default: null
},
debug: {
alias: 'D',
Expand All @@ -186,7 +190,8 @@ internals.options = function () {
environment: {
alias: 'e',
type: 'string',
description: 'value to set NODE_ENV before tests'
description: 'value to set NODE_ENV before tests',
default: null
},
flat: {
alias: 'f',
Expand All @@ -197,22 +202,26 @@ internals.options = function () {
globals: {
alias: ['I', 'ignore'],
type: 'string',
description: 'ignore a list of globals for the leak detection (comma separated)'
description: 'ignore a list of globals for the leak detection (comma separated)',
default: null
},
grep: {
alias: 'g',
type: 'string',
description: 'only run tests matching the given pattern which is internally compiled to a RegExp'
description: 'only run tests matching the given pattern which is internally compiled to a RegExp',
default: null
},
help: {
alias: 'h',
type: 'boolean',
description: 'display usage options'
description: 'display usage options',
default: null
},
id: {
alias: 'i',
type: 'range',
description: 'test identifier'
description: 'test identifier',
default: null
},
leaks: {
alias: 'l',
Expand All @@ -230,7 +239,7 @@ internals.options = function () {
alias: 'n',
type: 'string',
description: 'linter path to use',
default: 'eslint'
default: null
},
'lint-fix': {
type: 'boolean',
Expand All @@ -239,23 +248,25 @@ internals.options = function () {
},
'lint-options': {
type: 'string',
description: 'specify options to pass to linting program. It must be a string that is JSON.parse(able).'
description: 'specify options to pass to linting program. It must be a string that is JSON.parse(able).',
default: null
},
'lint-errors-threshold': {
type: 'number',
description: 'linter errors threshold in absolute value',
default: 0
default: null
},
'lint-warnings-threshold': {
type: 'number',
description: 'linter warnings threshold in absolute value',
default: 0
default: null
},
output: {
alias: 'o',
type: 'string',
description: 'file path to write test results',
multiple: true
multiple: true,
default: null
},
parallel: {
alias: 'p',
Expand All @@ -266,14 +277,15 @@ internals.options = function () {
pattern: {
alias: 'P',
type: 'string',
description: 'file pattern to use for locating tests'
description: 'file pattern to use for locating tests',
default: null
},
reporter: {
alias: 'r',
type: 'string',
description: 'reporter type [console, html, json, tap, lcov, clover, junit]',
default: 'console',
multiple: true
multiple: true,
default: null
},
shuffle: {
type: 'boolean',
Expand All @@ -283,45 +295,77 @@ internals.options = function () {
silence: {
alias: 's',
type: 'boolean',
description: 'silence test output'
description: 'silence test output',
default: null
},
'silent-skips': {
alias: 'k',
type: 'boolean',
description: 'don’t output skipped tests'
description: 'don’t output skipped tests',
default: null
},
sourcemaps: {
alias: ['S', 'sourcemaps'],
type: 'boolean',
description: 'enable support for sourcemaps'
description: 'enable support for sourcemaps',
default: null
},
threshold: {
alias: 't',
type: 'number',
description: 'code coverage threshold percentage'
description: 'code coverage threshold percentage',
default: null
},
timeout: {
alias: 'm',
type: 'number',
description: 'timeout for each test in milliseconds'
description: 'timeout for each test in milliseconds',
default: null
},
transform: {
alias: ['T', 'transform'],
type: 'string',
description: 'javascript file that exports an array of objects ie. [ { ext: ".js", transform: function (content, filename) { ... } } ]'
description: 'javascript file that exports an array of objects ie. [ { ext: ".js", transform: function (content, filename) { ... } } ]',
default: null
},
verbose: {
alias: 'v',
type: 'boolean',
description: 'verbose test output'
description: 'verbose test output',
default: null
},
version: {
alias: 'V',
type: 'boolean',
description: 'version information'
description: 'version information',
default: null
}
};

const defaults = {
verbose: false,
paths: ['test'],
coverage: false,
debug: true,
dry: false,
environment: 'test',
flat: false,
leaks: true,
lint: false,
linter: 'eslint',
'lint-fix': false,
'lint-errors-threshold': 0,
'lint-warnings-threshold': 0,
parallel: false,
reporter: 'console',
shuffle: false,
silence: false,
'silent-skips': false,
sourcemaps: false,
timeout: 2000,
verbose: false
};

const argv = Bossy.parse(definition);

if (argv instanceof Error) {
Expand All @@ -340,49 +384,55 @@ internals.options = function () {
process.exit(0);
}

const options = {
paths: argv._ ? [].concat(argv._) : ['test']
};
const options = Utils.mergeOptions(defaults, internals.rc);
options.paths = argv._ ? [].concat(argv._) : options.paths;

if (argv.assert) {
options.assert = require(argv.assert);
require('./').assertions = options.assert;
}

const keys = ['coverage', 'coverage-path', 'coverage-exclude', 'colors', 'dry', 'debug', 'environment', 'flat',
'grep', 'globals', 'timeout', 'parallel', 'pattern', 'reporter', 'threshold', 'context-timeout', 'shuffle', 'sourcemaps',
'lint', 'linter', 'transform', 'lint-options', 'lint-fix', 'lint-errors-threshold', 'lint-warnings-threshold', 'silent-skips'];
const keys = ['assert', 'colors', 'context-timeout', 'coverage', 'coverage-exclude',
'coverage-path', 'debug', 'dry', 'environment', 'flat', 'globals', 'grep',
'lint', 'lint-errors-threshold', 'lint-fix', 'lint-options', 'lint-warnings-threshold',
'linter', 'output', 'parallel', 'pattern', 'reporter', 'shuffle', 'silence',
'silent-skips', 'sourcemaps', 'threshold', 'timeout', 'transform', 'verbose'];
for (let i = 0; i < keys.length; ++i) {
if (argv.hasOwnProperty(keys[i]) && argv[keys[i]] !== undefined && argv[keys[i]] !== null) {
options[keys[i]] = argv[keys[i]];
}
}

options.leaks = !argv.leaks;
options.output = argv.output || process.stdout;
if (typeof argv.leaks === 'boolean') {
options.leaks = !argv.leaks;
}

if (argv.id) {
options.ids = argv.id;
}

if (Array.isArray(options.reporter) && argv.output) {
if (!Array.isArray(argv.output) || options.output.length !== options.reporter.length) {
if (Array.isArray(options.reporter) && options.output) {
if (!Array.isArray(options.output) || options.output.length !== options.reporter.length) {
console.error(Bossy.usage(definition, 'lab [options] [path]'));
process.exit(1);
}
}

if (!options.output) {
options.output = process.stdout;
}

if (options.assert) {
options.assert = require(options.assert);
require('./').assertions = options.assert;
}

if (options.globals) {
options.globals = options.globals.trim().split(',');
}

if (argv.silence) {
if (options.silence) {
options.progress = 0;
}
else if (argv.verbose) {
else if (options.verbose) {
options.progress = 2;
}

if (argv.id) {
options.ids = argv.id;
}

options.pattern = options.pattern ? '.*' + options.pattern + '.*?' : '';
if (options.transform) {
const transform = require(Path.resolve(options.transform));
Expand All @@ -398,11 +448,9 @@ internals.options = function () {
options.pattern = new RegExp(options.pattern + '\\.(js)$');
}

const merged = Utils.mergeOptions(internals.rc, options);
merged.coverage = (merged.coverage || merged.threshold > 0 || merged.reporter.indexOf('html') !== -1 || merged.reporter.indexOf('lcov') !== -1 || merged.reporter.indexOf('clover') !== -1);
merged.environment = merged.environment || 'test';
options.coverage = (options.coverage || options.threshold > 0 || options.reporter.indexOf('html') !== -1 || options.reporter.indexOf('lcov') !== -1 || options.reporter.indexOf('clover') !== -1);

return merged;
return options;
};

internals.mapTransform = function (transform) {
Expand Down
2 changes: 2 additions & 0 deletions test/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,10 @@ describe('CLI', () => {
expect(result.errorOutput).to.equal('');
expect(result.code).to.equal(0);
expect(result.output).to.contain('1 tests complete');
expect(result.output).to.contain('sets environment from .labrc.js');
expect(result.output).to.contain('Coverage: 100');
expect(result.output).to.contain('Linting results');
expect(result.output).to.not.contain('No global variable leaks detected');
done();
}, Path.join(__dirname, 'cli_labrc'));
});
Expand Down
4 changes: 3 additions & 1 deletion test/cli_labrc/.labrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@ module.exports = {
coverage: true,
environment: 'labrc',
threshold: 10,
lint: true
lint: true,
leaks: false,
verbose: true
};

0 comments on commit bbbc2b0

Please sign in to comment.