mocha 7.1.1 → 8.0.1
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 +110 -2
- package/bin/mocha +24 -4
- package/browser-entry.js +11 -0
- package/lib/browser/growl.js +2 -1
- package/lib/cli/cli.js +6 -3
- package/lib/cli/collect-files.js +14 -8
- package/lib/cli/config.js +6 -6
- package/lib/cli/init.js +1 -2
- 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 +202 -50
- 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 +16 -10
- package/lib/mocha.js +289 -123
- 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 +293 -0
- package/lib/nodejs/reporters/parallel-buffered.js +133 -0
- package/lib/nodejs/serializer.js +402 -0
- package/lib/nodejs/worker.js +154 -0
- package/lib/reporters/base.js +2 -2
- 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 +38 -72
- package/lib/runner.js +185 -85
- package/lib/suite.js +60 -27
- package/lib/test.js +48 -3
- package/lib/utils.js +32 -40
- package/mocha.js +2418 -2199
- package/package.json +71 -56
package/lib/interfaces/common.js
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
var Suite = require('../suite');
|
|
4
4
|
var errors = require('../errors');
|
|
5
5
|
var createMissingArgumentError = errors.createMissingArgumentError;
|
|
6
|
+
var createUnsupportedError = errors.createUnsupportedError;
|
|
7
|
+
var createForbiddenExclusivityError = errors.createForbiddenExclusivityError;
|
|
6
8
|
|
|
7
9
|
/**
|
|
8
10
|
* Functions common to more than one interface.
|
|
@@ -92,6 +94,9 @@ module.exports = function(suites, context, mocha) {
|
|
|
92
94
|
* @returns {Suite}
|
|
93
95
|
*/
|
|
94
96
|
only: function only(opts) {
|
|
97
|
+
if (mocha.options.forbidOnly) {
|
|
98
|
+
throw createForbiddenExclusivityError(mocha);
|
|
99
|
+
}
|
|
95
100
|
opts.isOnly = true;
|
|
96
101
|
return this.create(opts);
|
|
97
102
|
},
|
|
@@ -125,16 +130,14 @@ module.exports = function(suites, context, mocha) {
|
|
|
125
130
|
suite.file = opts.file;
|
|
126
131
|
suites.unshift(suite);
|
|
127
132
|
if (opts.isOnly) {
|
|
128
|
-
|
|
129
|
-
throw new Error('`.only` forbidden');
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
suite.parent.appendOnlySuite(suite);
|
|
133
|
+
suite.markOnly();
|
|
133
134
|
}
|
|
134
|
-
if (
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
135
|
+
if (
|
|
136
|
+
suite.pending &&
|
|
137
|
+
mocha.options.forbidPending &&
|
|
138
|
+
shouldBeTested(suite)
|
|
139
|
+
) {
|
|
140
|
+
throw createUnsupportedError('Pending test forbidden');
|
|
138
141
|
}
|
|
139
142
|
if (typeof opts.fn === 'function') {
|
|
140
143
|
opts.fn.call(suite);
|
|
@@ -165,7 +168,10 @@ module.exports = function(suites, context, mocha) {
|
|
|
165
168
|
* @returns {*}
|
|
166
169
|
*/
|
|
167
170
|
only: function(mocha, test) {
|
|
168
|
-
|
|
171
|
+
if (mocha.options.forbidOnly) {
|
|
172
|
+
throw createForbiddenExclusivityError(mocha);
|
|
173
|
+
}
|
|
174
|
+
test.markOnly();
|
|
169
175
|
return test;
|
|
170
176
|
},
|
|
171
177
|
|
package/lib/mocha.js
CHANGED
|
@@ -9,28 +9,59 @@
|
|
|
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
|
+
*/
|
|
39
|
+
var mochaStates = utils.defineConstants({
|
|
40
|
+
/**
|
|
41
|
+
* Initial state of the mocha instance
|
|
42
|
+
*/
|
|
43
|
+
INIT: 'init',
|
|
44
|
+
/**
|
|
45
|
+
* Mocha instance is running tests
|
|
46
|
+
*/
|
|
47
|
+
RUNNING: 'running',
|
|
48
|
+
/**
|
|
49
|
+
* Mocha instance is done running tests and references to test functions and hooks are cleaned.
|
|
50
|
+
* You can reset this state by unloading the test files.
|
|
51
|
+
*/
|
|
52
|
+
REFERENCES_CLEANED: 'referencesCleaned',
|
|
53
|
+
/**
|
|
54
|
+
* Mocha instance is disposed and can no longer be used.
|
|
55
|
+
*/
|
|
56
|
+
DISPOSED: 'disposed'
|
|
57
|
+
});
|
|
58
|
+
|
|
28
59
|
/**
|
|
29
60
|
* To require local UIs and reporters when running in node.
|
|
30
61
|
*/
|
|
31
62
|
|
|
32
|
-
if (!
|
|
33
|
-
var cwd =
|
|
63
|
+
if (!utils.isBrowser() && typeof module.paths !== 'undefined') {
|
|
64
|
+
var cwd = utils.cwd();
|
|
34
65
|
module.paths.push(cwd, path.join(cwd, 'node_modules'));
|
|
35
66
|
}
|
|
36
67
|
|
|
@@ -38,11 +69,6 @@ if (!process.browser) {
|
|
|
38
69
|
* Expose internals.
|
|
39
70
|
*/
|
|
40
71
|
|
|
41
|
-
/**
|
|
42
|
-
* @public
|
|
43
|
-
* @class utils
|
|
44
|
-
* @memberof Mocha
|
|
45
|
-
*/
|
|
46
72
|
exports.utils = utils;
|
|
47
73
|
exports.interfaces = require('./interfaces');
|
|
48
74
|
/**
|
|
@@ -90,6 +116,11 @@ exports.Test = require('./test');
|
|
|
90
116
|
* @param {number} [options.slow] - Slow threshold value.
|
|
91
117
|
* @param {number|string} [options.timeout] - Timeout threshold value.
|
|
92
118
|
* @param {string} [options.ui] - Interface name.
|
|
119
|
+
* @param {boolean} [options.parallel] - Run jobs in parallel
|
|
120
|
+
* @param {number} [options.jobs] - Max number of worker processes for parallel runs
|
|
121
|
+
* @param {MochaRootHookObject} [options.rootHooks] - Hooks to bootstrap the root
|
|
122
|
+
* suite with
|
|
123
|
+
* @param {boolean} [options.isWorker] - Should be `true` if `Mocha` process is running in a worker process.
|
|
93
124
|
*/
|
|
94
125
|
function Mocha(options) {
|
|
95
126
|
options = utils.assign({}, mocharc, options || {});
|
|
@@ -97,6 +128,8 @@ function Mocha(options) {
|
|
|
97
128
|
this.options = options;
|
|
98
129
|
// root suite
|
|
99
130
|
this.suite = new exports.Suite('', new exports.Context(), true);
|
|
131
|
+
this._cleanReferencesAfterRun = true;
|
|
132
|
+
this._state = mochaStates.INIT;
|
|
100
133
|
|
|
101
134
|
this.grep(options.grep)
|
|
102
135
|
.fgrep(options.fgrep)
|
|
@@ -136,6 +169,43 @@ function Mocha(options) {
|
|
|
136
169
|
this[opt]();
|
|
137
170
|
}
|
|
138
171
|
}, this);
|
|
172
|
+
|
|
173
|
+
if (options.rootHooks) {
|
|
174
|
+
this.rootHooks(options.rootHooks);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* The class which we'll instantiate in {@link Mocha#run}. Defaults to
|
|
179
|
+
* {@link Runner} in serial mode; changes in parallel mode.
|
|
180
|
+
* @memberof Mocha
|
|
181
|
+
* @private
|
|
182
|
+
*/
|
|
183
|
+
this._runnerClass = exports.Runner;
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Whether or not to call {@link Mocha#loadFiles} implicitly when calling
|
|
187
|
+
* {@link Mocha#run}. If this is `true`, then it's up to the consumer to call
|
|
188
|
+
* {@link Mocha#loadFiles} _or_ {@link Mocha#loadFilesAsync}.
|
|
189
|
+
* @private
|
|
190
|
+
* @memberof Mocha
|
|
191
|
+
*/
|
|
192
|
+
this._lazyLoadFiles = false;
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* It's useful for a Mocha instance to know if it's running in a worker process.
|
|
196
|
+
* We could derive this via other means, but it's helpful to have a flag to refer to.
|
|
197
|
+
* @memberof Mocha
|
|
198
|
+
* @private
|
|
199
|
+
*/
|
|
200
|
+
this.isWorker = Boolean(options.isWorker);
|
|
201
|
+
|
|
202
|
+
if (
|
|
203
|
+
options.parallel &&
|
|
204
|
+
(typeof options.jobs === 'undefined' || options.jobs > 1)
|
|
205
|
+
) {
|
|
206
|
+
debug('attempting to enable parallel mode');
|
|
207
|
+
this.parallelMode(true);
|
|
208
|
+
}
|
|
139
209
|
}
|
|
140
210
|
|
|
141
211
|
/**
|
|
@@ -186,52 +256,52 @@ Mocha.prototype.addFile = function(file) {
|
|
|
186
256
|
* // Use XUnit reporter and direct its output to file
|
|
187
257
|
* mocha.reporter('xunit', { output: '/path/to/testspec.xunit.xml' });
|
|
188
258
|
*/
|
|
189
|
-
Mocha.prototype.reporter = function(
|
|
190
|
-
if (typeof
|
|
191
|
-
this._reporter =
|
|
259
|
+
Mocha.prototype.reporter = function(reporterName, reporterOptions) {
|
|
260
|
+
if (typeof reporterName === 'function') {
|
|
261
|
+
this._reporter = reporterName;
|
|
192
262
|
} else {
|
|
193
|
-
|
|
194
|
-
var
|
|
263
|
+
reporterName = reporterName || 'spec';
|
|
264
|
+
var reporter;
|
|
195
265
|
// Try to load a built-in reporter.
|
|
196
|
-
if (builtinReporters[
|
|
197
|
-
|
|
266
|
+
if (builtinReporters[reporterName]) {
|
|
267
|
+
reporter = builtinReporters[reporterName];
|
|
198
268
|
}
|
|
199
269
|
// Try to load reporters from process.cwd() and node_modules
|
|
200
|
-
if (!
|
|
270
|
+
if (!reporter) {
|
|
201
271
|
try {
|
|
202
|
-
|
|
272
|
+
reporter = require(reporterName);
|
|
203
273
|
} catch (err) {
|
|
204
274
|
if (
|
|
205
|
-
err.code
|
|
206
|
-
err.message.indexOf('Cannot find module')
|
|
275
|
+
err.code === 'MODULE_NOT_FOUND' ||
|
|
276
|
+
err.message.indexOf('Cannot find module') >= 0
|
|
207
277
|
) {
|
|
208
278
|
// Try to load reporters from a path (absolute or relative)
|
|
209
279
|
try {
|
|
210
|
-
|
|
280
|
+
reporter = require(path.resolve(utils.cwd(), reporterName));
|
|
211
281
|
} catch (_err) {
|
|
212
|
-
_err.code
|
|
213
|
-
_err.message.indexOf('Cannot find module')
|
|
214
|
-
?
|
|
215
|
-
:
|
|
216
|
-
sQuote(
|
|
282
|
+
_err.code === 'MODULE_NOT_FOUND' ||
|
|
283
|
+
_err.message.indexOf('Cannot find module') >= 0
|
|
284
|
+
? utils.warn(sQuote(reporterName) + ' reporter not found')
|
|
285
|
+
: utils.warn(
|
|
286
|
+
sQuote(reporterName) +
|
|
217
287
|
' reporter blew up with error:\n' +
|
|
218
288
|
err.stack
|
|
219
289
|
);
|
|
220
290
|
}
|
|
221
291
|
} else {
|
|
222
|
-
|
|
223
|
-
sQuote(
|
|
292
|
+
utils.warn(
|
|
293
|
+
sQuote(reporterName) + ' reporter blew up with error:\n' + err.stack
|
|
224
294
|
);
|
|
225
295
|
}
|
|
226
296
|
}
|
|
227
297
|
}
|
|
228
|
-
if (!
|
|
298
|
+
if (!reporter) {
|
|
229
299
|
throw createInvalidReporterError(
|
|
230
|
-
'invalid reporter ' + sQuote(
|
|
231
|
-
|
|
300
|
+
'invalid reporter ' + sQuote(reporterName),
|
|
301
|
+
reporterName
|
|
232
302
|
);
|
|
233
303
|
}
|
|
234
|
-
this._reporter =
|
|
304
|
+
this._reporter = reporter;
|
|
235
305
|
}
|
|
236
306
|
this.options.reporterOption = reporterOptions;
|
|
237
307
|
// alias option name is used in public reporters xunit/tap/progress
|
|
@@ -340,7 +410,7 @@ Mocha.prototype.loadFiles = function(fn) {
|
|
|
340
410
|
Mocha.prototype.loadFilesAsync = function() {
|
|
341
411
|
var self = this;
|
|
342
412
|
var suite = this.suite;
|
|
343
|
-
this.
|
|
413
|
+
this.lazyLoadFiles(true);
|
|
344
414
|
|
|
345
415
|
if (!esmUtils) {
|
|
346
416
|
return new Promise(function(resolve) {
|
|
@@ -388,7 +458,18 @@ Mocha.unloadFile = function(file) {
|
|
|
388
458
|
* @chainable
|
|
389
459
|
*/
|
|
390
460
|
Mocha.prototype.unloadFiles = function() {
|
|
391
|
-
this.
|
|
461
|
+
if (this._state === mochaStates.DISPOSED) {
|
|
462
|
+
throw createMochaInstanceAlreadyDisposedError(
|
|
463
|
+
'Mocha instance is already disposed, it cannot be used again.',
|
|
464
|
+
this._cleanReferencesAfterRun,
|
|
465
|
+
this
|
|
466
|
+
);
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
this.files.forEach(function(file) {
|
|
470
|
+
Mocha.unloadFile(file);
|
|
471
|
+
});
|
|
472
|
+
this._state = mochaStates.INIT;
|
|
392
473
|
return this;
|
|
393
474
|
};
|
|
394
475
|
|
|
@@ -475,37 +556,51 @@ Mocha.prototype.invert = function() {
|
|
|
475
556
|
};
|
|
476
557
|
|
|
477
558
|
/**
|
|
478
|
-
* Enables or disables
|
|
559
|
+
* Enables or disables checking for global variables leaked while running tests.
|
|
479
560
|
*
|
|
480
|
-
* @deprecated since v7.0.0
|
|
481
561
|
* @public
|
|
482
|
-
* @see
|
|
483
|
-
* @param {boolean} [
|
|
562
|
+
* @see [CLI option](../#-check-leaks)
|
|
563
|
+
* @param {boolean} [checkLeaks=true] - Whether to check for global variable leaks.
|
|
484
564
|
* @return {Mocha} this
|
|
485
565
|
* @chainable
|
|
486
566
|
*/
|
|
487
|
-
Mocha.prototype.
|
|
488
|
-
|
|
489
|
-
'"ignoreLeaks()" is DEPRECATED, please use "checkLeaks()" instead.'
|
|
490
|
-
);
|
|
491
|
-
this.options.checkLeaks = !ignoreLeaks;
|
|
567
|
+
Mocha.prototype.checkLeaks = function(checkLeaks) {
|
|
568
|
+
this.options.checkLeaks = checkLeaks !== false;
|
|
492
569
|
return this;
|
|
493
570
|
};
|
|
494
571
|
|
|
495
572
|
/**
|
|
496
|
-
* Enables or disables
|
|
497
|
-
*
|
|
573
|
+
* Enables or disables whether or not to dispose after each test run.
|
|
574
|
+
* Disable this to ensure you can run the test suite multiple times.
|
|
575
|
+
* If disabled, be sure to dispose mocha when you're done to prevent memory leaks.
|
|
498
576
|
* @public
|
|
499
|
-
* @see
|
|
500
|
-
* @param {boolean}
|
|
577
|
+
* @see {@link Mocha#dispose}
|
|
578
|
+
* @param {boolean} cleanReferencesAfterRun
|
|
501
579
|
* @return {Mocha} this
|
|
502
580
|
* @chainable
|
|
503
581
|
*/
|
|
504
|
-
Mocha.prototype.
|
|
505
|
-
this.
|
|
582
|
+
Mocha.prototype.cleanReferencesAfterRun = function(cleanReferencesAfterRun) {
|
|
583
|
+
this._cleanReferencesAfterRun = cleanReferencesAfterRun !== false;
|
|
506
584
|
return this;
|
|
507
585
|
};
|
|
508
586
|
|
|
587
|
+
/**
|
|
588
|
+
* Manually dispose this mocha instance. Mark this instance as `disposed` and unable to run more tests.
|
|
589
|
+
* It also removes function references to tests functions and hooks, so variables trapped in closures can be cleaned by the garbage collector.
|
|
590
|
+
* @public
|
|
591
|
+
*/
|
|
592
|
+
Mocha.prototype.dispose = function() {
|
|
593
|
+
if (this._state === mochaStates.RUNNING) {
|
|
594
|
+
throw createMochaInstanceAlreadyRunningError(
|
|
595
|
+
'Cannot dispose while the mocha instance is still running tests.'
|
|
596
|
+
);
|
|
597
|
+
}
|
|
598
|
+
this.unloadFiles();
|
|
599
|
+
this._previousRunner && this._previousRunner.dispose();
|
|
600
|
+
this.suite.dispose();
|
|
601
|
+
this._state = mochaStates.DISPOSED;
|
|
602
|
+
};
|
|
603
|
+
|
|
509
604
|
/**
|
|
510
605
|
* Displays full stack trace upon test failure.
|
|
511
606
|
*
|
|
@@ -531,7 +626,7 @@ Mocha.prototype.fullTrace = function(fullTrace) {
|
|
|
531
626
|
Mocha.prototype.growl = function() {
|
|
532
627
|
this.options.growl = this.isGrowlCapable();
|
|
533
628
|
if (!this.options.growl) {
|
|
534
|
-
var detail =
|
|
629
|
+
var detail = utils.isBrowser()
|
|
535
630
|
? 'notification support not available in this browser...'
|
|
536
631
|
: 'notification support prerequisites not installed...';
|
|
537
632
|
console.error(detail + ' cannot enable!');
|
|
@@ -589,24 +684,6 @@ Mocha.prototype.global = function(global) {
|
|
|
589
684
|
// for backwards compability, 'globals' is an alias of 'global'
|
|
590
685
|
Mocha.prototype.globals = Mocha.prototype.global;
|
|
591
686
|
|
|
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
687
|
/**
|
|
611
688
|
* Enables or disables TTY color output by screen-oriented reporters.
|
|
612
689
|
*
|
|
@@ -621,25 +698,6 @@ Mocha.prototype.color = function(color) {
|
|
|
621
698
|
return this;
|
|
622
699
|
};
|
|
623
700
|
|
|
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
701
|
/**
|
|
644
702
|
* Enables or disables reporter to use inline diffs (rather than +/-)
|
|
645
703
|
* in test failure output.
|
|
@@ -655,22 +713,6 @@ Mocha.prototype.inlineDiffs = function(inlineDiffs) {
|
|
|
655
713
|
return this;
|
|
656
714
|
};
|
|
657
715
|
|
|
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
716
|
/**
|
|
675
717
|
* Enables or disables reporter to include diff in test failure output.
|
|
676
718
|
*
|
|
@@ -696,7 +738,6 @@ Mocha.prototype.diff = function(diff) {
|
|
|
696
738
|
* @public
|
|
697
739
|
* @see [CLI option](../#-timeout-ms-t-ms)
|
|
698
740
|
* @see [Timeouts](../#timeouts)
|
|
699
|
-
* @see {@link Mocha#enableTimeouts}
|
|
700
741
|
* @param {number|string} msecs - Timeout threshold value.
|
|
701
742
|
* @return {Mocha} this
|
|
702
743
|
* @chainable
|
|
@@ -755,22 +796,6 @@ Mocha.prototype.slow = function(msecs) {
|
|
|
755
796
|
return this;
|
|
756
797
|
};
|
|
757
798
|
|
|
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
799
|
/**
|
|
775
800
|
* Forces all tests to either accept a `done` callback or return a promise.
|
|
776
801
|
*
|
|
@@ -856,6 +881,29 @@ Mocha.prototype.forbidPending = function(forbidPending) {
|
|
|
856
881
|
return this;
|
|
857
882
|
};
|
|
858
883
|
|
|
884
|
+
/**
|
|
885
|
+
* Throws an error if mocha is in the wrong state to be able to transition to a "running" state.
|
|
886
|
+
* @private
|
|
887
|
+
*/
|
|
888
|
+
Mocha.prototype._guardRunningStateTransition = function() {
|
|
889
|
+
if (this._state === mochaStates.RUNNING) {
|
|
890
|
+
throw createMochaInstanceAlreadyRunningError(
|
|
891
|
+
'Mocha instance is currently running tests, cannot start a next test run until this one is done',
|
|
892
|
+
this
|
|
893
|
+
);
|
|
894
|
+
}
|
|
895
|
+
if (
|
|
896
|
+
this._state === mochaStates.DISPOSED ||
|
|
897
|
+
this._state === mochaStates.REFERENCES_CLEANED
|
|
898
|
+
) {
|
|
899
|
+
throw createMochaInstanceAlreadyDisposedError(
|
|
900
|
+
'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.',
|
|
901
|
+
this._cleanReferencesAfterRun,
|
|
902
|
+
this
|
|
903
|
+
);
|
|
904
|
+
}
|
|
905
|
+
};
|
|
906
|
+
|
|
859
907
|
/**
|
|
860
908
|
* Mocha version as specified by "package.json".
|
|
861
909
|
*
|
|
@@ -896,13 +944,23 @@ Object.defineProperty(Mocha.prototype, 'version', {
|
|
|
896
944
|
* mocha.run(failures => process.exitCode = failures ? 1 : 0);
|
|
897
945
|
*/
|
|
898
946
|
Mocha.prototype.run = function(fn) {
|
|
899
|
-
|
|
947
|
+
this._guardRunningStateTransition();
|
|
948
|
+
this._state = mochaStates.RUNNING;
|
|
949
|
+
if (this._previousRunner) {
|
|
950
|
+
this._previousRunner.dispose();
|
|
951
|
+
this.suite.reset();
|
|
952
|
+
}
|
|
953
|
+
if (this.files.length && !this._lazyLoadFiles) {
|
|
900
954
|
this.loadFiles();
|
|
901
955
|
}
|
|
956
|
+
var self = this;
|
|
902
957
|
var suite = this.suite;
|
|
903
958
|
var options = this.options;
|
|
904
959
|
options.files = this.files;
|
|
905
|
-
var runner = new
|
|
960
|
+
var runner = new this._runnerClass(suite, {
|
|
961
|
+
delay: options.delay,
|
|
962
|
+
cleanReferencesAfterRun: this._cleanReferencesAfterRun
|
|
963
|
+
});
|
|
906
964
|
createStatsCollector(runner);
|
|
907
965
|
var reporter = new this._reporter(runner, options);
|
|
908
966
|
runner.checkLeaks = options.checkLeaks === true;
|
|
@@ -927,6 +985,12 @@ Mocha.prototype.run = function(fn) {
|
|
|
927
985
|
exports.reporters.Base.hideDiff = !options.diff;
|
|
928
986
|
|
|
929
987
|
function done(failures) {
|
|
988
|
+
self._previousRunner = runner;
|
|
989
|
+
if (self._cleanReferencesAfterRun) {
|
|
990
|
+
self._state = mochaStates.REFERENCES_CLEANED;
|
|
991
|
+
} else {
|
|
992
|
+
self._state = mochaStates.INIT;
|
|
993
|
+
}
|
|
930
994
|
fn = fn || utils.noop;
|
|
931
995
|
if (reporter.done) {
|
|
932
996
|
reporter.done(failures, fn);
|
|
@@ -935,5 +999,107 @@ Mocha.prototype.run = function(fn) {
|
|
|
935
999
|
}
|
|
936
1000
|
}
|
|
937
1001
|
|
|
938
|
-
return runner.run(done);
|
|
1002
|
+
return runner.run(done, {files: this.files, options: options});
|
|
939
1003
|
};
|
|
1004
|
+
|
|
1005
|
+
/**
|
|
1006
|
+
* Assigns hooks to the root suite
|
|
1007
|
+
* @param {MochaRootHookObject} [hooks] - Hooks to assign to root suite
|
|
1008
|
+
* @chainable
|
|
1009
|
+
*/
|
|
1010
|
+
Mocha.prototype.rootHooks = function rootHooks(hooks) {
|
|
1011
|
+
if (utils.type(hooks) === 'object') {
|
|
1012
|
+
var beforeAll = [].concat(hooks.beforeAll || []);
|
|
1013
|
+
var beforeEach = [].concat(hooks.beforeEach || []);
|
|
1014
|
+
var afterAll = [].concat(hooks.afterAll || []);
|
|
1015
|
+
var afterEach = [].concat(hooks.afterEach || []);
|
|
1016
|
+
var rootSuite = this.suite;
|
|
1017
|
+
beforeAll.forEach(function(hook) {
|
|
1018
|
+
rootSuite.beforeAll(hook);
|
|
1019
|
+
});
|
|
1020
|
+
beforeEach.forEach(function(hook) {
|
|
1021
|
+
rootSuite.beforeEach(hook);
|
|
1022
|
+
});
|
|
1023
|
+
afterAll.forEach(function(hook) {
|
|
1024
|
+
rootSuite.afterAll(hook);
|
|
1025
|
+
});
|
|
1026
|
+
afterEach.forEach(function(hook) {
|
|
1027
|
+
rootSuite.afterEach(hook);
|
|
1028
|
+
});
|
|
1029
|
+
}
|
|
1030
|
+
return this;
|
|
1031
|
+
};
|
|
1032
|
+
|
|
1033
|
+
/**
|
|
1034
|
+
* Toggles parallel mode.
|
|
1035
|
+
*
|
|
1036
|
+
* Must be run before calling {@link Mocha#run}. Changes the `Runner` class to
|
|
1037
|
+
* use; also enables lazy file loading if not already done so.
|
|
1038
|
+
* @param {boolean} [enable] - If `true`, enable; otherwise disable.
|
|
1039
|
+
* @throws If run in browser
|
|
1040
|
+
* @throws If Mocha not in "INIT" state
|
|
1041
|
+
* @returns {Mocha}
|
|
1042
|
+
* @chainable
|
|
1043
|
+
* @public
|
|
1044
|
+
*/
|
|
1045
|
+
Mocha.prototype.parallelMode = function parallelMode(enable) {
|
|
1046
|
+
if (utils.isBrowser()) {
|
|
1047
|
+
throw errors.createUnsupportedError(
|
|
1048
|
+
'parallel mode is only supported in Node.js'
|
|
1049
|
+
);
|
|
1050
|
+
}
|
|
1051
|
+
var parallel = enable === true;
|
|
1052
|
+
if (
|
|
1053
|
+
parallel === this.options.parallel &&
|
|
1054
|
+
this._lazyLoadFiles &&
|
|
1055
|
+
this._runnerClass !== exports.Runner
|
|
1056
|
+
) {
|
|
1057
|
+
return this;
|
|
1058
|
+
}
|
|
1059
|
+
if (this._state !== mochaStates.INIT) {
|
|
1060
|
+
throw errors.createUnsupportedError(
|
|
1061
|
+
'cannot change parallel mode after having called run()'
|
|
1062
|
+
);
|
|
1063
|
+
}
|
|
1064
|
+
this.options.parallel = parallel;
|
|
1065
|
+
|
|
1066
|
+
// swap Runner class
|
|
1067
|
+
this._runnerClass = parallel
|
|
1068
|
+
? require('./nodejs/parallel-buffered-runner')
|
|
1069
|
+
: exports.Runner;
|
|
1070
|
+
|
|
1071
|
+
// lazyLoadFiles may have been set `true` otherwise (for ESM loading),
|
|
1072
|
+
// so keep `true` if so.
|
|
1073
|
+
return this.lazyLoadFiles(this._lazyLoadFiles || parallel);
|
|
1074
|
+
};
|
|
1075
|
+
|
|
1076
|
+
/**
|
|
1077
|
+
* Disables implicit call to {@link Mocha#loadFiles} in {@link Mocha#run}. This
|
|
1078
|
+
* setting is used by watch mode, parallel mode, and for loading ESM files.
|
|
1079
|
+
* @todo This should throw if we've already loaded files; such behavior
|
|
1080
|
+
* necessitates adding a new state.
|
|
1081
|
+
* @param {boolean} [enable] - If `true`, disable eager loading of files in
|
|
1082
|
+
* {@link Mocha#run}
|
|
1083
|
+
* @chainable
|
|
1084
|
+
* @public
|
|
1085
|
+
*/
|
|
1086
|
+
Mocha.prototype.lazyLoadFiles = function lazyLoadFiles(enable) {
|
|
1087
|
+
this._lazyLoadFiles = enable === true;
|
|
1088
|
+
debug('set lazy load to %s', enable);
|
|
1089
|
+
return this;
|
|
1090
|
+
};
|
|
1091
|
+
|
|
1092
|
+
/**
|
|
1093
|
+
* An alternative way to define root hooks that works with parallel runs.
|
|
1094
|
+
* @typedef {Object} MochaRootHookObject
|
|
1095
|
+
* @property {Function|Function[]} [beforeAll] - "Before all" hook(s)
|
|
1096
|
+
* @property {Function|Function[]} [beforeEach] - "Before each" hook(s)
|
|
1097
|
+
* @property {Function|Function[]} [afterAll] - "After all" hook(s)
|
|
1098
|
+
* @property {Function|Function[]} [afterEach] - "After each" hook(s)
|
|
1099
|
+
*/
|
|
1100
|
+
|
|
1101
|
+
/**
|
|
1102
|
+
* An function that returns a {@link MochaRootHookObject}, either sync or async.
|
|
1103
|
+
* @callback MochaRootHookFunction
|
|
1104
|
+
* @returns {MochaRootHookObject|Promise<MochaRootHookObject>}
|
|
1105
|
+
*/
|