mocha 9.0.3 → 9.1.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 +8 -0
- package/bin/mocha +18 -27
- package/lib/cli/cli.js +3 -2
- package/lib/cli/node-flags.js +2 -5
- package/lib/cli/run-option-metadata.js +3 -0
- package/lib/cli/run.js +8 -0
- package/lib/mocha.js +33 -16
- package/lib/reporters/base.js +1 -1
- package/lib/reporters/json.js +28 -3
- package/lib/runner.js +5 -2
- package/mocha-es2018.js +276 -140
- package/mocha.js +2720 -2579
- package/mocha.js.map +1 -1
- package/package.json +3 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
# 9.1.0 / 2021-08-20
|
|
2
|
+
|
|
3
|
+
## :tada: Enhancements
|
|
4
|
+
|
|
5
|
+
- [#4716](https://github.com/mochajs/mocha/issues/4716): Add new option `--fail-zero` ([**@juergba**](https://github.com/juergba))
|
|
6
|
+
- [#4691](https://github.com/mochajs/mocha/issues/4691): Add new option `--node-option` ([**@juergba**](https://github.com/juergba))
|
|
7
|
+
- [#4607](https://github.com/mochajs/mocha/issues/4607): Add output option to `JSON` reporter ([**@dorny**](https://github.com/dorny))
|
|
8
|
+
|
|
1
9
|
# 9.0.3 / 2021-07-25
|
|
2
10
|
|
|
3
11
|
## :bug: Fixes
|
package/bin/mocha
CHANGED
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
* @private
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
const {deprecate} = require('../lib/utils');
|
|
14
13
|
const {loadOptions} = require('../lib/cli/options');
|
|
15
14
|
const {
|
|
16
15
|
unparseNodeFlags,
|
|
@@ -23,6 +22,7 @@ const {aliases} = require('../lib/cli/run-option-metadata');
|
|
|
23
22
|
|
|
24
23
|
const mochaArgs = {};
|
|
25
24
|
const nodeArgs = {};
|
|
25
|
+
let hasInspect = false;
|
|
26
26
|
|
|
27
27
|
const opts = loadOptions(process.argv.slice(2));
|
|
28
28
|
debug('loaded opts', opts);
|
|
@@ -59,48 +59,39 @@ Object.keys(opts).forEach(opt => {
|
|
|
59
59
|
|
|
60
60
|
// disable 'timeout' for debugFlags
|
|
61
61
|
Object.keys(nodeArgs).forEach(opt => disableTimeouts(opt));
|
|
62
|
+
mochaArgs['node-option'] &&
|
|
63
|
+
mochaArgs['node-option'].forEach(opt => disableTimeouts(opt));
|
|
62
64
|
|
|
63
65
|
// Native debugger handling
|
|
64
66
|
// see https://nodejs.org/api/debugger.html#debugger_debugger
|
|
65
|
-
// look for 'inspect'
|
|
67
|
+
// look for 'inspect' that would launch this debugger,
|
|
66
68
|
// remove it from Mocha's opts and prepend it to Node's opts.
|
|
67
69
|
// A deprecation warning will be printed by node, if applicable.
|
|
68
70
|
// (mochaArgs._ are "positional" arguments, not prefixed with - or --)
|
|
69
71
|
if (mochaArgs._) {
|
|
70
|
-
const i = mochaArgs._.findIndex(val => val === 'inspect'
|
|
72
|
+
const i = mochaArgs._.findIndex(val => val === 'inspect');
|
|
71
73
|
if (i > -1) {
|
|
72
|
-
|
|
74
|
+
mochaArgs._.splice(i, 1);
|
|
73
75
|
disableTimeouts('inspect');
|
|
74
|
-
|
|
76
|
+
hasInspect = true;
|
|
75
77
|
}
|
|
76
78
|
}
|
|
77
79
|
|
|
78
|
-
|
|
79
|
-
if (nodeArgs.gc) {
|
|
80
|
-
deprecate(
|
|
81
|
-
'"-gc" is deprecated and will be removed from a future version of Mocha. Use "--gc-global" instead.'
|
|
82
|
-
);
|
|
83
|
-
nodeArgs['gc-global'] = nodeArgs.gc;
|
|
84
|
-
delete nodeArgs.gc;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// --require/-r is treated as Mocha flag except when 'esm' is preloaded
|
|
88
|
-
if (mochaArgs.require && mochaArgs.require.includes('esm')) {
|
|
89
|
-
nodeArgs.require = ['esm'];
|
|
90
|
-
mochaArgs.require = mochaArgs.require.filter(mod => mod !== 'esm');
|
|
91
|
-
if (!mochaArgs.require.length) {
|
|
92
|
-
delete mochaArgs.require;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
if (Object.keys(nodeArgs).length) {
|
|
80
|
+
if (mochaArgs['node-option'] || Object.keys(nodeArgs).length || hasInspect) {
|
|
97
81
|
const {spawn} = require('child_process');
|
|
98
82
|
const mochaPath = require.resolve('../lib/cli/cli.js');
|
|
99
83
|
|
|
100
|
-
|
|
84
|
+
const nodeArgv =
|
|
85
|
+
(mochaArgs['node-option'] && mochaArgs['node-option'].map(v => '--' + v)) ||
|
|
86
|
+
unparseNodeFlags(nodeArgs);
|
|
87
|
+
|
|
88
|
+
if (hasInspect) nodeArgv.unshift('inspect');
|
|
89
|
+
delete mochaArgs['node-option'];
|
|
90
|
+
|
|
91
|
+
debug('final node argv', nodeArgv);
|
|
101
92
|
|
|
102
93
|
const args = [].concat(
|
|
103
|
-
|
|
94
|
+
nodeArgv,
|
|
104
95
|
mochaPath,
|
|
105
96
|
unparse(mochaArgs, {alias: aliases})
|
|
106
97
|
);
|
|
@@ -147,5 +138,5 @@ if (Object.keys(nodeArgs).length) {
|
|
|
147
138
|
});
|
|
148
139
|
} else {
|
|
149
140
|
debug('running Mocha in-process');
|
|
150
|
-
require('../lib/cli/cli').main(
|
|
141
|
+
require('../lib/cli/cli').main([], mochaArgs);
|
|
151
142
|
}
|
package/lib/cli/cli.js
CHANGED
|
@@ -33,8 +33,9 @@ const {cwd} = require('../utils');
|
|
|
33
33
|
* @public
|
|
34
34
|
* @summary Mocha's main command-line entry-point.
|
|
35
35
|
* @param {string[]} argv - Array of arguments to parse, or by default the lovely `process.argv.slice(2)`
|
|
36
|
+
* @param {object} [mochaArgs] - Object of already parsed Mocha arguments (by bin/mocha)
|
|
36
37
|
*/
|
|
37
|
-
exports.main = (argv = process.argv.slice(2)) => {
|
|
38
|
+
exports.main = (argv = process.argv.slice(2), mochaArgs) => {
|
|
38
39
|
debug('entered main with raw args', argv);
|
|
39
40
|
// ensure we can require() from current working directory
|
|
40
41
|
if (typeof module.paths !== 'undefined') {
|
|
@@ -43,7 +44,7 @@ exports.main = (argv = process.argv.slice(2)) => {
|
|
|
43
44
|
|
|
44
45
|
Error.stackTraceLimit = Infinity; // configurable via --stack-trace-limit?
|
|
45
46
|
|
|
46
|
-
var args = loadOptions(argv);
|
|
47
|
+
var args = mochaArgs || loadOptions(argv);
|
|
47
48
|
|
|
48
49
|
yargs()
|
|
49
50
|
.scriptName('mocha')
|
package/lib/cli/node-flags.js
CHANGED
|
@@ -49,7 +49,7 @@ exports.isNodeFlag = (flag, bareword = true) => {
|
|
|
49
49
|
// and also any V8 flags with `--v8-` prefix
|
|
50
50
|
(!isMochaFlag(flag) && nodeFlags && nodeFlags.has(flag)) ||
|
|
51
51
|
debugFlags.has(flag) ||
|
|
52
|
-
/(?:preserve-symlinks(?:-main)?|harmony(?:[_-]|$)|(?:trace[_-].+$)|gc
|
|
52
|
+
/(?:preserve-symlinks(?:-main)?|harmony(?:[_-]|$)|(?:trace[_-].+$)|gc[_-]global$|es[_-]staging$|use[_-]strict$|v8[_-](?!options).+?$)/.test(
|
|
53
53
|
flag
|
|
54
54
|
)
|
|
55
55
|
);
|
|
@@ -67,7 +67,6 @@ exports.impliesNoTimeouts = flag => debugFlags.has(flag);
|
|
|
67
67
|
/**
|
|
68
68
|
* All non-strictly-boolean arguments to node--those with values--must specify those values using `=`, e.g., `--inspect=0.0.0.0`.
|
|
69
69
|
* Unparse these arguments using `yargs-unparser` (which would result in `--inspect 0.0.0.0`), then supply `=` where we have values.
|
|
70
|
-
* Apparently --require in Node.js v8 does NOT want `=`.
|
|
71
70
|
* There's probably an easier or more robust way to do this; fixes welcome
|
|
72
71
|
* @param {Object} opts - Arguments object
|
|
73
72
|
* @returns {string[]} Unparsed arguments using `=` to specify values
|
|
@@ -79,9 +78,7 @@ exports.unparseNodeFlags = opts => {
|
|
|
79
78
|
? args
|
|
80
79
|
.join(' ')
|
|
81
80
|
.split(/\b/)
|
|
82
|
-
.map((arg
|
|
83
|
-
arg === ' ' && args[index - 1] !== 'require' ? '=' : arg
|
|
84
|
-
)
|
|
81
|
+
.map(arg => (arg === ' ' ? '=' : arg))
|
|
85
82
|
.join('')
|
|
86
83
|
.split(' ')
|
|
87
84
|
: [];
|
|
@@ -18,6 +18,7 @@ const TYPES = (exports.types = {
|
|
|
18
18
|
'file',
|
|
19
19
|
'global',
|
|
20
20
|
'ignore',
|
|
21
|
+
'node-option',
|
|
21
22
|
'reporter-option',
|
|
22
23
|
'require',
|
|
23
24
|
'spec',
|
|
@@ -34,6 +35,7 @@ const TYPES = (exports.types = {
|
|
|
34
35
|
'diff',
|
|
35
36
|
'dry-run',
|
|
36
37
|
'exit',
|
|
38
|
+
'fail-zero',
|
|
37
39
|
'forbid-only',
|
|
38
40
|
'forbid-pending',
|
|
39
41
|
'full-trace',
|
|
@@ -79,6 +81,7 @@ exports.aliases = {
|
|
|
79
81
|
invert: ['i'],
|
|
80
82
|
jobs: ['j'],
|
|
81
83
|
'no-colors': ['C'],
|
|
84
|
+
'node-option': ['n'],
|
|
82
85
|
parallel: ['p'],
|
|
83
86
|
reporter: ['R'],
|
|
84
87
|
'reporter-option': ['reporter-options', 'O'],
|
package/lib/cli/run.js
CHANGED
|
@@ -98,6 +98,10 @@ exports.builder = yargs =>
|
|
|
98
98
|
requiresArg: true,
|
|
99
99
|
coerce: list
|
|
100
100
|
},
|
|
101
|
+
'fail-zero': {
|
|
102
|
+
description: 'Fail test run if no test(s) encountered',
|
|
103
|
+
group: GROUPS.RULES
|
|
104
|
+
},
|
|
101
105
|
fgrep: {
|
|
102
106
|
conflicts: 'grep',
|
|
103
107
|
description: 'Only run tests containing this string',
|
|
@@ -176,6 +180,10 @@ exports.builder = yargs =>
|
|
|
176
180
|
group: GROUPS.OUTPUT,
|
|
177
181
|
hidden: true
|
|
178
182
|
},
|
|
183
|
+
'node-option': {
|
|
184
|
+
description: 'Node or V8 option (no leading "--")',
|
|
185
|
+
group: GROUPS.CONFIG
|
|
186
|
+
},
|
|
179
187
|
package: {
|
|
180
188
|
description: 'Path to package.json for config',
|
|
181
189
|
group: GROUPS.CONFIG,
|
package/lib/mocha.js
CHANGED
|
@@ -164,6 +164,7 @@ exports.run = function(...args) {
|
|
|
164
164
|
* @param {boolean} [options.delay] - Delay root suite execution?
|
|
165
165
|
* @param {boolean} [options.diff] - Show diff on failure?
|
|
166
166
|
* @param {boolean} [options.dryRun] - Report tests without running them?
|
|
167
|
+
* @param {boolean} [options.failZero] - Fail test run if zero tests?
|
|
167
168
|
* @param {string} [options.fgrep] - Test filter given string.
|
|
168
169
|
* @param {boolean} [options.forbidOnly] - Tests marked `only` fail the suite?
|
|
169
170
|
* @param {boolean} [options.forbidPending] - Pending tests fail the suite?
|
|
@@ -223,6 +224,7 @@ function Mocha(options = {}) {
|
|
|
223
224
|
'delay',
|
|
224
225
|
'diff',
|
|
225
226
|
'dryRun',
|
|
227
|
+
'failZero',
|
|
226
228
|
'forbidOnly',
|
|
227
229
|
'forbidPending',
|
|
228
230
|
'fullTrace',
|
|
@@ -581,7 +583,7 @@ Mocha.prototype.fgrep = function(str) {
|
|
|
581
583
|
Mocha.prototype.grep = function(re) {
|
|
582
584
|
if (utils.isString(re)) {
|
|
583
585
|
// extract args if it's regex-like, i.e: [string, pattern, flag]
|
|
584
|
-
var arg = re.match(/^\/(.*)\/(
|
|
586
|
+
var arg = re.match(/^\/(.*)\/([gimy]{0,4})$|.*/);
|
|
585
587
|
this.options.grep = new RegExp(arg[1] || arg[0], arg[2]);
|
|
586
588
|
} else {
|
|
587
589
|
this.options.grep = re;
|
|
@@ -778,20 +780,6 @@ Mocha.prototype.diff = function(diff) {
|
|
|
778
780
|
return this;
|
|
779
781
|
};
|
|
780
782
|
|
|
781
|
-
/**
|
|
782
|
-
* Enables or disables running tests in dry-run mode.
|
|
783
|
-
*
|
|
784
|
-
* @public
|
|
785
|
-
* @see [CLI option](../#-dry-run)
|
|
786
|
-
* @param {boolean} [dryRun=true] - Whether to activate dry-run mode.
|
|
787
|
-
* @return {Mocha} this
|
|
788
|
-
* @chainable
|
|
789
|
-
*/
|
|
790
|
-
Mocha.prototype.dryRun = function(dryRun) {
|
|
791
|
-
this.options.dryRun = dryRun !== false;
|
|
792
|
-
return this;
|
|
793
|
-
};
|
|
794
|
-
|
|
795
783
|
/**
|
|
796
784
|
* @summary
|
|
797
785
|
* Sets timeout threshold value.
|
|
@@ -918,6 +906,34 @@ Mocha.prototype.delay = function delay() {
|
|
|
918
906
|
return this;
|
|
919
907
|
};
|
|
920
908
|
|
|
909
|
+
/**
|
|
910
|
+
* Enables or disables running tests in dry-run mode.
|
|
911
|
+
*
|
|
912
|
+
* @public
|
|
913
|
+
* @see [CLI option](../#-dry-run)
|
|
914
|
+
* @param {boolean} [dryRun=true] - Whether to activate dry-run mode.
|
|
915
|
+
* @return {Mocha} this
|
|
916
|
+
* @chainable
|
|
917
|
+
*/
|
|
918
|
+
Mocha.prototype.dryRun = function(dryRun) {
|
|
919
|
+
this.options.dryRun = dryRun !== false;
|
|
920
|
+
return this;
|
|
921
|
+
};
|
|
922
|
+
|
|
923
|
+
/**
|
|
924
|
+
* Fails test run if no tests encountered with exit-code 1.
|
|
925
|
+
*
|
|
926
|
+
* @public
|
|
927
|
+
* @see [CLI option](../#-fail-zero)
|
|
928
|
+
* @param {boolean} [failZero=true] - Whether to fail test run.
|
|
929
|
+
* @return {Mocha} this
|
|
930
|
+
* @chainable
|
|
931
|
+
*/
|
|
932
|
+
Mocha.prototype.failZero = function(failZero) {
|
|
933
|
+
this.options.failZero = failZero !== false;
|
|
934
|
+
return this;
|
|
935
|
+
};
|
|
936
|
+
|
|
921
937
|
/**
|
|
922
938
|
* Causes tests marked `only` to fail the suite.
|
|
923
939
|
*
|
|
@@ -1023,9 +1039,10 @@ Mocha.prototype.run = function(fn) {
|
|
|
1023
1039
|
var options = this.options;
|
|
1024
1040
|
options.files = this.files;
|
|
1025
1041
|
const runner = new this._runnerClass(suite, {
|
|
1042
|
+
cleanReferencesAfterRun: this._cleanReferencesAfterRun,
|
|
1026
1043
|
delay: options.delay,
|
|
1027
1044
|
dryRun: options.dryRun,
|
|
1028
|
-
|
|
1045
|
+
failZero: options.failZero
|
|
1029
1046
|
});
|
|
1030
1047
|
createStatsCollector(runner);
|
|
1031
1048
|
var reporter = new this._reporter(runner, options);
|
package/lib/reporters/base.js
CHANGED
package/lib/reporters/json.js
CHANGED
|
@@ -7,12 +7,16 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
var Base = require('./base');
|
|
10
|
+
var fs = require('fs');
|
|
11
|
+
var path = require('path');
|
|
12
|
+
const createUnsupportedError = require('../errors').createUnsupportedError;
|
|
13
|
+
const utils = require('../utils');
|
|
10
14
|
var constants = require('../runner').constants;
|
|
11
15
|
var EVENT_TEST_PASS = constants.EVENT_TEST_PASS;
|
|
16
|
+
var EVENT_TEST_PENDING = constants.EVENT_TEST_PENDING;
|
|
12
17
|
var EVENT_TEST_FAIL = constants.EVENT_TEST_FAIL;
|
|
13
18
|
var EVENT_TEST_END = constants.EVENT_TEST_END;
|
|
14
19
|
var EVENT_RUN_END = constants.EVENT_RUN_END;
|
|
15
|
-
var EVENT_TEST_PENDING = constants.EVENT_TEST_PENDING;
|
|
16
20
|
|
|
17
21
|
/**
|
|
18
22
|
* Expose `JSON`.
|
|
@@ -30,7 +34,7 @@ exports = module.exports = JSONReporter;
|
|
|
30
34
|
* @param {Runner} runner - Instance triggers reporter actions.
|
|
31
35
|
* @param {Object} [options] - runner options
|
|
32
36
|
*/
|
|
33
|
-
function JSONReporter(runner, options) {
|
|
37
|
+
function JSONReporter(runner, options = {}) {
|
|
34
38
|
Base.call(this, runner, options);
|
|
35
39
|
|
|
36
40
|
var self = this;
|
|
@@ -38,6 +42,14 @@ function JSONReporter(runner, options) {
|
|
|
38
42
|
var pending = [];
|
|
39
43
|
var failures = [];
|
|
40
44
|
var passes = [];
|
|
45
|
+
var output;
|
|
46
|
+
|
|
47
|
+
if (options.reporterOption && options.reporterOption.output) {
|
|
48
|
+
if (utils.isBrowser()) {
|
|
49
|
+
throw createUnsupportedError('file output not supported in browser');
|
|
50
|
+
}
|
|
51
|
+
output = options.reporterOption.output;
|
|
52
|
+
}
|
|
41
53
|
|
|
42
54
|
runner.on(EVENT_TEST_END, function(test) {
|
|
43
55
|
tests.push(test);
|
|
@@ -66,7 +78,20 @@ function JSONReporter(runner, options) {
|
|
|
66
78
|
|
|
67
79
|
runner.testResults = obj;
|
|
68
80
|
|
|
69
|
-
|
|
81
|
+
var json = JSON.stringify(obj, null, 2);
|
|
82
|
+
if (output) {
|
|
83
|
+
try {
|
|
84
|
+
fs.mkdirSync(path.dirname(output), {recursive: true});
|
|
85
|
+
fs.writeFileSync(output, json);
|
|
86
|
+
} catch (err) {
|
|
87
|
+
console.error(
|
|
88
|
+
`${Base.symbols.err} [mocha] writing output to "${output}" failed: ${err.message}\n`
|
|
89
|
+
);
|
|
90
|
+
process.stdout.write(json);
|
|
91
|
+
}
|
|
92
|
+
} else {
|
|
93
|
+
process.stdout.write(json);
|
|
94
|
+
}
|
|
70
95
|
});
|
|
71
96
|
}
|
|
72
97
|
|
package/lib/runner.js
CHANGED
|
@@ -135,10 +135,11 @@ class Runner extends EventEmitter {
|
|
|
135
135
|
* @public
|
|
136
136
|
* @class
|
|
137
137
|
* @param {Suite} suite - Root suite
|
|
138
|
-
* @param {Object|boolean} [opts] - Options. If `boolean` (deprecated), whether
|
|
138
|
+
* @param {Object|boolean} [opts] - Options. If `boolean` (deprecated), whether to delay execution of root suite until ready.
|
|
139
|
+
* @param {boolean} [opts.cleanReferencesAfterRun] - Whether to clean references to test fns and hooks when a suite is done.
|
|
139
140
|
* @param {boolean} [opts.delay] - Whether to delay execution of root suite until ready.
|
|
140
141
|
* @param {boolean} [opts.dryRun] - Whether to report tests without running them.
|
|
141
|
-
* @param {boolean} [
|
|
142
|
+
* @param {boolean} [options.failZero] - Whether to fail test run if zero tests encountered.
|
|
142
143
|
*/
|
|
143
144
|
constructor(suite, opts) {
|
|
144
145
|
super();
|
|
@@ -1044,6 +1045,8 @@ Runner.prototype.run = function(fn, opts = {}) {
|
|
|
1044
1045
|
fn = fn || function() {};
|
|
1045
1046
|
|
|
1046
1047
|
const end = () => {
|
|
1048
|
+
if (!this.total && this._opts.failZero) this.failures = 1;
|
|
1049
|
+
|
|
1047
1050
|
debug('run(): root suite completed; emitting %s', constants.EVENT_RUN_END);
|
|
1048
1051
|
this.emit(constants.EVENT_RUN_END);
|
|
1049
1052
|
};
|