mocha 7.1.2 → 8.1.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 +143 -2
- package/bin/mocha +24 -4
- package/browser-entry.js +37 -9
- package/lib/browser/growl.js +2 -1
- package/lib/browser/highlight-tags.js +39 -0
- package/lib/browser/parse-query.js +24 -0
- package/lib/browser/progress.js +4 -0
- package/lib/browser/template.html +7 -5
- package/lib/cli/cli.js +6 -3
- package/lib/cli/collect-files.js +17 -10
- package/lib/cli/config.js +6 -6
- package/lib/cli/init.js +1 -2
- package/lib/cli/lookup-files.js +145 -0
- package/lib/cli/node-flags.js +2 -2
- package/lib/cli/options.js +14 -90
- package/lib/cli/run-helpers.js +133 -36
- package/lib/cli/run-option-metadata.js +4 -2
- package/lib/cli/run.js +71 -11
- package/lib/cli/watch-run.js +211 -51
- package/lib/context.js +0 -15
- package/lib/errors.js +202 -9
- package/lib/esm-utils.js +11 -6
- package/lib/hook.js +32 -0
- package/lib/interfaces/common.js +21 -10
- package/lib/mocha.js +301 -126
- package/lib/mocharc.json +0 -1
- package/lib/nodejs/buffered-worker-pool.js +174 -0
- package/lib/{growl.js → nodejs/growl.js} +3 -2
- package/lib/nodejs/parallel-buffered-runner.js +295 -0
- package/lib/nodejs/reporters/parallel-buffered.js +133 -0
- package/lib/nodejs/serializer.js +404 -0
- package/lib/nodejs/worker.js +154 -0
- package/lib/pending.js +4 -0
- package/lib/reporters/base.js +25 -12
- package/lib/reporters/doc.js +6 -0
- package/lib/reporters/json-stream.js +1 -0
- package/lib/reporters/json.js +1 -0
- package/lib/reporters/landing.js +11 -3
- package/lib/reporters/tap.js +1 -2
- package/lib/reporters/xunit.js +3 -2
- package/lib/runnable.js +39 -47
- package/lib/runner.js +219 -118
- package/lib/suite.js +61 -27
- package/lib/test.js +48 -3
- package/lib/utils.js +33 -209
- package/mocha.js +25522 -17715
- package/mocha.js.map +1 -0
- package/package.json +87 -68
- package/lib/browser/tty.js +0 -13
package/lib/mocha.js
CHANGED
|
@@ -9,40 +9,72 @@
|
|
|
9
9
|
var escapeRe = require('escape-string-regexp');
|
|
10
10
|
var path = require('path');
|
|
11
11
|
var builtinReporters = require('./reporters');
|
|
12
|
-
var growl = require('./growl');
|
|
12
|
+
var growl = require('./nodejs/growl');
|
|
13
13
|
var utils = require('./utils');
|
|
14
14
|
var mocharc = require('./mocharc.json');
|
|
15
15
|
var errors = require('./errors');
|
|
16
16
|
var Suite = require('./suite');
|
|
17
|
-
var esmUtils = utils.supportsEsModules()
|
|
17
|
+
var esmUtils = utils.supportsEsModules(true)
|
|
18
|
+
? require('./esm-utils')
|
|
19
|
+
: undefined;
|
|
18
20
|
var createStatsCollector = require('./stats-collector');
|
|
19
21
|
var createInvalidReporterError = errors.createInvalidReporterError;
|
|
20
22
|
var createInvalidInterfaceError = errors.createInvalidInterfaceError;
|
|
23
|
+
var createMochaInstanceAlreadyDisposedError =
|
|
24
|
+
errors.createMochaInstanceAlreadyDisposedError;
|
|
25
|
+
var createMochaInstanceAlreadyRunningError =
|
|
26
|
+
errors.createMochaInstanceAlreadyRunningError;
|
|
21
27
|
var EVENT_FILE_PRE_REQUIRE = Suite.constants.EVENT_FILE_PRE_REQUIRE;
|
|
22
28
|
var EVENT_FILE_POST_REQUIRE = Suite.constants.EVENT_FILE_POST_REQUIRE;
|
|
23
29
|
var EVENT_FILE_REQUIRE = Suite.constants.EVENT_FILE_REQUIRE;
|
|
24
30
|
var sQuote = utils.sQuote;
|
|
31
|
+
var debug = require('debug')('mocha:mocha');
|
|
25
32
|
|
|
26
33
|
exports = module.exports = Mocha;
|
|
27
34
|
|
|
35
|
+
/**
|
|
36
|
+
* A Mocha instance is a finite state machine.
|
|
37
|
+
* These are the states it can be in.
|
|
38
|
+
* @private
|
|
39
|
+
*/
|
|
40
|
+
var mochaStates = utils.defineConstants({
|
|
41
|
+
/**
|
|
42
|
+
* Initial state of the mocha instance
|
|
43
|
+
* @private
|
|
44
|
+
*/
|
|
45
|
+
INIT: 'init',
|
|
46
|
+
/**
|
|
47
|
+
* Mocha instance is running tests
|
|
48
|
+
* @private
|
|
49
|
+
*/
|
|
50
|
+
RUNNING: 'running',
|
|
51
|
+
/**
|
|
52
|
+
* Mocha instance is done running tests and references to test functions and hooks are cleaned.
|
|
53
|
+
* You can reset this state by unloading the test files.
|
|
54
|
+
* @private
|
|
55
|
+
*/
|
|
56
|
+
REFERENCES_CLEANED: 'referencesCleaned',
|
|
57
|
+
/**
|
|
58
|
+
* Mocha instance is disposed and can no longer be used.
|
|
59
|
+
* @private
|
|
60
|
+
*/
|
|
61
|
+
DISPOSED: 'disposed'
|
|
62
|
+
});
|
|
63
|
+
|
|
28
64
|
/**
|
|
29
65
|
* To require local UIs and reporters when running in node.
|
|
30
66
|
*/
|
|
31
67
|
|
|
32
|
-
if (!
|
|
33
|
-
var cwd =
|
|
68
|
+
if (!utils.isBrowser() && typeof module.paths !== 'undefined') {
|
|
69
|
+
var cwd = utils.cwd();
|
|
34
70
|
module.paths.push(cwd, path.join(cwd, 'node_modules'));
|
|
35
71
|
}
|
|
36
72
|
|
|
37
73
|
/**
|
|
38
74
|
* Expose internals.
|
|
75
|
+
* @private
|
|
39
76
|
*/
|
|
40
77
|
|
|
41
|
-
/**
|
|
42
|
-
* @public
|
|
43
|
-
* @class utils
|
|
44
|
-
* @memberof Mocha
|
|
45
|
-
*/
|
|
46
78
|
exports.utils = utils;
|
|
47
79
|
exports.interfaces = require('./interfaces');
|
|
48
80
|
/**
|
|
@@ -90,6 +122,11 @@ exports.Test = require('./test');
|
|
|
90
122
|
* @param {number} [options.slow] - Slow threshold value.
|
|
91
123
|
* @param {number|string} [options.timeout] - Timeout threshold value.
|
|
92
124
|
* @param {string} [options.ui] - Interface name.
|
|
125
|
+
* @param {boolean} [options.parallel] - Run jobs in parallel
|
|
126
|
+
* @param {number} [options.jobs] - Max number of worker processes for parallel runs
|
|
127
|
+
* @param {MochaRootHookObject} [options.rootHooks] - Hooks to bootstrap the root
|
|
128
|
+
* suite with
|
|
129
|
+
* @param {boolean} [options.isWorker] - Should be `true` if `Mocha` process is running in a worker process.
|
|
93
130
|
*/
|
|
94
131
|
function Mocha(options) {
|
|
95
132
|
options = utils.assign({}, mocharc, options || {});
|
|
@@ -97,6 +134,8 @@ function Mocha(options) {
|
|
|
97
134
|
this.options = options;
|
|
98
135
|
// root suite
|
|
99
136
|
this.suite = new exports.Suite('', new exports.Context(), true);
|
|
137
|
+
this._cleanReferencesAfterRun = true;
|
|
138
|
+
this._state = mochaStates.INIT;
|
|
100
139
|
|
|
101
140
|
this.grep(options.grep)
|
|
102
141
|
.fgrep(options.fgrep)
|
|
@@ -136,6 +175,43 @@ function Mocha(options) {
|
|
|
136
175
|
this[opt]();
|
|
137
176
|
}
|
|
138
177
|
}, this);
|
|
178
|
+
|
|
179
|
+
if (options.rootHooks) {
|
|
180
|
+
this.rootHooks(options.rootHooks);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* The class which we'll instantiate in {@link Mocha#run}. Defaults to
|
|
185
|
+
* {@link Runner} in serial mode; changes in parallel mode.
|
|
186
|
+
* @memberof Mocha
|
|
187
|
+
* @private
|
|
188
|
+
*/
|
|
189
|
+
this._runnerClass = exports.Runner;
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Whether or not to call {@link Mocha#loadFiles} implicitly when calling
|
|
193
|
+
* {@link Mocha#run}. If this is `true`, then it's up to the consumer to call
|
|
194
|
+
* {@link Mocha#loadFiles} _or_ {@link Mocha#loadFilesAsync}.
|
|
195
|
+
* @private
|
|
196
|
+
* @memberof Mocha
|
|
197
|
+
*/
|
|
198
|
+
this._lazyLoadFiles = false;
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* It's useful for a Mocha instance to know if it's running in a worker process.
|
|
202
|
+
* We could derive this via other means, but it's helpful to have a flag to refer to.
|
|
203
|
+
* @memberof Mocha
|
|
204
|
+
* @private
|
|
205
|
+
*/
|
|
206
|
+
this.isWorker = Boolean(options.isWorker);
|
|
207
|
+
|
|
208
|
+
if (
|
|
209
|
+
options.parallel &&
|
|
210
|
+
(typeof options.jobs === 'undefined' || options.jobs > 1)
|
|
211
|
+
) {
|
|
212
|
+
debug('attempting to enable parallel mode');
|
|
213
|
+
this.parallelMode(true);
|
|
214
|
+
}
|
|
139
215
|
}
|
|
140
216
|
|
|
141
217
|
/**
|
|
@@ -176,7 +252,7 @@ Mocha.prototype.addFile = function(file) {
|
|
|
176
252
|
* @public
|
|
177
253
|
* @see [CLI option](../#-reporter-name-r-name)
|
|
178
254
|
* @see [Reporters](../#reporters)
|
|
179
|
-
* @param {String|Function}
|
|
255
|
+
* @param {String|Function} reporterName - Reporter name or constructor.
|
|
180
256
|
* @param {Object} [reporterOptions] - Options used to configure the reporter.
|
|
181
257
|
* @returns {Mocha} this
|
|
182
258
|
* @chainable
|
|
@@ -186,52 +262,52 @@ Mocha.prototype.addFile = function(file) {
|
|
|
186
262
|
* // Use XUnit reporter and direct its output to file
|
|
187
263
|
* mocha.reporter('xunit', { output: '/path/to/testspec.xunit.xml' });
|
|
188
264
|
*/
|
|
189
|
-
Mocha.prototype.reporter = function(
|
|
190
|
-
if (typeof
|
|
191
|
-
this._reporter =
|
|
265
|
+
Mocha.prototype.reporter = function(reporterName, reporterOptions) {
|
|
266
|
+
if (typeof reporterName === 'function') {
|
|
267
|
+
this._reporter = reporterName;
|
|
192
268
|
} else {
|
|
193
|
-
|
|
194
|
-
var
|
|
269
|
+
reporterName = reporterName || 'spec';
|
|
270
|
+
var reporter;
|
|
195
271
|
// Try to load a built-in reporter.
|
|
196
|
-
if (builtinReporters[
|
|
197
|
-
|
|
272
|
+
if (builtinReporters[reporterName]) {
|
|
273
|
+
reporter = builtinReporters[reporterName];
|
|
198
274
|
}
|
|
199
275
|
// Try to load reporters from process.cwd() and node_modules
|
|
200
|
-
if (!
|
|
276
|
+
if (!reporter) {
|
|
201
277
|
try {
|
|
202
|
-
|
|
278
|
+
reporter = require(reporterName);
|
|
203
279
|
} catch (err) {
|
|
204
280
|
if (
|
|
205
|
-
err.code
|
|
206
|
-
err.message.indexOf('Cannot find module')
|
|
281
|
+
err.code === 'MODULE_NOT_FOUND' ||
|
|
282
|
+
err.message.indexOf('Cannot find module') >= 0
|
|
207
283
|
) {
|
|
208
284
|
// Try to load reporters from a path (absolute or relative)
|
|
209
285
|
try {
|
|
210
|
-
|
|
286
|
+
reporter = require(path.resolve(utils.cwd(), reporterName));
|
|
211
287
|
} catch (_err) {
|
|
212
|
-
_err.code
|
|
213
|
-
_err.message.indexOf('Cannot find module')
|
|
214
|
-
?
|
|
215
|
-
:
|
|
216
|
-
sQuote(
|
|
288
|
+
_err.code === 'MODULE_NOT_FOUND' ||
|
|
289
|
+
_err.message.indexOf('Cannot find module') >= 0
|
|
290
|
+
? utils.warn(sQuote(reporterName) + ' reporter not found')
|
|
291
|
+
: utils.warn(
|
|
292
|
+
sQuote(reporterName) +
|
|
217
293
|
' reporter blew up with error:\n' +
|
|
218
294
|
err.stack
|
|
219
295
|
);
|
|
220
296
|
}
|
|
221
297
|
} else {
|
|
222
|
-
|
|
223
|
-
sQuote(
|
|
298
|
+
utils.warn(
|
|
299
|
+
sQuote(reporterName) + ' reporter blew up with error:\n' + err.stack
|
|
224
300
|
);
|
|
225
301
|
}
|
|
226
302
|
}
|
|
227
303
|
}
|
|
228
|
-
if (!
|
|
304
|
+
if (!reporter) {
|
|
229
305
|
throw createInvalidReporterError(
|
|
230
|
-
'invalid reporter ' + sQuote(
|
|
231
|
-
|
|
306
|
+
'invalid reporter ' + sQuote(reporterName),
|
|
307
|
+
reporterName
|
|
232
308
|
);
|
|
233
309
|
}
|
|
234
|
-
this._reporter =
|
|
310
|
+
this._reporter = reporter;
|
|
235
311
|
}
|
|
236
312
|
this.options.reporterOption = reporterOptions;
|
|
237
313
|
// alias option name is used in public reporters xunit/tap/progress
|
|
@@ -340,7 +416,7 @@ Mocha.prototype.loadFiles = function(fn) {
|
|
|
340
416
|
Mocha.prototype.loadFilesAsync = function() {
|
|
341
417
|
var self = this;
|
|
342
418
|
var suite = this.suite;
|
|
343
|
-
this.
|
|
419
|
+
this.lazyLoadFiles(true);
|
|
344
420
|
|
|
345
421
|
if (!esmUtils) {
|
|
346
422
|
return new Promise(function(resolve) {
|
|
@@ -388,7 +464,18 @@ Mocha.unloadFile = function(file) {
|
|
|
388
464
|
* @chainable
|
|
389
465
|
*/
|
|
390
466
|
Mocha.prototype.unloadFiles = function() {
|
|
391
|
-
this.
|
|
467
|
+
if (this._state === mochaStates.DISPOSED) {
|
|
468
|
+
throw createMochaInstanceAlreadyDisposedError(
|
|
469
|
+
'Mocha instance is already disposed, it cannot be used again.',
|
|
470
|
+
this._cleanReferencesAfterRun,
|
|
471
|
+
this
|
|
472
|
+
);
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
this.files.forEach(function(file) {
|
|
476
|
+
Mocha.unloadFile(file);
|
|
477
|
+
});
|
|
478
|
+
this._state = mochaStates.INIT;
|
|
392
479
|
return this;
|
|
393
480
|
};
|
|
394
481
|
|
|
@@ -475,37 +562,51 @@ Mocha.prototype.invert = function() {
|
|
|
475
562
|
};
|
|
476
563
|
|
|
477
564
|
/**
|
|
478
|
-
* Enables or disables
|
|
565
|
+
* Enables or disables checking for global variables leaked while running tests.
|
|
479
566
|
*
|
|
480
|
-
* @deprecated since v7.0.0
|
|
481
567
|
* @public
|
|
482
|
-
* @see
|
|
483
|
-
* @param {boolean} [
|
|
568
|
+
* @see [CLI option](../#-check-leaks)
|
|
569
|
+
* @param {boolean} [checkLeaks=true] - Whether to check for global variable leaks.
|
|
484
570
|
* @return {Mocha} this
|
|
485
571
|
* @chainable
|
|
486
572
|
*/
|
|
487
|
-
Mocha.prototype.
|
|
488
|
-
|
|
489
|
-
'"ignoreLeaks()" is DEPRECATED, please use "checkLeaks()" instead.'
|
|
490
|
-
);
|
|
491
|
-
this.options.checkLeaks = !ignoreLeaks;
|
|
573
|
+
Mocha.prototype.checkLeaks = function(checkLeaks) {
|
|
574
|
+
this.options.checkLeaks = checkLeaks !== false;
|
|
492
575
|
return this;
|
|
493
576
|
};
|
|
494
577
|
|
|
495
578
|
/**
|
|
496
|
-
* Enables or disables
|
|
497
|
-
*
|
|
579
|
+
* Enables or disables whether or not to dispose after each test run.
|
|
580
|
+
* Disable this to ensure you can run the test suite multiple times.
|
|
581
|
+
* If disabled, be sure to dispose mocha when you're done to prevent memory leaks.
|
|
498
582
|
* @public
|
|
499
|
-
* @see
|
|
500
|
-
* @param {boolean}
|
|
583
|
+
* @see {@link Mocha#dispose}
|
|
584
|
+
* @param {boolean} cleanReferencesAfterRun
|
|
501
585
|
* @return {Mocha} this
|
|
502
586
|
* @chainable
|
|
503
587
|
*/
|
|
504
|
-
Mocha.prototype.
|
|
505
|
-
this.
|
|
588
|
+
Mocha.prototype.cleanReferencesAfterRun = function(cleanReferencesAfterRun) {
|
|
589
|
+
this._cleanReferencesAfterRun = cleanReferencesAfterRun !== false;
|
|
506
590
|
return this;
|
|
507
591
|
};
|
|
508
592
|
|
|
593
|
+
/**
|
|
594
|
+
* Manually dispose this mocha instance. Mark this instance as `disposed` and unable to run more tests.
|
|
595
|
+
* It also removes function references to tests functions and hooks, so variables trapped in closures can be cleaned by the garbage collector.
|
|
596
|
+
* @public
|
|
597
|
+
*/
|
|
598
|
+
Mocha.prototype.dispose = function() {
|
|
599
|
+
if (this._state === mochaStates.RUNNING) {
|
|
600
|
+
throw createMochaInstanceAlreadyRunningError(
|
|
601
|
+
'Cannot dispose while the mocha instance is still running tests.'
|
|
602
|
+
);
|
|
603
|
+
}
|
|
604
|
+
this.unloadFiles();
|
|
605
|
+
this._previousRunner && this._previousRunner.dispose();
|
|
606
|
+
this.suite.dispose();
|
|
607
|
+
this._state = mochaStates.DISPOSED;
|
|
608
|
+
};
|
|
609
|
+
|
|
509
610
|
/**
|
|
510
611
|
* Displays full stack trace upon test failure.
|
|
511
612
|
*
|
|
@@ -531,7 +632,7 @@ Mocha.prototype.fullTrace = function(fullTrace) {
|
|
|
531
632
|
Mocha.prototype.growl = function() {
|
|
532
633
|
this.options.growl = this.isGrowlCapable();
|
|
533
634
|
if (!this.options.growl) {
|
|
534
|
-
var detail =
|
|
635
|
+
var detail = utils.isBrowser()
|
|
535
636
|
? 'notification support not available in this browser...'
|
|
536
637
|
: 'notification support prerequisites not installed...';
|
|
537
638
|
console.error(detail + ' cannot enable!');
|
|
@@ -589,24 +690,6 @@ Mocha.prototype.global = function(global) {
|
|
|
589
690
|
// for backwards compability, 'globals' is an alias of 'global'
|
|
590
691
|
Mocha.prototype.globals = Mocha.prototype.global;
|
|
591
692
|
|
|
592
|
-
/**
|
|
593
|
-
* Enables or disables TTY color output by screen-oriented reporters.
|
|
594
|
-
*
|
|
595
|
-
* @deprecated since v7.0.0
|
|
596
|
-
* @public
|
|
597
|
-
* @see {@link Mocha#color}
|
|
598
|
-
* @param {boolean} colors - Whether to enable color output.
|
|
599
|
-
* @return {Mocha} this
|
|
600
|
-
* @chainable
|
|
601
|
-
*/
|
|
602
|
-
Mocha.prototype.useColors = function(colors) {
|
|
603
|
-
utils.deprecate('"useColors()" is DEPRECATED, please use "color()" instead.');
|
|
604
|
-
if (colors !== undefined) {
|
|
605
|
-
this.options.color = colors;
|
|
606
|
-
}
|
|
607
|
-
return this;
|
|
608
|
-
};
|
|
609
|
-
|
|
610
693
|
/**
|
|
611
694
|
* Enables or disables TTY color output by screen-oriented reporters.
|
|
612
695
|
*
|
|
@@ -621,25 +704,6 @@ Mocha.prototype.color = function(color) {
|
|
|
621
704
|
return this;
|
|
622
705
|
};
|
|
623
706
|
|
|
624
|
-
/**
|
|
625
|
-
* Determines if reporter should use inline diffs (rather than +/-)
|
|
626
|
-
* in test failure output.
|
|
627
|
-
*
|
|
628
|
-
* @deprecated since v7.0.0
|
|
629
|
-
* @public
|
|
630
|
-
* @see {@link Mocha#inlineDiffs}
|
|
631
|
-
* @param {boolean} [inlineDiffs=false] - Whether to use inline diffs.
|
|
632
|
-
* @return {Mocha} this
|
|
633
|
-
* @chainable
|
|
634
|
-
*/
|
|
635
|
-
Mocha.prototype.useInlineDiffs = function(inlineDiffs) {
|
|
636
|
-
utils.deprecate(
|
|
637
|
-
'"useInlineDiffs()" is DEPRECATED, please use "inlineDiffs()" instead.'
|
|
638
|
-
);
|
|
639
|
-
this.options.inlineDiffs = inlineDiffs !== undefined && inlineDiffs;
|
|
640
|
-
return this;
|
|
641
|
-
};
|
|
642
|
-
|
|
643
707
|
/**
|
|
644
708
|
* Enables or disables reporter to use inline diffs (rather than +/-)
|
|
645
709
|
* in test failure output.
|
|
@@ -655,22 +719,6 @@ Mocha.prototype.inlineDiffs = function(inlineDiffs) {
|
|
|
655
719
|
return this;
|
|
656
720
|
};
|
|
657
721
|
|
|
658
|
-
/**
|
|
659
|
-
* Determines if reporter should include diffs in test failure output.
|
|
660
|
-
*
|
|
661
|
-
* @deprecated since v7.0.0
|
|
662
|
-
* @public
|
|
663
|
-
* @see {@link Mocha#diff}
|
|
664
|
-
* @param {boolean} [hideDiff=false] - Whether to hide diffs.
|
|
665
|
-
* @return {Mocha} this
|
|
666
|
-
* @chainable
|
|
667
|
-
*/
|
|
668
|
-
Mocha.prototype.hideDiff = function(hideDiff) {
|
|
669
|
-
utils.deprecate('"hideDiff()" is DEPRECATED, please use "diff()" instead.');
|
|
670
|
-
this.options.diff = !(hideDiff === true);
|
|
671
|
-
return this;
|
|
672
|
-
};
|
|
673
|
-
|
|
674
722
|
/**
|
|
675
723
|
* Enables or disables reporter to include diff in test failure output.
|
|
676
724
|
*
|
|
@@ -696,7 +744,6 @@ Mocha.prototype.diff = function(diff) {
|
|
|
696
744
|
* @public
|
|
697
745
|
* @see [CLI option](../#-timeout-ms-t-ms)
|
|
698
746
|
* @see [Timeouts](../#timeouts)
|
|
699
|
-
* @see {@link Mocha#enableTimeouts}
|
|
700
747
|
* @param {number|string} msecs - Timeout threshold value.
|
|
701
748
|
* @return {Mocha} this
|
|
702
749
|
* @chainable
|
|
@@ -728,8 +775,8 @@ Mocha.prototype.timeout = function(msecs) {
|
|
|
728
775
|
* // Allow any failed test to retry one more time
|
|
729
776
|
* mocha.retries(1);
|
|
730
777
|
*/
|
|
731
|
-
Mocha.prototype.retries = function(
|
|
732
|
-
this.suite.retries(
|
|
778
|
+
Mocha.prototype.retries = function(retry) {
|
|
779
|
+
this.suite.retries(retry);
|
|
733
780
|
return this;
|
|
734
781
|
};
|
|
735
782
|
|
|
@@ -755,22 +802,6 @@ Mocha.prototype.slow = function(msecs) {
|
|
|
755
802
|
return this;
|
|
756
803
|
};
|
|
757
804
|
|
|
758
|
-
/**
|
|
759
|
-
* Enables or disables timeouts.
|
|
760
|
-
*
|
|
761
|
-
* @public
|
|
762
|
-
* @see [CLI option](../#-timeout-ms-t-ms)
|
|
763
|
-
* @param {boolean} enableTimeouts - Whether to enable timeouts.
|
|
764
|
-
* @return {Mocha} this
|
|
765
|
-
* @chainable
|
|
766
|
-
*/
|
|
767
|
-
Mocha.prototype.enableTimeouts = function(enableTimeouts) {
|
|
768
|
-
this.suite.enableTimeouts(
|
|
769
|
-
arguments.length && enableTimeouts !== undefined ? enableTimeouts : true
|
|
770
|
-
);
|
|
771
|
-
return this;
|
|
772
|
-
};
|
|
773
|
-
|
|
774
805
|
/**
|
|
775
806
|
* Forces all tests to either accept a `done` callback or return a promise.
|
|
776
807
|
*
|
|
@@ -856,6 +887,29 @@ Mocha.prototype.forbidPending = function(forbidPending) {
|
|
|
856
887
|
return this;
|
|
857
888
|
};
|
|
858
889
|
|
|
890
|
+
/**
|
|
891
|
+
* Throws an error if mocha is in the wrong state to be able to transition to a "running" state.
|
|
892
|
+
* @private
|
|
893
|
+
*/
|
|
894
|
+
Mocha.prototype._guardRunningStateTransition = function() {
|
|
895
|
+
if (this._state === mochaStates.RUNNING) {
|
|
896
|
+
throw createMochaInstanceAlreadyRunningError(
|
|
897
|
+
'Mocha instance is currently running tests, cannot start a next test run until this one is done',
|
|
898
|
+
this
|
|
899
|
+
);
|
|
900
|
+
}
|
|
901
|
+
if (
|
|
902
|
+
this._state === mochaStates.DISPOSED ||
|
|
903
|
+
this._state === mochaStates.REFERENCES_CLEANED
|
|
904
|
+
) {
|
|
905
|
+
throw createMochaInstanceAlreadyDisposedError(
|
|
906
|
+
'Mocha instance is already disposed, cannot start a new test run. Please create a new mocha instance. Be sure to set disable `cleanReferencesAfterRun` when you want to reuse the same mocha instance for multiple test runs.',
|
|
907
|
+
this._cleanReferencesAfterRun,
|
|
908
|
+
this
|
|
909
|
+
);
|
|
910
|
+
}
|
|
911
|
+
};
|
|
912
|
+
|
|
859
913
|
/**
|
|
860
914
|
* Mocha version as specified by "package.json".
|
|
861
915
|
*
|
|
@@ -873,6 +927,7 @@ Object.defineProperty(Mocha.prototype, 'version', {
|
|
|
873
927
|
/**
|
|
874
928
|
* Callback to be invoked when test execution is complete.
|
|
875
929
|
*
|
|
930
|
+
* @private
|
|
876
931
|
* @callback DoneCB
|
|
877
932
|
* @param {number} failures - Number of failures that occurred.
|
|
878
933
|
*/
|
|
@@ -896,13 +951,23 @@ Object.defineProperty(Mocha.prototype, 'version', {
|
|
|
896
951
|
* mocha.run(failures => process.exitCode = failures ? 1 : 0);
|
|
897
952
|
*/
|
|
898
953
|
Mocha.prototype.run = function(fn) {
|
|
899
|
-
|
|
954
|
+
this._guardRunningStateTransition();
|
|
955
|
+
this._state = mochaStates.RUNNING;
|
|
956
|
+
if (this._previousRunner) {
|
|
957
|
+
this._previousRunner.dispose();
|
|
958
|
+
this.suite.reset();
|
|
959
|
+
}
|
|
960
|
+
if (this.files.length && !this._lazyLoadFiles) {
|
|
900
961
|
this.loadFiles();
|
|
901
962
|
}
|
|
963
|
+
var self = this;
|
|
902
964
|
var suite = this.suite;
|
|
903
965
|
var options = this.options;
|
|
904
966
|
options.files = this.files;
|
|
905
|
-
var runner = new
|
|
967
|
+
var runner = new this._runnerClass(suite, {
|
|
968
|
+
delay: options.delay,
|
|
969
|
+
cleanReferencesAfterRun: this._cleanReferencesAfterRun
|
|
970
|
+
});
|
|
906
971
|
createStatsCollector(runner);
|
|
907
972
|
var reporter = new this._reporter(runner, options);
|
|
908
973
|
runner.checkLeaks = options.checkLeaks === true;
|
|
@@ -927,6 +992,12 @@ Mocha.prototype.run = function(fn) {
|
|
|
927
992
|
exports.reporters.Base.hideDiff = !options.diff;
|
|
928
993
|
|
|
929
994
|
function done(failures) {
|
|
995
|
+
self._previousRunner = runner;
|
|
996
|
+
if (self._cleanReferencesAfterRun) {
|
|
997
|
+
self._state = mochaStates.REFERENCES_CLEANED;
|
|
998
|
+
} else {
|
|
999
|
+
self._state = mochaStates.INIT;
|
|
1000
|
+
}
|
|
930
1001
|
fn = fn || utils.noop;
|
|
931
1002
|
if (reporter.done) {
|
|
932
1003
|
reporter.done(failures, fn);
|
|
@@ -935,5 +1006,109 @@ Mocha.prototype.run = function(fn) {
|
|
|
935
1006
|
}
|
|
936
1007
|
}
|
|
937
1008
|
|
|
938
|
-
return runner.run(done);
|
|
1009
|
+
return runner.run(done, {files: this.files, options: options});
|
|
1010
|
+
};
|
|
1011
|
+
|
|
1012
|
+
/**
|
|
1013
|
+
* Assigns hooks to the root suite
|
|
1014
|
+
* @param {MochaRootHookObject} [hooks] - Hooks to assign to root suite
|
|
1015
|
+
* @chainable
|
|
1016
|
+
*/
|
|
1017
|
+
Mocha.prototype.rootHooks = function rootHooks(hooks) {
|
|
1018
|
+
if (utils.type(hooks) === 'object') {
|
|
1019
|
+
var beforeAll = [].concat(hooks.beforeAll || []);
|
|
1020
|
+
var beforeEach = [].concat(hooks.beforeEach || []);
|
|
1021
|
+
var afterAll = [].concat(hooks.afterAll || []);
|
|
1022
|
+
var afterEach = [].concat(hooks.afterEach || []);
|
|
1023
|
+
var rootSuite = this.suite;
|
|
1024
|
+
beforeAll.forEach(function(hook) {
|
|
1025
|
+
rootSuite.beforeAll(hook);
|
|
1026
|
+
});
|
|
1027
|
+
beforeEach.forEach(function(hook) {
|
|
1028
|
+
rootSuite.beforeEach(hook);
|
|
1029
|
+
});
|
|
1030
|
+
afterAll.forEach(function(hook) {
|
|
1031
|
+
rootSuite.afterAll(hook);
|
|
1032
|
+
});
|
|
1033
|
+
afterEach.forEach(function(hook) {
|
|
1034
|
+
rootSuite.afterEach(hook);
|
|
1035
|
+
});
|
|
1036
|
+
}
|
|
1037
|
+
return this;
|
|
1038
|
+
};
|
|
1039
|
+
|
|
1040
|
+
/**
|
|
1041
|
+
* Toggles parallel mode.
|
|
1042
|
+
*
|
|
1043
|
+
* Must be run before calling {@link Mocha#run}. Changes the `Runner` class to
|
|
1044
|
+
* use; also enables lazy file loading if not already done so.
|
|
1045
|
+
* @param {boolean} [enable] - If `true`, enable; otherwise disable.
|
|
1046
|
+
* @throws If run in browser
|
|
1047
|
+
* @throws If Mocha not in "INIT" state
|
|
1048
|
+
* @returns {Mocha}
|
|
1049
|
+
* @chainable
|
|
1050
|
+
* @public
|
|
1051
|
+
*/
|
|
1052
|
+
Mocha.prototype.parallelMode = function parallelMode(enable) {
|
|
1053
|
+
if (utils.isBrowser()) {
|
|
1054
|
+
throw errors.createUnsupportedError(
|
|
1055
|
+
'parallel mode is only supported in Node.js'
|
|
1056
|
+
);
|
|
1057
|
+
}
|
|
1058
|
+
var parallel = enable === true;
|
|
1059
|
+
if (
|
|
1060
|
+
parallel === this.options.parallel &&
|
|
1061
|
+
this._lazyLoadFiles &&
|
|
1062
|
+
this._runnerClass !== exports.Runner
|
|
1063
|
+
) {
|
|
1064
|
+
return this;
|
|
1065
|
+
}
|
|
1066
|
+
if (this._state !== mochaStates.INIT) {
|
|
1067
|
+
throw errors.createUnsupportedError(
|
|
1068
|
+
'cannot change parallel mode after having called run()'
|
|
1069
|
+
);
|
|
1070
|
+
}
|
|
1071
|
+
this.options.parallel = parallel;
|
|
1072
|
+
|
|
1073
|
+
// swap Runner class
|
|
1074
|
+
this._runnerClass = parallel
|
|
1075
|
+
? require('./nodejs/parallel-buffered-runner')
|
|
1076
|
+
: exports.Runner;
|
|
1077
|
+
|
|
1078
|
+
// lazyLoadFiles may have been set `true` otherwise (for ESM loading),
|
|
1079
|
+
// so keep `true` if so.
|
|
1080
|
+
return this.lazyLoadFiles(this._lazyLoadFiles || parallel);
|
|
1081
|
+
};
|
|
1082
|
+
|
|
1083
|
+
/**
|
|
1084
|
+
* Disables implicit call to {@link Mocha#loadFiles} in {@link Mocha#run}. This
|
|
1085
|
+
* setting is used by watch mode, parallel mode, and for loading ESM files.
|
|
1086
|
+
* @todo This should throw if we've already loaded files; such behavior
|
|
1087
|
+
* necessitates adding a new state.
|
|
1088
|
+
* @param {boolean} [enable] - If `true`, disable eager loading of files in
|
|
1089
|
+
* {@link Mocha#run}
|
|
1090
|
+
* @chainable
|
|
1091
|
+
* @public
|
|
1092
|
+
*/
|
|
1093
|
+
Mocha.prototype.lazyLoadFiles = function lazyLoadFiles(enable) {
|
|
1094
|
+
this._lazyLoadFiles = enable === true;
|
|
1095
|
+
debug('set lazy load to %s', enable);
|
|
1096
|
+
return this;
|
|
939
1097
|
};
|
|
1098
|
+
|
|
1099
|
+
/**
|
|
1100
|
+
* An alternative way to define root hooks that works with parallel runs.
|
|
1101
|
+
* @private
|
|
1102
|
+
* @typedef {Object} MochaRootHookObject
|
|
1103
|
+
* @property {Function|Function[]} [beforeAll] - "Before all" hook(s)
|
|
1104
|
+
* @property {Function|Function[]} [beforeEach] - "Before each" hook(s)
|
|
1105
|
+
* @property {Function|Function[]} [afterAll] - "After all" hook(s)
|
|
1106
|
+
* @property {Function|Function[]} [afterEach] - "After each" hook(s)
|
|
1107
|
+
*/
|
|
1108
|
+
|
|
1109
|
+
/**
|
|
1110
|
+
* An function that returns a {@link MochaRootHookObject}, either sync or async.
|
|
1111
|
+
* @private
|
|
1112
|
+
* @callback MochaRootHookFunction
|
|
1113
|
+
* @returns {MochaRootHookObject|Promise<MochaRootHookObject>}
|
|
1114
|
+
*/
|