diff --git a/docs/index.md b/docs/index.md index b6a70eba7c..df4a942976 100644 --- a/docs/index.md +++ b/docs/index.md @@ -2214,11 +2214,16 @@ If no custom path was given, and if there are multiple configuration files in th 1. `.mocharc.jsonc` 1. `.mocharc.json` +### Environment Variables + +The `MOCHA_OPTIONS` environment variable may be used to specify command line arguments. These arguments take priority over those found in configuration files. + ### Merging Mocha will also _merge_ any options found in `package.json` into its run-time configuration. In case of conflict, the priority is: 1. Arguments specified on command-line +1. Arguments specified in `MOCHA_OPTIONS` environment variable. 1. Configuration file (`.mocharc.js`, `.mocharc.yml`, etc.) 1. `mocha` property of `package.json` diff --git a/lib/cli/options.js b/lib/cli/options.js index 8fa9470e6f..d238737d37 100644 --- a/lib/cli/options.js +++ b/lib/cli/options.js @@ -208,9 +208,10 @@ module.exports.loadPkgRc = loadPkgRc; * Priority list: * * 1. Command-line args - * 2. RC file (`.mocharc.c?js`, `.mocharc.ya?ml`, `mocharc.json`) - * 3. `mocha` prop of `package.json` - * 4. default configuration (`lib/mocharc.json`) + * 2. `MOCHA_OPTIONS` environment variable. + * 3. RC file (`.mocharc.c?js`, `.mocharc.ya?ml`, `mocharc.json`) + * 4. `mocha` prop of `package.json` + * 5. default configuration (`lib/mocharc.json`) * * If a {@link module:lib/cli/one-and-dones.ONE_AND_DONE_ARGS "one-and-done" option} is present in the `argv` array, no external config files will be read. * @summary Parses options read from `.mocharc.*` and `package.json`. @@ -231,6 +232,7 @@ const loadOptions = (argv = []) => { return args; } + const envConfig = parse(process.env.MOCHA_OPTIONS || ''); const rcConfig = loadRc(args); const pkgConfig = loadPkgRc(args); @@ -243,7 +245,14 @@ const loadOptions = (argv = []) => { args._ = args._.concat(pkgConfig._ || []); } - args = parse(args._, mocharc, args, rcConfig || {}, pkgConfig || {}); + args = parse( + args._, + mocharc, + args, + envConfig, + rcConfig || {}, + pkgConfig || {} + ); // recombine positional arguments and "spec" if (args.spec) { diff --git a/test/node-unit/cli/options.spec.js b/test/node-unit/cli/options.spec.js index 0508514cdd..60357d12ae 100644 --- a/test/node-unit/cli/options.spec.js +++ b/test/node-unit/cli/options.spec.js @@ -42,9 +42,10 @@ describe('options', function () { /** * Order of priority: * 1. Command-line args - * 2. RC file (`.mocharc.js`, `.mocharc.ya?ml`, `mocharc.json`) - * 3. `mocha` prop of `package.json` - * 4. default rc + * 2. `MOCHA_OPTIONS` environment variable + * 3. RC file (`.mocharc.js`, `.mocharc.ya?ml`, `mocharc.json`) + * 4. `mocha` prop of `package.json` + * 5. default rc */ describe('loadOptions()', function () { describe('when no parameter provided', function () { @@ -408,6 +409,30 @@ describe('options', function () { }); }); + describe('env options', function () { + it('should parse flags from MOCHA_OPTIONS', function () { + readFileSync = sinon.stub().onFirstCall().returns('{}'); + findConfig = sinon.stub().returns('/some/.mocharc.json'); + loadConfig = sinon.stub().returns({}); + findupSync = sinon.stub().returns('/some/package.json'); + sinon + .stub(process, 'env') + .value({MOCHA_OPTIONS: '--retries 42 --color'}); + + loadOptions = proxyLoadOptions({ + readFileSync, + findConfig, + loadConfig, + findupSync + }); + + expect(loadOptions(), 'to satisfy', { + retries: 42, + color: true + }); + }); + }); + describe('config priority', function () { it('should prioritize package.json over defaults', function () { readFileSync = sinon.stub(); @@ -474,6 +499,27 @@ describe('options', function () { '500' ); }); + + it('should prioritize env over rc file', function () { + readFileSync = sinon.stub(); + readFileSync.onFirstCall().returns('{}'); + readFileSync.onSecondCall().returns(''); + findConfig = sinon.stub().returns('/some/.mocharc.json'); + loadConfig = sinon.stub().returns({retries: 300}); + findupSync = sinon.stub().returns('/some/package.json'); + sinon + .stub(process, 'env') + .value({MOCHA_OPTIONS: '--retries 800 --color'}); + + loadOptions = proxyLoadOptions({ + readFileSync, + findConfig, + loadConfig, + findupSync + }); + + expect(loadOptions(), 'to have property', 'retries', 800); + }); }); describe('when called with a one-and-done arg', function () {