mocha 6.1.4 → 6.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,81 @@
1
+ # 6.2.3 / 2020-03-25
2
+
3
+ ## :lock: Security Fixes
4
+
5
+ - [848d6fb8](https://github.com/mochajs/mocha/commit/848d6fb8feef659564b296db457312d38176910d): Update dependencies mkdirp, yargs-parser and yargs ([**@juergba**](https://github.com/juergba))
6
+
7
+ # 6.2.2 / 2019-10-18
8
+
9
+ ## :bug: Fixes
10
+
11
+ - [#4025](https://github.com/mochajs/mocha/issues/4025): Fix duplicate `EVENT_RUN_END` events upon uncaught exception ([**@juergba**](https://github.com/juergba))
12
+ - [#4051](https://github.com/mochajs/mocha/issues/4051): Fix "unhide" function in `html` reporter (browser) ([**@pec9399**](https://github.com/pec9399))
13
+ - [#4063](https://github.com/mochajs/mocha/issues/4063): Fix use of [esm](https://npm.im/esm) in Node.js v8.x ([**@boneskull**](https://github.com/boneskull))
14
+ - [#4033](https://github.com/mochajs/mocha/issues/4033): Fix output when multiple async exceptions are thrown ([**@juergba**](https://github.com/juergba))
15
+
16
+ ## :book: Documentation
17
+
18
+ - [#4046](https://github.com/mochajs/mocha/issues/4046): Site accessibility fixes ([**@Mia-jeong**](https://github.com/Mia-jeong))
19
+ - [#4026](https://github.com/mochajs/mocha/issues/4026): Update docs for custom reporters in browser ([**@Lindsay-Needs-Sleep**](https://github.com/Lindsay-Needs-Sleep))
20
+ - [#3971](https://github.com/mochajs/mocha/issues/3971): Adopt new OpenJS Foundation Code of Conduct ([**@craigtaub**](https://github.com/craigtaub))
21
+
22
+ # 6.2.1 / 2019-09-29
23
+
24
+ ## :bug: Fixes
25
+
26
+ - [#3955](https://github.com/mochajs/mocha/issues/3955): tty.getWindowSize is not a function inside a "worker_threads" worker ([**@1999**](https://github.com/1999))
27
+ - [#3970](https://github.com/mochajs/mocha/issues/3970): remove extraGlobals() ([**@juergba**](https://github.com/juergba))
28
+ - [#3984](https://github.com/mochajs/mocha/issues/3984): Update yargs-unparser to v1.6.0 ([**@juergba**](https://github.com/juergba))
29
+ - [#3983](https://github.com/mochajs/mocha/issues/3983): Package 'esm': spawn child-process for correct loading ([**@juergba**](https://github.com/juergba))
30
+ - [#3986](https://github.com/mochajs/mocha/issues/3986): Update yargs to v13.3.0 and yargs-parser to v13.1.1 ([**@juergba**](https://github.com/juergba))
31
+
32
+ ## :book: Documentation
33
+
34
+ - [#3886](https://github.com/mochajs/mocha/issues/3886): fix styles on mochajs.org ([**@outsideris**](https://github.com/outsideris))
35
+ - [#3966](https://github.com/mochajs/mocha/issues/3966): Remove jsdoc index.html placeholder from eleventy file structure and fix broken link in jsdoc tutorial ([**@Munter**](https://github.com/Munter))
36
+ - [#3765](https://github.com/mochajs/mocha/issues/3765): Add Matomo to website ([**@MarioDiaz98**](https://github.com/MarioDiaz98))
37
+ - [#3947](https://github.com/mochajs/mocha/issues/3947): Clarify effect of .skip() ([**@oliversalzburg**](https://github.com/oliversalzburg))
38
+
39
+ # 6.2.0 / 2019-07-18
40
+
41
+ ## :tada: Enhancements
42
+
43
+ - [#3827](https://github.com/mochajs/mocha/issues/3827): Do not fork child-process if no Node flags are present ([**@boneskull**](https://github.com/boneskull))
44
+ - [#3725](https://github.com/mochajs/mocha/issues/3725): Base reporter store ref to console.log, see [mocha/wiki](https://github.com/mochajs/mocha/wiki/HOW-TO:-Correctly-stub-stdout) ([**@craigtaub**](https://github.com/craigtaub))
45
+
46
+ ## :bug: Fixes
47
+
48
+ - [#3942](https://github.com/mochajs/mocha/issues/3942): Fix "No test files found" Error when file is passed via `--file` ([**@gabegorelick**](https://github.com/gabegorelick))
49
+ - [#3914](https://github.com/mochajs/mocha/issues/3914): Modify Mocha constructor to accept options `global` or `globals` ([**@pascalpp**](https://github.com/pascalpp))
50
+ - [#3894](https://github.com/mochajs/mocha/issues/3894): Fix parsing of config files with `_mocha` binary ([**@juergba**](https://github.com/juergba))
51
+ - [#3834](https://github.com/mochajs/mocha/issues/3834): Fix CLI parsing with default values ([**@boneskull**](https://github.com/boneskull), [**@juergba**](https://github.com/juergba))
52
+ - [#3831](https://github.com/mochajs/mocha/issues/3831): Fix `--timeout`/`--slow` string values and duplicate arguments ([**@boneskull**](https://github.com/boneskull), [**@juergba**](https://github.com/juergba))
53
+
54
+ ## :book: Documentation
55
+
56
+ - [#3906](https://github.com/mochajs/mocha/issues/3906): Document option to define custom report name for XUnit reporter ([**@pkuczynski**](https://github.com/pkuczynski))
57
+ - [#3889](https://github.com/mochajs/mocha/issues/3889): Adds doc links for mocha-examples ([**@craigtaub**](https://github.com/craigtaub))
58
+ - [#3887](https://github.com/mochajs/mocha/issues/3887): Fix broken links ([**@toyjhlee**](https://github.com/toyjhlee))
59
+ - [#3841](https://github.com/mochajs/mocha/issues/3841): Fix anchors to configuration section ([**@trescube**](https://github.com/trescube))
60
+
61
+ ## :mag: Coverage
62
+
63
+ - [#3915](https://github.com/mochajs/mocha/issues/3915), [#3929](https://github.com/mochajs/mocha/issues/3929): Increase tests coverage for `--watch` options ([**@geigerzaehler**](https://github.com/geigerzaehler))
64
+
65
+ ## :nut_and_bolt: Other
66
+
67
+ - [#3953](https://github.com/mochajs/mocha/issues/3953): Collect test files later, prepares improvements to the `--watch` mode behavior ([**@geigerzaehler**](https://github.com/geigerzaehler))
68
+ - [#3939](https://github.com/mochajs/mocha/issues/3939): Upgrade for npm audit ([**@boneskull**](https://github.com/boneskull))
69
+ - [#3930](https://github.com/mochajs/mocha/issues/3930): Extract `runWatch` into separate module ([**@geigerzaehler**](https://github.com/geigerzaehler))
70
+ - [#3922](https://github.com/mochajs/mocha/issues/3922): Add `mocha.min.js` file to stacktrace filter ([**@brian-lagerman**](https://github.com/brian-lagerman))
71
+ - [#3919](https://github.com/mochajs/mocha/issues/3919): Update CI config files to use Node-12.x ([**@plroebuck**](https://github.com/plroebuck))
72
+ - [#3892](https://github.com/mochajs/mocha/issues/3892): Rework reporter tests ([**@plroebuck**](https://github.com/plroebuck))
73
+ - [#3872](https://github.com/mochajs/mocha/issues/3872): Rename `--exclude` to `--ignore` and create alias ([**@boneskull**](https://github.com/boneskull))
74
+ - [#3963](https://github.com/mochajs/mocha/issues/3963): Hide stacktrace when cli args are missing ([**@outsideris**](https://github.com/outsideris))
75
+ - [#3956](https://github.com/mochajs/mocha/issues/3956): Do not redeclare variable in docs array example ([**@DanielRuf**](https://github.com/DanielRuf))
76
+ - [#3957](https://github.com/mochajs/mocha/issues/3957): Remove duplicate line-height property in `mocha.css` ([**@DanielRuf**](https://github.com/DanielRuf))
77
+ - [#3960](https://github.com/mochajs/mocha/issues/3960): Don't re-initialize grep option on watch re-run ([**@geigerzaehler**](https://github.com/geigerzaehler))
78
+
1
79
  # 6.1.4 / 2019-04-18
2
80
 
3
81
  ## :lock: Security Fixes
package/README.md CHANGED
@@ -58,26 +58,26 @@
58
58
 
59
59
  Does your company use Mocha? Ask your manager or marketing team if your company would be interested in supporting our project. Support will allow the maintainers to dedicate more time for maintenance and new features for everyone. Also, your company's logo will show [on GitHub](https://github.com/mochajs/mocha#readme) and on [our site](https://mochajs.org) - who doesn't want a little extra exposure? [Here's the info](https://opencollective.com/mochajs#sponsor).
60
60
 
61
- [![MochaJS Backer](https://opencollective.com/mochajs/sponsor/0/avatar)](https://opencollective.com/mochajs/sponsor/0/website)
62
- [![MochaJS Backer](https://opencollective.com/mochajs/sponsor/1/avatar)](https://opencollective.com/mochajs/sponsor/1/website)
63
- [![MochaJS Backer](https://opencollective.com/mochajs/sponsor/2/avatar)](https://opencollective.com/mochajs/sponsor/2/website)
64
- [![MochaJS Backer](https://opencollective.com/mochajs/sponsor/3/avatar)](https://opencollective.com/mochajs/sponsor/3/website)
65
- [![MochaJS Backer](https://opencollective.com/mochajs/sponsor/4/avatar)](https://opencollective.com/mochajs/sponsor/4/website)
66
- [![MochaJS Backer](https://opencollective.com/mochajs/sponsor/5/avatar)](https://opencollective.com/mochajs/sponsor/5/website)
67
- [![MochaJS Backer](https://opencollective.com/mochajs/sponsor/6/avatar)](https://opencollective.com/mochajs/sponsor/6/website)
68
- [![MochaJS Backer](https://opencollective.com/mochajs/sponsor/7/avatar)](https://opencollective.com/mochajs/sponsor/7/website)
69
- [![MochaJS Backer](https://opencollective.com/mochajs/sponsor/8/avatar)](https://opencollective.com/mochajs/sponsor/8/website)
70
- [![MochaJS Backer](https://opencollective.com/mochajs/sponsor/9/avatar)](https://opencollective.com/mochajs/sponsor/9/website)
71
- [![MochaJS Backer](https://opencollective.com/mochajs/sponsor/10/avatar)](https://opencollective.com/mochajs/sponsor/10/website)
72
- [![MochaJS Backer](https://opencollective.com/mochajs/sponsor/11/avatar)](https://opencollective.com/mochajs/sponsor/11/website)
73
- [![MochaJS Backer](https://opencollective.com/mochajs/sponsor/12/avatar)](https://opencollective.com/mochajs/sponsor/12/website)
74
- [![MochaJS Backer](https://opencollective.com/mochajs/sponsor/13/avatar)](https://opencollective.com/mochajs/sponsor/13/website)
75
- [![MochaJS Backer](https://opencollective.com/mochajs/sponsor/14/avatar)](https://opencollective.com/mochajs/sponsor/14/website)
76
- [![MochaJS Backer](https://opencollective.com/mochajs/sponsor/15/avatar)](https://opencollective.com/mochajs/sponsor/15/website)
77
- [![MochaJS Backer](https://opencollective.com/mochajs/sponsor/16/avatar)](https://opencollective.com/mochajs/sponsor/16/website)
78
- [![MochaJS Backer](https://opencollective.com/mochajs/sponsor/17/avatar)](https://opencollective.com/mochajs/sponsor/17/website)
79
- [![MochaJS Backer](https://opencollective.com/mochajs/sponsor/18/avatar)](https://opencollective.com/mochajs/sponsor/18/website)
80
- [![MochaJS Backer](https://opencollective.com/mochajs/sponsor/19/avatar)](https://opencollective.com/mochajs/sponsor/19/website)
61
+ [![MochaJS Sponsor](https://opencollective.com/mochajs/sponsor/0/avatar)](https://opencollective.com/mochajs/sponsor/0/website)
62
+ [![MochaJS Sponsor](https://opencollective.com/mochajs/sponsor/1/avatar)](https://opencollective.com/mochajs/sponsor/1/website)
63
+ [![MochaJS Sponsor](https://opencollective.com/mochajs/sponsor/2/avatar)](https://opencollective.com/mochajs/sponsor/2/website)
64
+ [![MochaJS Sponsor](https://opencollective.com/mochajs/sponsor/3/avatar)](https://opencollective.com/mochajs/sponsor/3/website)
65
+ [![MochaJS Sponsor](https://opencollective.com/mochajs/sponsor/4/avatar)](https://opencollective.com/mochajs/sponsor/4/website)
66
+ [![MochaJS Sponsor](https://opencollective.com/mochajs/sponsor/5/avatar)](https://opencollective.com/mochajs/sponsor/5/website)
67
+ [![MochaJS Sponsor](https://opencollective.com/mochajs/sponsor/6/avatar)](https://opencollective.com/mochajs/sponsor/6/website)
68
+ [![MochaJS Sponsor](https://opencollective.com/mochajs/sponsor/7/avatar)](https://opencollective.com/mochajs/sponsor/7/website)
69
+ [![MochaJS Sponsor](https://opencollective.com/mochajs/sponsor/8/avatar)](https://opencollective.com/mochajs/sponsor/8/website)
70
+ [![MochaJS Sponsor](https://opencollective.com/mochajs/sponsor/9/avatar)](https://opencollective.com/mochajs/sponsor/9/website)
71
+ [![MochaJS Sponsor](https://opencollective.com/mochajs/sponsor/10/avatar)](https://opencollective.com/mochajs/sponsor/10/website)
72
+ [![MochaJS Sponsor](https://opencollective.com/mochajs/sponsor/11/avatar)](https://opencollective.com/mochajs/sponsor/11/website)
73
+ [![MochaJS Sponsor](https://opencollective.com/mochajs/sponsor/12/avatar)](https://opencollective.com/mochajs/sponsor/12/website)
74
+ [![MochaJS Sponsor](https://opencollective.com/mochajs/sponsor/13/avatar)](https://opencollective.com/mochajs/sponsor/13/website)
75
+ [![MochaJS Sponsor](https://opencollective.com/mochajs/sponsor/14/avatar)](https://opencollective.com/mochajs/sponsor/14/website)
76
+ [![MochaJS Sponsor](https://opencollective.com/mochajs/sponsor/15/avatar)](https://opencollective.com/mochajs/sponsor/15/website)
77
+ [![MochaJS Sponsor](https://opencollective.com/mochajs/sponsor/16/avatar)](https://opencollective.com/mochajs/sponsor/16/website)
78
+ [![MochaJS Sponsor](https://opencollective.com/mochajs/sponsor/17/avatar)](https://opencollective.com/mochajs/sponsor/17/website)
79
+ [![MochaJS Sponsor](https://opencollective.com/mochajs/sponsor/18/avatar)](https://opencollective.com/mochajs/sponsor/18/website)
80
+ [![MochaJS Sponsor](https://opencollective.com/mochajs/sponsor/19/avatar)](https://opencollective.com/mochajs/sponsor/19/website)
81
81
 
82
82
  ## Development
83
83
 
package/bin/mocha CHANGED
@@ -3,14 +3,14 @@
3
3
  'use strict';
4
4
 
5
5
  /**
6
- * This wrapper executable checks for known node flags and appends them when found, before invoking the "real" _mocha(1) executable.
6
+ * This wrapper executable checks for known node flags and appends them when found,
7
+ * before invoking the "real" executable (`lib/cli/cli.js`)
7
8
  *
8
9
  * @module bin/mocha
9
10
  * @private
10
11
  */
11
12
 
12
13
  const {deprecate, warn} = require('../lib/utils');
13
- const {spawn} = require('child_process');
14
14
  const {loadOptions} = require('../lib/cli/options');
15
15
  const {
16
16
  unparseNodeFlags,
@@ -22,7 +22,6 @@ const debug = require('debug')('mocha:cli:mocha');
22
22
  const {aliases} = require('../lib/cli/run-option-metadata');
23
23
  const nodeEnv = require('node-environment-flags');
24
24
 
25
- const mochaPath = require.resolve('./_mocha');
26
25
  const mochaArgs = {};
27
26
  const nodeArgs = {};
28
27
 
@@ -99,9 +98,7 @@ if (/^(debug|inspect)$/.test(mochaArgs._[0])) {
99
98
  .forEach(opt => {
100
99
  const newOpt = opt === 'debug' ? 'inspect' : 'inspect-brk';
101
100
  warn(
102
- `"--${opt}" is not available in Node.js ${
103
- process.version
104
- }; use "--${newOpt}" instead.`
101
+ `"--${opt}" is not available in Node.js ${process.version}; use "--${newOpt}" instead.`
105
102
  );
106
103
  nodeArgs[newOpt] = nodeArgs[opt];
107
104
  mochaArgs.timeout = false;
@@ -118,32 +115,49 @@ if (nodeArgs.gc) {
118
115
  delete nodeArgs.gc;
119
116
  }
120
117
 
121
- debug('final node args', nodeArgs);
118
+ // --require/-r is treated as Mocha flag except when 'esm' is preloaded
119
+ if (mochaArgs.require && mochaArgs.require.includes('esm')) {
120
+ nodeArgs.require = ['esm'];
121
+ mochaArgs.require = mochaArgs.require.filter(mod => mod !== 'esm');
122
+ if (!mochaArgs.require.length) {
123
+ delete mochaArgs.require;
124
+ }
125
+ delete mochaArgs.r;
126
+ }
122
127
 
123
- const args = [].concat(
124
- unparseNodeFlags(nodeArgs),
125
- mochaPath,
126
- unparse(mochaArgs, {alias: aliases})
127
- );
128
+ if (Object.keys(nodeArgs).length) {
129
+ const {spawn} = require('child_process');
130
+ const mochaPath = require.resolve('../lib/cli/cli.js');
128
131
 
129
- debug(`exec ${process.execPath} w/ args:`, args);
132
+ debug('final node args', nodeArgs);
130
133
 
131
- const proc = spawn(process.execPath, args, {
132
- stdio: 'inherit'
133
- });
134
+ const args = [].concat(
135
+ unparseNodeFlags(nodeArgs),
136
+ mochaPath,
137
+ unparse(mochaArgs, {alias: aliases})
138
+ );
139
+
140
+ debug(`exec ${process.execPath} w/ args:`, args);
134
141
 
135
- proc.on('exit', (code, signal) => {
136
- process.on('exit', () => {
137
- if (signal) {
138
- process.kill(process.pid, signal);
139
- } else {
140
- process.exit(code);
141
- }
142
+ const proc = spawn(process.execPath, args, {
143
+ stdio: 'inherit'
142
144
  });
143
- });
144
145
 
145
- // terminate children.
146
- process.on('SIGINT', () => {
147
- proc.kill('SIGINT'); // calls runner.abort()
148
- proc.kill('SIGTERM'); // if that didn't work, we're probably in an infinite loop, so make it die.
149
- });
146
+ proc.on('exit', (code, signal) => {
147
+ process.on('exit', () => {
148
+ if (signal) {
149
+ process.kill(process.pid, signal);
150
+ } else {
151
+ process.exit(code);
152
+ }
153
+ });
154
+ });
155
+
156
+ // terminate children.
157
+ process.on('SIGINT', () => {
158
+ proc.kill('SIGINT'); // calls runner.abort()
159
+ proc.kill('SIGTERM'); // if that didn't work, we're probably in an infinite loop, so make it die.
160
+ });
161
+ } else {
162
+ require('../lib/cli/cli').main(unparse(mochaArgs, {alias: aliases}));
163
+ }
package/lib/cli/cli.js CHANGED
@@ -1,3 +1,5 @@
1
+ #!/usr/bin/env node
2
+
1
3
  'use strict';
2
4
 
3
5
  /**
@@ -32,6 +34,8 @@ exports.main = (argv = process.argv.slice(2)) => {
32
34
 
33
35
  Error.stackTraceLimit = Infinity; // configurable via --stack-trace-limit?
34
36
 
37
+ var args = loadOptions(argv);
38
+
35
39
  yargs()
36
40
  .scriptName('mocha')
37
41
  .command(commands.run)
@@ -60,7 +64,8 @@ exports.main = (argv = process.argv.slice(2)) => {
60
64
  `
61
65
  )
62
66
  .parserConfiguration(YARGS_PARSER_CONFIG)
63
- .parse(argv, loadOptions(argv));
67
+ .config(args)
68
+ .parse(args._);
64
69
  };
65
70
 
66
71
  // allow direct execution
@@ -0,0 +1,85 @@
1
+ 'use strict';
2
+
3
+ const path = require('path');
4
+ const ansi = require('ansi-colors');
5
+ const debug = require('debug')('mocha:cli:run:helpers');
6
+ const minimatch = require('minimatch');
7
+ const utils = require('../utils');
8
+
9
+ /**
10
+ * Exports a function that collects test files from CLI parameters.
11
+ * @see module:lib/cli/run-helpers
12
+ * @see module:lib/cli/watch-run
13
+ * @module
14
+ * @private
15
+ */
16
+
17
+ /**
18
+ * Smash together an array of test files in the correct order
19
+ * @param {Object} opts - Options
20
+ * @param {string[]} opts.extension - File extensions to use
21
+ * @param {string[]} opts.spec - Files, dirs, globs to run
22
+ * @param {string[]} opts.ignore - Files, dirs, globs to ignore
23
+ * @param {string[]} opts.file - List of additional files to include
24
+ * @param {boolean} opts.recursive - Find files recursively
25
+ * @param {boolean} opts.sort - Sort test files
26
+ * @returns {string[]} List of files to test
27
+ * @private
28
+ */
29
+ module.exports = ({ignore, extension, file, recursive, sort, spec} = {}) => {
30
+ let files = [];
31
+ const unmatched = [];
32
+ spec.forEach(arg => {
33
+ let newFiles;
34
+ try {
35
+ newFiles = utils.lookupFiles(arg, extension, recursive);
36
+ } catch (err) {
37
+ if (err.code === 'ERR_MOCHA_NO_FILES_MATCH_PATTERN') {
38
+ unmatched.push({message: err.message, pattern: err.pattern});
39
+ return;
40
+ }
41
+
42
+ throw err;
43
+ }
44
+
45
+ if (typeof newFiles !== 'undefined') {
46
+ if (typeof newFiles === 'string') {
47
+ newFiles = [newFiles];
48
+ }
49
+ newFiles = newFiles.filter(fileName =>
50
+ ignore.every(pattern => !minimatch(fileName, pattern))
51
+ );
52
+ }
53
+
54
+ files = files.concat(newFiles);
55
+ });
56
+
57
+ const fileArgs = file.map(filepath => path.resolve(filepath));
58
+ files = files.map(filepath => path.resolve(filepath));
59
+
60
+ // ensure we don't sort the stuff from fileArgs; order is important!
61
+ if (sort) {
62
+ files.sort();
63
+ }
64
+
65
+ // add files given through --file to be ran first
66
+ files = fileArgs.concat(files);
67
+ debug('files (in order): ', files);
68
+
69
+ if (!files.length) {
70
+ // give full message details when only 1 file is missing
71
+ const noneFoundMsg =
72
+ unmatched.length === 1
73
+ ? `Error: No test files found: ${JSON.stringify(unmatched[0].pattern)}` // stringify to print escaped characters raw
74
+ : 'Error: No test files found';
75
+ console.error(ansi.red(noneFoundMsg));
76
+ process.exit(1);
77
+ } else {
78
+ // print messages as an warning
79
+ unmatched.forEach(warning => {
80
+ console.warn(ansi.yellow(`Warning: ${warning.message}`));
81
+ });
82
+ }
83
+
84
+ return files;
85
+ };
@@ -68,6 +68,7 @@ exports.impliesNoTimeouts = flag => debugFlags.has(flag);
68
68
  /**
69
69
  * All non-strictly-boolean arguments to node--those with values--must specify those values using `=`, e.g., `--inspect=0.0.0.0`.
70
70
  * Unparse these arguments using `yargs-unparser` (which would result in `--inspect 0.0.0.0`), then supply `=` where we have values.
71
+ * Apparently --require in Node.js v8 does NOT want `=`.
71
72
  * There's probably an easier or more robust way to do this; fixes welcome
72
73
  * @param {Object} opts - Arguments object
73
74
  * @returns {string[]} Unparsed arguments using `=` to specify values
@@ -79,7 +80,9 @@ exports.unparseNodeFlags = opts => {
79
80
  ? args
80
81
  .join(' ')
81
82
  .split(/\b/)
82
- .map(arg => (arg === ' ' ? '=' : arg))
83
+ .map((arg, index, args) =>
84
+ arg === ' ' && args[index - 1] !== 'require' ? '=' : arg
85
+ )
83
86
  .join('')
84
87
  .split(' ')
85
88
  : [];
@@ -7,6 +7,7 @@
7
7
  */
8
8
 
9
9
  const fs = require('fs');
10
+ const ansi = require('ansi-colors');
10
11
  const yargsParser = require('yargs-parser');
11
12
  const {types, aliases} = require('./run-option-metadata');
12
13
  const {ONE_AND_DONE_ARGS} = require('./one-and-dones');
@@ -16,7 +17,6 @@ const {loadConfig, findConfig} = require('./config');
16
17
  const findUp = require('find-up');
17
18
  const {deprecate} = require('../utils');
18
19
  const debug = require('debug')('mocha:cli:options');
19
- const {createMissingArgumentError} = require('../errors');
20
20
  const {isNodeFlag} = require('./node-flags');
21
21
 
22
22
  /**
@@ -54,15 +54,26 @@ const configuration = Object.assign({}, YARGS_PARSER_CONFIG, {
54
54
  });
55
55
 
56
56
  /**
57
- * This is a really fancy way to ensure unique values for `array`-type
58
- * options.
57
+ * This is a really fancy way to:
58
+ * - ensure unique values for `array`-type options
59
+ * - use its array's last element for `boolean`/`number`/`string`- options given multiple times
59
60
  * This is passed as the `coerce` option to `yargs-parser`
60
61
  * @private
61
62
  * @ignore
62
63
  */
63
- const coerceOpts = types.array.reduce(
64
- (acc, arg) => Object.assign(acc, {[arg]: v => Array.from(new Set(list(v)))}),
65
- {}
64
+ const coerceOpts = Object.assign(
65
+ types.array.reduce(
66
+ (acc, arg) =>
67
+ Object.assign(acc, {[arg]: v => Array.from(new Set(list(v)))}),
68
+ {}
69
+ ),
70
+ types.boolean
71
+ .concat(types.string, types.number)
72
+ .reduce(
73
+ (acc, arg) =>
74
+ Object.assign(acc, {[arg]: v => (Array.isArray(v) ? v.pop() : v)}),
75
+ {}
76
+ )
66
77
  );
67
78
 
68
79
  /**
@@ -80,11 +91,12 @@ const nargOpts = types.array
80
91
  /**
81
92
  * Wrapper around `yargs-parser` which applies our settings
82
93
  * @param {string|string[]} args - Arguments to parse
94
+ * @param {Object} defaultValues - Default values of mocharc.json
83
95
  * @param {...Object} configObjects - `configObjects` for yargs-parser
84
96
  * @private
85
97
  * @ignore
86
98
  */
87
- const parse = (args = [], ...configObjects) => {
99
+ const parse = (args = [], defaultValues = {}, ...configObjects) => {
88
100
  // save node-specific args for special handling.
89
101
  // 1. when these args have a "=" they should be considered to have values
90
102
  // 2. if they don't, they just boolean flags
@@ -109,6 +121,7 @@ const parse = (args = [], ...configObjects) => {
109
121
  const result = yargsParser.detailed(args, {
110
122
  configuration,
111
123
  configObjects,
124
+ default: defaultValues,
112
125
  coerce: coerceOpts,
113
126
  narg: nargOpts,
114
127
  alias: aliases,
@@ -118,7 +131,8 @@ const parse = (args = [], ...configObjects) => {
118
131
  boolean: types.boolean.concat(nodeArgs.map(pair => pair[0]))
119
132
  });
120
133
  if (result.error) {
121
- throw createMissingArgumentError(result.error.message);
134
+ console.error(ansi.red(`Error: ${result.error.message}`));
135
+ process.exit(1);
122
136
  }
123
137
 
124
138
  // reapply "=" arg values from above
@@ -189,6 +203,7 @@ module.exports = function getOptions() {
189
203
  * @param {string|boolean} [args.opts] - Filepath to mocha.opts; defaults to whatever's in `mocharc.opts`, or `false` to skip
190
204
  * @returns {external:yargsParser.Arguments|void} If read, object containing parsed arguments
191
205
  * @memberof module:lib/cli/options
206
+ * @see {@link /#mochaopts|mocha.opts}
192
207
  * @public
193
208
  */
194
209
  const loadMochaOpts = (args = {}) => {
@@ -324,11 +339,11 @@ const loadOptions = (argv = []) => {
324
339
 
325
340
  args = parse(
326
341
  args._,
342
+ mocharc,
327
343
  args,
328
344
  rcConfig || {},
329
345
  pkgConfig || {},
330
- optsConfig || {},
331
- mocharc
346
+ optsConfig || {}
332
347
  );
333
348
 
334
349
  // recombine positional arguments and "spec"