mocha 5.1.0 → 6.0.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 +653 -981
- package/README.md +2 -1
- package/{images → assets/growl}/error.png +0 -0
- package/{images → assets/growl}/ok.png +0 -0
- package/bin/_mocha +4 -595
- package/bin/mocha +84 -58
- package/bin/options.js +6 -39
- package/browser-entry.js +21 -17
- package/lib/browser/growl.js +164 -2
- package/lib/browser/progress.js +11 -11
- package/lib/{template.html → browser/template.html} +0 -0
- package/lib/browser/tty.js +2 -2
- package/lib/cli/cli.js +68 -0
- package/lib/cli/commands.js +13 -0
- package/lib/cli/config.js +79 -0
- package/lib/cli/index.js +9 -0
- package/lib/cli/init.js +37 -0
- package/lib/cli/node-flags.js +48 -0
- package/lib/cli/one-and-dones.js +70 -0
- package/lib/cli/options.js +299 -0
- package/lib/cli/run-helpers.js +328 -0
- package/lib/cli/run-option-metadata.js +72 -0
- package/lib/cli/run.js +293 -0
- package/lib/context.js +14 -14
- package/lib/errors.js +139 -0
- package/lib/growl.js +135 -0
- package/lib/hook.js +5 -16
- package/lib/interfaces/bdd.js +14 -13
- package/lib/interfaces/common.js +59 -16
- package/lib/interfaces/exports.js +4 -7
- package/lib/interfaces/qunit.js +8 -10
- package/lib/interfaces/tdd.js +10 -11
- package/lib/mocha.js +442 -255
- package/lib/mocharc.json +10 -0
- package/lib/pending.js +1 -5
- package/lib/reporters/base.js +92 -117
- package/lib/reporters/doc.js +18 -9
- package/lib/reporters/dot.js +13 -13
- package/lib/reporters/html.js +76 -47
- package/lib/reporters/json-stream.js +38 -23
- package/lib/reporters/json.js +26 -23
- package/lib/reporters/landing.js +9 -8
- package/lib/reporters/list.js +11 -10
- package/lib/reporters/markdown.js +13 -12
- package/lib/reporters/min.js +4 -3
- package/lib/reporters/nyan.js +36 -35
- package/lib/reporters/progress.js +8 -7
- package/lib/reporters/spec.js +14 -11
- package/lib/reporters/tap.js +243 -32
- package/lib/reporters/xunit.js +52 -33
- package/lib/runnable.js +103 -90
- package/lib/runner.js +156 -107
- package/lib/stats-collector.js +81 -0
- package/lib/suite.js +57 -51
- package/lib/test.js +13 -13
- package/lib/utils.js +192 -103
- package/mocha.js +3836 -2046
- package/package.json +122 -38
- package/bin/.eslintrc.yml +0 -3
- package/lib/browser/.eslintrc.yml +0 -4
- package/lib/ms.js +0 -94
- package/lib/reporters/base.js.orig +0 -498
- package/lib/reporters/json.js.orig +0 -128
package/lib/runner.js
CHANGED
|
@@ -12,6 +12,7 @@ var utils = require('./utils');
|
|
|
12
12
|
var inherits = utils.inherits;
|
|
13
13
|
var debug = require('debug')('mocha:runner');
|
|
14
14
|
var Runnable = require('./runnable');
|
|
15
|
+
var createStatsCollector = require('./stats-collector');
|
|
15
16
|
var stackFilter = utils.stackTraceFilter();
|
|
16
17
|
var stringify = utils.stringify;
|
|
17
18
|
var type = utils.type;
|
|
@@ -58,12 +59,11 @@ module.exports = Runner;
|
|
|
58
59
|
* @memberof Mocha
|
|
59
60
|
* @public
|
|
60
61
|
* @class
|
|
61
|
-
* @api public
|
|
62
62
|
* @param {Suite} [suite] Root suite
|
|
63
63
|
* @param {boolean} [delay] Whether or not to delay execution of root suite
|
|
64
64
|
* until ready.
|
|
65
65
|
*/
|
|
66
|
-
function Runner
|
|
66
|
+
function Runner(suite, delay) {
|
|
67
67
|
var self = this;
|
|
68
68
|
this._globals = [];
|
|
69
69
|
this._abort = false;
|
|
@@ -72,22 +72,23 @@ function Runner (suite, delay) {
|
|
|
72
72
|
this.started = false;
|
|
73
73
|
this.total = suite.total();
|
|
74
74
|
this.failures = 0;
|
|
75
|
-
this.on('test end', function
|
|
75
|
+
this.on('test end', function(test) {
|
|
76
76
|
self.checkGlobals(test);
|
|
77
77
|
});
|
|
78
|
-
this.on('hook end', function
|
|
78
|
+
this.on('hook end', function(hook) {
|
|
79
79
|
self.checkGlobals(hook);
|
|
80
80
|
});
|
|
81
81
|
this._defaultGrep = /.*/;
|
|
82
82
|
this.grep(this._defaultGrep);
|
|
83
83
|
this.globals(this.globalProps().concat(extraGlobals()));
|
|
84
|
+
createStatsCollector(this);
|
|
84
85
|
}
|
|
85
86
|
|
|
86
87
|
/**
|
|
87
88
|
* Wrapper for setImmediate, process.nextTick, or browser polyfill.
|
|
88
89
|
*
|
|
89
90
|
* @param {Function} fn
|
|
90
|
-
* @
|
|
91
|
+
* @private
|
|
91
92
|
*/
|
|
92
93
|
Runner.immediately = global.setImmediate || process.nextTick;
|
|
93
94
|
|
|
@@ -100,14 +101,13 @@ inherits(Runner, EventEmitter);
|
|
|
100
101
|
* Run tests with full titles matching `re`. Updates runner.total
|
|
101
102
|
* with number of tests matched.
|
|
102
103
|
*
|
|
103
|
-
* @api public
|
|
104
104
|
* @public
|
|
105
105
|
* @memberof Mocha.Runner
|
|
106
106
|
* @param {RegExp} re
|
|
107
107
|
* @param {boolean} invert
|
|
108
108
|
* @return {Runner} Runner instance.
|
|
109
109
|
*/
|
|
110
|
-
Runner.prototype.grep = function
|
|
110
|
+
Runner.prototype.grep = function(re, invert) {
|
|
111
111
|
debug('grep %s', re);
|
|
112
112
|
this._grep = re;
|
|
113
113
|
this._invert = invert;
|
|
@@ -120,16 +120,15 @@ Runner.prototype.grep = function (re, invert) {
|
|
|
120
120
|
* given suite.
|
|
121
121
|
*
|
|
122
122
|
* @memberof Mocha.Runner
|
|
123
|
-
* @api public
|
|
124
123
|
* @public
|
|
125
124
|
* @param {Suite} suite
|
|
126
125
|
* @return {number}
|
|
127
126
|
*/
|
|
128
|
-
Runner.prototype.grepTotal = function
|
|
127
|
+
Runner.prototype.grepTotal = function(suite) {
|
|
129
128
|
var self = this;
|
|
130
129
|
var total = 0;
|
|
131
130
|
|
|
132
|
-
suite.eachTest(function
|
|
131
|
+
suite.eachTest(function(test) {
|
|
133
132
|
var match = self._grep.test(test.fullTitle());
|
|
134
133
|
if (self._invert) {
|
|
135
134
|
match = !match;
|
|
@@ -146,9 +145,9 @@ Runner.prototype.grepTotal = function (suite) {
|
|
|
146
145
|
* Return a list of global properties.
|
|
147
146
|
*
|
|
148
147
|
* @return {Array}
|
|
149
|
-
* @
|
|
148
|
+
* @private
|
|
150
149
|
*/
|
|
151
|
-
Runner.prototype.globalProps = function
|
|
150
|
+
Runner.prototype.globalProps = function() {
|
|
152
151
|
var props = Object.keys(global);
|
|
153
152
|
|
|
154
153
|
// non-enumerables
|
|
@@ -165,13 +164,12 @@ Runner.prototype.globalProps = function () {
|
|
|
165
164
|
/**
|
|
166
165
|
* Allow the given `arr` of globals.
|
|
167
166
|
*
|
|
168
|
-
* @api public
|
|
169
167
|
* @public
|
|
170
168
|
* @memberof Mocha.Runner
|
|
171
169
|
* @param {Array} arr
|
|
172
170
|
* @return {Runner} Runner instance.
|
|
173
171
|
*/
|
|
174
|
-
Runner.prototype.globals = function
|
|
172
|
+
Runner.prototype.globals = function(arr) {
|
|
175
173
|
if (!arguments.length) {
|
|
176
174
|
return this._globals;
|
|
177
175
|
}
|
|
@@ -183,9 +181,9 @@ Runner.prototype.globals = function (arr) {
|
|
|
183
181
|
/**
|
|
184
182
|
* Check for global variable leaks.
|
|
185
183
|
*
|
|
186
|
-
* @
|
|
184
|
+
* @private
|
|
187
185
|
*/
|
|
188
|
-
Runner.prototype.checkGlobals = function
|
|
186
|
+
Runner.prototype.checkGlobals = function(test) {
|
|
189
187
|
if (this.ignoreLeaks) {
|
|
190
188
|
return;
|
|
191
189
|
}
|
|
@@ -207,7 +205,10 @@ Runner.prototype.checkGlobals = function (test) {
|
|
|
207
205
|
this._globals = this._globals.concat(leaks);
|
|
208
206
|
|
|
209
207
|
if (leaks.length > 1) {
|
|
210
|
-
this.fail(
|
|
208
|
+
this.fail(
|
|
209
|
+
test,
|
|
210
|
+
new Error('global leaks detected: ' + leaks.join(', ') + '')
|
|
211
|
+
);
|
|
211
212
|
} else if (leaks.length) {
|
|
212
213
|
this.fail(test, new Error('global leak detected: ' + leaks[0]));
|
|
213
214
|
}
|
|
@@ -216,11 +217,11 @@ Runner.prototype.checkGlobals = function (test) {
|
|
|
216
217
|
/**
|
|
217
218
|
* Fail the given `test`.
|
|
218
219
|
*
|
|
219
|
-
* @
|
|
220
|
+
* @private
|
|
220
221
|
* @param {Test} test
|
|
221
222
|
* @param {Error} err
|
|
222
223
|
*/
|
|
223
|
-
Runner.prototype.fail = function
|
|
224
|
+
Runner.prototype.fail = function(test, err) {
|
|
224
225
|
if (test.isPending()) {
|
|
225
226
|
return;
|
|
226
227
|
}
|
|
@@ -228,15 +229,14 @@ Runner.prototype.fail = function (test, err) {
|
|
|
228
229
|
++this.failures;
|
|
229
230
|
test.state = 'failed';
|
|
230
231
|
|
|
231
|
-
if (!(err
|
|
232
|
-
err =
|
|
232
|
+
if (!isError(err)) {
|
|
233
|
+
err = thrown2Error(err);
|
|
233
234
|
}
|
|
234
235
|
|
|
235
236
|
try {
|
|
236
|
-
err.stack =
|
|
237
|
-
? err.stack
|
|
238
|
-
|
|
239
|
-
} catch (ignored) {
|
|
237
|
+
err.stack =
|
|
238
|
+
this.fullStackTrace || !err.stack ? err.stack : stackFilter(err.stack);
|
|
239
|
+
} catch (ignore) {
|
|
240
240
|
// some environments do not take kindly to monkeying with the stack
|
|
241
241
|
}
|
|
242
242
|
|
|
@@ -247,7 +247,8 @@ Runner.prototype.fail = function (test, err) {
|
|
|
247
247
|
* Fail the given `hook` with `err`.
|
|
248
248
|
*
|
|
249
249
|
* Hook failures work in the following pattern:
|
|
250
|
-
* - If bail,
|
|
250
|
+
* - If bail, run corresponding `after each` and `after` hooks,
|
|
251
|
+
* then exit
|
|
251
252
|
* - Failed `before` hook skips all tests in a suite and subsuites,
|
|
252
253
|
* but jumps to corresponding `after` hook
|
|
253
254
|
* - Failed `before each` hook skips remaining tests in a
|
|
@@ -259,36 +260,34 @@ Runner.prototype.fail = function (test, err) {
|
|
|
259
260
|
* suite and subsuites, but executes other `after each`
|
|
260
261
|
* hooks
|
|
261
262
|
*
|
|
262
|
-
* @
|
|
263
|
+
* @private
|
|
263
264
|
* @param {Hook} hook
|
|
264
265
|
* @param {Error} err
|
|
265
266
|
*/
|
|
266
|
-
Runner.prototype.failHook = function
|
|
267
|
+
Runner.prototype.failHook = function(hook, err) {
|
|
267
268
|
if (hook.ctx && hook.ctx.currentTest) {
|
|
268
269
|
hook.originalTitle = hook.originalTitle || hook.title;
|
|
269
|
-
hook.title =
|
|
270
|
+
hook.title =
|
|
271
|
+
hook.originalTitle + ' for "' + hook.ctx.currentTest.title + '"';
|
|
270
272
|
}
|
|
271
273
|
|
|
272
|
-
if (this.suite.bail()) {
|
|
273
|
-
this.emit('end');
|
|
274
|
-
}
|
|
275
274
|
this.fail(hook, err);
|
|
276
275
|
};
|
|
277
276
|
|
|
278
277
|
/**
|
|
279
278
|
* Run hook `name` callbacks and then invoke `fn()`.
|
|
280
279
|
*
|
|
281
|
-
* @
|
|
280
|
+
* @private
|
|
282
281
|
* @param {string} name
|
|
283
282
|
* @param {Function} fn
|
|
284
283
|
*/
|
|
285
284
|
|
|
286
|
-
Runner.prototype.hook = function
|
|
285
|
+
Runner.prototype.hook = function(name, fn) {
|
|
287
286
|
var suite = this.suite;
|
|
288
287
|
var hooks = suite['_' + name];
|
|
289
288
|
var self = this;
|
|
290
289
|
|
|
291
|
-
function next
|
|
290
|
+
function next(i) {
|
|
292
291
|
var hook = hooks[i];
|
|
293
292
|
if (!hook) {
|
|
294
293
|
return fn();
|
|
@@ -300,12 +299,12 @@ Runner.prototype.hook = function (name, fn) {
|
|
|
300
299
|
self.emit('hook', hook);
|
|
301
300
|
|
|
302
301
|
if (!hook.listeners('error').length) {
|
|
303
|
-
hook.on('error', function
|
|
302
|
+
hook.on('error', function(err) {
|
|
304
303
|
self.failHook(hook, err);
|
|
305
304
|
});
|
|
306
305
|
}
|
|
307
306
|
|
|
308
|
-
hook.run(function
|
|
307
|
+
hook.run(function(err) {
|
|
309
308
|
var testError = hook.error();
|
|
310
309
|
if (testError) {
|
|
311
310
|
self.fail(self.test, testError);
|
|
@@ -315,9 +314,12 @@ Runner.prototype.hook = function (name, fn) {
|
|
|
315
314
|
if (name === 'beforeEach' || name === 'afterEach') {
|
|
316
315
|
self.test.pending = true;
|
|
317
316
|
} else {
|
|
318
|
-
suite.tests.forEach(function
|
|
317
|
+
suite.tests.forEach(function(test) {
|
|
319
318
|
test.pending = true;
|
|
320
319
|
});
|
|
320
|
+
suite.suites.forEach(function(suite) {
|
|
321
|
+
suite.pending = true;
|
|
322
|
+
});
|
|
321
323
|
// a pending hook won't be executed twice.
|
|
322
324
|
hook.pending = true;
|
|
323
325
|
}
|
|
@@ -334,7 +336,7 @@ Runner.prototype.hook = function (name, fn) {
|
|
|
334
336
|
});
|
|
335
337
|
}
|
|
336
338
|
|
|
337
|
-
Runner.immediately(function
|
|
339
|
+
Runner.immediately(function() {
|
|
338
340
|
next(0);
|
|
339
341
|
});
|
|
340
342
|
};
|
|
@@ -343,16 +345,16 @@ Runner.prototype.hook = function (name, fn) {
|
|
|
343
345
|
* Run hook `name` for the given array of `suites`
|
|
344
346
|
* in order, and callback `fn(err, errSuite)`.
|
|
345
347
|
*
|
|
346
|
-
* @
|
|
348
|
+
* @private
|
|
347
349
|
* @param {string} name
|
|
348
350
|
* @param {Array} suites
|
|
349
351
|
* @param {Function} fn
|
|
350
352
|
*/
|
|
351
|
-
Runner.prototype.hooks = function
|
|
353
|
+
Runner.prototype.hooks = function(name, suites, fn) {
|
|
352
354
|
var self = this;
|
|
353
355
|
var orig = this.suite;
|
|
354
356
|
|
|
355
|
-
function next
|
|
357
|
+
function next(suite) {
|
|
356
358
|
self.suite = suite;
|
|
357
359
|
|
|
358
360
|
if (!suite) {
|
|
@@ -360,7 +362,7 @@ Runner.prototype.hooks = function (name, suites, fn) {
|
|
|
360
362
|
return fn();
|
|
361
363
|
}
|
|
362
364
|
|
|
363
|
-
self.hook(name, function
|
|
365
|
+
self.hook(name, function(err) {
|
|
364
366
|
if (err) {
|
|
365
367
|
var errSuite = self.suite;
|
|
366
368
|
self.suite = orig;
|
|
@@ -379,9 +381,9 @@ Runner.prototype.hooks = function (name, suites, fn) {
|
|
|
379
381
|
*
|
|
380
382
|
* @param {String} name
|
|
381
383
|
* @param {Function} fn
|
|
382
|
-
* @
|
|
384
|
+
* @private
|
|
383
385
|
*/
|
|
384
|
-
Runner.prototype.hookUp = function
|
|
386
|
+
Runner.prototype.hookUp = function(name, fn) {
|
|
385
387
|
var suites = [this.suite].concat(this.parents()).reverse();
|
|
386
388
|
this.hooks(name, suites, fn);
|
|
387
389
|
};
|
|
@@ -391,9 +393,9 @@ Runner.prototype.hookUp = function (name, fn) {
|
|
|
391
393
|
*
|
|
392
394
|
* @param {String} name
|
|
393
395
|
* @param {Function} fn
|
|
394
|
-
* @
|
|
396
|
+
* @private
|
|
395
397
|
*/
|
|
396
|
-
Runner.prototype.hookDown = function
|
|
398
|
+
Runner.prototype.hookDown = function(name, fn) {
|
|
397
399
|
var suites = [this.suite].concat(this.parents());
|
|
398
400
|
this.hooks(name, suites, fn);
|
|
399
401
|
};
|
|
@@ -403,9 +405,9 @@ Runner.prototype.hookDown = function (name, fn) {
|
|
|
403
405
|
* closest to furthest.
|
|
404
406
|
*
|
|
405
407
|
* @return {Array}
|
|
406
|
-
* @
|
|
408
|
+
* @private
|
|
407
409
|
*/
|
|
408
|
-
Runner.prototype.parents = function
|
|
410
|
+
Runner.prototype.parents = function() {
|
|
409
411
|
var suite = this.suite;
|
|
410
412
|
var suites = [];
|
|
411
413
|
while (suite.parent) {
|
|
@@ -419,9 +421,9 @@ Runner.prototype.parents = function () {
|
|
|
419
421
|
* Run the current test and callback `fn(err)`.
|
|
420
422
|
*
|
|
421
423
|
* @param {Function} fn
|
|
422
|
-
* @
|
|
424
|
+
* @private
|
|
423
425
|
*/
|
|
424
|
-
Runner.prototype.runTest = function
|
|
426
|
+
Runner.prototype.runTest = function(fn) {
|
|
425
427
|
var self = this;
|
|
426
428
|
var test = this.test;
|
|
427
429
|
|
|
@@ -435,7 +437,7 @@ Runner.prototype.runTest = function (fn) {
|
|
|
435
437
|
if (this.asyncOnly) {
|
|
436
438
|
test.asyncOnly = true;
|
|
437
439
|
}
|
|
438
|
-
test.on('error', function
|
|
440
|
+
test.on('error', function(err) {
|
|
439
441
|
self.fail(test, err);
|
|
440
442
|
});
|
|
441
443
|
if (this.allowUncaught) {
|
|
@@ -452,16 +454,16 @@ Runner.prototype.runTest = function (fn) {
|
|
|
452
454
|
/**
|
|
453
455
|
* Run tests in the given `suite` and invoke the callback `fn()` when complete.
|
|
454
456
|
*
|
|
455
|
-
* @
|
|
457
|
+
* @private
|
|
456
458
|
* @param {Suite} suite
|
|
457
459
|
* @param {Function} fn
|
|
458
460
|
*/
|
|
459
|
-
Runner.prototype.runTests = function
|
|
461
|
+
Runner.prototype.runTests = function(suite, fn) {
|
|
460
462
|
var self = this;
|
|
461
463
|
var tests = suite.tests.slice();
|
|
462
464
|
var test;
|
|
463
465
|
|
|
464
|
-
function hookErr
|
|
466
|
+
function hookErr(_, errSuite, after) {
|
|
465
467
|
// before/after Each hook for errSuite failed:
|
|
466
468
|
var orig = self.suite;
|
|
467
469
|
|
|
@@ -471,7 +473,7 @@ Runner.prototype.runTests = function (suite, fn) {
|
|
|
471
473
|
|
|
472
474
|
if (self.suite) {
|
|
473
475
|
// call hookUp afterEach
|
|
474
|
-
self.hookUp('afterEach', function
|
|
476
|
+
self.hookUp('afterEach', function(err2, errSuite2) {
|
|
475
477
|
self.suite = orig;
|
|
476
478
|
// some hooks may fail even now
|
|
477
479
|
if (err2) {
|
|
@@ -487,10 +489,10 @@ Runner.prototype.runTests = function (suite, fn) {
|
|
|
487
489
|
}
|
|
488
490
|
}
|
|
489
491
|
|
|
490
|
-
function next
|
|
492
|
+
function next(err, errSuite) {
|
|
491
493
|
// if we bail after first err
|
|
492
494
|
if (self.failures && suite._bail) {
|
|
493
|
-
|
|
495
|
+
tests = [];
|
|
494
496
|
}
|
|
495
497
|
|
|
496
498
|
if (self._abort) {
|
|
@@ -544,8 +546,8 @@ Runner.prototype.runTests = function (suite, fn) {
|
|
|
544
546
|
}
|
|
545
547
|
|
|
546
548
|
// execute test and hook(s)
|
|
547
|
-
self.emit('test', self.test = test);
|
|
548
|
-
self.hookDown('beforeEach', function
|
|
549
|
+
self.emit('test', (self.test = test));
|
|
550
|
+
self.hookDown('beforeEach', function(err, errSuite) {
|
|
549
551
|
if (test.isPending()) {
|
|
550
552
|
if (self.forbidPending) {
|
|
551
553
|
test.isPending = alwaysFalse;
|
|
@@ -561,7 +563,7 @@ Runner.prototype.runTests = function (suite, fn) {
|
|
|
561
563
|
return hookErr(err, errSuite, false);
|
|
562
564
|
}
|
|
563
565
|
self.currentRunnable = self.test;
|
|
564
|
-
self.runTest(function
|
|
566
|
+
self.runTest(function(err) {
|
|
565
567
|
test = self.test;
|
|
566
568
|
if (err) {
|
|
567
569
|
var retry = test.currentRetry();
|
|
@@ -575,6 +577,8 @@ Runner.prototype.runTests = function (suite, fn) {
|
|
|
575
577
|
clonedTest.currentRetry(retry + 1);
|
|
576
578
|
tests.unshift(clonedTest);
|
|
577
579
|
|
|
580
|
+
self.emit('retry', test, err);
|
|
581
|
+
|
|
578
582
|
// Early return + hook trigger so that it doesn't
|
|
579
583
|
// increment the count wrong
|
|
580
584
|
return self.hookUp('afterEach', next);
|
|
@@ -603,18 +607,18 @@ Runner.prototype.runTests = function (suite, fn) {
|
|
|
603
607
|
next();
|
|
604
608
|
};
|
|
605
609
|
|
|
606
|
-
function alwaysFalse
|
|
610
|
+
function alwaysFalse() {
|
|
607
611
|
return false;
|
|
608
612
|
}
|
|
609
613
|
|
|
610
614
|
/**
|
|
611
615
|
* Run the given `suite` and invoke the callback `fn()` when complete.
|
|
612
616
|
*
|
|
613
|
-
* @
|
|
617
|
+
* @private
|
|
614
618
|
* @param {Suite} suite
|
|
615
619
|
* @param {Function} fn
|
|
616
620
|
*/
|
|
617
|
-
Runner.prototype.runSuite = function
|
|
621
|
+
Runner.prototype.runSuite = function(suite, fn) {
|
|
618
622
|
var i = 0;
|
|
619
623
|
var self = this;
|
|
620
624
|
var total = this.grepTotal(suite);
|
|
@@ -626,9 +630,9 @@ Runner.prototype.runSuite = function (suite, fn) {
|
|
|
626
630
|
return fn();
|
|
627
631
|
}
|
|
628
632
|
|
|
629
|
-
this.emit('suite', this.suite = suite);
|
|
633
|
+
this.emit('suite', (this.suite = suite));
|
|
630
634
|
|
|
631
|
-
function next
|
|
635
|
+
function next(errSuite) {
|
|
632
636
|
if (errSuite) {
|
|
633
637
|
// current suite failed on a hook from errSuite
|
|
634
638
|
if (errSuite === suite) {
|
|
@@ -654,7 +658,7 @@ Runner.prototype.runSuite = function (suite, fn) {
|
|
|
654
658
|
// huge recursive loop and thus a maximum call stack error.
|
|
655
659
|
// See comment in `this.runTests()` for more information.
|
|
656
660
|
if (self._grep !== self._defaultGrep) {
|
|
657
|
-
Runner.immediately(function
|
|
661
|
+
Runner.immediately(function() {
|
|
658
662
|
self.runSuite(curr, next);
|
|
659
663
|
});
|
|
660
664
|
} else {
|
|
@@ -662,7 +666,7 @@ Runner.prototype.runSuite = function (suite, fn) {
|
|
|
662
666
|
}
|
|
663
667
|
}
|
|
664
668
|
|
|
665
|
-
function done
|
|
669
|
+
function done(errSuite) {
|
|
666
670
|
self.suite = suite;
|
|
667
671
|
self.nextSuite = next;
|
|
668
672
|
|
|
@@ -676,7 +680,7 @@ Runner.prototype.runSuite = function (suite, fn) {
|
|
|
676
680
|
// remove reference to test
|
|
677
681
|
delete self.test;
|
|
678
682
|
|
|
679
|
-
self.hook('afterAll', function
|
|
683
|
+
self.hook('afterAll', function() {
|
|
680
684
|
self.emit('suite end', suite);
|
|
681
685
|
fn(errSuite);
|
|
682
686
|
});
|
|
@@ -685,7 +689,7 @@ Runner.prototype.runSuite = function (suite, fn) {
|
|
|
685
689
|
|
|
686
690
|
this.nextSuite = next;
|
|
687
691
|
|
|
688
|
-
this.hook('beforeAll', function
|
|
692
|
+
this.hook('beforeAll', function(err) {
|
|
689
693
|
if (err) {
|
|
690
694
|
return done();
|
|
691
695
|
}
|
|
@@ -697,17 +701,27 @@ Runner.prototype.runSuite = function (suite, fn) {
|
|
|
697
701
|
* Handle uncaught exceptions.
|
|
698
702
|
*
|
|
699
703
|
* @param {Error} err
|
|
700
|
-
* @
|
|
704
|
+
* @private
|
|
701
705
|
*/
|
|
702
|
-
Runner.prototype.uncaught = function
|
|
706
|
+
Runner.prototype.uncaught = function(err) {
|
|
703
707
|
if (err) {
|
|
704
|
-
debug(
|
|
705
|
-
|
|
706
|
-
|
|
708
|
+
debug(
|
|
709
|
+
'uncaught exception %s',
|
|
710
|
+
err ===
|
|
711
|
+
function() {
|
|
712
|
+
return this;
|
|
713
|
+
}.call(err)
|
|
714
|
+
? err.message || err
|
|
715
|
+
: err
|
|
716
|
+
);
|
|
707
717
|
} else {
|
|
708
718
|
debug('uncaught undefined exception');
|
|
709
719
|
err = undefinedError();
|
|
710
720
|
}
|
|
721
|
+
|
|
722
|
+
if (!isError(err)) {
|
|
723
|
+
err = thrown2Error(err);
|
|
724
|
+
}
|
|
711
725
|
err.uncaught = true;
|
|
712
726
|
|
|
713
727
|
var runnable = this.currentRunnable;
|
|
@@ -776,8 +790,8 @@ Runner.prototype.uncaught = function (err) {
|
|
|
776
790
|
*
|
|
777
791
|
* @param {Suite} suite
|
|
778
792
|
*/
|
|
779
|
-
function cleanSuiteReferences
|
|
780
|
-
function cleanArrReferences
|
|
793
|
+
function cleanSuiteReferences(suite) {
|
|
794
|
+
function cleanArrReferences(arr) {
|
|
781
795
|
for (var i = 0; i < arr.length; i++) {
|
|
782
796
|
delete arr[i].fn;
|
|
783
797
|
}
|
|
@@ -808,32 +822,36 @@ function cleanSuiteReferences (suite) {
|
|
|
808
822
|
* Run the root suite and invoke `fn(failures)`
|
|
809
823
|
* on completion.
|
|
810
824
|
*
|
|
811
|
-
* @api public
|
|
812
825
|
* @public
|
|
813
826
|
* @memberof Mocha.Runner
|
|
814
827
|
* @param {Function} fn
|
|
815
828
|
* @return {Runner} Runner instance.
|
|
816
829
|
*/
|
|
817
|
-
Runner.prototype.run = function
|
|
830
|
+
Runner.prototype.run = function(fn) {
|
|
818
831
|
var self = this;
|
|
819
832
|
var rootSuite = this.suite;
|
|
820
833
|
|
|
821
|
-
fn = fn || function
|
|
834
|
+
fn = fn || function() {};
|
|
822
835
|
|
|
823
|
-
function uncaught
|
|
836
|
+
function uncaught(err) {
|
|
824
837
|
self.uncaught(err);
|
|
825
838
|
}
|
|
826
839
|
|
|
827
|
-
function start
|
|
840
|
+
function start() {
|
|
828
841
|
// If there is an `only` filter
|
|
829
842
|
if (hasOnly(rootSuite)) {
|
|
830
843
|
filterOnly(rootSuite);
|
|
831
844
|
}
|
|
832
845
|
self.started = true;
|
|
833
|
-
|
|
834
|
-
|
|
846
|
+
Runner.immediately(function() {
|
|
847
|
+
self.emit('start');
|
|
848
|
+
});
|
|
849
|
+
|
|
850
|
+
self.runSuite(rootSuite, function() {
|
|
835
851
|
debug('finished running');
|
|
836
|
-
|
|
852
|
+
Runner.immediately(function() {
|
|
853
|
+
self.emit('end');
|
|
854
|
+
});
|
|
837
855
|
});
|
|
838
856
|
}
|
|
839
857
|
|
|
@@ -843,7 +861,7 @@ Runner.prototype.run = function (fn) {
|
|
|
843
861
|
this.on('suite end', cleanSuiteReferences);
|
|
844
862
|
|
|
845
863
|
// callback
|
|
846
|
-
this.on('end', function
|
|
864
|
+
this.on('end', function() {
|
|
847
865
|
debug('end');
|
|
848
866
|
process.removeListener('uncaughtException', uncaught);
|
|
849
867
|
fn(self.failures);
|
|
@@ -869,10 +887,9 @@ Runner.prototype.run = function (fn) {
|
|
|
869
887
|
*
|
|
870
888
|
* @memberof Mocha.Runner
|
|
871
889
|
* @public
|
|
872
|
-
* @api public
|
|
873
890
|
* @return {Runner} Runner instance.
|
|
874
891
|
*/
|
|
875
|
-
Runner.prototype.abort = function
|
|
892
|
+
Runner.prototype.abort = function() {
|
|
876
893
|
debug('aborting');
|
|
877
894
|
this._abort = true;
|
|
878
895
|
|
|
@@ -884,9 +901,9 @@ Runner.prototype.abort = function () {
|
|
|
884
901
|
*
|
|
885
902
|
* @param {Array} suite
|
|
886
903
|
* @returns {Boolean}
|
|
887
|
-
* @
|
|
904
|
+
* @private
|
|
888
905
|
*/
|
|
889
|
-
function filterOnly
|
|
906
|
+
function filterOnly(suite) {
|
|
890
907
|
if (suite._onlyTests.length) {
|
|
891
908
|
// If the suite contains `only` tests, run those and ignore any nested suites.
|
|
892
909
|
suite.tests = suite._onlyTests;
|
|
@@ -894,7 +911,7 @@ function filterOnly (suite) {
|
|
|
894
911
|
} else {
|
|
895
912
|
// Otherwise, do not run any of the tests in this suite.
|
|
896
913
|
suite.tests = [];
|
|
897
|
-
suite._onlySuites.forEach(function
|
|
914
|
+
suite._onlySuites.forEach(function(onlySuite) {
|
|
898
915
|
// If there are other `only` tests/suites nested in the current `only` suite, then filter that `only` suite.
|
|
899
916
|
// Otherwise, all of the tests on this `only` suite should be run, so don't filter it.
|
|
900
917
|
if (hasOnly(onlySuite)) {
|
|
@@ -902,8 +919,10 @@ function filterOnly (suite) {
|
|
|
902
919
|
}
|
|
903
920
|
});
|
|
904
921
|
// Run the `only` suites, as well as any other suites that have `only` tests/suites as descendants.
|
|
905
|
-
suite.suites = suite.suites.filter(function
|
|
906
|
-
return
|
|
922
|
+
suite.suites = suite.suites.filter(function(childSuite) {
|
|
923
|
+
return (
|
|
924
|
+
suite._onlySuites.indexOf(childSuite) !== -1 || filterOnly(childSuite)
|
|
925
|
+
);
|
|
907
926
|
});
|
|
908
927
|
}
|
|
909
928
|
// Keep the suite only if there is something to run
|
|
@@ -915,22 +934,26 @@ function filterOnly (suite) {
|
|
|
915
934
|
*
|
|
916
935
|
* @param {Array} suite
|
|
917
936
|
* @returns {Boolean}
|
|
918
|
-
* @
|
|
937
|
+
* @private
|
|
919
938
|
*/
|
|
920
|
-
function hasOnly
|
|
921
|
-
return
|
|
939
|
+
function hasOnly(suite) {
|
|
940
|
+
return (
|
|
941
|
+
suite._onlyTests.length ||
|
|
942
|
+
suite._onlySuites.length ||
|
|
943
|
+
suite.suites.some(hasOnly)
|
|
944
|
+
);
|
|
922
945
|
}
|
|
923
946
|
|
|
924
947
|
/**
|
|
925
948
|
* Filter leaks with the given globals flagged as `ok`.
|
|
926
949
|
*
|
|
927
|
-
* @
|
|
950
|
+
* @private
|
|
928
951
|
* @param {Array} ok
|
|
929
952
|
* @param {Array} globals
|
|
930
953
|
* @return {Array}
|
|
931
954
|
*/
|
|
932
|
-
function filterLeaks
|
|
933
|
-
return globals.filter(function
|
|
955
|
+
function filterLeaks(ok, globals) {
|
|
956
|
+
return globals.filter(function(key) {
|
|
934
957
|
// Firefox and Chrome exposes iframes as index inside the window object
|
|
935
958
|
if (/^\d+/.test(key)) {
|
|
936
959
|
return false;
|
|
@@ -939,13 +962,13 @@ function filterLeaks (ok, globals) {
|
|
|
939
962
|
// in firefox
|
|
940
963
|
// if runner runs in an iframe, this iframe's window.getInterface method
|
|
941
964
|
// not init at first it is assigned in some seconds
|
|
942
|
-
if (global.navigator &&
|
|
965
|
+
if (global.navigator && /^getInterface/.test(key)) {
|
|
943
966
|
return false;
|
|
944
967
|
}
|
|
945
968
|
|
|
946
969
|
// an iframe could be approached by window[iframeIndex]
|
|
947
970
|
// in ie6,7,8 and opera, iframeIndex is enumerable, this could cause leak
|
|
948
|
-
if (global.navigator &&
|
|
971
|
+
if (global.navigator && /^\d+/.test(key)) {
|
|
949
972
|
return false;
|
|
950
973
|
}
|
|
951
974
|
|
|
@@ -954,7 +977,7 @@ function filterLeaks (ok, globals) {
|
|
|
954
977
|
return false;
|
|
955
978
|
}
|
|
956
979
|
|
|
957
|
-
var matched = ok.filter(function
|
|
980
|
+
var matched = ok.filter(function(ok) {
|
|
958
981
|
if (~ok.indexOf('*')) {
|
|
959
982
|
return key.indexOf(ok.split('*')[0]) === 0;
|
|
960
983
|
}
|
|
@@ -964,22 +987,48 @@ function filterLeaks (ok, globals) {
|
|
|
964
987
|
});
|
|
965
988
|
}
|
|
966
989
|
|
|
990
|
+
/**
|
|
991
|
+
* Check if argument is an instance of Error object or a duck-typed equivalent.
|
|
992
|
+
*
|
|
993
|
+
* @private
|
|
994
|
+
* @param {Object} err - object to check
|
|
995
|
+
* @param {string} err.message - error message
|
|
996
|
+
* @returns {boolean}
|
|
997
|
+
*/
|
|
998
|
+
function isError(err) {
|
|
999
|
+
return err instanceof Error || (err && typeof err.message === 'string');
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
/**
|
|
1003
|
+
*
|
|
1004
|
+
* Converts thrown non-extensible type into proper Error.
|
|
1005
|
+
*
|
|
1006
|
+
* @private
|
|
1007
|
+
* @param {*} thrown - Non-extensible type thrown by code
|
|
1008
|
+
* @return {Error}
|
|
1009
|
+
*/
|
|
1010
|
+
function thrown2Error(err) {
|
|
1011
|
+
return new Error(
|
|
1012
|
+
'the ' + type(err) + ' ' + stringify(err) + ' was thrown, throw an Error :)'
|
|
1013
|
+
);
|
|
1014
|
+
}
|
|
1015
|
+
|
|
967
1016
|
/**
|
|
968
1017
|
* Array of globals dependent on the environment.
|
|
969
1018
|
*
|
|
970
1019
|
* @return {Array}
|
|
971
|
-
* @
|
|
1020
|
+
* @private
|
|
972
1021
|
*/
|
|
973
|
-
function extraGlobals
|
|
1022
|
+
function extraGlobals() {
|
|
974
1023
|
if (typeof process === 'object' && typeof process.version === 'string') {
|
|
975
1024
|
var parts = process.version.split('.');
|
|
976
|
-
var nodeVersion = parts.reduce(function
|
|
977
|
-
return a << 8 | v;
|
|
1025
|
+
var nodeVersion = parts.reduce(function(a, v) {
|
|
1026
|
+
return (a << 8) | v;
|
|
978
1027
|
});
|
|
979
1028
|
|
|
980
1029
|
// 'errno' was renamed to process._errno in v0.9.11.
|
|
981
1030
|
|
|
982
|
-
if (nodeVersion <
|
|
1031
|
+
if (nodeVersion < 0x00090b) {
|
|
983
1032
|
return ['errno'];
|
|
984
1033
|
}
|
|
985
1034
|
}
|