mocha 10.5.0 → 10.5.2
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/lib/cli/collect-files.js +49 -7
- package/lib/cli/run-helpers.js +47 -6
- package/lib/cli/watch-run.js +2 -2
- package/lib/nodejs/serializer.js +6 -10
- package/lib/utils.js +33 -0
- package/mocha.js +35 -2
- package/mocha.js.map +1 -1
- package/package.json +1 -1
package/lib/cli/collect-files.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const fs = require('fs');
|
|
3
4
|
const path = require('path');
|
|
4
5
|
const ansi = require('ansi-colors');
|
|
5
6
|
const debug = require('debug')('mocha:cli:run:helpers');
|
|
@@ -19,7 +20,7 @@ const {castArray} = require('../utils');
|
|
|
19
20
|
/**
|
|
20
21
|
* Smash together an array of test files in the correct order
|
|
21
22
|
* @param {FileCollectionOptions} [opts] - Options
|
|
22
|
-
* @returns {
|
|
23
|
+
* @returns {FileCollectionResponse} An object containing a list of files to test and unmatched files.
|
|
23
24
|
* @private
|
|
24
25
|
*/
|
|
25
26
|
module.exports = ({
|
|
@@ -30,7 +31,7 @@ module.exports = ({
|
|
|
30
31
|
sort,
|
|
31
32
|
spec
|
|
32
33
|
} = {}) => {
|
|
33
|
-
const
|
|
34
|
+
const unmatchedSpecFiles = [];
|
|
34
35
|
const specFiles = spec.reduce((specFiles, arg) => {
|
|
35
36
|
try {
|
|
36
37
|
const moreSpecFiles = castArray(lookupFiles(arg, extension, recursive))
|
|
@@ -44,7 +45,7 @@ module.exports = ({
|
|
|
44
45
|
return [...specFiles, ...moreSpecFiles];
|
|
45
46
|
} catch (err) {
|
|
46
47
|
if (err.code === NO_FILES_MATCH_PATTERN) {
|
|
47
|
-
|
|
48
|
+
unmatchedSpecFiles.push({message: err.message, pattern: err.pattern});
|
|
48
49
|
return specFiles;
|
|
49
50
|
}
|
|
50
51
|
|
|
@@ -52,6 +53,27 @@ module.exports = ({
|
|
|
52
53
|
}
|
|
53
54
|
}, []);
|
|
54
55
|
|
|
56
|
+
// check that each file passed in to --file exists
|
|
57
|
+
|
|
58
|
+
const unmatchedFiles = [];
|
|
59
|
+
fileArgs.forEach(file => {
|
|
60
|
+
const fileAbsolutePath = path.resolve(file);
|
|
61
|
+
try {
|
|
62
|
+
// Used instead of fs.existsSync to ensure that file-ending less files are still resolved correctly
|
|
63
|
+
require.resolve(fileAbsolutePath);
|
|
64
|
+
} catch (err) {
|
|
65
|
+
if (err.code === 'MODULE_NOT_FOUND') {
|
|
66
|
+
unmatchedFiles.push({
|
|
67
|
+
pattern: file,
|
|
68
|
+
absolutePath: fileAbsolutePath
|
|
69
|
+
});
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
throw err;
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
|
|
55
77
|
// ensure we don't sort the stuff from fileArgs; order is important!
|
|
56
78
|
if (sort) {
|
|
57
79
|
specFiles.sort();
|
|
@@ -67,19 +89,24 @@ module.exports = ({
|
|
|
67
89
|
if (!files.length) {
|
|
68
90
|
// give full message details when only 1 file is missing
|
|
69
91
|
const noneFoundMsg =
|
|
70
|
-
|
|
71
|
-
? `Error: No test files found: ${JSON.stringify(
|
|
92
|
+
unmatchedSpecFiles.length === 1
|
|
93
|
+
? `Error: No test files found: ${JSON.stringify(
|
|
94
|
+
unmatchedSpecFiles[0].pattern
|
|
95
|
+
)}` // stringify to print escaped characters raw
|
|
72
96
|
: 'Error: No test files found';
|
|
73
97
|
console.error(ansi.red(noneFoundMsg));
|
|
74
98
|
process.exit(1);
|
|
75
99
|
} else {
|
|
76
100
|
// print messages as a warning
|
|
77
|
-
|
|
101
|
+
unmatchedSpecFiles.forEach(warning => {
|
|
78
102
|
console.warn(ansi.yellow(`Warning: ${warning.message}`));
|
|
79
103
|
});
|
|
80
104
|
}
|
|
81
105
|
|
|
82
|
-
return
|
|
106
|
+
return {
|
|
107
|
+
files,
|
|
108
|
+
unmatchedFiles
|
|
109
|
+
};
|
|
83
110
|
};
|
|
84
111
|
|
|
85
112
|
/**
|
|
@@ -93,3 +120,18 @@ module.exports = ({
|
|
|
93
120
|
* @property {boolean} recursive - Find files recursively
|
|
94
121
|
* @property {boolean} sort - Sort test files
|
|
95
122
|
*/
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Diagnostic object containing unmatched files
|
|
126
|
+
* @typedef {Object} UnmatchedFile -
|
|
127
|
+
* @property {string} absolutePath - A list of unmatched files derived from the file arguments passed in.
|
|
128
|
+
* @property {string} pattern - A list of unmatched files derived from the file arguments passed in.
|
|
129
|
+
*
|
|
130
|
+
*/
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Response object containing a list of files to test and unmatched files.
|
|
134
|
+
* @typedef {Object} FileCollectionResponse
|
|
135
|
+
* @property {string[]} files - A list of files to test
|
|
136
|
+
* @property {UnmatchedFile[]} unmatchedFiles - A list of unmatched files derived from the file arguments passed in.
|
|
137
|
+
*/
|
package/lib/cli/run-helpers.js
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
const fs = require('fs');
|
|
11
11
|
const path = require('path');
|
|
12
|
+
const ansi = require('ansi-colors');
|
|
12
13
|
const debug = require('debug')('mocha:cli:run:helpers');
|
|
13
14
|
const {watchRun, watchParallelRun} = require('./watch-run');
|
|
14
15
|
const collectFiles = require('./collect-files');
|
|
@@ -16,6 +17,7 @@ const {format} = require('util');
|
|
|
16
17
|
const {createInvalidLegacyPluginError} = require('../errors');
|
|
17
18
|
const {requireOrImport} = require('../nodejs/esm-utils');
|
|
18
19
|
const PluginLoader = require('../plugin-loader');
|
|
20
|
+
const {UnmatchedFile} = require('./collect-files');
|
|
19
21
|
|
|
20
22
|
/**
|
|
21
23
|
* Exits Mocha when tests + code under test has finished execution (default)
|
|
@@ -106,6 +108,32 @@ exports.handleRequires = async (requires = [], {ignoredPlugins = []} = {}) => {
|
|
|
106
108
|
return plugins;
|
|
107
109
|
};
|
|
108
110
|
|
|
111
|
+
/**
|
|
112
|
+
* Logs errors and exits the app if unmatched files exist
|
|
113
|
+
* @param {Mocha} mocha - Mocha instance
|
|
114
|
+
* @param {UnmatchedFile} unmatchedFiles - object containing unmatched file paths
|
|
115
|
+
* @returns {Promise<Runner>}
|
|
116
|
+
* @private
|
|
117
|
+
*/
|
|
118
|
+
const handleUnmatchedFiles = (mocha, unmatchedFiles) => {
|
|
119
|
+
if (unmatchedFiles.length === 0) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
unmatchedFiles.forEach(({pattern, absolutePath}) => {
|
|
124
|
+
console.error(
|
|
125
|
+
ansi.yellow(
|
|
126
|
+
`Warning: Cannot find any files matching pattern "${pattern}" at the absolute path "${absolutePath}"`
|
|
127
|
+
)
|
|
128
|
+
);
|
|
129
|
+
});
|
|
130
|
+
console.log(
|
|
131
|
+
'No test file(s) found with the given pattern, exiting with code 1'
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
return mocha.run(exitMocha(1));
|
|
135
|
+
};
|
|
136
|
+
|
|
109
137
|
/**
|
|
110
138
|
* Collect and load test files, then run mocha instance.
|
|
111
139
|
* @param {Mocha} mocha - Mocha instance
|
|
@@ -117,9 +145,14 @@ exports.handleRequires = async (requires = [], {ignoredPlugins = []} = {}) => {
|
|
|
117
145
|
* @private
|
|
118
146
|
*/
|
|
119
147
|
const singleRun = async (mocha, {exit}, fileCollectParams) => {
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
148
|
+
const fileCollectionObj = collectFiles(fileCollectParams);
|
|
149
|
+
|
|
150
|
+
if (fileCollectionObj.unmatchedFiles.length > 0) {
|
|
151
|
+
return handleUnmatchedFiles(mocha, fileCollectionObj.unmatchedFiles);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
debug('single run with %d file(s)', fileCollectionObj.files.length);
|
|
155
|
+
mocha.files = fileCollectionObj.files;
|
|
123
156
|
|
|
124
157
|
// handles ESM modules
|
|
125
158
|
await mocha.loadFilesAsync();
|
|
@@ -140,9 +173,17 @@ const singleRun = async (mocha, {exit}, fileCollectParams) => {
|
|
|
140
173
|
* @private
|
|
141
174
|
*/
|
|
142
175
|
const parallelRun = async (mocha, options, fileCollectParams) => {
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
|
|
176
|
+
const fileCollectionObj = collectFiles(fileCollectParams);
|
|
177
|
+
|
|
178
|
+
if (fileCollectionObj.unmatchedFiles.length > 0) {
|
|
179
|
+
return handleUnmatchedFiles(mocha, fileCollectionObj.unmatchedFiles);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
debug(
|
|
183
|
+
'executing %d test file(s) in parallel mode',
|
|
184
|
+
fileCollectionObj.files.length
|
|
185
|
+
);
|
|
186
|
+
mocha.files = fileCollectionObj.files;
|
|
146
187
|
|
|
147
188
|
// note that we DO NOT load any files here; this is handled by the worker
|
|
148
189
|
return mocha.run(options.exit ? exitMocha : exitMochaLater);
|
package/lib/cli/watch-run.js
CHANGED
|
@@ -58,7 +58,7 @@ exports.watchParallelRun = (
|
|
|
58
58
|
newMocha.suite.ctx = new Context();
|
|
59
59
|
|
|
60
60
|
// reset the list of files
|
|
61
|
-
newMocha.files = collectFiles(fileCollectParams);
|
|
61
|
+
newMocha.files = collectFiles(fileCollectParams).files;
|
|
62
62
|
|
|
63
63
|
// because we've swapped out the root suite (see the `run` inner function
|
|
64
64
|
// in `createRerunner`), we need to call `mocha.ui()` again to set up the context/globals.
|
|
@@ -120,7 +120,7 @@ exports.watchRun = (mocha, {watchFiles, watchIgnore}, fileCollectParams) => {
|
|
|
120
120
|
newMocha.suite.ctx = new Context();
|
|
121
121
|
|
|
122
122
|
// reset the list of files
|
|
123
|
-
newMocha.files = collectFiles(fileCollectParams);
|
|
123
|
+
newMocha.files = collectFiles(fileCollectParams).files;
|
|
124
124
|
|
|
125
125
|
// because we've swapped out the root suite (see the `run` inner function
|
|
126
126
|
// in `createRerunner`), we need to call `mocha.ui()` again to set up the context/globals.
|
package/lib/nodejs/serializer.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
'use strict';
|
|
8
8
|
|
|
9
|
-
const {type} = require('../utils');
|
|
9
|
+
const {type, breakCircularDeps} = require('../utils');
|
|
10
10
|
const {createInvalidArgumentTypeError} = require('../errors');
|
|
11
11
|
// this is not named `mocha:parallel:serializer` because it's noisy and it's
|
|
12
12
|
// helpful to be able to write `DEBUG=mocha:parallel*` and get everything else.
|
|
@@ -188,14 +188,9 @@ class SerializableEvent {
|
|
|
188
188
|
* @param {Array<object|string>} pairs - List of parent/key tuples to process; modified in-place. This JSDoc type is an approximation
|
|
189
189
|
* @param {object} parent - Some parent object
|
|
190
190
|
* @param {string} key - Key to inspect
|
|
191
|
-
* @param {WeakSet<Object>} seenObjects - For avoiding circular references
|
|
192
191
|
*/
|
|
193
|
-
static _serialize(pairs, parent, key
|
|
192
|
+
static _serialize(pairs, parent, key) {
|
|
194
193
|
let value = parent[key];
|
|
195
|
-
if (seenObjects.has(value)) {
|
|
196
|
-
parent[key] = Object.create(null);
|
|
197
|
-
return;
|
|
198
|
-
}
|
|
199
194
|
let _type = type(value);
|
|
200
195
|
if (_type === 'error') {
|
|
201
196
|
// we need to reference the stack prop b/c it's lazily-loaded.
|
|
@@ -263,13 +258,14 @@ class SerializableEvent {
|
|
|
263
258
|
error: this.originalError
|
|
264
259
|
});
|
|
265
260
|
|
|
261
|
+
// mutates the object
|
|
262
|
+
breakCircularDeps(result);
|
|
263
|
+
|
|
266
264
|
const pairs = Object.keys(result).map(key => [result, key]);
|
|
267
|
-
const seenObjects = new WeakSet();
|
|
268
265
|
|
|
269
266
|
let pair;
|
|
270
267
|
while ((pair = pairs.shift())) {
|
|
271
|
-
SerializableEvent._serialize(pairs, ...pair
|
|
272
|
-
seenObjects.add(pair[0]);
|
|
268
|
+
SerializableEvent._serialize(pairs, ...pair);
|
|
273
269
|
}
|
|
274
270
|
|
|
275
271
|
this.data = result.data;
|
package/lib/utils.js
CHANGED
|
@@ -647,3 +647,36 @@ exports.assignNewMochaID = obj => {
|
|
|
647
647
|
*/
|
|
648
648
|
exports.getMochaID = obj =>
|
|
649
649
|
obj && typeof obj === 'object' ? obj[MOCHA_ID_PROP_NAME] : undefined;
|
|
650
|
+
|
|
651
|
+
/**
|
|
652
|
+
* Replaces any detected circular dependency with the string '[Circular]'
|
|
653
|
+
* Mutates original object
|
|
654
|
+
* @param inputObj {*}
|
|
655
|
+
* @returns {*}
|
|
656
|
+
*/
|
|
657
|
+
exports.breakCircularDeps = inputObj => {
|
|
658
|
+
const seen = new Set();
|
|
659
|
+
|
|
660
|
+
function _breakCircularDeps(obj) {
|
|
661
|
+
if (obj && typeof obj !== 'object') {
|
|
662
|
+
return obj;
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
if (seen.has(obj)) {
|
|
666
|
+
return '[Circular]';
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
seen.add(obj);
|
|
670
|
+
for (const k in obj) {
|
|
671
|
+
if (Object.prototype.hasOwnProperty.call(obj, k)) {
|
|
672
|
+
obj[k] = _breakCircularDeps(obj[k], k);
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
// deleting means only a seen object that is its own child will be detected
|
|
677
|
+
seen.delete(obj);
|
|
678
|
+
return obj;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
return _breakCircularDeps(inputObj);
|
|
682
|
+
};
|
package/mocha.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// mocha@10.5.
|
|
1
|
+
// mocha@10.5.2 in javascript ES2018
|
|
2
2
|
(function (global, factory) {
|
|
3
3
|
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
|
4
4
|
typeof define === 'function' && define.amd ? define(factory) :
|
|
@@ -11460,6 +11460,39 @@
|
|
|
11460
11460
|
*/
|
|
11461
11461
|
exports.getMochaID = obj =>
|
|
11462
11462
|
obj && typeof obj === 'object' ? obj[MOCHA_ID_PROP_NAME] : undefined;
|
|
11463
|
+
|
|
11464
|
+
/**
|
|
11465
|
+
* Replaces any detected circular dependency with the string '[Circular]'
|
|
11466
|
+
* Mutates original object
|
|
11467
|
+
* @param inputObj {*}
|
|
11468
|
+
* @returns {*}
|
|
11469
|
+
*/
|
|
11470
|
+
exports.breakCircularDeps = inputObj => {
|
|
11471
|
+
const seen = new Set();
|
|
11472
|
+
|
|
11473
|
+
function _breakCircularDeps(obj) {
|
|
11474
|
+
if (obj && typeof obj !== 'object') {
|
|
11475
|
+
return obj;
|
|
11476
|
+
}
|
|
11477
|
+
|
|
11478
|
+
if (seen.has(obj)) {
|
|
11479
|
+
return '[Circular]';
|
|
11480
|
+
}
|
|
11481
|
+
|
|
11482
|
+
seen.add(obj);
|
|
11483
|
+
for (const k in obj) {
|
|
11484
|
+
if (Object.prototype.hasOwnProperty.call(obj, k)) {
|
|
11485
|
+
obj[k] = _breakCircularDeps(obj[k]);
|
|
11486
|
+
}
|
|
11487
|
+
}
|
|
11488
|
+
|
|
11489
|
+
// deleting means only a seen object that is its own child will be detected
|
|
11490
|
+
seen.delete(obj);
|
|
11491
|
+
return obj;
|
|
11492
|
+
}
|
|
11493
|
+
|
|
11494
|
+
return _breakCircularDeps(inputObj);
|
|
11495
|
+
};
|
|
11463
11496
|
}(utils$3));
|
|
11464
11497
|
|
|
11465
11498
|
var _nodeResolve_empty = {};
|
|
@@ -18986,7 +19019,7 @@
|
|
|
18986
19019
|
};
|
|
18987
19020
|
|
|
18988
19021
|
var name = "mocha";
|
|
18989
|
-
var version = "10.5.
|
|
19022
|
+
var version = "10.5.2";
|
|
18990
19023
|
var homepage = "https://mochajs.org/";
|
|
18991
19024
|
var notifyLogo = "https://ibin.co/4QuRuGjXvl36.png";
|
|
18992
19025
|
var require$$17 = {
|