mocha 8.4.0 → 9.0.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 +59 -0
- package/lib/cli/config.js +1 -1
- package/lib/cli/lookup-files.js +2 -8
- package/lib/cli/run-helpers.js +6 -6
- package/lib/cli/run-option-metadata.js +1 -0
- package/lib/cli/run.js +4 -0
- package/lib/errors.js +2 -2
- package/lib/esm-utils.js +65 -14
- package/lib/mocha.js +23 -14
- package/lib/reporters/base.js +14 -13
- package/lib/runner.js +16 -14
- package/lib/utils.js +0 -68
- package/mocha-es2018.js +19698 -0
- package/mocha.js +4575 -4225
- package/mocha.js.map +1 -1
- package/package.json +15 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,62 @@
|
|
|
1
|
+
# 9.0.3 / 2021-07-25
|
|
2
|
+
|
|
3
|
+
## :bug: Fixes
|
|
4
|
+
|
|
5
|
+
- [#4702](https://github.com/mochajs/mocha/issues/4702): Error rethrow from cwd-relative path while loading `.mocharc.js` ([**@kirill-golovan**](https://github.com/kirill-golovan))
|
|
6
|
+
|
|
7
|
+
- [#4688](https://github.com/mochajs/mocha/issues/4688): Usage of custom interface in parallel mode ([**@juergba**](https://github.com/juergba))
|
|
8
|
+
|
|
9
|
+
- [#4687](https://github.com/mochajs/mocha/issues/4687): ESM: don't swallow `MODULE_NOT_FOUND` errors in case of `type:module` ([**@giltayar**](https://github.com/giltayar))
|
|
10
|
+
|
|
11
|
+
# 9.0.2 / 2021-07-03
|
|
12
|
+
|
|
13
|
+
## :bug: Fixes
|
|
14
|
+
|
|
15
|
+
- [#4668](https://github.com/mochajs/mocha/issues/4668): ESM: make `--require <dir>` work with new `import`-first loading ([**@giltayar**](https://github.com/giltayar))
|
|
16
|
+
|
|
17
|
+
## :nut_and_bolt: Other
|
|
18
|
+
|
|
19
|
+
- [#4674](https://github.com/mochajs/mocha/issues/4674): Update production dependencies ([**@juergba**](https://github.com/juergba))
|
|
20
|
+
|
|
21
|
+
# 9.0.1 / 2021-06-18
|
|
22
|
+
|
|
23
|
+
## :nut_and_bolt: Other
|
|
24
|
+
|
|
25
|
+
- [#4657](https://github.com/mochajs/mocha/issues/4657): Browser: add separate bundle for modern browsers ([**@juergba**](https://github.com/juergba))
|
|
26
|
+
|
|
27
|
+
We added a separate browser bundle `mocha-es2018.js` in javascript ES2018, as we skipped the transpilation down to ES5. This is an **experimental step towards freezing Mocha's support of IE11**.
|
|
28
|
+
|
|
29
|
+
- [#4653](https://github.com/mochajs/mocha/issues/4653): ESM: proper version check in `hasStableEsmImplementation` ([**@alexander-fenster**](https://github.com/alexander-fenster))
|
|
30
|
+
|
|
31
|
+
# 9.0.0 / 2021-06-07
|
|
32
|
+
|
|
33
|
+
## :boom: Breaking Changes
|
|
34
|
+
|
|
35
|
+
- [#4633](https://github.com/mochajs/mocha/issues/4633): **Drop Node.js v10.x support** ([**@juergba**](https://github.com/juergba))
|
|
36
|
+
|
|
37
|
+
- [#4635](https://github.com/mochajs/mocha/issues/4635): `import`-first loading of test files ([**@giltayar**](https://github.com/giltayar))
|
|
38
|
+
|
|
39
|
+
**Mocha is going ESM-first!** This means that it will now use ESM `import(test_file)` to load the test files, instead of the CommonJS `require(test_file)`. This is not a problem, as `import` can also load most files that `require` does. In the rare cases where this fails, it will fallback to `require(...)`. This ESM-first approach is the next step in Mocha's ESM migration, and allows ESM loaders to load and transform the test file.
|
|
40
|
+
|
|
41
|
+
- [#4636](https://github.com/mochajs/mocha/issues/4636): Remove deprecated `utils.lookupFiles()` ([**@juergba**](https://github.com/juergba))
|
|
42
|
+
|
|
43
|
+
- [#4638](https://github.com/mochajs/mocha/issues/4638): Limit the size of `actual`/`expected` for `diff` generation ([**@juergba**](https://github.com/juergba))
|
|
44
|
+
|
|
45
|
+
- [#4389](https://github.com/mochajs/mocha/issues/4389): Refactoring: Consuming log-symbols alternate to code for win32 in reporters/base ([**@MoonSupport**](https://github.com/MoonSupport))
|
|
46
|
+
|
|
47
|
+
## :tada: Enhancements
|
|
48
|
+
|
|
49
|
+
- [#4640](https://github.com/mochajs/mocha/issues/4640): Add new option `--dry-run` ([**@juergba**](https://github.com/juergba))
|
|
50
|
+
|
|
51
|
+
## :bug: Fixes
|
|
52
|
+
|
|
53
|
+
- [#4128](https://github.com/mochajs/mocha/issues/4128): Fix: control stringification of error message ([**@syeutyu**](https://github.com/syeutyu))
|
|
54
|
+
|
|
55
|
+
## :nut_and_bolt: Other
|
|
56
|
+
|
|
57
|
+
- [#4646](https://github.com/mochajs/mocha/issues/4646): Deprecate `Runner(suite: Suite, delay: boolean)` signature ([**@juergba**](https://github.com/juergba))
|
|
58
|
+
- [#4643](https://github.com/mochajs/mocha/issues/4643): Update production dependencies ([**@juergba**](https://github.com/juergba))
|
|
59
|
+
|
|
1
60
|
# 8.4.0 / 2021-05-07
|
|
2
61
|
|
|
3
62
|
## :tada: Enhancements
|
package/lib/cli/config.js
CHANGED
package/lib/cli/lookup-files.js
CHANGED
|
@@ -8,11 +8,9 @@
|
|
|
8
8
|
var fs = require('fs');
|
|
9
9
|
var path = require('path');
|
|
10
10
|
var glob = require('glob');
|
|
11
|
-
var {format} = require('util');
|
|
12
11
|
var errors = require('../errors');
|
|
13
12
|
var createNoFilesMatchPatternError = errors.createNoFilesMatchPatternError;
|
|
14
13
|
var createMissingArgumentError = errors.createMissingArgumentError;
|
|
15
|
-
var {sQuote, dQuote} = require('../utils');
|
|
16
14
|
const debug = require('debug')('mocha:cli:lookup-files');
|
|
17
15
|
|
|
18
16
|
/**
|
|
@@ -91,7 +89,7 @@ module.exports = function lookupFiles(
|
|
|
91
89
|
files.push(...glob.sync(pattern, {nodir: true}));
|
|
92
90
|
if (!files.length) {
|
|
93
91
|
throw createNoFilesMatchPatternError(
|
|
94
|
-
|
|
92
|
+
`Cannot find any files matching pattern "${filepath}"`,
|
|
95
93
|
filepath
|
|
96
94
|
);
|
|
97
95
|
}
|
|
@@ -127,11 +125,7 @@ module.exports = function lookupFiles(
|
|
|
127
125
|
}
|
|
128
126
|
if (!extensions.length) {
|
|
129
127
|
throw createMissingArgumentError(
|
|
130
|
-
|
|
131
|
-
'Argument %s required when argument %s is a directory',
|
|
132
|
-
sQuote('extensions'),
|
|
133
|
-
sQuote('filepath')
|
|
134
|
-
),
|
|
128
|
+
`Argument '${extensions}' required when argument '${filepath}' is a directory`,
|
|
135
129
|
'extensions',
|
|
136
130
|
'array'
|
|
137
131
|
);
|
package/lib/cli/run-helpers.js
CHANGED
|
@@ -195,10 +195,10 @@ exports.runMocha = async (mocha, options) => {
|
|
|
195
195
|
* it actually exists. This must be run _after_ requires are processed (see
|
|
196
196
|
* {@link handleRequires}), as it'll prevent interfaces from loading otherwise.
|
|
197
197
|
* @param {Object} opts - Options object
|
|
198
|
-
* @param {"reporter"|"
|
|
199
|
-
* @param {Object} [map] -
|
|
200
|
-
*
|
|
201
|
-
* name
|
|
198
|
+
* @param {"reporter"|"ui"} pluginType - Type of plugin.
|
|
199
|
+
* @param {Object} [map] - Used as a cache of sorts;
|
|
200
|
+
* `Mocha.reporters` where each key corresponds to a reporter name,
|
|
201
|
+
* `Mocha.interfaces` where each key corresponds to an interface name.
|
|
202
202
|
* @private
|
|
203
203
|
*/
|
|
204
204
|
exports.validateLegacyPlugin = (opts, pluginType, map = {}) => {
|
|
@@ -226,12 +226,12 @@ exports.validateLegacyPlugin = (opts, pluginType, map = {}) => {
|
|
|
226
226
|
// if this exists, then it's already loaded, so nothing more to do.
|
|
227
227
|
if (!map[pluginId]) {
|
|
228
228
|
try {
|
|
229
|
-
|
|
229
|
+
map[pluginId] = require(pluginId);
|
|
230
230
|
} catch (err) {
|
|
231
231
|
if (err.code === 'MODULE_NOT_FOUND') {
|
|
232
232
|
// Try to load reporters from a path (absolute or relative)
|
|
233
233
|
try {
|
|
234
|
-
|
|
234
|
+
map[pluginId] = require(path.resolve(pluginId));
|
|
235
235
|
} catch (err) {
|
|
236
236
|
throw createUnknownError(err);
|
|
237
237
|
}
|
package/lib/cli/run.js
CHANGED
|
@@ -83,6 +83,10 @@ exports.builder = yargs =>
|
|
|
83
83
|
description: 'Show diff on failure',
|
|
84
84
|
group: GROUPS.OUTPUT
|
|
85
85
|
},
|
|
86
|
+
'dry-run': {
|
|
87
|
+
description: 'Report tests without executing them',
|
|
88
|
+
group: GROUPS.RULES
|
|
89
|
+
},
|
|
86
90
|
exit: {
|
|
87
91
|
description: 'Force Mocha to quit after tests complete',
|
|
88
92
|
group: GROUPS.RULES
|
package/lib/errors.js
CHANGED
|
@@ -328,7 +328,7 @@ function createFatalError(message, value) {
|
|
|
328
328
|
/**
|
|
329
329
|
* Dynamically creates a plugin-type-specific error based on plugin type
|
|
330
330
|
* @param {string} message - Error message
|
|
331
|
-
* @param {"reporter"|"
|
|
331
|
+
* @param {"reporter"|"ui"} pluginType - Plugin type. Future: expand as needed
|
|
332
332
|
* @param {string} [pluginId] - Name/path of plugin, if any
|
|
333
333
|
* @throws When `pluginType` is not known
|
|
334
334
|
* @public
|
|
@@ -339,7 +339,7 @@ function createInvalidLegacyPluginError(message, pluginType, pluginId) {
|
|
|
339
339
|
switch (pluginType) {
|
|
340
340
|
case 'reporter':
|
|
341
341
|
return createInvalidReporterError(message, pluginId);
|
|
342
|
-
case '
|
|
342
|
+
case 'ui':
|
|
343
343
|
return createInvalidInterfaceError(message, pluginId);
|
|
344
344
|
default:
|
|
345
345
|
throw new Error('unknown pluginType "' + pluginType + '"');
|
package/lib/esm-utils.js
CHANGED
|
@@ -30,14 +30,73 @@ const formattedImport = async file => {
|
|
|
30
30
|
return import(file);
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
const hasStableEsmImplementation = (() => {
|
|
34
|
+
const [major, minor] = process.version.split('.');
|
|
35
|
+
// ESM is stable from v12.22.0 onward
|
|
36
|
+
// https://nodejs.org/api/esm.html#esm_modules_ecmascript_modules
|
|
37
|
+
const majorNumber = parseInt(major.slice(1), 10);
|
|
38
|
+
const minorNumber = parseInt(minor, 10);
|
|
39
|
+
return majorNumber > 12 || (majorNumber === 12 && minorNumber >= 22);
|
|
40
|
+
})();
|
|
41
|
+
|
|
42
|
+
exports.requireOrImport = hasStableEsmImplementation
|
|
43
|
+
? async file => {
|
|
44
|
+
if (path.extname(file) === '.mjs') {
|
|
45
|
+
return formattedImport(file);
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
return dealWithExports(await formattedImport(file));
|
|
49
|
+
} catch (err) {
|
|
50
|
+
if (
|
|
51
|
+
err.code === 'ERR_MODULE_NOT_FOUND' ||
|
|
52
|
+
err.code === 'ERR_UNKNOWN_FILE_EXTENSION' ||
|
|
53
|
+
err.code === 'ERR_UNSUPPORTED_DIR_IMPORT'
|
|
54
|
+
) {
|
|
55
|
+
try {
|
|
56
|
+
return require(file);
|
|
57
|
+
} catch (requireErr) {
|
|
58
|
+
if (requireErr.code === 'ERR_REQUIRE_ESM') {
|
|
59
|
+
// This happens when the test file is a JS file, but via type:module is actually ESM,
|
|
60
|
+
// AND has an import to a file that doesn't exist.
|
|
61
|
+
// This throws an `ERR_MODULE_NOT_FOUND` // error above,
|
|
62
|
+
// and when we try to `require` it here, it throws an `ERR_REQUIRE_ESM`.
|
|
63
|
+
// What we want to do is throw the original error (the `ERR_MODULE_NOT_FOUND`),
|
|
64
|
+
// and not the `ERR_REQUIRE_ESM` error, which is a red herring.
|
|
65
|
+
throw err;
|
|
66
|
+
} else {
|
|
67
|
+
throw requireErr;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
} else {
|
|
71
|
+
throw err;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
: implementationOfRequireOrImportForUnstableEsm;
|
|
76
|
+
|
|
77
|
+
function dealWithExports(module) {
|
|
78
|
+
if (module.default) {
|
|
79
|
+
return module.default;
|
|
80
|
+
} else {
|
|
81
|
+
return {...module, default: undefined};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
exports.loadFilesAsync = async (files, preLoadFunc, postLoadFunc) => {
|
|
86
|
+
for (const file of files) {
|
|
87
|
+
preLoadFunc(file);
|
|
88
|
+
const result = await exports.requireOrImport(path.resolve(file));
|
|
89
|
+
postLoadFunc(file, result);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/* istanbul ignore next */
|
|
94
|
+
async function implementationOfRequireOrImportForUnstableEsm(file) {
|
|
34
95
|
if (path.extname(file) === '.mjs') {
|
|
35
96
|
return formattedImport(file);
|
|
36
97
|
}
|
|
37
|
-
// This is currently the only known way of figuring out whether a file is CJS or ESM
|
|
38
|
-
//
|
|
39
|
-
// Another option here would be to always use `import()`, as this also supports CJS, but I would be
|
|
40
|
-
// wary of using it for _all_ existing test files, till ESM is fully stable.
|
|
98
|
+
// This is currently the only known way of figuring out whether a file is CJS or ESM in
|
|
99
|
+
// Node.js that doesn't necessitate calling `import` first.
|
|
41
100
|
try {
|
|
42
101
|
return require(file);
|
|
43
102
|
} catch (err) {
|
|
@@ -47,12 +106,4 @@ exports.requireOrImport = async file => {
|
|
|
47
106
|
throw err;
|
|
48
107
|
}
|
|
49
108
|
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
exports.loadFilesAsync = async (files, preLoadFunc, postLoadFunc) => {
|
|
53
|
-
for (const file of files) {
|
|
54
|
-
preLoadFunc(file);
|
|
55
|
-
const result = await exports.requireOrImport(path.resolve(file));
|
|
56
|
-
postLoadFunc(file, result);
|
|
57
|
-
}
|
|
58
|
-
};
|
|
109
|
+
}
|
package/lib/mocha.js
CHANGED
|
@@ -30,7 +30,6 @@ const {
|
|
|
30
30
|
EVENT_FILE_POST_REQUIRE,
|
|
31
31
|
EVENT_FILE_REQUIRE
|
|
32
32
|
} = Suite.constants;
|
|
33
|
-
var sQuote = utils.sQuote;
|
|
34
33
|
var debug = require('debug')('mocha:mocha');
|
|
35
34
|
|
|
36
35
|
exports = module.exports = Mocha;
|
|
@@ -164,6 +163,7 @@ exports.run = function(...args) {
|
|
|
164
163
|
* @param {boolean} [options.color] - Color TTY output from reporter?
|
|
165
164
|
* @param {boolean} [options.delay] - Delay root suite execution?
|
|
166
165
|
* @param {boolean} [options.diff] - Show diff on failure?
|
|
166
|
+
* @param {boolean} [options.dryRun] - Report tests without running them?
|
|
167
167
|
* @param {string} [options.fgrep] - Test filter given string.
|
|
168
168
|
* @param {boolean} [options.forbidOnly] - Tests marked `only` fail the suite?
|
|
169
169
|
* @param {boolean} [options.forbidPending] - Pending tests fail the suite?
|
|
@@ -200,7 +200,7 @@ function Mocha(options = {}) {
|
|
|
200
200
|
.ui(options.ui)
|
|
201
201
|
.reporter(
|
|
202
202
|
options.reporter,
|
|
203
|
-
options.reporterOption || options.reporterOptions //
|
|
203
|
+
options.reporterOption || options.reporterOptions // for backwards compability
|
|
204
204
|
)
|
|
205
205
|
.slow(options.slow)
|
|
206
206
|
.global(options.global);
|
|
@@ -222,6 +222,7 @@ function Mocha(options = {}) {
|
|
|
222
222
|
'color',
|
|
223
223
|
'delay',
|
|
224
224
|
'diff',
|
|
225
|
+
'dryRun',
|
|
225
226
|
'forbidOnly',
|
|
226
227
|
'forbidPending',
|
|
227
228
|
'fullTrace',
|
|
@@ -346,23 +347,19 @@ Mocha.prototype.reporter = function(reporterName, reporterOptions) {
|
|
|
346
347
|
reporter = require(path.resolve(utils.cwd(), reporterName));
|
|
347
348
|
} catch (_err) {
|
|
348
349
|
_err.code === 'MODULE_NOT_FOUND'
|
|
349
|
-
? warn(
|
|
350
|
+
? warn(`'${reporterName}' reporter not found`)
|
|
350
351
|
: warn(
|
|
351
|
-
|
|
352
|
-
' reporter blew up with error:\n' +
|
|
353
|
-
err.stack
|
|
352
|
+
`'${reporterName}' reporter blew up with error:\n ${err.stack}`
|
|
354
353
|
);
|
|
355
354
|
}
|
|
356
355
|
} else {
|
|
357
|
-
warn(
|
|
358
|
-
sQuote(reporterName) + ' reporter blew up with error:\n' + err.stack
|
|
359
|
-
);
|
|
356
|
+
warn(`'${reporterName}' reporter blew up with error:\n ${err.stack}`);
|
|
360
357
|
}
|
|
361
358
|
}
|
|
362
359
|
}
|
|
363
360
|
if (!reporter) {
|
|
364
361
|
throw createInvalidReporterError(
|
|
365
|
-
|
|
362
|
+
`invalid reporter '${reporterName}'`,
|
|
366
363
|
reporterName
|
|
367
364
|
);
|
|
368
365
|
}
|
|
@@ -396,10 +393,7 @@ Mocha.prototype.ui = function(ui) {
|
|
|
396
393
|
try {
|
|
397
394
|
bindInterface = require(ui);
|
|
398
395
|
} catch (err) {
|
|
399
|
-
throw createInvalidInterfaceError(
|
|
400
|
-
'invalid interface ' + sQuote(ui),
|
|
401
|
-
ui
|
|
402
|
-
);
|
|
396
|
+
throw createInvalidInterfaceError(`invalid interface '${ui}'`, ui);
|
|
403
397
|
}
|
|
404
398
|
}
|
|
405
399
|
}
|
|
@@ -784,6 +778,20 @@ Mocha.prototype.diff = function(diff) {
|
|
|
784
778
|
return this;
|
|
785
779
|
};
|
|
786
780
|
|
|
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
|
+
|
|
787
795
|
/**
|
|
788
796
|
* @summary
|
|
789
797
|
* Sets timeout threshold value.
|
|
@@ -1016,6 +1024,7 @@ Mocha.prototype.run = function(fn) {
|
|
|
1016
1024
|
options.files = this.files;
|
|
1017
1025
|
const runner = new this._runnerClass(suite, {
|
|
1018
1026
|
delay: options.delay,
|
|
1027
|
+
dryRun: options.dryRun,
|
|
1019
1028
|
cleanReferencesAfterRun: this._cleanReferencesAfterRun
|
|
1020
1029
|
});
|
|
1021
1030
|
createStatsCollector(runner);
|
package/lib/reporters/base.js
CHANGED
|
@@ -10,6 +10,7 @@ var diff = require('diff');
|
|
|
10
10
|
var milliseconds = require('ms');
|
|
11
11
|
var utils = require('../utils');
|
|
12
12
|
var supportsColor = require('supports-color');
|
|
13
|
+
var symbols = require('log-symbols');
|
|
13
14
|
var constants = require('../runner').constants;
|
|
14
15
|
var EVENT_TEST_PASS = constants.EVENT_TEST_PASS;
|
|
15
16
|
var EVENT_TEST_FAIL = constants.EVENT_TEST_FAIL;
|
|
@@ -88,20 +89,13 @@ exports.colors = {
|
|
|
88
89
|
*/
|
|
89
90
|
|
|
90
91
|
exports.symbols = {
|
|
91
|
-
ok:
|
|
92
|
-
err:
|
|
93
|
-
dot: '
|
|
92
|
+
ok: symbols.success,
|
|
93
|
+
err: symbols.err,
|
|
94
|
+
dot: '.',
|
|
94
95
|
comma: ',',
|
|
95
96
|
bang: '!'
|
|
96
97
|
};
|
|
97
98
|
|
|
98
|
-
// With node.js on Windows: use symbols available in terminal default fonts
|
|
99
|
-
if (process.platform === 'win32') {
|
|
100
|
-
exports.symbols.ok = '\u221A';
|
|
101
|
-
exports.symbols.err = '\u00D7';
|
|
102
|
-
exports.symbols.dot = '.';
|
|
103
|
-
}
|
|
104
|
-
|
|
105
99
|
/**
|
|
106
100
|
* Color `str` with the given `type`,
|
|
107
101
|
* allowing colors to be disabled,
|
|
@@ -196,6 +190,13 @@ function stringifyDiffObjs(err) {
|
|
|
196
190
|
*/
|
|
197
191
|
var generateDiff = (exports.generateDiff = function(actual, expected) {
|
|
198
192
|
try {
|
|
193
|
+
const diffSize = 2048;
|
|
194
|
+
if (actual.length > diffSize) {
|
|
195
|
+
actual = actual.substring(0, diffSize) + ' ... Lines skipped';
|
|
196
|
+
}
|
|
197
|
+
if (expected.length > diffSize) {
|
|
198
|
+
expected = expected.substring(0, diffSize) + ' ... Lines skipped';
|
|
199
|
+
}
|
|
199
200
|
return exports.inlineDiffs
|
|
200
201
|
? inlineDiff(actual, expected)
|
|
201
202
|
: unifiedDiff(actual, expected);
|
|
@@ -242,10 +243,10 @@ exports.list = function(failures) {
|
|
|
242
243
|
err = test.err;
|
|
243
244
|
}
|
|
244
245
|
var message;
|
|
245
|
-
if (
|
|
246
|
-
message = err.message + '';
|
|
247
|
-
} else if (typeof err.inspect === 'function') {
|
|
246
|
+
if (typeof err.inspect === 'function') {
|
|
248
247
|
message = err.inspect() + '';
|
|
248
|
+
} else if (err.message && typeof err.message.toString === 'function') {
|
|
249
|
+
message = err.message + '';
|
|
249
250
|
} else {
|
|
250
251
|
message = '';
|
|
251
252
|
}
|
package/lib/runner.js
CHANGED
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
* Module dependencies.
|
|
5
5
|
* @private
|
|
6
6
|
*/
|
|
7
|
-
var util = require('util');
|
|
8
7
|
var EventEmitter = require('events').EventEmitter;
|
|
9
8
|
var Pending = require('./pending');
|
|
10
9
|
var utils = require('./utils');
|
|
@@ -19,8 +18,6 @@ var EVENT_ROOT_SUITE_RUN = Suite.constants.EVENT_ROOT_SUITE_RUN;
|
|
|
19
18
|
var STATE_FAILED = Runnable.constants.STATE_FAILED;
|
|
20
19
|
var STATE_PASSED = Runnable.constants.STATE_PASSED;
|
|
21
20
|
var STATE_PENDING = Runnable.constants.STATE_PENDING;
|
|
22
|
-
var dQuote = utils.dQuote;
|
|
23
|
-
var sQuote = utils.sQuote;
|
|
24
21
|
var stackFilter = utils.stackTraceFilter();
|
|
25
22
|
var stringify = utils.stringify;
|
|
26
23
|
|
|
@@ -138,8 +135,9 @@ class Runner extends EventEmitter {
|
|
|
138
135
|
* @public
|
|
139
136
|
* @class
|
|
140
137
|
* @param {Suite} suite - Root suite
|
|
141
|
-
* @param {Object|boolean} [opts] - Options. If `boolean
|
|
138
|
+
* @param {Object|boolean} [opts] - Options. If `boolean` (deprecated), whether or not to delay execution of root suite until ready.
|
|
142
139
|
* @param {boolean} [opts.delay] - Whether to delay execution of root suite until ready.
|
|
140
|
+
* @param {boolean} [opts.dryRun] - Whether to report tests without running them.
|
|
143
141
|
* @param {boolean} [opts.cleanReferencesAfterRun] - Whether to clean references to test fns and hooks when a suite is done.
|
|
144
142
|
*/
|
|
145
143
|
constructor(suite, opts) {
|
|
@@ -148,7 +146,10 @@ class Runner extends EventEmitter {
|
|
|
148
146
|
opts = {};
|
|
149
147
|
}
|
|
150
148
|
if (typeof opts === 'boolean') {
|
|
151
|
-
// TODO:
|
|
149
|
+
// TODO: remove this
|
|
150
|
+
require('./errors').deprecate(
|
|
151
|
+
'"Runner(suite: Suite, delay: boolean)" is deprecated. Use "Runner(suite: Suite, {delay: boolean})" instead.'
|
|
152
|
+
);
|
|
152
153
|
this._delay = opts;
|
|
153
154
|
opts = {};
|
|
154
155
|
} else {
|
|
@@ -407,9 +408,8 @@ Runner.prototype.checkGlobals = function(test) {
|
|
|
407
408
|
this._globals = this._globals.concat(leaks);
|
|
408
409
|
|
|
409
410
|
if (leaks.length) {
|
|
410
|
-
var msg =
|
|
411
|
-
|
|
412
|
-
this.fail(test, error);
|
|
411
|
+
var msg = `global leak(s) detected: ${leaks.map(e => `'${e}'`).join(', ')}`;
|
|
412
|
+
this.fail(test, new Error(msg));
|
|
413
413
|
}
|
|
414
414
|
};
|
|
415
415
|
|
|
@@ -476,6 +476,8 @@ Runner.prototype.fail = function(test, err, force) {
|
|
|
476
476
|
*/
|
|
477
477
|
|
|
478
478
|
Runner.prototype.hook = function(name, fn) {
|
|
479
|
+
if (this._opts.dryRun) return fn();
|
|
480
|
+
|
|
479
481
|
var suite = this.suite;
|
|
480
482
|
var hooks = suite.getHooks(name);
|
|
481
483
|
var self = this;
|
|
@@ -554,8 +556,7 @@ Runner.prototype.hook = function(name, fn) {
|
|
|
554
556
|
function setHookTitle(hook) {
|
|
555
557
|
hook.originalTitle = hook.originalTitle || hook.title;
|
|
556
558
|
if (hook.ctx && hook.ctx.currentTest) {
|
|
557
|
-
hook.title =
|
|
558
|
-
hook.originalTitle + ' for ' + dQuote(hook.ctx.currentTest.title);
|
|
559
|
+
hook.title = `${hook.originalTitle} for "${hook.ctx.currentTest.title}"`;
|
|
559
560
|
} else {
|
|
560
561
|
var parentTitle;
|
|
561
562
|
if (hook.parent.title) {
|
|
@@ -563,7 +564,7 @@ Runner.prototype.hook = function(name, fn) {
|
|
|
563
564
|
} else {
|
|
564
565
|
parentTitle = hook.parent.root ? '{root}' : '';
|
|
565
566
|
}
|
|
566
|
-
hook.title = hook.originalTitle
|
|
567
|
+
hook.title = `${hook.originalTitle} in "${parentTitle}"`;
|
|
567
568
|
}
|
|
568
569
|
}
|
|
569
570
|
}
|
|
@@ -609,7 +610,7 @@ Runner.prototype.hooks = function(name, suites, fn) {
|
|
|
609
610
|
};
|
|
610
611
|
|
|
611
612
|
/**
|
|
612
|
-
* Run hooks from
|
|
613
|
+
* Run 'afterEach' hooks from bottom up.
|
|
613
614
|
*
|
|
614
615
|
* @param {String} name
|
|
615
616
|
* @param {Function} fn
|
|
@@ -621,7 +622,7 @@ Runner.prototype.hookUp = function(name, fn) {
|
|
|
621
622
|
};
|
|
622
623
|
|
|
623
624
|
/**
|
|
624
|
-
* Run hooks from
|
|
625
|
+
* Run 'beforeEach' hooks from top level down.
|
|
625
626
|
*
|
|
626
627
|
* @param {String} name
|
|
627
628
|
* @param {Function} fn
|
|
@@ -656,6 +657,8 @@ Runner.prototype.parents = function() {
|
|
|
656
657
|
* @private
|
|
657
658
|
*/
|
|
658
659
|
Runner.prototype.runTest = function(fn) {
|
|
660
|
+
if (this._opts.dryRun) return fn();
|
|
661
|
+
|
|
659
662
|
var self = this;
|
|
660
663
|
var test = this.test;
|
|
661
664
|
|
|
@@ -701,7 +704,6 @@ Runner.prototype.runTests = function(suite, fn) {
|
|
|
701
704
|
self.suite = after ? errSuite.parent : errSuite;
|
|
702
705
|
|
|
703
706
|
if (self.suite) {
|
|
704
|
-
// call hookUp afterEach
|
|
705
707
|
self.hookUp(HOOK_TYPE_AFTER_EACH, function(err2, errSuite2) {
|
|
706
708
|
self.suite = orig;
|
|
707
709
|
// some hooks may fail even now
|
package/lib/utils.js
CHANGED
|
@@ -13,7 +13,6 @@ const {nanoid} = require('nanoid/non-secure');
|
|
|
13
13
|
var path = require('path');
|
|
14
14
|
var util = require('util');
|
|
15
15
|
var he = require('he');
|
|
16
|
-
const errors = require('./errors');
|
|
17
16
|
|
|
18
17
|
const MOCHA_ID_PROP_NAME = '__mocha_id__';
|
|
19
18
|
|
|
@@ -519,44 +518,6 @@ exports.clamp = function clamp(value, range) {
|
|
|
519
518
|
return Math.min(Math.max(value, range[0]), range[1]);
|
|
520
519
|
};
|
|
521
520
|
|
|
522
|
-
/**
|
|
523
|
-
* Single quote text by combining with undirectional ASCII quotation marks.
|
|
524
|
-
*
|
|
525
|
-
* @description
|
|
526
|
-
* Provides a simple means of markup for quoting text to be used in output.
|
|
527
|
-
* Use this to quote names of variables, methods, and packages.
|
|
528
|
-
*
|
|
529
|
-
* <samp>package 'foo' cannot be found</samp>
|
|
530
|
-
*
|
|
531
|
-
* @private
|
|
532
|
-
* @param {string} str - Value to be quoted.
|
|
533
|
-
* @returns {string} quoted value
|
|
534
|
-
* @example
|
|
535
|
-
* sQuote('n') // => 'n'
|
|
536
|
-
*/
|
|
537
|
-
exports.sQuote = function(str) {
|
|
538
|
-
return "'" + str + "'";
|
|
539
|
-
};
|
|
540
|
-
|
|
541
|
-
/**
|
|
542
|
-
* Double quote text by combining with undirectional ASCII quotation marks.
|
|
543
|
-
*
|
|
544
|
-
* @description
|
|
545
|
-
* Provides a simple means of markup for quoting text to be used in output.
|
|
546
|
-
* Use this to quote names of datatypes, classes, pathnames, and strings.
|
|
547
|
-
*
|
|
548
|
-
* <samp>argument 'value' must be "string" or "number"</samp>
|
|
549
|
-
*
|
|
550
|
-
* @private
|
|
551
|
-
* @param {string} str - Value to be quoted.
|
|
552
|
-
* @returns {string} quoted value
|
|
553
|
-
* @example
|
|
554
|
-
* dQuote('number') // => "number"
|
|
555
|
-
*/
|
|
556
|
-
exports.dQuote = function(str) {
|
|
557
|
-
return '"' + str + '"';
|
|
558
|
-
};
|
|
559
|
-
|
|
560
521
|
/**
|
|
561
522
|
* It's a noop.
|
|
562
523
|
* @public
|
|
@@ -650,35 +611,6 @@ exports.isBrowser = function isBrowser() {
|
|
|
650
611
|
return Boolean(process.browser);
|
|
651
612
|
};
|
|
652
613
|
|
|
653
|
-
/**
|
|
654
|
-
* Lookup file names at the given `path`.
|
|
655
|
-
*
|
|
656
|
-
* @description
|
|
657
|
-
* Filenames are returned in _traversal_ order by the OS/filesystem.
|
|
658
|
-
* **Make no assumption that the names will be sorted in any fashion.**
|
|
659
|
-
*
|
|
660
|
-
* @public
|
|
661
|
-
* @alias module:lib/cli.lookupFiles
|
|
662
|
-
* @param {string} filepath - Base path to start searching from.
|
|
663
|
-
* @param {string[]} [extensions=[]] - File extensions to look for.
|
|
664
|
-
* @param {boolean} [recursive=false] - Whether to recurse into subdirectories.
|
|
665
|
-
* @return {string[]} An array of paths.
|
|
666
|
-
* @throws {Error} if no files match pattern.
|
|
667
|
-
* @throws {TypeError} if `filepath` is directory and `extensions` not provided.
|
|
668
|
-
* @deprecated Moved to {@link module:lib/cli.lookupFiles}
|
|
669
|
-
*/
|
|
670
|
-
exports.lookupFiles = (...args) => {
|
|
671
|
-
if (exports.isBrowser()) {
|
|
672
|
-
throw errors.createUnsupportedError(
|
|
673
|
-
'lookupFiles() is only supported in Node.js!'
|
|
674
|
-
);
|
|
675
|
-
}
|
|
676
|
-
errors.deprecate(
|
|
677
|
-
'`lookupFiles()` in module `mocha/lib/utils` has moved to module `mocha/lib/cli` and will be removed in the next major revision of Mocha'
|
|
678
|
-
);
|
|
679
|
-
return require('./cli').lookupFiles(...args);
|
|
680
|
-
};
|
|
681
|
-
|
|
682
614
|
/*
|
|
683
615
|
* Casts `value` to an array; useful for optionally accepting array parameters
|
|
684
616
|
*
|