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.
Files changed (63) hide show
  1. package/CHANGELOG.md +653 -981
  2. package/README.md +2 -1
  3. package/{images → assets/growl}/error.png +0 -0
  4. package/{images → assets/growl}/ok.png +0 -0
  5. package/bin/_mocha +4 -595
  6. package/bin/mocha +84 -58
  7. package/bin/options.js +6 -39
  8. package/browser-entry.js +21 -17
  9. package/lib/browser/growl.js +164 -2
  10. package/lib/browser/progress.js +11 -11
  11. package/lib/{template.html → browser/template.html} +0 -0
  12. package/lib/browser/tty.js +2 -2
  13. package/lib/cli/cli.js +68 -0
  14. package/lib/cli/commands.js +13 -0
  15. package/lib/cli/config.js +79 -0
  16. package/lib/cli/index.js +9 -0
  17. package/lib/cli/init.js +37 -0
  18. package/lib/cli/node-flags.js +48 -0
  19. package/lib/cli/one-and-dones.js +70 -0
  20. package/lib/cli/options.js +299 -0
  21. package/lib/cli/run-helpers.js +328 -0
  22. package/lib/cli/run-option-metadata.js +72 -0
  23. package/lib/cli/run.js +293 -0
  24. package/lib/context.js +14 -14
  25. package/lib/errors.js +139 -0
  26. package/lib/growl.js +135 -0
  27. package/lib/hook.js +5 -16
  28. package/lib/interfaces/bdd.js +14 -13
  29. package/lib/interfaces/common.js +59 -16
  30. package/lib/interfaces/exports.js +4 -7
  31. package/lib/interfaces/qunit.js +8 -10
  32. package/lib/interfaces/tdd.js +10 -11
  33. package/lib/mocha.js +442 -255
  34. package/lib/mocharc.json +10 -0
  35. package/lib/pending.js +1 -5
  36. package/lib/reporters/base.js +92 -117
  37. package/lib/reporters/doc.js +18 -9
  38. package/lib/reporters/dot.js +13 -13
  39. package/lib/reporters/html.js +76 -47
  40. package/lib/reporters/json-stream.js +38 -23
  41. package/lib/reporters/json.js +26 -23
  42. package/lib/reporters/landing.js +9 -8
  43. package/lib/reporters/list.js +11 -10
  44. package/lib/reporters/markdown.js +13 -12
  45. package/lib/reporters/min.js +4 -3
  46. package/lib/reporters/nyan.js +36 -35
  47. package/lib/reporters/progress.js +8 -7
  48. package/lib/reporters/spec.js +14 -11
  49. package/lib/reporters/tap.js +243 -32
  50. package/lib/reporters/xunit.js +52 -33
  51. package/lib/runnable.js +103 -90
  52. package/lib/runner.js +156 -107
  53. package/lib/stats-collector.js +81 -0
  54. package/lib/suite.js +57 -51
  55. package/lib/test.js +13 -13
  56. package/lib/utils.js +192 -103
  57. package/mocha.js +3836 -2046
  58. package/package.json +122 -38
  59. package/bin/.eslintrc.yml +0 -3
  60. package/lib/browser/.eslintrc.yml +0 -4
  61. package/lib/ms.js +0 -94
  62. package/lib/reporters/base.js.orig +0 -498
  63. 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 (suite, delay) {
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 (test) {
75
+ this.on('test end', function(test) {
76
76
  self.checkGlobals(test);
77
77
  });
78
- this.on('hook end', function (hook) {
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
- * @api private
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 (re, invert) {
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 (suite) {
127
+ Runner.prototype.grepTotal = function(suite) {
129
128
  var self = this;
130
129
  var total = 0;
131
130
 
132
- suite.eachTest(function (test) {
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
- * @api private
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 (arr) {
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
- * @api private
184
+ * @private
187
185
  */
188
- Runner.prototype.checkGlobals = function (test) {
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(test, new Error('global leaks detected: ' + leaks.join(', ') + ''));
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
- * @api private
220
+ * @private
220
221
  * @param {Test} test
221
222
  * @param {Error} err
222
223
  */
223
- Runner.prototype.fail = function (test, err) {
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 instanceof Error || (err && typeof err.message === 'string'))) {
232
- err = new Error('the ' + type(err) + ' ' + stringify(err) + ' was thrown, throw an Error :)');
232
+ if (!isError(err)) {
233
+ err = thrown2Error(err);
233
234
  }
234
235
 
235
236
  try {
236
- err.stack = (this.fullStackTrace || !err.stack)
237
- ? err.stack
238
- : stackFilter(err.stack);
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, then exit
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
- * @api private
263
+ * @private
263
264
  * @param {Hook} hook
264
265
  * @param {Error} err
265
266
  */
266
- Runner.prototype.failHook = function (hook, err) {
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 = hook.originalTitle + ' for "' + hook.ctx.currentTest.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
- * @api private
280
+ * @private
282
281
  * @param {string} name
283
282
  * @param {Function} fn
284
283
  */
285
284
 
286
- Runner.prototype.hook = function (name, fn) {
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 (i) {
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 (err) {
302
+ hook.on('error', function(err) {
304
303
  self.failHook(hook, err);
305
304
  });
306
305
  }
307
306
 
308
- hook.run(function (err) {
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 (test) {
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
- * @api private
348
+ * @private
347
349
  * @param {string} name
348
350
  * @param {Array} suites
349
351
  * @param {Function} fn
350
352
  */
351
- Runner.prototype.hooks = function (name, suites, fn) {
353
+ Runner.prototype.hooks = function(name, suites, fn) {
352
354
  var self = this;
353
355
  var orig = this.suite;
354
356
 
355
- function next (suite) {
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 (err) {
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
- * @api private
384
+ * @private
383
385
  */
384
- Runner.prototype.hookUp = function (name, fn) {
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
- * @api private
396
+ * @private
395
397
  */
396
- Runner.prototype.hookDown = function (name, fn) {
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
- * @api private
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
- * @api private
424
+ * @private
423
425
  */
424
- Runner.prototype.runTest = function (fn) {
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 (err) {
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
- * @api private
457
+ * @private
456
458
  * @param {Suite} suite
457
459
  * @param {Function} fn
458
460
  */
459
- Runner.prototype.runTests = function (suite, fn) {
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 (_, errSuite, after) {
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 (err2, errSuite2) {
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 (err, errSuite) {
492
+ function next(err, errSuite) {
491
493
  // if we bail after first err
492
494
  if (self.failures && suite._bail) {
493
- return fn();
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 (err, errSuite) {
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 (err) {
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
- * @api private
617
+ * @private
614
618
  * @param {Suite} suite
615
619
  * @param {Function} fn
616
620
  */
617
- Runner.prototype.runSuite = function (suite, fn) {
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 (errSuite) {
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 (errSuite) {
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 (err) {
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
- * @api private
704
+ * @private
701
705
  */
702
- Runner.prototype.uncaught = function (err) {
706
+ Runner.prototype.uncaught = function(err) {
703
707
  if (err) {
704
- debug('uncaught exception %s', err === (function () {
705
- return this;
706
- }.call(err)) ? (err.message || err) : err);
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 (suite) {
780
- function cleanArrReferences (arr) {
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 (fn) {
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 (err) {
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
- self.emit('start');
834
- self.runSuite(rootSuite, function () {
846
+ Runner.immediately(function() {
847
+ self.emit('start');
848
+ });
849
+
850
+ self.runSuite(rootSuite, function() {
835
851
  debug('finished running');
836
- self.emit('end');
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
- * @api private
904
+ * @private
888
905
  */
889
- function filterOnly (suite) {
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 (onlySuite) {
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 (childSuite) {
906
- return suite._onlySuites.indexOf(childSuite) !== -1 || filterOnly(childSuite);
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
- * @api private
937
+ * @private
919
938
  */
920
- function hasOnly (suite) {
921
- return suite._onlyTests.length || suite._onlySuites.length || suite.suites.some(hasOnly);
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
- * @api private
950
+ * @private
928
951
  * @param {Array} ok
929
952
  * @param {Array} globals
930
953
  * @return {Array}
931
954
  */
932
- function filterLeaks (ok, globals) {
933
- return globals.filter(function (key) {
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 && (/^getInterface/).test(key)) {
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 && (/^\d+/).test(key)) {
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 (ok) {
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
- * @api private
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 (a, v) {
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 < 0x00090B) {
1031
+ if (nodeVersion < 0x00090b) {
983
1032
  return ['errno'];
984
1033
  }
985
1034
  }