mocha 7.0.1 → 7.2.0
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 +86 -2
- package/bin/mocha +7 -2
- package/browser-entry.js +13 -2
- package/lib/cli/cli.js +4 -1
- package/lib/cli/collect-files.js +2 -1
- package/lib/cli/config.js +8 -6
- package/lib/cli/options.js +4 -4
- package/lib/cli/run-helpers.js +93 -33
- package/lib/cli/run.js +23 -5
- package/lib/errors.js +179 -9
- package/lib/esm-utils.js +31 -0
- package/lib/hook.js +8 -0
- package/lib/interfaces/common.js +6 -3
- package/lib/mocha.js +226 -16
- package/lib/mocharc.json +1 -1
- package/lib/reporters/doc.js +6 -0
- package/lib/reporters/json-stream.js +1 -0
- package/lib/reporters/json.js +1 -0
- package/lib/reporters/landing.js +8 -0
- package/lib/runnable.js +21 -42
- package/lib/runner.js +173 -63
- package/lib/suite.js +29 -3
- package/lib/test.js +33 -2
- package/lib/utils.js +36 -35
- package/mocha.js +749 -185
- package/package.json +56 -549
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,87 @@
|
|
|
1
|
+
# 7.2.0 / 2020-05-22
|
|
2
|
+
|
|
3
|
+
## :tada: Enhancements
|
|
4
|
+
|
|
5
|
+
- [#4234](https://github.com/mochajs/mocha/issues/4234): Add ability to run tests in a mocha instance multiple times ([**@nicojs**](https://github.com/nicojs))
|
|
6
|
+
- [#4219](https://github.com/mochajs/mocha/issues/4219): Exposing filename in JSON, doc, and json-stream reporters ([**@Daniel0113**](https://github.com/Daniel0113))
|
|
7
|
+
- [#4244](https://github.com/mochajs/mocha/issues/4244): Add Root Hook Plugins ([**@boneskull**](https://github.com/boneskull))
|
|
8
|
+
|
|
9
|
+
## :bug: Fixes
|
|
10
|
+
|
|
11
|
+
- [#4258](https://github.com/mochajs/mocha/issues/4258): Fix missing dot in name of configuration file ([**@sonicdoe**](https://github.com/sonicdoe))
|
|
12
|
+
- [#4194](https://github.com/mochajs/mocha/issues/4194): Check if module.paths really exists ([**@ematipico**](https://github.com/ematipico))
|
|
13
|
+
- [#4256](https://github.com/mochajs/mocha/issues/4256): `--forbid-only` does not recognize `it.only` when `before` crashes ([**@arvidOtt**](https://github.com/arvidOtt))
|
|
14
|
+
- [#4152](https://github.com/mochajs/mocha/issues/4152): Bug with multiple async done() calls ([**@boneskull**](https://github.com/boneskull))
|
|
15
|
+
- [#4275](https://github.com/mochajs/mocha/issues/4275): Improper warnings for invalid reporters ([**@boneskull**](https://github.com/boneskull))
|
|
16
|
+
- [#4288](https://github.com/mochajs/mocha/issues/4288): Broken hook.spec.js test for IE11 ([**@boneskull**](https://github.com/boneskull))
|
|
17
|
+
|
|
18
|
+
## :book: Documentation
|
|
19
|
+
|
|
20
|
+
- [#4081](https://github.com/mochajs/mocha/issues/4081): Insufficient white space for API docs in view on mobile ([**@HyunSangHan**](https://github.com/HyunSangHan))
|
|
21
|
+
- [#4255](https://github.com/mochajs/mocha/issues/4255): Update mocha-docdash for UI fixes on API docs ([**@craigtaub**](https://github.com/craigtaub))
|
|
22
|
+
- [#4235](https://github.com/mochajs/mocha/issues/4235): Enable emoji on website; enable normal ul elements ([**@boneskull**](https://github.com/boneskull))
|
|
23
|
+
- [#4272](https://github.com/mochajs/mocha/issues/4272): Fetch sponsors at build time, show ALL non-skeevy sponsors ([**@boneskull**](https://github.com/boneskull))
|
|
24
|
+
|
|
25
|
+
## :nut_and_bolt: Other
|
|
26
|
+
|
|
27
|
+
- [#4249](https://github.com/mochajs/mocha/issues/4249): Refactoring improving encapsulation ([**@arvidOtt**](https://github.com/arvidOtt))
|
|
28
|
+
- [#4242](https://github.com/mochajs/mocha/issues/4242): CI add job names, add Node.js v14 to matrix ([**@boneskull**](https://github.com/boneskull))
|
|
29
|
+
- [#4237](https://github.com/mochajs/mocha/issues/4237): Refactor validatePlugins to throw coded errors ([**@boneskull**](https://github.com/boneskull))
|
|
30
|
+
- [#4236](https://github.com/mochajs/mocha/issues/4236): Better debug output ([**@boneskull**](https://github.com/boneskull))
|
|
31
|
+
|
|
32
|
+
# 7.1.2 / 2020-04-26
|
|
33
|
+
|
|
34
|
+
## :nut_and_bolt: Other
|
|
35
|
+
|
|
36
|
+
- [#4251](https://github.com/mochajs/mocha/issues/4251): Prevent karma-mocha from stalling ([**@juergba**](https://github.com/juergba))
|
|
37
|
+
- [#4222](https://github.com/mochajs/mocha/issues/4222): Update dependency mkdirp to v0.5.5 ([**@outsideris**](https://github.com/outsideris))
|
|
38
|
+
|
|
39
|
+
## :book: Documentation
|
|
40
|
+
|
|
41
|
+
- [#4208](https://github.com/mochajs/mocha/issues/4208): Add Wallaby logo to site ([**@boneskull**](https://github.com/boneskull))
|
|
42
|
+
|
|
43
|
+
# 7.1.1 / 2020-03-18
|
|
44
|
+
|
|
45
|
+
## :lock: Security Fixes
|
|
46
|
+
|
|
47
|
+
- [#4204](https://github.com/mochajs/mocha/issues/4204): Update dependencies mkdirp, yargs-parser and yargs ([**@juergba**](https://github.com/juergba))
|
|
48
|
+
|
|
49
|
+
## :bug: Fixes
|
|
50
|
+
|
|
51
|
+
- [#3660](https://github.com/mochajs/mocha/issues/3660): Fix `runner` listening to `start` and `end` events ([**@juergba**](https://github.com/juergba))
|
|
52
|
+
|
|
53
|
+
## :book: Documentation
|
|
54
|
+
|
|
55
|
+
- [#4190](https://github.com/mochajs/mocha/issues/4190): Show Netlify badge on footer ([**@outsideris**](https://github.com/outsideris))
|
|
56
|
+
|
|
57
|
+
# 7.1.0 / 2020-02-26
|
|
58
|
+
|
|
59
|
+
## :tada: Enhancements
|
|
60
|
+
|
|
61
|
+
[#4038](https://github.com/mochajs/mocha/issues/4038): Add Node.js native ESM support ([**@giltayar**](https://github.com/giltayar))
|
|
62
|
+
|
|
63
|
+
Mocha supports writing your test files as ES modules:
|
|
64
|
+
|
|
65
|
+
- Node.js only v12.11.0 and above
|
|
66
|
+
- Node.js below v13.2.0, you must set `--experimental-modules` option
|
|
67
|
+
- current limitations: please check our [documentation](https://mochajs.org/#nodejs-native-esm-support)
|
|
68
|
+
- for programmatic usage: see [API: loadFilesAsync()](https://mochajs.org/api/mocha#loadFilesAsync)
|
|
69
|
+
|
|
70
|
+
**Note:** Node.JS native [ECMAScript Modules](https://nodejs.org/api/esm.html) implementation has status: **Stability: 1 - Experimental**
|
|
71
|
+
|
|
72
|
+
## :bug: Fixes
|
|
73
|
+
|
|
74
|
+
- [#4181](https://github.com/mochajs/mocha/issues/4181): Programmatic API cannot access retried test objects ([**@juergba**](https://github.com/juergba))
|
|
75
|
+
- [#4174](https://github.com/mochajs/mocha/issues/4174): Browser: fix `allowUncaught` option ([**@juergba**](https://github.com/juergba))
|
|
76
|
+
|
|
77
|
+
## :book: Documentation
|
|
78
|
+
|
|
79
|
+
- [#4058](https://github.com/mochajs/mocha/issues/4058): Manage author list in AUTHORS instead of `package.json` ([**@outsideris**](https://github.com/outsideris))
|
|
80
|
+
|
|
81
|
+
## :nut_and_bolt: Other
|
|
82
|
+
|
|
83
|
+
- [#4138](https://github.com/mochajs/mocha/issues/4138): Upgrade ESLint v6.8 ([**@kaicataldo**](https://github.com/kaicataldo))
|
|
84
|
+
|
|
1
85
|
# 7.0.1 / 2020-01-25
|
|
2
86
|
|
|
3
87
|
## :bug: Fixes
|
|
@@ -493,7 +577,7 @@ This release fixes a class of tests which report as _false positives_. **Certain
|
|
|
493
577
|
|
|
494
578
|
- [#3226](https://github.com/mochajs/mocha/issues/3226): Do not swallow errors that are thrown asynchronously from passing tests ([@boneskull](https://github.com/boneskull)). Example:
|
|
495
579
|
|
|
496
|
-
|
|
580
|
+
\`\`\`js
|
|
497
581
|
it('should actually fail, sorry!', function (done) {
|
|
498
582
|
// passing assertion
|
|
499
583
|
assert(true === true);
|
|
@@ -506,7 +590,7 @@ This release fixes a class of tests which report as _false positives_. **Certain
|
|
|
506
590
|
throw new Error('chaos!');
|
|
507
591
|
}, 100);
|
|
508
592
|
});
|
|
509
|
-
|
|
593
|
+
\`\`\`
|
|
510
594
|
|
|
511
595
|
Previously to this version, Mocha would have _silently swallowed_ the `chaos!` exception, and you wouldn't know. Well, _now you know_. Mocha cannot recover from this gracefully, so it will exit with a nonzero code.
|
|
512
596
|
|
package/bin/mocha
CHANGED
|
@@ -34,7 +34,7 @@ debug('loaded opts', opts);
|
|
|
34
34
|
*/
|
|
35
35
|
const disableTimeouts = value => {
|
|
36
36
|
if (impliesNoTimeouts(value)) {
|
|
37
|
-
debug(
|
|
37
|
+
debug('option %s disabled timeouts', value);
|
|
38
38
|
mochaArgs.timeout = 0;
|
|
39
39
|
delete mochaArgs.timeouts;
|
|
40
40
|
delete mochaArgs.t;
|
|
@@ -108,7 +108,11 @@ if (Object.keys(nodeArgs).length) {
|
|
|
108
108
|
unparse(mochaArgs, {alias: aliases})
|
|
109
109
|
);
|
|
110
110
|
|
|
111
|
-
debug(
|
|
111
|
+
debug(
|
|
112
|
+
'forking child process via command: %s %s',
|
|
113
|
+
process.execPath,
|
|
114
|
+
args.join(' ')
|
|
115
|
+
);
|
|
112
116
|
|
|
113
117
|
const proc = spawn(process.execPath, args, {
|
|
114
118
|
stdio: 'inherit'
|
|
@@ -130,5 +134,6 @@ if (Object.keys(nodeArgs).length) {
|
|
|
130
134
|
proc.kill('SIGTERM'); // if that didn't work, we're probably in an infinite loop, so make it die.
|
|
131
135
|
});
|
|
132
136
|
} else {
|
|
137
|
+
debug('running Mocha in-process');
|
|
133
138
|
require('../lib/cli/cli').main(unparse(mochaArgs, {alias: aliases}));
|
|
134
139
|
}
|
package/browser-entry.js
CHANGED
|
@@ -52,6 +52,17 @@ process.removeListener = function(e, fn) {
|
|
|
52
52
|
}
|
|
53
53
|
};
|
|
54
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Implements listenerCount for 'uncaughtException'.
|
|
57
|
+
*/
|
|
58
|
+
|
|
59
|
+
process.listenerCount = function(name) {
|
|
60
|
+
if (name === 'uncaughtException') {
|
|
61
|
+
return uncaughtExceptionHandlers.length;
|
|
62
|
+
}
|
|
63
|
+
return 0;
|
|
64
|
+
};
|
|
65
|
+
|
|
55
66
|
/**
|
|
56
67
|
* Implements uncaughtException listener.
|
|
57
68
|
*/
|
|
@@ -60,7 +71,7 @@ process.on = function(e, fn) {
|
|
|
60
71
|
if (e === 'uncaughtException') {
|
|
61
72
|
global.onerror = function(err, url, line) {
|
|
62
73
|
fn(new Error(err + ' (' + url + ':' + line + ')'));
|
|
63
|
-
return !mocha.allowUncaught;
|
|
74
|
+
return !mocha.options.allowUncaught;
|
|
64
75
|
};
|
|
65
76
|
uncaughtExceptionHandlers.push(fn);
|
|
66
77
|
}
|
|
@@ -129,7 +140,7 @@ mocha.setup = function(opts) {
|
|
|
129
140
|
opts = {ui: opts};
|
|
130
141
|
}
|
|
131
142
|
for (var opt in opts) {
|
|
132
|
-
if (
|
|
143
|
+
if (Object.prototype.hasOwnProperty.call(opts, opt)) {
|
|
133
144
|
this[opt](opts[opt]);
|
|
134
145
|
}
|
|
135
146
|
}
|
package/lib/cli/cli.js
CHANGED
|
@@ -19,6 +19,7 @@ const {loadOptions, YARGS_PARSER_CONFIG} = require('./options');
|
|
|
19
19
|
const commands = require('./commands');
|
|
20
20
|
const ansi = require('ansi-colors');
|
|
21
21
|
const {repository, homepage, version, gitter} = require('../../package.json');
|
|
22
|
+
const {cwd} = require('../utils');
|
|
22
23
|
|
|
23
24
|
/**
|
|
24
25
|
* - Accepts an `Array` of arguments
|
|
@@ -30,7 +31,9 @@ const {repository, homepage, version, gitter} = require('../../package.json');
|
|
|
30
31
|
exports.main = (argv = process.argv.slice(2)) => {
|
|
31
32
|
debug('entered main with raw args', argv);
|
|
32
33
|
// ensure we can require() from current working directory
|
|
33
|
-
module.paths
|
|
34
|
+
if (typeof module.paths !== 'undefined') {
|
|
35
|
+
module.paths.push(cwd(), path.resolve('node_modules'));
|
|
36
|
+
}
|
|
34
37
|
|
|
35
38
|
Error.stackTraceLimit = Infinity; // configurable via --stack-trace-limit?
|
|
36
39
|
|
package/lib/cli/collect-files.js
CHANGED
|
@@ -5,6 +5,7 @@ const ansi = require('ansi-colors');
|
|
|
5
5
|
const debug = require('debug')('mocha:cli:run:helpers');
|
|
6
6
|
const minimatch = require('minimatch');
|
|
7
7
|
const utils = require('../utils');
|
|
8
|
+
const {NO_FILES_MATCH_PATTERN} = require('../errors').constants;
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Exports a function that collects test files from CLI parameters.
|
|
@@ -34,7 +35,7 @@ module.exports = ({ignore, extension, file, recursive, sort, spec} = {}) => {
|
|
|
34
35
|
try {
|
|
35
36
|
newFiles = utils.lookupFiles(arg, extension, recursive);
|
|
36
37
|
} catch (err) {
|
|
37
|
-
if (err.code ===
|
|
38
|
+
if (err.code === NO_FILES_MATCH_PATTERN) {
|
|
38
39
|
unmatched.push({message: err.message, pattern: err.pattern});
|
|
39
40
|
return;
|
|
40
41
|
}
|
package/lib/cli/config.js
CHANGED
|
@@ -12,6 +12,7 @@ const fs = require('fs');
|
|
|
12
12
|
const path = require('path');
|
|
13
13
|
const debug = require('debug')('mocha:cli:config');
|
|
14
14
|
const findUp = require('find-up');
|
|
15
|
+
const utils = require('../utils');
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* These are the valid config files, in order of precedence;
|
|
@@ -21,6 +22,7 @@ const findUp = require('find-up');
|
|
|
21
22
|
* @private
|
|
22
23
|
*/
|
|
23
24
|
exports.CONFIG_FILES = [
|
|
25
|
+
'.mocharc.cjs',
|
|
24
26
|
'.mocharc.js',
|
|
25
27
|
'.mocharc.yaml',
|
|
26
28
|
'.mocharc.yml',
|
|
@@ -42,11 +44,11 @@ const parsers = (exports.parsers = {
|
|
|
42
44
|
js: filepath => {
|
|
43
45
|
const cwdFilepath = path.resolve(filepath);
|
|
44
46
|
try {
|
|
45
|
-
debug(
|
|
47
|
+
debug('parsers: load using cwd-relative path: "%s"', cwdFilepath);
|
|
46
48
|
return require(cwdFilepath);
|
|
47
49
|
} catch (err) {
|
|
48
50
|
if (isModuleNotFoundError(err)) {
|
|
49
|
-
debug(
|
|
51
|
+
debug('parsers: retry load as module-relative path: "%s"', filepath);
|
|
50
52
|
return require(filepath);
|
|
51
53
|
} else {
|
|
52
54
|
throw err; // rethrow
|
|
@@ -69,13 +71,13 @@ const parsers = (exports.parsers = {
|
|
|
69
71
|
*/
|
|
70
72
|
exports.loadConfig = filepath => {
|
|
71
73
|
let config = {};
|
|
72
|
-
debug(
|
|
74
|
+
debug('loadConfig: trying to parse config at %s', filepath);
|
|
73
75
|
|
|
74
76
|
const ext = path.extname(filepath);
|
|
75
77
|
try {
|
|
76
78
|
if (ext === '.yml' || ext === '.yaml') {
|
|
77
79
|
config = parsers.yaml(filepath);
|
|
78
|
-
} else if (ext === '.js') {
|
|
80
|
+
} else if (ext === '.js' || ext === '.cjs') {
|
|
79
81
|
config = parsers.js(filepath);
|
|
80
82
|
} else {
|
|
81
83
|
config = parsers.json(filepath);
|
|
@@ -92,10 +94,10 @@ exports.loadConfig = filepath => {
|
|
|
92
94
|
* @param {string} [cwd] - Current working directory
|
|
93
95
|
* @returns {string|null} Filepath to config, if found
|
|
94
96
|
*/
|
|
95
|
-
exports.findConfig = (cwd =
|
|
97
|
+
exports.findConfig = (cwd = utils.cwd()) => {
|
|
96
98
|
const filepath = findUp.sync(exports.CONFIG_FILES, {cwd});
|
|
97
99
|
if (filepath) {
|
|
98
|
-
debug(
|
|
100
|
+
debug('findConfig: found config file %s', filepath);
|
|
99
101
|
}
|
|
100
102
|
return filepath;
|
|
101
103
|
};
|
package/lib/cli/options.js
CHANGED
|
@@ -244,16 +244,16 @@ const loadPkgRc = (args = {}) => {
|
|
|
244
244
|
try {
|
|
245
245
|
const pkg = JSON.parse(fs.readFileSync(filepath, 'utf8'));
|
|
246
246
|
if (pkg.mocha) {
|
|
247
|
-
debug(`
|
|
247
|
+
debug('`mocha` prop of package.json parsed: %O', pkg.mocha);
|
|
248
248
|
result = pkg.mocha;
|
|
249
249
|
} else {
|
|
250
|
-
debug(
|
|
250
|
+
debug('no config found in %s', filepath);
|
|
251
251
|
}
|
|
252
252
|
} catch (err) {
|
|
253
253
|
if (args.package) {
|
|
254
254
|
throw new Error(`Unable to read/parse ${filepath}: ${err}`);
|
|
255
255
|
}
|
|
256
|
-
debug(
|
|
256
|
+
debug('failed to read default package.json at %s; ignoring', filepath);
|
|
257
257
|
}
|
|
258
258
|
}
|
|
259
259
|
return result;
|
|
@@ -265,7 +265,7 @@ module.exports.loadPkgRc = loadPkgRc;
|
|
|
265
265
|
* Priority list:
|
|
266
266
|
*
|
|
267
267
|
* 1. Command-line args
|
|
268
|
-
* 2. RC file (`.mocharc.js`, `.mocharc.ya?ml`, `mocharc.json`)
|
|
268
|
+
* 2. RC file (`.mocharc.c?js`, `.mocharc.ya?ml`, `mocharc.json`)
|
|
269
269
|
* 3. `mocha` prop of `package.json`
|
|
270
270
|
* 4. `mocha.opts`
|
|
271
271
|
* 5. default configuration (`lib/mocharc.json`)
|
package/lib/cli/run-helpers.js
CHANGED
|
@@ -12,10 +12,9 @@ const path = require('path');
|
|
|
12
12
|
const debug = require('debug')('mocha:cli:run:helpers');
|
|
13
13
|
const watchRun = require('./watch-run');
|
|
14
14
|
const collectFiles = require('./collect-files');
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
exports.watchRun = watchRun;
|
|
15
|
+
const {type} = require('../utils');
|
|
16
|
+
const {format} = require('util');
|
|
17
|
+
const {createInvalidPluginError, createUnsupportedError} = require('../errors');
|
|
19
18
|
|
|
20
19
|
/**
|
|
21
20
|
* Exits Mocha when tests + code under test has finished execution (default)
|
|
@@ -75,36 +74,79 @@ exports.list = str =>
|
|
|
75
74
|
Array.isArray(str) ? exports.list(str.join(',')) : str.split(/ *, */);
|
|
76
75
|
|
|
77
76
|
/**
|
|
78
|
-
* `require()` the modules as required by `--require <require
|
|
77
|
+
* `require()` the modules as required by `--require <require>`.
|
|
78
|
+
*
|
|
79
|
+
* Returns array of `mochaHooks` exports, if any.
|
|
79
80
|
* @param {string[]} requires - Modules to require
|
|
81
|
+
* @returns {Promise<MochaRootHookObject|MochaRootHookFunction>} Any root hooks
|
|
80
82
|
* @private
|
|
81
83
|
*/
|
|
82
|
-
exports.handleRequires = (requires = []) =>
|
|
83
|
-
requires.
|
|
84
|
+
exports.handleRequires = async (requires = []) =>
|
|
85
|
+
requires.reduce((acc, mod) => {
|
|
84
86
|
let modpath = mod;
|
|
85
|
-
|
|
87
|
+
// this is relative to cwd
|
|
88
|
+
if (fs.existsSync(mod) || fs.existsSync(`${mod}.js`)) {
|
|
86
89
|
modpath = path.resolve(mod);
|
|
87
|
-
debug(
|
|
90
|
+
debug('resolved required file %s to %s', mod, modpath);
|
|
88
91
|
}
|
|
89
|
-
require(modpath);
|
|
90
|
-
|
|
91
|
-
|
|
92
|
+
const requiredModule = require(modpath);
|
|
93
|
+
if (type(requiredModule) === 'object' && requiredModule.mochaHooks) {
|
|
94
|
+
const mochaHooksType = type(requiredModule.mochaHooks);
|
|
95
|
+
if (/function$/.test(mochaHooksType) || mochaHooksType === 'object') {
|
|
96
|
+
debug('found root hooks in required file %s', mod);
|
|
97
|
+
acc.push(requiredModule.mochaHooks);
|
|
98
|
+
} else {
|
|
99
|
+
throw createUnsupportedError(
|
|
100
|
+
'mochaHooks must be an object or a function returning (or fulfilling with) an object'
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
debug('loaded required module "%s"', mod);
|
|
105
|
+
return acc;
|
|
106
|
+
}, []);
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Loads root hooks as exported via `mochaHooks` from required files.
|
|
110
|
+
* These can be sync/async functions returning objects, or just objects.
|
|
111
|
+
* Flattens to a single object.
|
|
112
|
+
* @param {Array<MochaRootHookObject|MochaRootHookFunction>} rootHooks - Array of root hooks
|
|
113
|
+
* @private
|
|
114
|
+
* @returns {MochaRootHookObject}
|
|
115
|
+
*/
|
|
116
|
+
exports.loadRootHooks = async rootHooks => {
|
|
117
|
+
const rootHookObjects = await Promise.all(
|
|
118
|
+
rootHooks.map(async hook => (/function$/.test(type(hook)) ? hook() : hook))
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
return rootHookObjects.reduce(
|
|
122
|
+
(acc, hook) => {
|
|
123
|
+
acc.beforeAll = acc.beforeAll.concat(hook.beforeAll || []);
|
|
124
|
+
acc.beforeEach = acc.beforeEach.concat(hook.beforeEach || []);
|
|
125
|
+
acc.afterAll = acc.afterAll.concat(hook.afterAll || []);
|
|
126
|
+
acc.afterEach = acc.afterEach.concat(hook.afterEach || []);
|
|
127
|
+
return acc;
|
|
128
|
+
},
|
|
129
|
+
{beforeAll: [], beforeEach: [], afterAll: [], afterEach: []}
|
|
130
|
+
);
|
|
92
131
|
};
|
|
93
132
|
|
|
94
133
|
/**
|
|
95
|
-
* Collect test files
|
|
134
|
+
* Collect and load test files, then run mocha instance.
|
|
96
135
|
* @param {Mocha} mocha - Mocha instance
|
|
97
136
|
* @param {Options} [opts] - Command line options
|
|
98
137
|
* @param {boolean} [opts.exit] - Whether or not to force-exit after tests are complete
|
|
99
138
|
* @param {Object} fileCollectParams - Parameters that control test
|
|
100
139
|
* file collection. See `lib/cli/collect-files.js`.
|
|
101
|
-
* @returns {Runner}
|
|
140
|
+
* @returns {Promise<Runner>}
|
|
102
141
|
* @private
|
|
103
142
|
*/
|
|
104
|
-
|
|
143
|
+
const singleRun = async (mocha, {exit}, fileCollectParams) => {
|
|
105
144
|
const files = collectFiles(fileCollectParams);
|
|
106
|
-
debug('
|
|
145
|
+
debug('single run with %d file(s)', files.length);
|
|
107
146
|
mocha.files = files;
|
|
147
|
+
|
|
148
|
+
// handles ESM modules
|
|
149
|
+
await mocha.loadFilesAsync();
|
|
108
150
|
return mocha.run(exit ? exitMocha : exitMochaLater);
|
|
109
151
|
};
|
|
110
152
|
|
|
@@ -113,8 +155,9 @@ exports.singleRun = (mocha, {exit}, fileCollectParams) => {
|
|
|
113
155
|
* @param {Mocha} mocha - Mocha instance
|
|
114
156
|
* @param {Object} opts - Command line options
|
|
115
157
|
* @private
|
|
158
|
+
* @returns {Promise}
|
|
116
159
|
*/
|
|
117
|
-
exports.runMocha = (mocha, options) => {
|
|
160
|
+
exports.runMocha = async (mocha, options) => {
|
|
118
161
|
const {
|
|
119
162
|
watch = false,
|
|
120
163
|
extension = [],
|
|
@@ -140,40 +183,57 @@ exports.runMocha = (mocha, options) => {
|
|
|
140
183
|
if (watch) {
|
|
141
184
|
watchRun(mocha, {watchFiles, watchIgnore}, fileCollectParams);
|
|
142
185
|
} else {
|
|
143
|
-
|
|
186
|
+
await singleRun(mocha, {exit}, fileCollectParams);
|
|
144
187
|
}
|
|
145
188
|
};
|
|
146
189
|
|
|
147
190
|
/**
|
|
148
|
-
* Used for `--reporter` and `--ui`. Ensures there's only one, and asserts
|
|
149
|
-
*
|
|
150
|
-
* @
|
|
151
|
-
* interfaces from loading.
|
|
191
|
+
* Used for `--reporter` and `--ui`. Ensures there's only one, and asserts that
|
|
192
|
+
* it actually exists. This must be run _after_ requires are processed (see
|
|
193
|
+
* {@link handleRequires}), as it'll prevent interfaces from loading otherwise.
|
|
152
194
|
* @param {Object} opts - Options object
|
|
153
|
-
* @param {
|
|
154
|
-
* @param {Object} [map] - An object perhaps having key `key
|
|
195
|
+
* @param {"reporter"|"interface"} pluginType - Type of plugin.
|
|
196
|
+
* @param {Object} [map] - An object perhaps having key `key`. Used as a cache
|
|
197
|
+
* of sorts; `Mocha.reporters` is one, where each key corresponds to a reporter
|
|
198
|
+
* name
|
|
155
199
|
* @private
|
|
156
200
|
*/
|
|
157
|
-
exports.validatePlugin = (opts,
|
|
158
|
-
|
|
159
|
-
|
|
201
|
+
exports.validatePlugin = (opts, pluginType, map = {}) => {
|
|
202
|
+
/**
|
|
203
|
+
* This should be a unique identifier; either a string (present in `map`),
|
|
204
|
+
* or a resolvable (via `require.resolve`) module ID/path.
|
|
205
|
+
* @type {string}
|
|
206
|
+
*/
|
|
207
|
+
const pluginId = opts[pluginType];
|
|
208
|
+
|
|
209
|
+
if (Array.isArray(pluginId)) {
|
|
210
|
+
throw createInvalidPluginError(
|
|
211
|
+
`"--${pluginType}" can only be specified once`,
|
|
212
|
+
pluginType
|
|
213
|
+
);
|
|
160
214
|
}
|
|
161
215
|
|
|
162
|
-
const unknownError =
|
|
216
|
+
const unknownError = err =>
|
|
217
|
+
createInvalidPluginError(
|
|
218
|
+
format('Could not load %s "%s":\n\n %O', pluginType, pluginId, err),
|
|
219
|
+
pluginType,
|
|
220
|
+
pluginId
|
|
221
|
+
);
|
|
163
222
|
|
|
164
|
-
if
|
|
223
|
+
// if this exists, then it's already loaded, so nothing more to do.
|
|
224
|
+
if (!map[pluginId]) {
|
|
165
225
|
try {
|
|
166
|
-
opts[
|
|
226
|
+
opts[pluginType] = require(pluginId);
|
|
167
227
|
} catch (err) {
|
|
168
228
|
if (err.code === 'MODULE_NOT_FOUND') {
|
|
169
229
|
// Try to load reporters from a path (absolute or relative)
|
|
170
230
|
try {
|
|
171
|
-
opts[
|
|
231
|
+
opts[pluginType] = require(path.resolve(pluginId));
|
|
172
232
|
} catch (err) {
|
|
173
|
-
throw unknownError();
|
|
233
|
+
throw unknownError(err);
|
|
174
234
|
}
|
|
175
235
|
} else {
|
|
176
|
-
throw unknownError();
|
|
236
|
+
throw unknownError(err);
|
|
177
237
|
}
|
|
178
238
|
}
|
|
179
239
|
}
|
package/lib/cli/run.js
CHANGED
|
@@ -18,6 +18,7 @@ const {
|
|
|
18
18
|
list,
|
|
19
19
|
handleRequires,
|
|
20
20
|
validatePlugin,
|
|
21
|
+
loadRootHooks,
|
|
21
22
|
runMocha
|
|
22
23
|
} = require('./run-helpers');
|
|
23
24
|
const {ONE_AND_DONES, ONE_AND_DONE_ARGS} = require('./one-and-dones');
|
|
@@ -87,7 +88,6 @@ exports.builder = yargs =>
|
|
|
87
88
|
},
|
|
88
89
|
extension: {
|
|
89
90
|
default: defaults.extension,
|
|
90
|
-
defaultDescription: 'js',
|
|
91
91
|
description: 'File extension(s) to load',
|
|
92
92
|
group: GROUPS.FILES,
|
|
93
93
|
requiresArg: true,
|
|
@@ -286,12 +286,24 @@ exports.builder = yargs =>
|
|
|
286
286
|
);
|
|
287
287
|
}
|
|
288
288
|
|
|
289
|
+
if (argv.opts) {
|
|
290
|
+
throw createUnsupportedError(
|
|
291
|
+
`--opts: configuring Mocha via 'mocha.opts' is DEPRECATED and no longer supported.
|
|
292
|
+
Please use a configuration file instead.`
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
return true;
|
|
297
|
+
})
|
|
298
|
+
.middleware(async argv => {
|
|
289
299
|
// load requires first, because it can impact "plugin" validation
|
|
290
|
-
handleRequires(argv.require);
|
|
300
|
+
const rawRootHooks = await handleRequires(argv.require);
|
|
291
301
|
validatePlugin(argv, 'reporter', Mocha.reporters);
|
|
292
302
|
validatePlugin(argv, 'ui', Mocha.interfaces);
|
|
293
303
|
|
|
294
|
-
|
|
304
|
+
if (rawRootHooks.length) {
|
|
305
|
+
argv.rootHooks = await loadRootHooks(rawRootHooks);
|
|
306
|
+
}
|
|
295
307
|
})
|
|
296
308
|
.array(types.array)
|
|
297
309
|
.boolean(types.boolean)
|
|
@@ -299,8 +311,14 @@ exports.builder = yargs =>
|
|
|
299
311
|
.number(types.number)
|
|
300
312
|
.alias(aliases);
|
|
301
313
|
|
|
302
|
-
exports.handler = argv
|
|
314
|
+
exports.handler = async function(argv) {
|
|
303
315
|
debug('post-yargs config', argv);
|
|
304
316
|
const mocha = new Mocha(argv);
|
|
305
|
-
|
|
317
|
+
|
|
318
|
+
try {
|
|
319
|
+
await runMocha(mocha, argv);
|
|
320
|
+
} catch (err) {
|
|
321
|
+
console.error('\n' + (err.stack || `Error: ${err.message || err}`));
|
|
322
|
+
process.exit(1);
|
|
323
|
+
}
|
|
306
324
|
};
|