mocha 11.7.4 → 11.7.6
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/bin/_mocha +2 -2
- package/bin/mocha.js +46 -44
- package/browser-entry.js +20 -20
- package/index.js +2 -2
- package/lib/browser/highlight-tags.js +6 -6
- package/lib/browser/parse-query.js +5 -5
- package/lib/browser/template.html +2 -2
- package/lib/cli/cli.js +32 -27
- package/lib/cli/collect-files.js +25 -25
- package/lib/cli/commands.js +4 -4
- package/lib/cli/config.js +26 -25
- package/lib/cli/index.js +2 -2
- package/lib/cli/init.js +19 -19
- package/lib/cli/lookup-files.js +20 -20
- package/lib/cli/node-flags.js +12 -12
- package/lib/cli/one-and-dones.js +12 -11
- package/lib/cli/options.js +49 -49
- package/lib/cli/run-helpers.js +52 -54
- package/lib/cli/run-option-metadata.js +75 -75
- package/lib/cli/run.js +164 -159
- package/lib/cli/watch-run.js +75 -75
- package/lib/context.js +1 -1
- package/lib/error-constants.js +17 -17
- package/lib/errors.js +26 -26
- package/lib/hook.js +9 -9
- package/lib/interfaces/bdd.js +8 -8
- package/lib/interfaces/common.js +12 -12
- package/lib/interfaces/exports.js +8 -8
- package/lib/interfaces/index.js +5 -5
- package/lib/interfaces/qunit.js +7 -7
- package/lib/interfaces/tdd.js +7 -7
- package/lib/mocha.js +97 -97
- package/lib/nodejs/buffered-worker-pool.js +30 -30
- package/lib/nodejs/esm-utils.js +24 -21
- package/lib/nodejs/file-unloader.js +2 -2
- package/lib/nodejs/parallel-buffered-runner.js +67 -67
- package/lib/nodejs/reporters/parallel-buffered.js +13 -10
- package/lib/nodejs/serializer.js +47 -47
- package/lib/nodejs/worker.js +38 -38
- package/lib/pending.js +1 -1
- package/lib/plugin-loader.js +48 -48
- package/lib/reporters/base.js +97 -94
- package/lib/reporters/doc.js +17 -17
- package/lib/reporters/dot.js +14 -14
- package/lib/reporters/html.js +73 -67
- package/lib/reporters/index.js +16 -16
- package/lib/reporters/json-stream.js +10 -10
- package/lib/reporters/json.js +16 -16
- package/lib/reporters/landing.js +20 -20
- package/lib/reporters/list.js +10 -10
- package/lib/reporters/markdown.js +21 -21
- package/lib/reporters/min.js +7 -7
- package/lib/reporters/nyan.js +35 -35
- package/lib/reporters/progress.js +14 -14
- package/lib/reporters/spec.js +15 -15
- package/lib/reporters/tap.js +26 -26
- package/lib/reporters/xunit.js +38 -34
- package/lib/runnable.js +41 -41
- package/lib/runner.js +105 -105
- package/lib/stats-collector.js +4 -4
- package/lib/suite.js +56 -46
- package/lib/test.js +10 -10
- package/lib/utils.js +122 -122
- package/mocha.css +68 -50
- package/mocha.js +826 -803
- package/mocha.js.map +1 -1
- package/package.json +8 -13
package/lib/nodejs/esm-utils.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
const path = require(
|
|
2
|
-
const url = require(
|
|
3
|
-
const debug = require(
|
|
1
|
+
const path = require("node:path");
|
|
2
|
+
const url = require("node:url");
|
|
3
|
+
const debug = require("debug")("mocha:esm-utils");
|
|
4
4
|
|
|
5
|
-
const forward = x => x;
|
|
5
|
+
const forward = (x) => x;
|
|
6
6
|
|
|
7
7
|
const formattedImport = async (file, esmDecorator = forward) => {
|
|
8
8
|
if (path.isAbsolute(file)) {
|
|
@@ -23,7 +23,7 @@ const formattedImport = async (file, esmDecorator = forward) => {
|
|
|
23
23
|
const newErrorWithFilename = new SyntaxError(err.message);
|
|
24
24
|
newErrorWithFilename.stack = err.stack.replace(
|
|
25
25
|
/^SyntaxError/,
|
|
26
|
-
`SyntaxError[ @${file} ]
|
|
26
|
+
`SyntaxError[ @${file} ]`,
|
|
27
27
|
);
|
|
28
28
|
throw newErrorWithFilename;
|
|
29
29
|
}
|
|
@@ -33,23 +33,23 @@ const formattedImport = async (file, esmDecorator = forward) => {
|
|
|
33
33
|
return exports.doImport(esmDecorator(file));
|
|
34
34
|
};
|
|
35
35
|
|
|
36
|
-
exports.doImport = async file => import(file);
|
|
36
|
+
exports.doImport = async (file) => import(file);
|
|
37
37
|
|
|
38
38
|
// When require(esm) is not available, we need to use `import()` to load ESM modules.
|
|
39
39
|
// In this case, CJS modules are loaded using `import()` as well. When Node.js' builtin
|
|
40
40
|
// TypeScript support is enabled, `.ts` files are also loaded using `import()`, and
|
|
41
41
|
// compilers based on `require.extensions` are omitted.
|
|
42
42
|
const tryImportAndRequire = async (file, esmDecorator) => {
|
|
43
|
-
if (path.extname(file) ===
|
|
43
|
+
if (path.extname(file) === ".mjs") {
|
|
44
44
|
return formattedImport(file, esmDecorator);
|
|
45
45
|
}
|
|
46
46
|
try {
|
|
47
47
|
return dealWithExports(await formattedImport(file, esmDecorator));
|
|
48
48
|
} catch (err) {
|
|
49
49
|
if (
|
|
50
|
-
err.code ===
|
|
51
|
-
err.code ===
|
|
52
|
-
err.code ===
|
|
50
|
+
err.code === "ERR_MODULE_NOT_FOUND" ||
|
|
51
|
+
err.code === "ERR_UNKNOWN_FILE_EXTENSION" ||
|
|
52
|
+
err.code === "ERR_UNSUPPORTED_DIR_IMPORT"
|
|
53
53
|
) {
|
|
54
54
|
try {
|
|
55
55
|
// Importing a file usually works, but the resolution of `import` is the ESM
|
|
@@ -58,11 +58,11 @@ const tryImportAndRequire = async (file, esmDecorator) => {
|
|
|
58
58
|
return require(file);
|
|
59
59
|
} catch (requireErr) {
|
|
60
60
|
if (
|
|
61
|
-
requireErr.code ===
|
|
61
|
+
requireErr.code === "ERR_REQUIRE_ESM" ||
|
|
62
62
|
(requireErr instanceof SyntaxError &&
|
|
63
63
|
requireErr
|
|
64
64
|
.toString()
|
|
65
|
-
.includes(
|
|
65
|
+
.includes("Cannot use import statement outside a module"))
|
|
66
66
|
) {
|
|
67
67
|
// ERR_REQUIRE_ESM happens when the test file is a JS file, but via type:module is actually ESM,
|
|
68
68
|
// AND has an import to a file that doesn't exist.
|
|
@@ -91,13 +91,13 @@ const tryImportAndRequire = async (file, esmDecorator) => {
|
|
|
91
91
|
// and `require.cache` effective, while allowing us to load ESM modules
|
|
92
92
|
// and CJS modules in the same way.
|
|
93
93
|
const requireModule = async (file, esmDecorator) => {
|
|
94
|
-
if (path.extname(file) ===
|
|
94
|
+
if (path.extname(file) === ".mjs") {
|
|
95
95
|
return formattedImport(file, esmDecorator);
|
|
96
96
|
}
|
|
97
97
|
try {
|
|
98
98
|
return require(file);
|
|
99
99
|
} catch (requireErr) {
|
|
100
|
-
debug(
|
|
100
|
+
debug("requireModule caught err: %O", requireErr.message);
|
|
101
101
|
try {
|
|
102
102
|
return dealWithExports(await formattedImport(file, esmDecorator));
|
|
103
103
|
} catch (importErr) {
|
|
@@ -106,8 +106,8 @@ const requireModule = async (file, esmDecorator) => {
|
|
|
106
106
|
// What we actually care about is the original require() error.
|
|
107
107
|
// See: https://github.com/mochajs/mocha/issues/5393
|
|
108
108
|
if (
|
|
109
|
-
/\.(cts|mts|ts)$/.test(file)
|
|
110
|
-
importErr.code ===
|
|
109
|
+
/\.(cts|mts|ts)$/.test(file) &&
|
|
110
|
+
importErr.code === "ERR_UNKNOWN_FILE_EXTENSION"
|
|
111
111
|
) {
|
|
112
112
|
throw requireErr;
|
|
113
113
|
}
|
|
@@ -115,7 +115,7 @@ const requireModule = async (file, esmDecorator) => {
|
|
|
115
115
|
// Similarly, for an exports/imports mismatch such as a missing 'default',
|
|
116
116
|
// the require() error will be more informative for users.
|
|
117
117
|
// See: https://github.com/mochajs/mocha/issues/5411
|
|
118
|
-
if (importErr.code ===
|
|
118
|
+
if (importErr.code === "ERR_INTERNAL_ASSERTION") {
|
|
119
119
|
throw requireErr;
|
|
120
120
|
}
|
|
121
121
|
|
|
@@ -126,7 +126,10 @@ const requireModule = async (file, esmDecorator) => {
|
|
|
126
126
|
|
|
127
127
|
// We only assign this `requireOrImport` function once based on Node version
|
|
128
128
|
// We check for file extensions in `requireModule` and `tryImportAndRequire`
|
|
129
|
-
debug(
|
|
129
|
+
debug(
|
|
130
|
+
"assigning requireOrImport, require_module === %O",
|
|
131
|
+
process.features.require_module,
|
|
132
|
+
);
|
|
130
133
|
if (process.features.require_module) {
|
|
131
134
|
exports.requireOrImport = requireModule;
|
|
132
135
|
} else {
|
|
@@ -137,7 +140,7 @@ function dealWithExports(module) {
|
|
|
137
140
|
if (module.default) {
|
|
138
141
|
return module.default;
|
|
139
142
|
} else {
|
|
140
|
-
return {...module, default: undefined};
|
|
143
|
+
return { ...module, default: undefined };
|
|
141
144
|
}
|
|
142
145
|
}
|
|
143
146
|
|
|
@@ -145,13 +148,13 @@ exports.loadFilesAsync = async (
|
|
|
145
148
|
files,
|
|
146
149
|
preLoadFunc,
|
|
147
150
|
postLoadFunc,
|
|
148
|
-
esmDecorator
|
|
151
|
+
esmDecorator,
|
|
149
152
|
) => {
|
|
150
153
|
for (const file of files) {
|
|
151
154
|
preLoadFunc(file);
|
|
152
155
|
const result = await exports.requireOrImport(
|
|
153
156
|
path.resolve(file),
|
|
154
|
-
esmDecorator
|
|
157
|
+
esmDecorator,
|
|
155
158
|
);
|
|
156
159
|
postLoadFunc(file, result);
|
|
157
160
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* This module should not be in the browser bundle, so it's here.
|
|
@@ -10,6 +10,6 @@
|
|
|
10
10
|
* Deletes a file from the `require` cache.
|
|
11
11
|
* @param {string} file - File
|
|
12
12
|
*/
|
|
13
|
-
exports.unloadFile = file => {
|
|
13
|
+
exports.unloadFile = (file) => {
|
|
14
14
|
delete require.cache[require.resolve(file)];
|
|
15
15
|
};
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @private
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
"use strict";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* @typedef {import('../types.d.ts').FileRunner} FileRunner
|
|
@@ -13,29 +13,29 @@
|
|
|
13
13
|
* @typedef {import('../types.d.ts').SigIntListener} SigIntListener
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
const Runner = require(
|
|
17
|
-
const {EVENT_RUN_BEGIN, EVENT_RUN_END} = Runner.constants;
|
|
18
|
-
const debug = require(
|
|
19
|
-
const {BufferedWorkerPool} = require(
|
|
20
|
-
const {setInterval, clearInterval} = global;
|
|
21
|
-
const {createMap, constants} = require(
|
|
22
|
-
const {MOCHA_ID_PROP_NAME} = constants;
|
|
23
|
-
const {createFatalError} = require(
|
|
16
|
+
const Runner = require("../runner");
|
|
17
|
+
const { EVENT_RUN_BEGIN, EVENT_RUN_END } = Runner.constants;
|
|
18
|
+
const debug = require("debug")("mocha:parallel:parallel-buffered-runner");
|
|
19
|
+
const { BufferedWorkerPool } = require("./buffered-worker-pool");
|
|
20
|
+
const { setInterval, clearInterval } = global;
|
|
21
|
+
const { createMap, constants } = require("../utils");
|
|
22
|
+
const { MOCHA_ID_PROP_NAME } = constants;
|
|
23
|
+
const { createFatalError } = require("../errors");
|
|
24
24
|
|
|
25
25
|
const DEFAULT_WORKER_REPORTER = require.resolve(
|
|
26
|
-
|
|
26
|
+
"./reporters/parallel-buffered",
|
|
27
27
|
);
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* List of options to _not_ serialize for transmission to workers
|
|
31
31
|
*/
|
|
32
32
|
const DENY_OPTIONS = [
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
33
|
+
"globalSetup",
|
|
34
|
+
"globalTeardown",
|
|
35
|
+
"parallel",
|
|
36
|
+
"p",
|
|
37
|
+
"jobs",
|
|
38
|
+
"j",
|
|
39
39
|
];
|
|
40
40
|
|
|
41
41
|
/**
|
|
@@ -43,14 +43,14 @@ const DENY_OPTIONS = [
|
|
|
43
43
|
* @param {BufferedWorkerPool} pool - Worker pool
|
|
44
44
|
*/
|
|
45
45
|
/* istanbul ignore next */
|
|
46
|
-
const debugStats = pool => {
|
|
47
|
-
const {totalWorkers, busyWorkers, idleWorkers, pendingTasks} = pool.stats();
|
|
46
|
+
const debugStats = (pool) => {
|
|
47
|
+
const { totalWorkers, busyWorkers, idleWorkers, pendingTasks } = pool.stats();
|
|
48
48
|
debug(
|
|
49
|
-
|
|
49
|
+
"%d/%d busy workers; %d idle; %d tasks queued",
|
|
50
50
|
busyWorkers,
|
|
51
51
|
totalWorkers,
|
|
52
52
|
idleWorkers,
|
|
53
|
-
pendingTasks
|
|
53
|
+
pendingTasks,
|
|
54
54
|
);
|
|
55
55
|
};
|
|
56
56
|
|
|
@@ -59,13 +59,13 @@ const debugStats = pool => {
|
|
|
59
59
|
*/
|
|
60
60
|
const DEBUG_STATS_INTERVAL = 5000;
|
|
61
61
|
|
|
62
|
-
const ABORTED =
|
|
63
|
-
const IDLE =
|
|
64
|
-
const ABORTING =
|
|
65
|
-
const RUNNING =
|
|
66
|
-
const BAILING =
|
|
67
|
-
const BAILED =
|
|
68
|
-
const COMPLETE =
|
|
62
|
+
const ABORTED = "ABORTED";
|
|
63
|
+
const IDLE = "IDLE";
|
|
64
|
+
const ABORTING = "ABORTING";
|
|
65
|
+
const RUNNING = "RUNNING";
|
|
66
|
+
const BAILING = "BAILING";
|
|
67
|
+
const BAILED = "BAILED";
|
|
68
|
+
const COMPLETE = "COMPLETE";
|
|
69
69
|
|
|
70
70
|
const states = createMap({
|
|
71
71
|
[IDLE]: new Set([RUNNING, ABORTING]),
|
|
@@ -74,7 +74,7 @@ const states = createMap({
|
|
|
74
74
|
[ABORTED]: new Set(),
|
|
75
75
|
[ABORTING]: new Set([ABORTED]),
|
|
76
76
|
[BAILING]: new Set([BAILED, ABORTING]),
|
|
77
|
-
[BAILED]: new Set([COMPLETE, ABORTING])
|
|
77
|
+
[BAILED]: new Set([COMPLETE, ABORTING]),
|
|
78
78
|
});
|
|
79
79
|
|
|
80
80
|
/**
|
|
@@ -87,7 +87,7 @@ class ParallelBufferedRunner extends Runner {
|
|
|
87
87
|
super(...args);
|
|
88
88
|
|
|
89
89
|
let state = IDLE;
|
|
90
|
-
Object.defineProperty(this,
|
|
90
|
+
Object.defineProperty(this, "_state", {
|
|
91
91
|
get() {
|
|
92
92
|
return state;
|
|
93
93
|
},
|
|
@@ -97,7 +97,7 @@ class ParallelBufferedRunner extends Runner {
|
|
|
97
97
|
} else {
|
|
98
98
|
throw new Error(`invalid state transition: ${state} => ${newState}`);
|
|
99
99
|
}
|
|
100
|
-
}
|
|
100
|
+
},
|
|
101
101
|
});
|
|
102
102
|
|
|
103
103
|
this._workerReporter = DEFAULT_WORKER_REPORTER;
|
|
@@ -130,7 +130,7 @@ class ParallelBufferedRunner extends Runner {
|
|
|
130
130
|
event.data._bail &&
|
|
131
131
|
(failureCount || event.error)
|
|
132
132
|
) {
|
|
133
|
-
debug(
|
|
133
|
+
debug("run(): nonzero failure count & found bail flag");
|
|
134
134
|
// we need to let the events complete for this file, as the worker
|
|
135
135
|
// should run any cleanup hooks
|
|
136
136
|
this._state = BAILING;
|
|
@@ -141,13 +141,13 @@ class ParallelBufferedRunner extends Runner {
|
|
|
141
141
|
* Given an event, recursively find any objects in its data that have ID's, and create object references to already-seen objects.
|
|
142
142
|
* @param {Object} event - Event having `eventName`, maybe `data` and maybe `error`
|
|
143
143
|
*/
|
|
144
|
-
const linkEvent = event => {
|
|
145
|
-
const stack = [{parent: event, prop:
|
|
144
|
+
const linkEvent = (event) => {
|
|
145
|
+
const stack = [{ parent: event, prop: "data" }];
|
|
146
146
|
while (stack.length) {
|
|
147
|
-
const {parent, prop} = stack.pop();
|
|
147
|
+
const { parent, prop } = stack.pop();
|
|
148
148
|
const obj = parent[prop];
|
|
149
149
|
let newObj;
|
|
150
|
-
if (obj && typeof obj ===
|
|
150
|
+
if (obj && typeof obj === "object") {
|
|
151
151
|
if (obj[MOCHA_ID_PROP_NAME]) {
|
|
152
152
|
const id = obj[MOCHA_ID_PROP_NAME];
|
|
153
153
|
newObj = this._linkedObjectMap.has(id)
|
|
@@ -157,24 +157,24 @@ class ParallelBufferedRunner extends Runner {
|
|
|
157
157
|
parent[prop] = newObj;
|
|
158
158
|
} else {
|
|
159
159
|
throw createFatalError(
|
|
160
|
-
|
|
161
|
-
obj
|
|
160
|
+
"Object missing ID received in event data",
|
|
161
|
+
obj,
|
|
162
162
|
);
|
|
163
163
|
}
|
|
164
164
|
}
|
|
165
|
-
Object.keys(newObj).forEach(key => {
|
|
165
|
+
Object.keys(newObj).forEach((key) => {
|
|
166
166
|
const value = obj[key];
|
|
167
|
-
if (value && typeof value ===
|
|
168
|
-
stack.push({obj: value, parent: newObj, prop: key});
|
|
167
|
+
if (value && typeof value === "object" && value[MOCHA_ID_PROP_NAME]) {
|
|
168
|
+
stack.push({ obj: value, parent: newObj, prop: key });
|
|
169
169
|
}
|
|
170
170
|
});
|
|
171
171
|
}
|
|
172
172
|
};
|
|
173
173
|
|
|
174
|
-
return async file => {
|
|
175
|
-
debug(
|
|
174
|
+
return async (file) => {
|
|
175
|
+
debug("run(): enqueueing test file %s", file);
|
|
176
176
|
try {
|
|
177
|
-
const {failureCount, events} = await pool.run(file, options);
|
|
177
|
+
const { failureCount, events } = await pool.run(file, options);
|
|
178
178
|
|
|
179
179
|
if (this._state === BAILED) {
|
|
180
180
|
// short-circuit after a graceful bail. if this happens,
|
|
@@ -184,10 +184,10 @@ class ParallelBufferedRunner extends Runner {
|
|
|
184
184
|
return;
|
|
185
185
|
}
|
|
186
186
|
debug(
|
|
187
|
-
|
|
187
|
+
"run(): completed run of file %s; %d failures / %d events",
|
|
188
188
|
file,
|
|
189
189
|
failureCount,
|
|
190
|
-
events.length
|
|
190
|
+
events.length,
|
|
191
191
|
);
|
|
192
192
|
this.failures += failureCount; // can this ever be non-numeric?
|
|
193
193
|
let event = events.shift();
|
|
@@ -212,12 +212,12 @@ class ParallelBufferedRunner extends Runner {
|
|
|
212
212
|
} catch (err) {
|
|
213
213
|
if (this._state === BAILED || this._state === ABORTING) {
|
|
214
214
|
debug(
|
|
215
|
-
|
|
216
|
-
file
|
|
215
|
+
"run(): worker pool terminated with intent; skipping file %s",
|
|
216
|
+
file,
|
|
217
217
|
);
|
|
218
218
|
} else {
|
|
219
219
|
// this is an uncaught exception
|
|
220
|
-
debug(
|
|
220
|
+
debug("run(): encountered uncaught exception: %O", err);
|
|
221
221
|
if (this.allowUncaught) {
|
|
222
222
|
// still have to clean up
|
|
223
223
|
this._state = ABORTING;
|
|
@@ -226,7 +226,7 @@ class ParallelBufferedRunner extends Runner {
|
|
|
226
226
|
throw err;
|
|
227
227
|
}
|
|
228
228
|
} finally {
|
|
229
|
-
debug(
|
|
229
|
+
debug("run(): done running file %s", file);
|
|
230
230
|
}
|
|
231
231
|
};
|
|
232
232
|
}
|
|
@@ -240,27 +240,27 @@ class ParallelBufferedRunner extends Runner {
|
|
|
240
240
|
*/
|
|
241
241
|
_bindSigIntListener(pool) {
|
|
242
242
|
const sigIntListener = async () => {
|
|
243
|
-
debug(
|
|
243
|
+
debug("run(): caught a SIGINT");
|
|
244
244
|
this._state = ABORTING;
|
|
245
245
|
|
|
246
246
|
try {
|
|
247
|
-
debug(
|
|
247
|
+
debug("run(): force-terminating worker pool");
|
|
248
248
|
await pool.terminate(true);
|
|
249
249
|
} catch (err) {
|
|
250
250
|
console.error(
|
|
251
|
-
`Error while attempting to force-terminate worker pool: ${err}
|
|
251
|
+
`Error while attempting to force-terminate worker pool: ${err}`,
|
|
252
252
|
);
|
|
253
253
|
process.exitCode = 1;
|
|
254
254
|
} finally {
|
|
255
255
|
process.nextTick(() => {
|
|
256
|
-
debug(
|
|
256
|
+
debug("run(): imminent death");
|
|
257
257
|
this._state = ABORTED;
|
|
258
|
-
process.kill(process.pid,
|
|
258
|
+
process.kill(process.pid, "SIGINT");
|
|
259
259
|
});
|
|
260
260
|
}
|
|
261
261
|
};
|
|
262
262
|
|
|
263
|
-
process.once(
|
|
263
|
+
process.once("SIGINT", sigIntListener);
|
|
264
264
|
|
|
265
265
|
return sigIntListener;
|
|
266
266
|
}
|
|
@@ -279,7 +279,7 @@ class ParallelBufferedRunner extends Runner {
|
|
|
279
279
|
* number of test failures.
|
|
280
280
|
* @param {RunnerOptions} [opts] - options
|
|
281
281
|
*/
|
|
282
|
-
run(callback, {files, options = {}} = {}) {
|
|
282
|
+
run(callback, { files, options = {} } = {}) {
|
|
283
283
|
/**
|
|
284
284
|
* Listener on `Process.SIGINT` which tries to cleanly terminate the worker pool.
|
|
285
285
|
*/
|
|
@@ -287,7 +287,7 @@ class ParallelBufferedRunner extends Runner {
|
|
|
287
287
|
|
|
288
288
|
// assign the reporter the worker will use, which will be different than the
|
|
289
289
|
// main process' reporter
|
|
290
|
-
options = {...options, reporter: this._workerReporter};
|
|
290
|
+
options = { ...options, reporter: this._workerReporter };
|
|
291
291
|
|
|
292
292
|
// This function should _not_ return a `Promise`; its parent (`Runner#run`)
|
|
293
293
|
// returns this instance, so this should do the same. However, we want to make
|
|
@@ -304,14 +304,14 @@ class ParallelBufferedRunner extends Runner {
|
|
|
304
304
|
let pool;
|
|
305
305
|
|
|
306
306
|
try {
|
|
307
|
-
pool = BufferedWorkerPool.create({maxWorkers: options.jobs});
|
|
307
|
+
pool = BufferedWorkerPool.create({ maxWorkers: options.jobs });
|
|
308
308
|
|
|
309
309
|
sigIntListener = this._bindSigIntListener(pool);
|
|
310
310
|
|
|
311
311
|
/* istanbul ignore next */
|
|
312
312
|
debugInterval = setInterval(
|
|
313
313
|
() => debugStats(pool),
|
|
314
|
-
DEBUG_STATS_INTERVAL
|
|
314
|
+
DEBUG_STATS_INTERVAL,
|
|
315
315
|
).unref();
|
|
316
316
|
|
|
317
317
|
// this is set for uncaught exception handling in `Runner#uncaught`
|
|
@@ -321,21 +321,21 @@ class ParallelBufferedRunner extends Runner {
|
|
|
321
321
|
|
|
322
322
|
this.emit(EVENT_RUN_BEGIN);
|
|
323
323
|
|
|
324
|
-
options = {...options};
|
|
325
|
-
DENY_OPTIONS.forEach(opt => {
|
|
324
|
+
options = { ...options };
|
|
325
|
+
DENY_OPTIONS.forEach((opt) => {
|
|
326
326
|
delete options[opt];
|
|
327
327
|
});
|
|
328
328
|
|
|
329
329
|
const results = await Promise.allSettled(
|
|
330
|
-
files.map(this._createFileRunner(pool, options))
|
|
330
|
+
files.map(this._createFileRunner(pool, options)),
|
|
331
331
|
);
|
|
332
332
|
|
|
333
333
|
// note that pool may already be terminated due to --bail
|
|
334
334
|
await pool.terminate();
|
|
335
335
|
|
|
336
336
|
results
|
|
337
|
-
.filter(({status}) => status ===
|
|
338
|
-
.forEach(({reason}) => {
|
|
337
|
+
.filter(({ status }) => status === "rejected")
|
|
338
|
+
.forEach(({ reason }) => {
|
|
339
339
|
if (this.allowUncaught) {
|
|
340
340
|
// yep, just the first one.
|
|
341
341
|
throw reason;
|
|
@@ -350,19 +350,19 @@ class ParallelBufferedRunner extends Runner {
|
|
|
350
350
|
}
|
|
351
351
|
|
|
352
352
|
this.emit(EVENT_RUN_END);
|
|
353
|
-
debug(
|
|
353
|
+
debug("run(): completing with failure count %d", this.failures);
|
|
354
354
|
callback(this.failures);
|
|
355
355
|
} catch (err) {
|
|
356
356
|
// this `nextTick` takes us out of the `Promise` scope, so the
|
|
357
357
|
// exception will not be caught and returned as a rejected `Promise`,
|
|
358
358
|
// which would lead to an `unhandledRejection` event.
|
|
359
359
|
process.nextTick(() => {
|
|
360
|
-
debug(
|
|
360
|
+
debug("run(): re-throwing uncaught exception");
|
|
361
361
|
throw err;
|
|
362
362
|
});
|
|
363
363
|
} finally {
|
|
364
364
|
clearInterval(debugInterval);
|
|
365
|
-
process.removeListener(
|
|
365
|
+
process.removeListener("SIGINT", sigIntListener);
|
|
366
366
|
}
|
|
367
367
|
})();
|
|
368
368
|
return this;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @public
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
"use strict";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* @typedef {import('../../types.d.ts').BufferedEvent} BufferedEvent
|
|
@@ -28,11 +28,14 @@ const {
|
|
|
28
28
|
EVENT_DELAY_END,
|
|
29
29
|
EVENT_HOOK_BEGIN,
|
|
30
30
|
EVENT_HOOK_END,
|
|
31
|
-
EVENT_RUN_END
|
|
32
|
-
} = require(
|
|
33
|
-
const {
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
EVENT_RUN_END,
|
|
32
|
+
} = require("../../runner").constants;
|
|
33
|
+
const {
|
|
34
|
+
SerializableEvent,
|
|
35
|
+
SerializableWorkerResult,
|
|
36
|
+
} = require("../serializer");
|
|
37
|
+
const debug = require("debug")("mocha:reporters:buffered");
|
|
38
|
+
const Base = require("../../reporters/base");
|
|
36
39
|
|
|
37
40
|
/**
|
|
38
41
|
* List of events to listen to; these will be buffered and sent
|
|
@@ -48,7 +51,7 @@ const EVENT_NAMES = [
|
|
|
48
51
|
EVENT_TEST_RETRY,
|
|
49
52
|
EVENT_TEST_END,
|
|
50
53
|
EVENT_HOOK_BEGIN,
|
|
51
|
-
EVENT_HOOK_END
|
|
54
|
+
EVENT_HOOK_END,
|
|
52
55
|
];
|
|
53
56
|
|
|
54
57
|
/**
|
|
@@ -122,15 +125,15 @@ class ParallelBuffered extends Base {
|
|
|
122
125
|
* @chainable
|
|
123
126
|
*/
|
|
124
127
|
createListeners(runner) {
|
|
125
|
-
EVENT_NAMES.forEach(evt => {
|
|
128
|
+
EVENT_NAMES.forEach((evt) => {
|
|
126
129
|
runner.on(evt, this.createListener(evt));
|
|
127
130
|
});
|
|
128
|
-
ONCE_EVENT_NAMES.forEach(evt => {
|
|
131
|
+
ONCE_EVENT_NAMES.forEach((evt) => {
|
|
129
132
|
runner.once(evt, this.createListener(evt));
|
|
130
133
|
});
|
|
131
134
|
|
|
132
135
|
runner.once(EVENT_RUN_END, () => {
|
|
133
|
-
debug(
|
|
136
|
+
debug("received EVENT_RUN_END");
|
|
134
137
|
this.listeners.forEach((listener, evt) => {
|
|
135
138
|
runner.removeListener(evt, listener);
|
|
136
139
|
this.listeners.delete(evt);
|