mocha 8.1.2 → 8.3.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 +99 -1
- package/LICENSE +1 -1
- package/README.md +13 -2
- package/bin/mocha +0 -3
- package/lib/browser/growl.js +1 -1
- package/lib/cli/cli.js +19 -8
- package/lib/cli/collect-files.js +25 -25
- package/lib/cli/config.js +1 -2
- package/lib/cli/index.js +0 -6
- package/lib/cli/lookup-files.js +37 -31
- package/lib/cli/options.js +7 -5
- package/lib/cli/run-helpers.js +21 -56
- package/lib/cli/run.js +5 -9
- package/lib/cli/watch-run.js +55 -30
- package/lib/errors.js +231 -24
- package/lib/esm-utils.js +23 -1
- package/lib/hook.js +14 -9
- package/lib/mocha.js +264 -64
- package/lib/nodejs/buffered-worker-pool.js +1 -3
- package/lib/nodejs/file-unloader.js +15 -0
- package/lib/nodejs/parallel-buffered-runner.js +156 -18
- package/lib/nodejs/reporters/parallel-buffered.js +61 -29
- package/lib/nodejs/serializer.js +14 -6
- package/lib/nodejs/worker.js +9 -12
- package/lib/plugin-loader.js +286 -0
- package/lib/reporters/json-stream.js +2 -1
- package/lib/reporters/json.js +1 -0
- package/lib/runnable.js +13 -8
- package/lib/runner.js +238 -109
- package/lib/suite.js +34 -15
- package/lib/test.js +6 -2
- package/lib/utils.js +151 -63
- package/mocha.js +7866 -3746
- package/mocha.js.map +1 -1
- package/package.json +33 -22
package/lib/cli/run.js
CHANGED
|
@@ -19,8 +19,7 @@ const {
|
|
|
19
19
|
const {
|
|
20
20
|
list,
|
|
21
21
|
handleRequires,
|
|
22
|
-
|
|
23
|
-
loadRootHooks,
|
|
22
|
+
validateLegacyPlugin,
|
|
24
23
|
runMocha
|
|
25
24
|
} = require('./run-helpers');
|
|
26
25
|
const {ONE_AND_DONES, ONE_AND_DONE_ARGS} = require('./one-and-dones');
|
|
@@ -339,13 +338,10 @@ exports.builder = yargs =>
|
|
|
339
338
|
// currently a failing middleware does not work nicely with yargs' `fail()`.
|
|
340
339
|
try {
|
|
341
340
|
// load requires first, because it can impact "plugin" validation
|
|
342
|
-
const
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
if (rawRootHooks && rawRootHooks.length) {
|
|
347
|
-
argv.rootHooks = await loadRootHooks(rawRootHooks);
|
|
348
|
-
}
|
|
341
|
+
const plugins = await handleRequires(argv.require);
|
|
342
|
+
validateLegacyPlugin(argv, 'reporter', Mocha.reporters);
|
|
343
|
+
validateLegacyPlugin(argv, 'ui', Mocha.interfaces);
|
|
344
|
+
Object.assign(argv, plugins);
|
|
349
345
|
} catch (err) {
|
|
350
346
|
// this could be a bad --require, bad reporter, ui, etc.
|
|
351
347
|
console.error(`\n${symbols.error} ${ansi.red('ERROR:')}`, err);
|
package/lib/cli/watch-run.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const logSymbols = require('log-symbols');
|
|
3
4
|
const debug = require('debug')('mocha:cli:watch');
|
|
4
5
|
const path = require('path');
|
|
5
6
|
const chokidar = require('chokidar');
|
|
@@ -32,6 +33,7 @@ exports.watchParallelRun = (
|
|
|
32
33
|
fileCollectParams
|
|
33
34
|
) => {
|
|
34
35
|
debug('creating parallel watcher');
|
|
36
|
+
|
|
35
37
|
return createWatcher(mocha, {
|
|
36
38
|
watchFiles,
|
|
37
39
|
watchIgnore,
|
|
@@ -39,6 +41,9 @@ exports.watchParallelRun = (
|
|
|
39
41
|
// I don't know why we're cloning the root suite.
|
|
40
42
|
const rootSuite = mocha.suite.clone();
|
|
41
43
|
|
|
44
|
+
// ensure we aren't leaking event listeners
|
|
45
|
+
mocha.dispose();
|
|
46
|
+
|
|
42
47
|
// this `require` is needed because the require cache has been cleared. the dynamic
|
|
43
48
|
// exports set via the below call to `mocha.ui()` won't work properly if a
|
|
44
49
|
// test depends on this module (see `required-tokens.spec.js`).
|
|
@@ -68,9 +73,6 @@ exports.watchParallelRun = (
|
|
|
68
73
|
newMocha.lazyLoadFiles(true);
|
|
69
74
|
return newMocha;
|
|
70
75
|
},
|
|
71
|
-
afterRun({watcher}) {
|
|
72
|
-
blastCache(watcher);
|
|
73
|
-
},
|
|
74
76
|
fileCollectParams
|
|
75
77
|
});
|
|
76
78
|
};
|
|
@@ -91,7 +93,6 @@ exports.watchParallelRun = (
|
|
|
91
93
|
*/
|
|
92
94
|
exports.watchRun = (mocha, {watchFiles, watchIgnore}, fileCollectParams) => {
|
|
93
95
|
debug('creating serial watcher');
|
|
94
|
-
// list of all test files
|
|
95
96
|
|
|
96
97
|
return createWatcher(mocha, {
|
|
97
98
|
watchFiles,
|
|
@@ -102,6 +103,9 @@ exports.watchRun = (mocha, {watchFiles, watchIgnore}, fileCollectParams) => {
|
|
|
102
103
|
// I don't know why we're cloning the root suite.
|
|
103
104
|
const rootSuite = mocha.suite.clone();
|
|
104
105
|
|
|
106
|
+
// ensure we aren't leaking event listeners
|
|
107
|
+
mocha.dispose();
|
|
108
|
+
|
|
105
109
|
// this `require` is needed because the require cache has been cleared. the dynamic
|
|
106
110
|
// exports set via the below call to `mocha.ui()` won't work properly if a
|
|
107
111
|
// test depends on this module (see `required-tokens.spec.js`).
|
|
@@ -128,9 +132,6 @@ exports.watchRun = (mocha, {watchFiles, watchIgnore}, fileCollectParams) => {
|
|
|
128
132
|
|
|
129
133
|
return newMocha;
|
|
130
134
|
},
|
|
131
|
-
afterRun({watcher}) {
|
|
132
|
-
blastCache(watcher);
|
|
133
|
-
},
|
|
134
135
|
fileCollectParams
|
|
135
136
|
});
|
|
136
137
|
};
|
|
@@ -141,7 +142,6 @@ exports.watchRun = (mocha, {watchFiles, watchIgnore}, fileCollectParams) => {
|
|
|
141
142
|
* @param {Object} opts
|
|
142
143
|
* @param {BeforeWatchRun} [opts.beforeRun] - Function to call before
|
|
143
144
|
* `mocha.run()`
|
|
144
|
-
* @param {AfterWatchRun} [opts.afterRun] - Function to call after `mocha.run()`
|
|
145
145
|
* @param {string[]} [opts.watchFiles] - List of paths and patterns to watch. If
|
|
146
146
|
* not provided all files with an extension included in
|
|
147
147
|
* `fileCollectionParams.extension` are watched. See first argument of
|
|
@@ -155,13 +155,17 @@ exports.watchRun = (mocha, {watchFiles, watchIgnore}, fileCollectParams) => {
|
|
|
155
155
|
*/
|
|
156
156
|
const createWatcher = (
|
|
157
157
|
mocha,
|
|
158
|
-
{watchFiles, watchIgnore, beforeRun,
|
|
158
|
+
{watchFiles, watchIgnore, beforeRun, fileCollectParams}
|
|
159
159
|
) => {
|
|
160
160
|
if (!watchFiles) {
|
|
161
161
|
watchFiles = fileCollectParams.extension.map(ext => `**/*.${ext}`);
|
|
162
162
|
}
|
|
163
163
|
|
|
164
164
|
debug('ignoring files matching: %s', watchIgnore);
|
|
165
|
+
let globalFixtureContext;
|
|
166
|
+
|
|
167
|
+
// we handle global fixtures manually
|
|
168
|
+
mocha.enableGlobalSetup(false).enableGlobalTeardown(false);
|
|
165
169
|
|
|
166
170
|
const watcher = chokidar.watch(watchFiles, {
|
|
167
171
|
ignored: watchIgnore,
|
|
@@ -169,11 +173,14 @@ const createWatcher = (
|
|
|
169
173
|
});
|
|
170
174
|
|
|
171
175
|
const rerunner = createRerunner(mocha, watcher, {
|
|
172
|
-
beforeRun
|
|
173
|
-
afterRun
|
|
176
|
+
beforeRun
|
|
174
177
|
});
|
|
175
178
|
|
|
176
|
-
watcher.on('ready', () => {
|
|
179
|
+
watcher.on('ready', async () => {
|
|
180
|
+
if (!globalFixtureContext) {
|
|
181
|
+
debug('triggering global setup');
|
|
182
|
+
globalFixtureContext = await mocha.runGlobalSetup();
|
|
183
|
+
}
|
|
177
184
|
rerunner.run();
|
|
178
185
|
});
|
|
179
186
|
|
|
@@ -185,10 +192,39 @@ const createWatcher = (
|
|
|
185
192
|
process.on('exit', () => {
|
|
186
193
|
showCursor();
|
|
187
194
|
});
|
|
188
|
-
|
|
195
|
+
|
|
196
|
+
// this is for testing.
|
|
197
|
+
// win32 cannot gracefully shutdown via a signal from a parent
|
|
198
|
+
// process; a `SIGINT` from a parent will cause the process
|
|
199
|
+
// to immediately exit. during normal course of operation, a user
|
|
200
|
+
// will type Ctrl-C and the listener will be invoked, but this
|
|
201
|
+
// is not possible in automated testing.
|
|
202
|
+
// there may be another way to solve this, but it too will be a hack.
|
|
203
|
+
// for our watch tests on win32 we must _fork_ mocha with an IPC channel
|
|
204
|
+
if (process.connected) {
|
|
205
|
+
process.on('message', msg => {
|
|
206
|
+
if (msg === 'SIGINT') {
|
|
207
|
+
process.emit('SIGINT');
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
let exiting = false;
|
|
213
|
+
process.on('SIGINT', async () => {
|
|
189
214
|
showCursor();
|
|
190
|
-
console.
|
|
191
|
-
|
|
215
|
+
console.error(`${logSymbols.warning} [mocha] cleaning up, please wait...`);
|
|
216
|
+
if (!exiting) {
|
|
217
|
+
exiting = true;
|
|
218
|
+
if (mocha.hasGlobalTeardownFixtures()) {
|
|
219
|
+
debug('running global teardown');
|
|
220
|
+
try {
|
|
221
|
+
await mocha.runGlobalTeardown(globalFixtureContext);
|
|
222
|
+
} catch (err) {
|
|
223
|
+
console.error(err);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
process.exit(130);
|
|
227
|
+
}
|
|
192
228
|
});
|
|
193
229
|
|
|
194
230
|
// Keyboard shortcut for restarting when "rs\n" is typed (ala Nodemon)
|
|
@@ -212,12 +248,11 @@ const createWatcher = (
|
|
|
212
248
|
* @param {FSWatcher} watcher - chokidar `FSWatcher` instance
|
|
213
249
|
* @param {Object} [opts] - Options!
|
|
214
250
|
* @param {BeforeWatchRun} [opts.beforeRun] - Function to call before `mocha.run()`
|
|
215
|
-
* @param {AfterWatchRun} [opts.afterRun] - Function to call after `mocha.run()`
|
|
216
251
|
* @returns {Rerunner}
|
|
217
252
|
* @ignore
|
|
218
253
|
* @private
|
|
219
254
|
*/
|
|
220
|
-
const createRerunner = (mocha, watcher, {beforeRun
|
|
255
|
+
const createRerunner = (mocha, watcher, {beforeRun} = {}) => {
|
|
221
256
|
// Set to a `Runner` when mocha is running. Set to `null` when mocha is not
|
|
222
257
|
// running.
|
|
223
258
|
let runner = null;
|
|
@@ -226,16 +261,15 @@ const createRerunner = (mocha, watcher, {beforeRun, afterRun} = {}) => {
|
|
|
226
261
|
let rerunScheduled = false;
|
|
227
262
|
|
|
228
263
|
const run = () => {
|
|
229
|
-
mocha = beforeRun ? beforeRun({mocha, watcher}) : mocha;
|
|
230
|
-
|
|
264
|
+
mocha = beforeRun ? beforeRun({mocha, watcher}) || mocha : mocha;
|
|
231
265
|
runner = mocha.run(() => {
|
|
232
266
|
debug('finished watch run');
|
|
233
267
|
runner = null;
|
|
234
|
-
|
|
268
|
+
blastCache(watcher);
|
|
235
269
|
if (rerunScheduled) {
|
|
236
270
|
rerun();
|
|
237
271
|
} else {
|
|
238
|
-
|
|
272
|
+
console.error(`${logSymbols.info} [mocha] waiting for changes...`);
|
|
239
273
|
}
|
|
240
274
|
});
|
|
241
275
|
};
|
|
@@ -333,15 +367,6 @@ const blastCache = watcher => {
|
|
|
333
367
|
* @returns {Mocha}
|
|
334
368
|
*/
|
|
335
369
|
|
|
336
|
-
/**
|
|
337
|
-
* Callback to be run after `mocha.run()` completes. Typically used to clear
|
|
338
|
-
* require cache.
|
|
339
|
-
* @callback AfterWatchRun
|
|
340
|
-
* @private
|
|
341
|
-
* @param {{mocha: Mocha, watcher: FSWatcher}} options
|
|
342
|
-
* @returns {void}
|
|
343
|
-
*/
|
|
344
|
-
|
|
345
370
|
/**
|
|
346
371
|
* Object containing run control methods
|
|
347
372
|
* @typedef {Object} Rerunner
|
package/lib/errors.js
CHANGED
|
@@ -1,83 +1,182 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const {format} = require('util');
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* Contains error codes, factory functions to create throwable error objects,
|
|
7
|
+
* and warning/deprecation functions.
|
|
8
|
+
* @module
|
|
8
9
|
*/
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
12
|
+
* process.emitWarning or a polyfill
|
|
13
|
+
* @see https://nodejs.org/api/process.html#process_process_emitwarning_warning_options
|
|
14
|
+
* @ignore
|
|
15
|
+
*/
|
|
16
|
+
const emitWarning = (msg, type) => {
|
|
17
|
+
if (process.emitWarning) {
|
|
18
|
+
process.emitWarning(msg, type);
|
|
19
|
+
} else {
|
|
20
|
+
/* istanbul ignore next */
|
|
21
|
+
process.nextTick(function() {
|
|
22
|
+
console.warn(type + ': ' + msg);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Show a deprecation warning. Each distinct message is only displayed once.
|
|
29
|
+
* Ignores empty messages.
|
|
30
|
+
*
|
|
31
|
+
* @param {string} [msg] - Warning to print
|
|
32
|
+
* @private
|
|
33
|
+
*/
|
|
34
|
+
const deprecate = msg => {
|
|
35
|
+
msg = String(msg);
|
|
36
|
+
if (msg && !deprecate.cache[msg]) {
|
|
37
|
+
deprecate.cache[msg] = true;
|
|
38
|
+
emitWarning(msg, 'DeprecationWarning');
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
deprecate.cache = {};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Show a generic warning.
|
|
45
|
+
* Ignores empty messages.
|
|
46
|
+
*
|
|
47
|
+
* @param {string} [msg] - Warning to print
|
|
48
|
+
* @private
|
|
49
|
+
*/
|
|
50
|
+
const warn = msg => {
|
|
51
|
+
if (msg) {
|
|
52
|
+
emitWarning(msg);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* When Mocha throws exceptions (or rejects `Promise`s), it attempts to assign a `code` property to the `Error` object, for easier handling. These are the potential values of `code`.
|
|
58
|
+
* @public
|
|
59
|
+
* @namespace
|
|
60
|
+
* @memberof module:lib/errors
|
|
14
61
|
*/
|
|
15
62
|
var constants = {
|
|
16
63
|
/**
|
|
17
64
|
* An unrecoverable error.
|
|
65
|
+
* @constant
|
|
66
|
+
* @default
|
|
18
67
|
*/
|
|
19
68
|
FATAL: 'ERR_MOCHA_FATAL',
|
|
20
69
|
|
|
21
70
|
/**
|
|
22
71
|
* The type of an argument to a function call is invalid
|
|
72
|
+
* @constant
|
|
73
|
+
* @default
|
|
23
74
|
*/
|
|
24
75
|
INVALID_ARG_TYPE: 'ERR_MOCHA_INVALID_ARG_TYPE',
|
|
25
76
|
|
|
26
77
|
/**
|
|
27
78
|
* The value of an argument to a function call is invalid
|
|
79
|
+
* @constant
|
|
80
|
+
* @default
|
|
28
81
|
*/
|
|
29
82
|
INVALID_ARG_VALUE: 'ERR_MOCHA_INVALID_ARG_VALUE',
|
|
30
83
|
|
|
31
84
|
/**
|
|
32
85
|
* Something was thrown, but it wasn't an `Error`
|
|
86
|
+
* @constant
|
|
87
|
+
* @default
|
|
33
88
|
*/
|
|
34
89
|
INVALID_EXCEPTION: 'ERR_MOCHA_INVALID_EXCEPTION',
|
|
35
90
|
|
|
36
91
|
/**
|
|
37
92
|
* An interface (e.g., `Mocha.interfaces`) is unknown or invalid
|
|
93
|
+
* @constant
|
|
94
|
+
* @default
|
|
38
95
|
*/
|
|
39
96
|
INVALID_INTERFACE: 'ERR_MOCHA_INVALID_INTERFACE',
|
|
40
97
|
|
|
41
98
|
/**
|
|
42
99
|
* A reporter (.e.g, `Mocha.reporters`) is unknown or invalid
|
|
100
|
+
* @constant
|
|
101
|
+
* @default
|
|
43
102
|
*/
|
|
44
103
|
INVALID_REPORTER: 'ERR_MOCHA_INVALID_REPORTER',
|
|
45
104
|
|
|
46
105
|
/**
|
|
47
106
|
* `done()` was called twice in a `Test` or `Hook` callback
|
|
107
|
+
* @constant
|
|
108
|
+
* @default
|
|
48
109
|
*/
|
|
49
110
|
MULTIPLE_DONE: 'ERR_MOCHA_MULTIPLE_DONE',
|
|
50
111
|
|
|
51
112
|
/**
|
|
52
113
|
* No files matched the pattern provided by the user
|
|
114
|
+
* @constant
|
|
115
|
+
* @default
|
|
53
116
|
*/
|
|
54
117
|
NO_FILES_MATCH_PATTERN: 'ERR_MOCHA_NO_FILES_MATCH_PATTERN',
|
|
55
118
|
|
|
56
119
|
/**
|
|
57
120
|
* Known, but unsupported behavior of some kind
|
|
121
|
+
* @constant
|
|
122
|
+
* @default
|
|
58
123
|
*/
|
|
59
124
|
UNSUPPORTED: 'ERR_MOCHA_UNSUPPORTED',
|
|
60
125
|
|
|
61
126
|
/**
|
|
62
127
|
* Invalid state transition occurring in `Mocha` instance
|
|
128
|
+
* @constant
|
|
129
|
+
* @default
|
|
63
130
|
*/
|
|
64
131
|
INSTANCE_ALREADY_RUNNING: 'ERR_MOCHA_INSTANCE_ALREADY_RUNNING',
|
|
65
132
|
|
|
66
133
|
/**
|
|
67
134
|
* Invalid state transition occurring in `Mocha` instance
|
|
135
|
+
* @constant
|
|
136
|
+
* @default
|
|
68
137
|
*/
|
|
69
138
|
INSTANCE_ALREADY_DISPOSED: 'ERR_MOCHA_INSTANCE_ALREADY_DISPOSED',
|
|
70
139
|
|
|
71
140
|
/**
|
|
72
141
|
* Use of `only()` w/ `--forbid-only` results in this error.
|
|
142
|
+
* @constant
|
|
143
|
+
* @default
|
|
73
144
|
*/
|
|
74
|
-
FORBIDDEN_EXCLUSIVITY: 'ERR_MOCHA_FORBIDDEN_EXCLUSIVITY'
|
|
145
|
+
FORBIDDEN_EXCLUSIVITY: 'ERR_MOCHA_FORBIDDEN_EXCLUSIVITY',
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* To be thrown when a user-defined plugin implementation (e.g., `mochaHooks`) is invalid
|
|
149
|
+
* @constant
|
|
150
|
+
* @default
|
|
151
|
+
*/
|
|
152
|
+
INVALID_PLUGIN_IMPLEMENTATION: 'ERR_MOCHA_INVALID_PLUGIN_IMPLEMENTATION',
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* To be thrown when a builtin or third-party plugin definition (the _definition_ of `mochaHooks`) is invalid
|
|
156
|
+
* @constant
|
|
157
|
+
* @default
|
|
158
|
+
*/
|
|
159
|
+
INVALID_PLUGIN_DEFINITION: 'ERR_MOCHA_INVALID_PLUGIN_DEFINITION',
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* When a runnable exceeds its allowed run time.
|
|
163
|
+
* @constant
|
|
164
|
+
* @default
|
|
165
|
+
*/
|
|
166
|
+
TIMEOUT: 'ERR_MOCHA_TIMEOUT'
|
|
75
167
|
};
|
|
76
168
|
|
|
169
|
+
/**
|
|
170
|
+
* A set containing all string values of all Mocha error constants, for use by {@link isMochaError}.
|
|
171
|
+
* @private
|
|
172
|
+
*/
|
|
173
|
+
const MOCHA_ERRORS = new Set(Object.values(constants));
|
|
174
|
+
|
|
77
175
|
/**
|
|
78
176
|
* Creates an error object to be thrown when no files to be tested could be found using specified pattern.
|
|
79
177
|
*
|
|
80
178
|
* @public
|
|
179
|
+
* @static
|
|
81
180
|
* @param {string} message - Error message to be displayed.
|
|
82
181
|
* @param {string} pattern - User-specified argument value.
|
|
83
182
|
* @returns {Error} instance detailing the error condition
|
|
@@ -108,6 +207,7 @@ function createInvalidReporterError(message, reporter) {
|
|
|
108
207
|
* Creates an error object to be thrown when the interface specified in the options was not found.
|
|
109
208
|
*
|
|
110
209
|
* @public
|
|
210
|
+
* @static
|
|
111
211
|
* @param {string} message - Error message to be displayed.
|
|
112
212
|
* @param {string} ui - User-specified interface value.
|
|
113
213
|
* @returns {Error} instance detailing the error condition
|
|
@@ -123,6 +223,7 @@ function createInvalidInterfaceError(message, ui) {
|
|
|
123
223
|
* Creates an error object to be thrown when a behavior, option, or parameter is unsupported.
|
|
124
224
|
*
|
|
125
225
|
* @public
|
|
226
|
+
* @static
|
|
126
227
|
* @param {string} message - Error message to be displayed.
|
|
127
228
|
* @returns {Error} instance detailing the error condition
|
|
128
229
|
*/
|
|
@@ -136,6 +237,7 @@ function createUnsupportedError(message) {
|
|
|
136
237
|
* Creates an error object to be thrown when an argument is missing.
|
|
137
238
|
*
|
|
138
239
|
* @public
|
|
240
|
+
* @static
|
|
139
241
|
* @param {string} message - Error message to be displayed.
|
|
140
242
|
* @param {string} argument - Argument name.
|
|
141
243
|
* @param {string} expected - Expected argument datatype.
|
|
@@ -149,6 +251,7 @@ function createMissingArgumentError(message, argument, expected) {
|
|
|
149
251
|
* Creates an error object to be thrown when an argument did not use the supported type
|
|
150
252
|
*
|
|
151
253
|
* @public
|
|
254
|
+
* @static
|
|
152
255
|
* @param {string} message - Error message to be displayed.
|
|
153
256
|
* @param {string} argument - Argument name.
|
|
154
257
|
* @param {string} expected - Expected argument datatype.
|
|
@@ -167,6 +270,7 @@ function createInvalidArgumentTypeError(message, argument, expected) {
|
|
|
167
270
|
* Creates an error object to be thrown when an argument did not use the supported value
|
|
168
271
|
*
|
|
169
272
|
* @public
|
|
273
|
+
* @static
|
|
170
274
|
* @param {string} message - Error message to be displayed.
|
|
171
275
|
* @param {string} argument - Argument name.
|
|
172
276
|
* @param {string} value - Argument value.
|
|
@@ -186,6 +290,7 @@ function createInvalidArgumentValueError(message, argument, value, reason) {
|
|
|
186
290
|
* Creates an error object to be thrown when an exception was caught, but the `Error` is falsy or undefined.
|
|
187
291
|
*
|
|
188
292
|
* @public
|
|
293
|
+
* @static
|
|
189
294
|
* @param {string} message - Error message to be displayed.
|
|
190
295
|
* @returns {Error} instance detailing the error condition
|
|
191
296
|
*/
|
|
@@ -201,6 +306,7 @@ function createInvalidExceptionError(message, value) {
|
|
|
201
306
|
* Creates an error object to be thrown when an unrecoverable error occurs.
|
|
202
307
|
*
|
|
203
308
|
* @public
|
|
309
|
+
* @static
|
|
204
310
|
* @param {string} message - Error message to be displayed.
|
|
205
311
|
* @returns {Error} instance detailing the error condition
|
|
206
312
|
*/
|
|
@@ -219,9 +325,10 @@ function createFatalError(message, value) {
|
|
|
219
325
|
* @param {string} [pluginId] - Name/path of plugin, if any
|
|
220
326
|
* @throws When `pluginType` is not known
|
|
221
327
|
* @public
|
|
328
|
+
* @static
|
|
222
329
|
* @returns {Error}
|
|
223
330
|
*/
|
|
224
|
-
function
|
|
331
|
+
function createInvalidLegacyPluginError(message, pluginType, pluginId) {
|
|
225
332
|
switch (pluginType) {
|
|
226
333
|
case 'reporter':
|
|
227
334
|
return createInvalidReporterError(message, pluginId);
|
|
@@ -232,11 +339,28 @@ function createInvalidPluginError(message, pluginType, pluginId) {
|
|
|
232
339
|
}
|
|
233
340
|
}
|
|
234
341
|
|
|
342
|
+
/**
|
|
343
|
+
* **DEPRECATED**. Use {@link createInvalidLegacyPluginError} instead Dynamically creates a plugin-type-specific error based on plugin type
|
|
344
|
+
* @deprecated
|
|
345
|
+
* @param {string} message - Error message
|
|
346
|
+
* @param {"reporter"|"interface"} pluginType - Plugin type. Future: expand as needed
|
|
347
|
+
* @param {string} [pluginId] - Name/path of plugin, if any
|
|
348
|
+
* @throws When `pluginType` is not known
|
|
349
|
+
* @public
|
|
350
|
+
* @static
|
|
351
|
+
* @returns {Error}
|
|
352
|
+
*/
|
|
353
|
+
function createInvalidPluginError(...args) {
|
|
354
|
+
deprecate('Use createInvalidLegacyPluginError() instead');
|
|
355
|
+
return createInvalidLegacyPluginError(...args);
|
|
356
|
+
}
|
|
357
|
+
|
|
235
358
|
/**
|
|
236
359
|
* Creates an error object to be thrown when a mocha object's `run` method is executed while it is already disposed.
|
|
237
360
|
* @param {string} message The error message to be displayed.
|
|
238
361
|
* @param {boolean} cleanReferencesAfterRun the value of `cleanReferencesAfterRun`
|
|
239
362
|
* @param {Mocha} instance the mocha instance that throw this error
|
|
363
|
+
* @static
|
|
240
364
|
*/
|
|
241
365
|
function createMochaInstanceAlreadyDisposedError(
|
|
242
366
|
message,
|
|
@@ -253,6 +377,8 @@ function createMochaInstanceAlreadyDisposedError(
|
|
|
253
377
|
/**
|
|
254
378
|
* Creates an error object to be thrown when a mocha object's `run` method is called while a test run is in progress.
|
|
255
379
|
* @param {string} message The error message to be displayed.
|
|
380
|
+
* @static
|
|
381
|
+
* @public
|
|
256
382
|
*/
|
|
257
383
|
function createMochaInstanceAlreadyRunningError(message, instance) {
|
|
258
384
|
var err = new Error(message);
|
|
@@ -261,13 +387,14 @@ function createMochaInstanceAlreadyRunningError(message, instance) {
|
|
|
261
387
|
return err;
|
|
262
388
|
}
|
|
263
389
|
|
|
264
|
-
|
|
390
|
+
/**
|
|
265
391
|
* Creates an error object to be thrown when done() is called multiple times in a test
|
|
266
392
|
*
|
|
267
393
|
* @public
|
|
268
394
|
* @param {Runnable} runnable - Original runnable
|
|
269
395
|
* @param {Error} [originalErr] - Original error, if any
|
|
270
396
|
* @returns {Error} instance detailing the error condition
|
|
397
|
+
* @static
|
|
271
398
|
*/
|
|
272
399
|
function createMultipleDoneError(runnable, originalErr) {
|
|
273
400
|
var title;
|
|
@@ -301,6 +428,7 @@ function createMultipleDoneError(runnable, originalErr) {
|
|
|
301
428
|
/**
|
|
302
429
|
* Creates an error object to be thrown when `.only()` is used with
|
|
303
430
|
* `--forbid-only`.
|
|
431
|
+
* @static
|
|
304
432
|
* @public
|
|
305
433
|
* @param {Mocha} mocha - Mocha instance
|
|
306
434
|
* @returns {Error} Error with code {@link constants.FORBIDDEN_EXCLUSIVITY}
|
|
@@ -315,20 +443,99 @@ function createForbiddenExclusivityError(mocha) {
|
|
|
315
443
|
return err;
|
|
316
444
|
}
|
|
317
445
|
|
|
446
|
+
/**
|
|
447
|
+
* Creates an error object to be thrown when a plugin definition is invalid
|
|
448
|
+
* @static
|
|
449
|
+
* @param {string} msg - Error message
|
|
450
|
+
* @param {PluginDefinition} [pluginDef] - Problematic plugin definition
|
|
451
|
+
* @public
|
|
452
|
+
* @returns {Error} Error with code {@link constants.INVALID_PLUGIN_DEFINITION}
|
|
453
|
+
*/
|
|
454
|
+
function createInvalidPluginDefinitionError(msg, pluginDef) {
|
|
455
|
+
const err = new Error(msg);
|
|
456
|
+
err.code = constants.INVALID_PLUGIN_DEFINITION;
|
|
457
|
+
err.pluginDef = pluginDef;
|
|
458
|
+
return err;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* Creates an error object to be thrown when a plugin implementation (user code) is invalid
|
|
463
|
+
* @static
|
|
464
|
+
* @param {string} msg - Error message
|
|
465
|
+
* @param {Object} [opts] - Plugin definition and user-supplied implementation
|
|
466
|
+
* @param {PluginDefinition} [opts.pluginDef] - Plugin Definition
|
|
467
|
+
* @param {*} [opts.pluginImpl] - Plugin Implementation (user-supplied)
|
|
468
|
+
* @public
|
|
469
|
+
* @returns {Error} Error with code {@link constants.INVALID_PLUGIN_DEFINITION}
|
|
470
|
+
*/
|
|
471
|
+
function createInvalidPluginImplementationError(
|
|
472
|
+
msg,
|
|
473
|
+
{pluginDef, pluginImpl} = {}
|
|
474
|
+
) {
|
|
475
|
+
const err = new Error(msg);
|
|
476
|
+
err.code = constants.INVALID_PLUGIN_IMPLEMENTATION;
|
|
477
|
+
err.pluginDef = pluginDef;
|
|
478
|
+
err.pluginImpl = pluginImpl;
|
|
479
|
+
return err;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* Creates an error object to be thrown when a runnable exceeds its allowed run time.
|
|
484
|
+
* @static
|
|
485
|
+
* @param {string} msg - Error message
|
|
486
|
+
* @param {number} [timeout] - Timeout in ms
|
|
487
|
+
* @param {string} [file] - File, if given
|
|
488
|
+
* @returns {MochaTimeoutError}
|
|
489
|
+
*/
|
|
490
|
+
function createTimeoutError(msg, timeout, file) {
|
|
491
|
+
const err = new Error(msg);
|
|
492
|
+
err.code = constants.TIMEOUT;
|
|
493
|
+
err.timeout = timeout;
|
|
494
|
+
err.file = file;
|
|
495
|
+
return err;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
* Returns `true` if an error came out of Mocha.
|
|
500
|
+
* _Can suffer from false negatives, but not false positives._
|
|
501
|
+
* @static
|
|
502
|
+
* @public
|
|
503
|
+
* @param {*} err - Error, or anything
|
|
504
|
+
* @returns {boolean}
|
|
505
|
+
*/
|
|
506
|
+
const isMochaError = err =>
|
|
507
|
+
Boolean(err && typeof err === 'object' && MOCHA_ERRORS.has(err.code));
|
|
508
|
+
|
|
318
509
|
module.exports = {
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
510
|
+
constants,
|
|
511
|
+
createFatalError,
|
|
512
|
+
createForbiddenExclusivityError,
|
|
513
|
+
createInvalidArgumentTypeError,
|
|
514
|
+
createInvalidArgumentValueError,
|
|
515
|
+
createInvalidExceptionError,
|
|
516
|
+
createInvalidInterfaceError,
|
|
517
|
+
createInvalidLegacyPluginError,
|
|
518
|
+
createInvalidPluginDefinitionError,
|
|
519
|
+
createInvalidPluginError,
|
|
520
|
+
createInvalidPluginImplementationError,
|
|
521
|
+
createInvalidReporterError,
|
|
522
|
+
createMissingArgumentError,
|
|
523
|
+
createMochaInstanceAlreadyDisposedError,
|
|
524
|
+
createMochaInstanceAlreadyRunningError,
|
|
525
|
+
createMultipleDoneError,
|
|
526
|
+
createNoFilesMatchPatternError,
|
|
527
|
+
createTimeoutError,
|
|
528
|
+
createUnsupportedError,
|
|
529
|
+
deprecate,
|
|
530
|
+
isMochaError,
|
|
531
|
+
warn
|
|
334
532
|
};
|
|
533
|
+
|
|
534
|
+
/**
|
|
535
|
+
* The error thrown when a Runnable times out
|
|
536
|
+
* @memberof module:lib/errors
|
|
537
|
+
* @typedef {Error} MochaTimeoutError
|
|
538
|
+
* @property {constants.TIMEOUT} code - Error code
|
|
539
|
+
* @property {number?} timeout Timeout in ms
|
|
540
|
+
* @property {string?} file Filepath, if given
|
|
541
|
+
*/
|
package/lib/esm-utils.js
CHANGED
|
@@ -3,7 +3,29 @@ const url = require('url');
|
|
|
3
3
|
|
|
4
4
|
const formattedImport = async file => {
|
|
5
5
|
if (path.isAbsolute(file)) {
|
|
6
|
-
|
|
6
|
+
try {
|
|
7
|
+
return await import(url.pathToFileURL(file));
|
|
8
|
+
} catch (err) {
|
|
9
|
+
// This is a hack created because ESM in Node.js (at least in Node v15.5.1) does not emit
|
|
10
|
+
// the location of the syntax error in the error thrown.
|
|
11
|
+
// This is problematic because the user can't see what file has the problem,
|
|
12
|
+
// so we add the file location to the error.
|
|
13
|
+
// This `if` should be removed once Node.js fixes the problem.
|
|
14
|
+
if (
|
|
15
|
+
err instanceof SyntaxError &&
|
|
16
|
+
err.message &&
|
|
17
|
+
err.stack &&
|
|
18
|
+
!err.stack.includes(file)
|
|
19
|
+
) {
|
|
20
|
+
const newErrorWithFilename = new SyntaxError(err.message);
|
|
21
|
+
newErrorWithFilename.stack = err.stack.replace(
|
|
22
|
+
/^SyntaxError/,
|
|
23
|
+
`SyntaxError[ @${file} ]`
|
|
24
|
+
);
|
|
25
|
+
throw newErrorWithFilename;
|
|
26
|
+
}
|
|
27
|
+
throw err;
|
|
28
|
+
}
|
|
7
29
|
}
|
|
8
30
|
return import(file);
|
|
9
31
|
};
|