mocha 8.1.0 → 8.2.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 +83 -0
- package/README.md +2 -0
- package/browser-entry.js +2 -2
- package/lib/cli/cli.js +19 -8
- package/lib/cli/index.js +0 -6
- package/lib/cli/lookup-files.js +37 -31
- package/lib/cli/node-flags.js +6 -7
- package/lib/cli/options.js +5 -4
- package/lib/cli/run-helpers.js +21 -56
- package/lib/cli/run-option-metadata.js +25 -2
- package/lib/cli/run.js +5 -9
- package/lib/cli/watch-run.js +49 -30
- package/lib/errors.js +129 -20
- package/lib/hook.js +14 -9
- package/lib/mocha.js +266 -66
- 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 +15 -7
- package/lib/nodejs/worker.js +9 -12
- package/lib/plugin-loader.js +286 -0
- package/lib/reporters/base.js +3 -3
- package/lib/reporters/json-stream.js +2 -1
- package/lib/reporters/json.js +1 -0
- package/lib/runnable.js +6 -0
- package/lib/runner.js +209 -104
- package/lib/suite.js +34 -15
- package/lib/test.js +6 -2
- package/lib/utils.js +151 -66
- package/mocha.js +10008 -6258
- package/mocha.js.map +1 -1
- package/package.json +68 -56
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,
|
|
@@ -68,9 +70,6 @@ exports.watchParallelRun = (
|
|
|
68
70
|
newMocha.lazyLoadFiles(true);
|
|
69
71
|
return newMocha;
|
|
70
72
|
},
|
|
71
|
-
afterRun({watcher}) {
|
|
72
|
-
blastCache(watcher);
|
|
73
|
-
},
|
|
74
73
|
fileCollectParams
|
|
75
74
|
});
|
|
76
75
|
};
|
|
@@ -91,7 +90,6 @@ exports.watchParallelRun = (
|
|
|
91
90
|
*/
|
|
92
91
|
exports.watchRun = (mocha, {watchFiles, watchIgnore}, fileCollectParams) => {
|
|
93
92
|
debug('creating serial watcher');
|
|
94
|
-
// list of all test files
|
|
95
93
|
|
|
96
94
|
return createWatcher(mocha, {
|
|
97
95
|
watchFiles,
|
|
@@ -128,9 +126,6 @@ exports.watchRun = (mocha, {watchFiles, watchIgnore}, fileCollectParams) => {
|
|
|
128
126
|
|
|
129
127
|
return newMocha;
|
|
130
128
|
},
|
|
131
|
-
afterRun({watcher}) {
|
|
132
|
-
blastCache(watcher);
|
|
133
|
-
},
|
|
134
129
|
fileCollectParams
|
|
135
130
|
});
|
|
136
131
|
};
|
|
@@ -141,7 +136,6 @@ exports.watchRun = (mocha, {watchFiles, watchIgnore}, fileCollectParams) => {
|
|
|
141
136
|
* @param {Object} opts
|
|
142
137
|
* @param {BeforeWatchRun} [opts.beforeRun] - Function to call before
|
|
143
138
|
* `mocha.run()`
|
|
144
|
-
* @param {AfterWatchRun} [opts.afterRun] - Function to call after `mocha.run()`
|
|
145
139
|
* @param {string[]} [opts.watchFiles] - List of paths and patterns to watch. If
|
|
146
140
|
* not provided all files with an extension included in
|
|
147
141
|
* `fileCollectionParams.extension` are watched. See first argument of
|
|
@@ -155,13 +149,17 @@ exports.watchRun = (mocha, {watchFiles, watchIgnore}, fileCollectParams) => {
|
|
|
155
149
|
*/
|
|
156
150
|
const createWatcher = (
|
|
157
151
|
mocha,
|
|
158
|
-
{watchFiles, watchIgnore, beforeRun,
|
|
152
|
+
{watchFiles, watchIgnore, beforeRun, fileCollectParams}
|
|
159
153
|
) => {
|
|
160
154
|
if (!watchFiles) {
|
|
161
155
|
watchFiles = fileCollectParams.extension.map(ext => `**/*.${ext}`);
|
|
162
156
|
}
|
|
163
157
|
|
|
164
158
|
debug('ignoring files matching: %s', watchIgnore);
|
|
159
|
+
let globalFixtureContext;
|
|
160
|
+
|
|
161
|
+
// we handle global fixtures manually
|
|
162
|
+
mocha.enableGlobalSetup(false).enableGlobalTeardown(false);
|
|
165
163
|
|
|
166
164
|
const watcher = chokidar.watch(watchFiles, {
|
|
167
165
|
ignored: watchIgnore,
|
|
@@ -169,11 +167,14 @@ const createWatcher = (
|
|
|
169
167
|
});
|
|
170
168
|
|
|
171
169
|
const rerunner = createRerunner(mocha, watcher, {
|
|
172
|
-
beforeRun
|
|
173
|
-
afterRun
|
|
170
|
+
beforeRun
|
|
174
171
|
});
|
|
175
172
|
|
|
176
|
-
watcher.on('ready', () => {
|
|
173
|
+
watcher.on('ready', async () => {
|
|
174
|
+
if (!globalFixtureContext) {
|
|
175
|
+
debug('triggering global setup');
|
|
176
|
+
globalFixtureContext = await mocha.runGlobalSetup();
|
|
177
|
+
}
|
|
177
178
|
rerunner.run();
|
|
178
179
|
});
|
|
179
180
|
|
|
@@ -185,10 +186,39 @@ const createWatcher = (
|
|
|
185
186
|
process.on('exit', () => {
|
|
186
187
|
showCursor();
|
|
187
188
|
});
|
|
188
|
-
|
|
189
|
+
|
|
190
|
+
// this is for testing.
|
|
191
|
+
// win32 cannot gracefully shutdown via a signal from a parent
|
|
192
|
+
// process; a `SIGINT` from a parent will cause the process
|
|
193
|
+
// to immediately exit. during normal course of operation, a user
|
|
194
|
+
// will type Ctrl-C and the listener will be invoked, but this
|
|
195
|
+
// is not possible in automated testing.
|
|
196
|
+
// there may be another way to solve this, but it too will be a hack.
|
|
197
|
+
// for our watch tests on win32 we must _fork_ mocha with an IPC channel
|
|
198
|
+
if (process.connected) {
|
|
199
|
+
process.on('message', msg => {
|
|
200
|
+
if (msg === 'SIGINT') {
|
|
201
|
+
process.emit('SIGINT');
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
let exiting = false;
|
|
207
|
+
process.on('SIGINT', async () => {
|
|
189
208
|
showCursor();
|
|
190
|
-
console.
|
|
191
|
-
|
|
209
|
+
console.error(`${logSymbols.warning} [mocha] cleaning up, please wait...`);
|
|
210
|
+
if (!exiting) {
|
|
211
|
+
exiting = true;
|
|
212
|
+
if (mocha.hasGlobalTeardownFixtures()) {
|
|
213
|
+
debug('running global teardown');
|
|
214
|
+
try {
|
|
215
|
+
await mocha.runGlobalTeardown(globalFixtureContext);
|
|
216
|
+
} catch (err) {
|
|
217
|
+
console.error(err);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
process.exit(130);
|
|
221
|
+
}
|
|
192
222
|
});
|
|
193
223
|
|
|
194
224
|
// Keyboard shortcut for restarting when "rs\n" is typed (ala Nodemon)
|
|
@@ -212,12 +242,11 @@ const createWatcher = (
|
|
|
212
242
|
* @param {FSWatcher} watcher - chokidar `FSWatcher` instance
|
|
213
243
|
* @param {Object} [opts] - Options!
|
|
214
244
|
* @param {BeforeWatchRun} [opts.beforeRun] - Function to call before `mocha.run()`
|
|
215
|
-
* @param {AfterWatchRun} [opts.afterRun] - Function to call after `mocha.run()`
|
|
216
245
|
* @returns {Rerunner}
|
|
217
246
|
* @ignore
|
|
218
247
|
* @private
|
|
219
248
|
*/
|
|
220
|
-
const createRerunner = (mocha, watcher, {beforeRun
|
|
249
|
+
const createRerunner = (mocha, watcher, {beforeRun} = {}) => {
|
|
221
250
|
// Set to a `Runner` when mocha is running. Set to `null` when mocha is not
|
|
222
251
|
// running.
|
|
223
252
|
let runner = null;
|
|
@@ -226,16 +255,15 @@ const createRerunner = (mocha, watcher, {beforeRun, afterRun} = {}) => {
|
|
|
226
255
|
let rerunScheduled = false;
|
|
227
256
|
|
|
228
257
|
const run = () => {
|
|
229
|
-
mocha = beforeRun ? beforeRun({mocha, watcher}) : mocha;
|
|
230
|
-
|
|
258
|
+
mocha = beforeRun ? beforeRun({mocha, watcher}) || mocha : mocha;
|
|
231
259
|
runner = mocha.run(() => {
|
|
232
260
|
debug('finished watch run');
|
|
233
261
|
runner = null;
|
|
234
|
-
|
|
262
|
+
blastCache(watcher);
|
|
235
263
|
if (rerunScheduled) {
|
|
236
264
|
rerun();
|
|
237
265
|
} else {
|
|
238
|
-
|
|
266
|
+
console.error(`${logSymbols.info} [mocha] waiting for changes...`);
|
|
239
267
|
}
|
|
240
268
|
});
|
|
241
269
|
};
|
|
@@ -333,15 +361,6 @@ const blastCache = watcher => {
|
|
|
333
361
|
* @returns {Mocha}
|
|
334
362
|
*/
|
|
335
363
|
|
|
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
364
|
/**
|
|
346
365
|
* Object containing run control methods
|
|
347
366
|
* @typedef {Object} Rerunner
|
package/lib/errors.js
CHANGED
|
@@ -1,12 +1,57 @@
|
|
|
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
|
|
|
11
|
+
/**
|
|
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
|
+
process.nextTick(function() {
|
|
21
|
+
console.warn(type + ': ' + msg);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Show a deprecation warning. Each distinct message is only displayed once.
|
|
28
|
+
* Ignores empty messages.
|
|
29
|
+
*
|
|
30
|
+
* @param {string} [msg] - Warning to print
|
|
31
|
+
* @private
|
|
32
|
+
*/
|
|
33
|
+
const deprecate = msg => {
|
|
34
|
+
msg = String(msg);
|
|
35
|
+
if (msg && !deprecate.cache[msg]) {
|
|
36
|
+
deprecate.cache[msg] = true;
|
|
37
|
+
emitWarning(msg, 'DeprecationWarning');
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
deprecate.cache = {};
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Show a generic warning.
|
|
44
|
+
* Ignores empty messages.
|
|
45
|
+
*
|
|
46
|
+
* @param {string} [msg] - Warning to print
|
|
47
|
+
* @private
|
|
48
|
+
*/
|
|
49
|
+
const warn = msg => {
|
|
50
|
+
if (msg) {
|
|
51
|
+
emitWarning(msg);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
10
55
|
/**
|
|
11
56
|
* When Mocha throw exceptions (or otherwise errors), it attempts to assign a
|
|
12
57
|
* `code` property to the `Error` object, for easier handling. These are the
|
|
@@ -71,7 +116,17 @@ var constants = {
|
|
|
71
116
|
/**
|
|
72
117
|
* Use of `only()` w/ `--forbid-only` results in this error.
|
|
73
118
|
*/
|
|
74
|
-
FORBIDDEN_EXCLUSIVITY: 'ERR_MOCHA_FORBIDDEN_EXCLUSIVITY'
|
|
119
|
+
FORBIDDEN_EXCLUSIVITY: 'ERR_MOCHA_FORBIDDEN_EXCLUSIVITY',
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* To be thrown when a user-defined plugin implementation (e.g., `mochaHooks`) is invalid
|
|
123
|
+
*/
|
|
124
|
+
INVALID_PLUGIN_IMPLEMENTATION: 'ERR_MOCHA_INVALID_PLUGIN_IMPLEMENTATION',
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* To be thrown when a builtin or third-party plugin definition (the _definition_ of `mochaHooks`) is invalid
|
|
128
|
+
*/
|
|
129
|
+
INVALID_PLUGIN_DEFINITION: 'ERR_MOCHA_INVALID_PLUGIN_DEFINITION'
|
|
75
130
|
};
|
|
76
131
|
|
|
77
132
|
/**
|
|
@@ -221,7 +276,7 @@ function createFatalError(message, value) {
|
|
|
221
276
|
* @public
|
|
222
277
|
* @returns {Error}
|
|
223
278
|
*/
|
|
224
|
-
function
|
|
279
|
+
function createInvalidLegacyPluginError(message, pluginType, pluginId) {
|
|
225
280
|
switch (pluginType) {
|
|
226
281
|
case 'reporter':
|
|
227
282
|
return createInvalidReporterError(message, pluginId);
|
|
@@ -232,6 +287,21 @@ function createInvalidPluginError(message, pluginType, pluginId) {
|
|
|
232
287
|
}
|
|
233
288
|
}
|
|
234
289
|
|
|
290
|
+
/**
|
|
291
|
+
* **DEPRECATED**. Use {@link createInvalidLegacyPluginError} instead Dynamically creates a plugin-type-specific error based on plugin type
|
|
292
|
+
* @deprecated
|
|
293
|
+
* @param {string} message - Error message
|
|
294
|
+
* @param {"reporter"|"interface"} pluginType - Plugin type. Future: expand as needed
|
|
295
|
+
* @param {string} [pluginId] - Name/path of plugin, if any
|
|
296
|
+
* @throws When `pluginType` is not known
|
|
297
|
+
* @public
|
|
298
|
+
* @returns {Error}
|
|
299
|
+
*/
|
|
300
|
+
function createInvalidPluginError(...args) {
|
|
301
|
+
deprecate('Use createInvalidLegacyPluginError() instead');
|
|
302
|
+
return createInvalidLegacyPluginError(...args);
|
|
303
|
+
}
|
|
304
|
+
|
|
235
305
|
/**
|
|
236
306
|
* Creates an error object to be thrown when a mocha object's `run` method is executed while it is already disposed.
|
|
237
307
|
* @param {string} message The error message to be displayed.
|
|
@@ -315,20 +385,59 @@ function createForbiddenExclusivityError(mocha) {
|
|
|
315
385
|
return err;
|
|
316
386
|
}
|
|
317
387
|
|
|
388
|
+
/**
|
|
389
|
+
* Creates an error object to be thrown when a plugin definition is invalid
|
|
390
|
+
* @param {string} msg - Error message
|
|
391
|
+
* @param {PluginDefinition} [pluginDef] - Problematic plugin definition
|
|
392
|
+
* @public
|
|
393
|
+
* @returns {Error} Error with code {@link constants.INVALID_PLUGIN_DEFINITION}
|
|
394
|
+
*/
|
|
395
|
+
function createInvalidPluginDefinitionError(msg, pluginDef) {
|
|
396
|
+
const err = new Error(msg);
|
|
397
|
+
err.code = constants.INVALID_PLUGIN_DEFINITION;
|
|
398
|
+
err.pluginDef = pluginDef;
|
|
399
|
+
return err;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Creates an error object to be thrown when a plugin implementation (user code) is invalid
|
|
404
|
+
* @param {string} msg - Error message
|
|
405
|
+
* @param {Object} [opts] - Plugin definition and user-supplied implementation
|
|
406
|
+
* @param {PluginDefinition} [opts.pluginDef] - Plugin Definition
|
|
407
|
+
* @param {*} [opts.pluginImpl] - Plugin Implementation (user-supplied)
|
|
408
|
+
* @public
|
|
409
|
+
* @returns {Error} Error with code {@link constants.INVALID_PLUGIN_DEFINITION}
|
|
410
|
+
*/
|
|
411
|
+
function createInvalidPluginImplementationError(
|
|
412
|
+
msg,
|
|
413
|
+
{pluginDef, pluginImpl} = {}
|
|
414
|
+
) {
|
|
415
|
+
const err = new Error(msg);
|
|
416
|
+
err.code = constants.INVALID_PLUGIN_IMPLEMENTATION;
|
|
417
|
+
err.pluginDef = pluginDef;
|
|
418
|
+
err.pluginImpl = pluginImpl;
|
|
419
|
+
return err;
|
|
420
|
+
}
|
|
421
|
+
|
|
318
422
|
module.exports = {
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
423
|
+
constants,
|
|
424
|
+
createFatalError,
|
|
425
|
+
createForbiddenExclusivityError,
|
|
426
|
+
createInvalidArgumentTypeError,
|
|
427
|
+
createInvalidArgumentValueError,
|
|
428
|
+
createInvalidExceptionError,
|
|
429
|
+
createInvalidInterfaceError,
|
|
430
|
+
createInvalidLegacyPluginError,
|
|
431
|
+
createInvalidPluginDefinitionError,
|
|
432
|
+
createInvalidPluginError,
|
|
433
|
+
createInvalidPluginImplementationError,
|
|
434
|
+
createInvalidReporterError,
|
|
435
|
+
createMissingArgumentError,
|
|
436
|
+
createMochaInstanceAlreadyDisposedError,
|
|
437
|
+
createMochaInstanceAlreadyRunningError,
|
|
438
|
+
createMultipleDoneError,
|
|
439
|
+
createNoFilesMatchPatternError,
|
|
440
|
+
createUnsupportedError,
|
|
441
|
+
deprecate,
|
|
442
|
+
warn
|
|
334
443
|
};
|
package/lib/hook.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var Runnable = require('./runnable');
|
|
4
|
-
|
|
4
|
+
const {inherits, constants} = require('./utils');
|
|
5
|
+
const {MOCHA_ID_PROP_NAME} = constants;
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Expose `Hook`.
|
|
@@ -63,16 +64,20 @@ Hook.prototype.serialize = function serialize() {
|
|
|
63
64
|
return {
|
|
64
65
|
$$isPending: this.isPending(),
|
|
65
66
|
$$titlePath: this.titlePath(),
|
|
66
|
-
ctx:
|
|
67
|
-
currentTest
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
ctx:
|
|
68
|
+
this.ctx && this.ctx.currentTest
|
|
69
|
+
? {
|
|
70
|
+
currentTest: {
|
|
71
|
+
title: this.ctx.currentTest.title,
|
|
72
|
+
[MOCHA_ID_PROP_NAME]: this.ctx.currentTest.id
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
: {},
|
|
71
76
|
parent: {
|
|
72
|
-
|
|
73
|
-
title: this.parent.title
|
|
77
|
+
[MOCHA_ID_PROP_NAME]: this.parent.id
|
|
74
78
|
},
|
|
75
79
|
title: this.title,
|
|
76
|
-
type: this.type
|
|
80
|
+
type: this.type,
|
|
81
|
+
[MOCHA_ID_PROP_NAME]: this.id
|
|
77
82
|
};
|
|
78
83
|
};
|