mocha 8.1.3 → 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 +57 -1
- package/README.md +2 -0
- package/lib/cli/lookup-files.js +31 -31
- package/lib/cli/run-helpers.js +21 -56
- 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 +252 -55
- package/lib/nodejs/buffered-worker-pool.js +1 -3
- 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 +6 -0
- package/lib/runner.js +208 -103
- package/lib/suite.js +34 -15
- package/lib/test.js +6 -2
- package/lib/utils.js +121 -65
- package/mocha.js +6622 -2939
- package/mocha.js.map +1 -1
- package/package.json +18 -13
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
|
};
|
package/lib/mocha.js
CHANGED
|
@@ -18,15 +18,18 @@ var esmUtils = utils.supportsEsModules(true)
|
|
|
18
18
|
: undefined;
|
|
19
19
|
var createStatsCollector = require('./stats-collector');
|
|
20
20
|
const {
|
|
21
|
-
|
|
22
|
-
createInvalidInterfaceError,
|
|
21
|
+
warn,
|
|
23
22
|
createInvalidReporterError,
|
|
23
|
+
createInvalidInterfaceError,
|
|
24
24
|
createMochaInstanceAlreadyDisposedError,
|
|
25
|
-
createMochaInstanceAlreadyRunningError
|
|
25
|
+
createMochaInstanceAlreadyRunningError,
|
|
26
|
+
createUnsupportedError
|
|
26
27
|
} = require('./errors');
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
const {
|
|
29
|
+
EVENT_FILE_PRE_REQUIRE,
|
|
30
|
+
EVENT_FILE_POST_REQUIRE,
|
|
31
|
+
EVENT_FILE_REQUIRE
|
|
32
|
+
} = Suite.constants;
|
|
30
33
|
var sQuote = utils.sQuote;
|
|
31
34
|
var debug = require('debug')('mocha:mocha');
|
|
32
35
|
|
|
@@ -128,8 +131,8 @@ exports.Test = require('./test');
|
|
|
128
131
|
* suite with
|
|
129
132
|
* @param {boolean} [options.isWorker] - Should be `true` if `Mocha` process is running in a worker process.
|
|
130
133
|
*/
|
|
131
|
-
function Mocha(options) {
|
|
132
|
-
options =
|
|
134
|
+
function Mocha(options = {}) {
|
|
135
|
+
options = {...mocharc, ...options};
|
|
133
136
|
this.files = [];
|
|
134
137
|
this.options = options;
|
|
135
138
|
// root suite
|
|
@@ -205,6 +208,11 @@ function Mocha(options) {
|
|
|
205
208
|
*/
|
|
206
209
|
this.isWorker = Boolean(options.isWorker);
|
|
207
210
|
|
|
211
|
+
this.globalSetup(options.globalSetup)
|
|
212
|
+
.globalTeardown(options.globalTeardown)
|
|
213
|
+
.enableGlobalSetup(options.enableGlobalSetup)
|
|
214
|
+
.enableGlobalTeardown(options.enableGlobalTeardown);
|
|
215
|
+
|
|
208
216
|
if (
|
|
209
217
|
options.parallel &&
|
|
210
218
|
(typeof options.jobs === 'undefined' || options.jobs > 1)
|
|
@@ -277,25 +285,21 @@ Mocha.prototype.reporter = function(reporterName, reporterOptions) {
|
|
|
277
285
|
try {
|
|
278
286
|
reporter = require(reporterName);
|
|
279
287
|
} catch (err) {
|
|
280
|
-
if (
|
|
281
|
-
err.code === 'MODULE_NOT_FOUND' ||
|
|
282
|
-
err.message.indexOf('Cannot find module') >= 0
|
|
283
|
-
) {
|
|
288
|
+
if (err.code === 'MODULE_NOT_FOUND') {
|
|
284
289
|
// Try to load reporters from a path (absolute or relative)
|
|
285
290
|
try {
|
|
286
291
|
reporter = require(path.resolve(utils.cwd(), reporterName));
|
|
287
292
|
} catch (_err) {
|
|
288
|
-
_err.code === 'MODULE_NOT_FOUND'
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
: utils.warn(
|
|
293
|
+
_err.code === 'MODULE_NOT_FOUND'
|
|
294
|
+
? warn(sQuote(reporterName) + ' reporter not found')
|
|
295
|
+
: warn(
|
|
292
296
|
sQuote(reporterName) +
|
|
293
297
|
' reporter blew up with error:\n' +
|
|
294
298
|
err.stack
|
|
295
299
|
);
|
|
296
300
|
}
|
|
297
301
|
} else {
|
|
298
|
-
|
|
302
|
+
warn(
|
|
299
303
|
sQuote(reporterName) + ' reporter blew up with error:\n' + err.stack
|
|
300
304
|
);
|
|
301
305
|
}
|
|
@@ -965,11 +969,10 @@ Mocha.prototype.run = function(fn) {
|
|
|
965
969
|
if (this.files.length && !this._lazyLoadFiles) {
|
|
966
970
|
this.loadFiles();
|
|
967
971
|
}
|
|
968
|
-
var self = this;
|
|
969
972
|
var suite = this.suite;
|
|
970
973
|
var options = this.options;
|
|
971
974
|
options.files = this.files;
|
|
972
|
-
|
|
975
|
+
const runner = new this._runnerClass(suite, {
|
|
973
976
|
delay: options.delay,
|
|
974
977
|
cleanReferencesAfterRun: this._cleanReferencesAfterRun
|
|
975
978
|
});
|
|
@@ -996,22 +999,42 @@ Mocha.prototype.run = function(fn) {
|
|
|
996
999
|
exports.reporters.Base.inlineDiffs = options.inlineDiffs;
|
|
997
1000
|
exports.reporters.Base.hideDiff = !options.diff;
|
|
998
1001
|
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
self._state = mochaStates.INIT;
|
|
1005
|
-
}
|
|
1002
|
+
const done = failures => {
|
|
1003
|
+
this._previousRunner = runner;
|
|
1004
|
+
this._state = this._cleanReferencesAfterRun
|
|
1005
|
+
? mochaStates.REFERENCES_CLEANED
|
|
1006
|
+
: mochaStates.INIT;
|
|
1006
1007
|
fn = fn || utils.noop;
|
|
1007
|
-
if (reporter.done) {
|
|
1008
|
+
if (typeof reporter.done === 'function') {
|
|
1008
1009
|
reporter.done(failures, fn);
|
|
1009
1010
|
} else {
|
|
1010
1011
|
fn(failures);
|
|
1011
1012
|
}
|
|
1012
|
-
}
|
|
1013
|
+
};
|
|
1014
|
+
|
|
1015
|
+
const runAsync = async runner => {
|
|
1016
|
+
const context =
|
|
1017
|
+
this.options.enableGlobalSetup && this.hasGlobalSetupFixtures()
|
|
1018
|
+
? await this.runGlobalSetup(runner)
|
|
1019
|
+
: {};
|
|
1020
|
+
const failureCount = await runner.runAsync({
|
|
1021
|
+
files: this.files,
|
|
1022
|
+
options
|
|
1023
|
+
});
|
|
1024
|
+
if (this.options.enableGlobalTeardown && this.hasGlobalTeardownFixtures()) {
|
|
1025
|
+
await this.runGlobalTeardown(runner, {context});
|
|
1026
|
+
}
|
|
1027
|
+
return failureCount;
|
|
1028
|
+
};
|
|
1013
1029
|
|
|
1014
|
-
|
|
1030
|
+
// no "catch" here is intentional. errors coming out of
|
|
1031
|
+
// Runner#run are considered uncaught/unhandled and caught
|
|
1032
|
+
// by the `process` event listeners.
|
|
1033
|
+
// also: returning anything other than `runner` would be a breaking
|
|
1034
|
+
// change
|
|
1035
|
+
runAsync(runner).then(done);
|
|
1036
|
+
|
|
1037
|
+
return runner;
|
|
1015
1038
|
};
|
|
1016
1039
|
|
|
1017
1040
|
/**
|
|
@@ -1019,26 +1042,28 @@ Mocha.prototype.run = function(fn) {
|
|
|
1019
1042
|
* @param {MochaRootHookObject} [hooks] - Hooks to assign to root suite
|
|
1020
1043
|
* @chainable
|
|
1021
1044
|
*/
|
|
1022
|
-
Mocha.prototype.rootHooks = function rootHooks(
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1045
|
+
Mocha.prototype.rootHooks = function rootHooks({
|
|
1046
|
+
beforeAll = [],
|
|
1047
|
+
beforeEach = [],
|
|
1048
|
+
afterAll = [],
|
|
1049
|
+
afterEach = []
|
|
1050
|
+
} = {}) {
|
|
1051
|
+
beforeAll = utils.castArray(beforeAll);
|
|
1052
|
+
beforeEach = utils.castArray(beforeEach);
|
|
1053
|
+
afterAll = utils.castArray(afterAll);
|
|
1054
|
+
afterEach = utils.castArray(afterEach);
|
|
1055
|
+
beforeAll.forEach(hook => {
|
|
1056
|
+
this.suite.beforeAll(hook);
|
|
1057
|
+
});
|
|
1058
|
+
beforeEach.forEach(hook => {
|
|
1059
|
+
this.suite.beforeEach(hook);
|
|
1060
|
+
});
|
|
1061
|
+
afterAll.forEach(hook => {
|
|
1062
|
+
this.suite.afterAll(hook);
|
|
1063
|
+
});
|
|
1064
|
+
afterEach.forEach(hook => {
|
|
1065
|
+
this.suite.afterEach(hook);
|
|
1066
|
+
});
|
|
1042
1067
|
return this;
|
|
1043
1068
|
};
|
|
1044
1069
|
|
|
@@ -1047,18 +1072,21 @@ Mocha.prototype.rootHooks = function rootHooks(hooks) {
|
|
|
1047
1072
|
*
|
|
1048
1073
|
* Must be run before calling {@link Mocha#run}. Changes the `Runner` class to
|
|
1049
1074
|
* use; also enables lazy file loading if not already done so.
|
|
1075
|
+
*
|
|
1076
|
+
* Warning: when passed `false` and lazy loading has been enabled _via any means_ (including calling `parallelMode(true)`), this method will _not_ disable lazy loading. Lazy loading is a prerequisite for parallel
|
|
1077
|
+
* mode, but parallel mode is _not_ a prerequisite for lazy loading!
|
|
1050
1078
|
* @param {boolean} [enable] - If `true`, enable; otherwise disable.
|
|
1051
1079
|
* @throws If run in browser
|
|
1052
|
-
* @throws If Mocha not in
|
|
1080
|
+
* @throws If Mocha not in `INIT` state
|
|
1053
1081
|
* @returns {Mocha}
|
|
1054
1082
|
* @chainable
|
|
1055
1083
|
* @public
|
|
1056
1084
|
*/
|
|
1057
|
-
Mocha.prototype.parallelMode = function parallelMode(enable) {
|
|
1085
|
+
Mocha.prototype.parallelMode = function parallelMode(enable = true) {
|
|
1058
1086
|
if (utils.isBrowser()) {
|
|
1059
1087
|
throw createUnsupportedError('parallel mode is only supported in Node.js');
|
|
1060
1088
|
}
|
|
1061
|
-
|
|
1089
|
+
const parallel = Boolean(enable);
|
|
1062
1090
|
if (
|
|
1063
1091
|
parallel === this.options.parallel &&
|
|
1064
1092
|
this._lazyLoadFiles &&
|
|
@@ -1100,8 +1128,144 @@ Mocha.prototype.lazyLoadFiles = function lazyLoadFiles(enable) {
|
|
|
1100
1128
|
};
|
|
1101
1129
|
|
|
1102
1130
|
/**
|
|
1103
|
-
*
|
|
1131
|
+
* Configures one or more global setup fixtures.
|
|
1132
|
+
*
|
|
1133
|
+
* If given no parameters, _unsets_ any previously-set fixtures.
|
|
1134
|
+
* @chainable
|
|
1135
|
+
* @public
|
|
1136
|
+
* @param {MochaGlobalFixture|MochaGlobalFixture[]} [setupFns] - Global setup fixture(s)
|
|
1137
|
+
* @returns {Mocha}
|
|
1138
|
+
*/
|
|
1139
|
+
Mocha.prototype.globalSetup = function globalSetup(setupFns = []) {
|
|
1140
|
+
setupFns = utils.castArray(setupFns);
|
|
1141
|
+
this.options.globalSetup = setupFns;
|
|
1142
|
+
debug('configured %d global setup functions', setupFns.length);
|
|
1143
|
+
return this;
|
|
1144
|
+
};
|
|
1145
|
+
|
|
1146
|
+
/**
|
|
1147
|
+
* Configures one or more global teardown fixtures.
|
|
1148
|
+
*
|
|
1149
|
+
* If given no parameters, _unsets_ any previously-set fixtures.
|
|
1150
|
+
* @chainable
|
|
1151
|
+
* @public
|
|
1152
|
+
* @param {MochaGlobalFixture|MochaGlobalFixture[]} [teardownFns] - Global teardown fixture(s)
|
|
1153
|
+
* @returns {Mocha}
|
|
1154
|
+
*/
|
|
1155
|
+
Mocha.prototype.globalTeardown = function globalTeardown(teardownFns = []) {
|
|
1156
|
+
teardownFns = utils.castArray(teardownFns);
|
|
1157
|
+
this.options.globalTeardown = teardownFns;
|
|
1158
|
+
debug('configured %d global teardown functions', teardownFns.length);
|
|
1159
|
+
return this;
|
|
1160
|
+
};
|
|
1161
|
+
|
|
1162
|
+
/**
|
|
1163
|
+
* Run any global setup fixtures sequentially, if any.
|
|
1164
|
+
*
|
|
1165
|
+
* This is _automatically called_ by {@link Mocha#run} _unless_ the `runGlobalSetup` option is `false`; see {@link Mocha#enableGlobalSetup}.
|
|
1166
|
+
*
|
|
1167
|
+
* The context object this function resolves with should be consumed by {@link Mocha#runGlobalTeardown}.
|
|
1168
|
+
* @param {object} [context] - Context object if already have one
|
|
1169
|
+
* @public
|
|
1170
|
+
* @returns {Promise<object>} Context object
|
|
1171
|
+
*/
|
|
1172
|
+
Mocha.prototype.runGlobalSetup = async function runGlobalSetup(context = {}) {
|
|
1173
|
+
const {globalSetup} = this.options;
|
|
1174
|
+
if (globalSetup && globalSetup.length) {
|
|
1175
|
+
debug('run(): global setup starting');
|
|
1176
|
+
await this._runGlobalFixtures(globalSetup, context);
|
|
1177
|
+
debug('run(): global setup complete');
|
|
1178
|
+
}
|
|
1179
|
+
return context;
|
|
1180
|
+
};
|
|
1181
|
+
|
|
1182
|
+
/**
|
|
1183
|
+
* Run any global teardown fixtures sequentially, if any.
|
|
1184
|
+
*
|
|
1185
|
+
* This is _automatically called_ by {@link Mocha#run} _unless_ the `runGlobalTeardown` option is `false`; see {@link Mocha#enableGlobalTeardown}.
|
|
1186
|
+
*
|
|
1187
|
+
* Should be called with context object returned by {@link Mocha#runGlobalSetup}, if applicable.
|
|
1188
|
+
* @param {object} [context] - Context object if already have one
|
|
1189
|
+
* @public
|
|
1190
|
+
* @returns {Promise<object>} Context object
|
|
1191
|
+
*/
|
|
1192
|
+
Mocha.prototype.runGlobalTeardown = async function runGlobalTeardown(
|
|
1193
|
+
context = {}
|
|
1194
|
+
) {
|
|
1195
|
+
const {globalTeardown} = this.options;
|
|
1196
|
+
if (globalTeardown && globalTeardown.length) {
|
|
1197
|
+
debug('run(): global teardown starting');
|
|
1198
|
+
await this._runGlobalFixtures(globalTeardown, context);
|
|
1199
|
+
}
|
|
1200
|
+
debug('run(): global teardown complete');
|
|
1201
|
+
return context;
|
|
1202
|
+
};
|
|
1203
|
+
|
|
1204
|
+
/**
|
|
1205
|
+
* Run global fixtures sequentially with context `context`
|
|
1104
1206
|
* @private
|
|
1207
|
+
* @param {MochaGlobalFixture[]} [fixtureFns] - Fixtures to run
|
|
1208
|
+
* @param {object} [context] - context object
|
|
1209
|
+
* @returns {Promise<object>} context object
|
|
1210
|
+
*/
|
|
1211
|
+
Mocha.prototype._runGlobalFixtures = async function _runGlobalFixtures(
|
|
1212
|
+
fixtureFns = [],
|
|
1213
|
+
context = {}
|
|
1214
|
+
) {
|
|
1215
|
+
for await (const fixtureFn of fixtureFns) {
|
|
1216
|
+
await fixtureFn.call(context);
|
|
1217
|
+
}
|
|
1218
|
+
return context;
|
|
1219
|
+
};
|
|
1220
|
+
|
|
1221
|
+
/**
|
|
1222
|
+
* Toggle execution of any global setup fixture(s)
|
|
1223
|
+
*
|
|
1224
|
+
* @chainable
|
|
1225
|
+
* @public
|
|
1226
|
+
* @param {boolean } [enabled=true] - If `false`, do not run global setup fixture
|
|
1227
|
+
* @returns {Mocha}
|
|
1228
|
+
*/
|
|
1229
|
+
Mocha.prototype.enableGlobalSetup = function enableGlobalSetup(enabled = true) {
|
|
1230
|
+
this.options.enableGlobalSetup = Boolean(enabled);
|
|
1231
|
+
return this;
|
|
1232
|
+
};
|
|
1233
|
+
|
|
1234
|
+
/**
|
|
1235
|
+
* Toggle execution of any global teardown fixture(s)
|
|
1236
|
+
*
|
|
1237
|
+
* @chainable
|
|
1238
|
+
* @public
|
|
1239
|
+
* @param {boolean } [enabled=true] - If `false`, do not run global teardown fixture
|
|
1240
|
+
* @returns {Mocha}
|
|
1241
|
+
*/
|
|
1242
|
+
Mocha.prototype.enableGlobalTeardown = function enableGlobalTeardown(
|
|
1243
|
+
enabled = true
|
|
1244
|
+
) {
|
|
1245
|
+
this.options.enableGlobalTeardown = Boolean(enabled);
|
|
1246
|
+
return this;
|
|
1247
|
+
};
|
|
1248
|
+
|
|
1249
|
+
/**
|
|
1250
|
+
* Returns `true` if one or more global setup fixtures have been supplied.
|
|
1251
|
+
* @public
|
|
1252
|
+
* @returns {boolean}
|
|
1253
|
+
*/
|
|
1254
|
+
Mocha.prototype.hasGlobalSetupFixtures = function hasGlobalSetupFixtures() {
|
|
1255
|
+
return Boolean(this.options.globalSetup.length);
|
|
1256
|
+
};
|
|
1257
|
+
|
|
1258
|
+
/**
|
|
1259
|
+
* Returns `true` if one or more global teardown fixtures have been supplied.
|
|
1260
|
+
* @public
|
|
1261
|
+
* @returns {boolean}
|
|
1262
|
+
*/
|
|
1263
|
+
Mocha.prototype.hasGlobalTeardownFixtures = function hasGlobalTeardownFixtures() {
|
|
1264
|
+
return Boolean(this.options.globalTeardown.length);
|
|
1265
|
+
};
|
|
1266
|
+
|
|
1267
|
+
/**
|
|
1268
|
+
* An alternative way to define root hooks that works with parallel runs.
|
|
1105
1269
|
* @typedef {Object} MochaRootHookObject
|
|
1106
1270
|
* @property {Function|Function[]} [beforeAll] - "Before all" hook(s)
|
|
1107
1271
|
* @property {Function|Function[]} [beforeEach] - "Before each" hook(s)
|
|
@@ -1111,7 +1275,40 @@ Mocha.prototype.lazyLoadFiles = function lazyLoadFiles(enable) {
|
|
|
1111
1275
|
|
|
1112
1276
|
/**
|
|
1113
1277
|
* An function that returns a {@link MochaRootHookObject}, either sync or async.
|
|
1114
|
-
|
|
1115
|
-
* @callback MochaRootHookFunction
|
|
1278
|
+
@callback MochaRootHookFunction
|
|
1116
1279
|
* @returns {MochaRootHookObject|Promise<MochaRootHookObject>}
|
|
1117
1280
|
*/
|
|
1281
|
+
|
|
1282
|
+
/**
|
|
1283
|
+
* A function that's invoked _once_ which is either sync or async.
|
|
1284
|
+
* Can be a "teardown" or "setup". These will all share the same context.
|
|
1285
|
+
* @callback MochaGlobalFixture
|
|
1286
|
+
* @returns {void|Promise<void>}
|
|
1287
|
+
*/
|
|
1288
|
+
|
|
1289
|
+
/**
|
|
1290
|
+
* An object making up all necessary parts of a plugin loader and aggregator
|
|
1291
|
+
* @typedef {Object} PluginDefinition
|
|
1292
|
+
* @property {string} exportName - Named export to use
|
|
1293
|
+
* @property {string} [optionName] - Option name for Mocha constructor (use `exportName` if omitted)
|
|
1294
|
+
* @property {PluginValidator} [validate] - Validator function
|
|
1295
|
+
* @property {PluginFinalizer} [finalize] - Finalizer/aggregator function
|
|
1296
|
+
*/
|
|
1297
|
+
|
|
1298
|
+
/**
|
|
1299
|
+
* A (sync) function to assert a user-supplied plugin implementation is valid.
|
|
1300
|
+
*
|
|
1301
|
+
* Defined in a {@link PluginDefinition}.
|
|
1302
|
+
|
|
1303
|
+
* @callback PluginValidator
|
|
1304
|
+
* @param {*} value - Value to check
|
|
1305
|
+
* @this {PluginDefinition}
|
|
1306
|
+
* @returns {void}
|
|
1307
|
+
*/
|
|
1308
|
+
|
|
1309
|
+
/**
|
|
1310
|
+
* A function to finalize plugins impls of a particular ilk
|
|
1311
|
+
* @callback PluginFinalizer
|
|
1312
|
+
* @param {Array<*>} impls - User-supplied implementations
|
|
1313
|
+
* @returns {Promise<*>|*}
|
|
1314
|
+
*/
|
|
@@ -75,9 +75,7 @@ class BufferedWorkerPool {
|
|
|
75
75
|
process.execArgv.join(' ')
|
|
76
76
|
);
|
|
77
77
|
|
|
78
|
-
this.options =
|
|
79
|
-
maxWorkers
|
|
80
|
-
});
|
|
78
|
+
this.options = {...WORKER_POOL_DEFAULT_OPTS, opts, maxWorkers};
|
|
81
79
|
this._pool = workerpool.pool(WORKER_PATH, this.options);
|
|
82
80
|
}
|
|
83
81
|
|