mocha 7.0.0 → 7.1.2

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/mocha.js CHANGED
@@ -62,7 +62,7 @@ process.on = function(e, fn) {
62
62
  if (e === 'uncaughtException') {
63
63
  global.onerror = function(err, url, line) {
64
64
  fn(new Error(err + ' (' + url + ':' + line + ')'));
65
- return !mocha.allowUncaught;
65
+ return !mocha.options.allowUncaught;
66
66
  };
67
67
  uncaughtExceptionHandlers.push(fn);
68
68
  }
@@ -131,7 +131,7 @@ mocha.setup = function(opts) {
131
131
  opts = {ui: opts};
132
132
  }
133
133
  for (var opt in opts) {
134
- if (opts.hasOwnProperty(opt)) {
134
+ if (Object.prototype.hasOwnProperty.call(opts, opt)) {
135
135
  this[opt](opts[opt]);
136
136
  }
137
137
  }
@@ -1408,6 +1408,7 @@ var utils = require('./utils');
1408
1408
  var mocharc = require('./mocharc.json');
1409
1409
  var errors = require('./errors');
1410
1410
  var Suite = require('./suite');
1411
+ var esmUtils = utils.supportsEsModules() ? require('./esm-utils') : undefined;
1411
1412
  var createStatsCollector = require('./stats-collector');
1412
1413
  var createInvalidReporterError = errors.createInvalidReporterError;
1413
1414
  var createInvalidInterfaceError = errors.createInvalidInterfaceError;
@@ -1494,7 +1495,10 @@ function Mocha(options) {
1494
1495
  this.grep(options.grep)
1495
1496
  .fgrep(options.fgrep)
1496
1497
  .ui(options.ui)
1497
- .reporter(options.reporter, options.reporterOption)
1498
+ .reporter(
1499
+ options.reporter,
1500
+ options.reporterOption || options.reporterOptions // reporterOptions was previously the only way to specify options to reporter
1501
+ )
1498
1502
  .slow(options.slow)
1499
1503
  .global(options.global);
1500
1504
 
@@ -1681,16 +1685,18 @@ Mocha.prototype.ui = function(ui) {
1681
1685
  };
1682
1686
 
1683
1687
  /**
1684
- * Loads `files` prior to execution.
1688
+ * Loads `files` prior to execution. Does not support ES Modules.
1685
1689
  *
1686
1690
  * @description
1687
1691
  * The implementation relies on Node's `require` to execute
1688
1692
  * the test interface functions and will be subject to its cache.
1693
+ * Supports only CommonJS modules. To load ES modules, use Mocha#loadFilesAsync.
1689
1694
  *
1690
1695
  * @private
1691
1696
  * @see {@link Mocha#addFile}
1692
1697
  * @see {@link Mocha#run}
1693
1698
  * @see {@link Mocha#unloadFiles}
1699
+ * @see {@link Mocha#loadFilesAsync}
1694
1700
  * @param {Function} [fn] - Callback invoked upon completion.
1695
1701
  */
1696
1702
  Mocha.prototype.loadFiles = function(fn) {
@@ -1705,6 +1711,49 @@ Mocha.prototype.loadFiles = function(fn) {
1705
1711
  fn && fn();
1706
1712
  };
1707
1713
 
1714
+ /**
1715
+ * Loads `files` prior to execution. Supports Node ES Modules.
1716
+ *
1717
+ * @description
1718
+ * The implementation relies on Node's `require` and `import` to execute
1719
+ * the test interface functions and will be subject to its cache.
1720
+ * Supports both CJS and ESM modules.
1721
+ *
1722
+ * @public
1723
+ * @see {@link Mocha#addFile}
1724
+ * @see {@link Mocha#run}
1725
+ * @see {@link Mocha#unloadFiles}
1726
+ * @returns {Promise}
1727
+ * @example
1728
+ *
1729
+ * // loads ESM (and CJS) test files asynchronously, then runs root suite
1730
+ * mocha.loadFilesAsync()
1731
+ * .then(() => mocha.run(failures => process.exitCode = failures ? 1 : 0))
1732
+ * .catch(() => process.exitCode = 1);
1733
+ */
1734
+ Mocha.prototype.loadFilesAsync = function() {
1735
+ var self = this;
1736
+ var suite = this.suite;
1737
+ this.loadAsync = true;
1738
+
1739
+ if (!esmUtils) {
1740
+ return new Promise(function(resolve) {
1741
+ self.loadFiles(resolve);
1742
+ });
1743
+ }
1744
+
1745
+ return esmUtils.loadFilesAsync(
1746
+ this.files,
1747
+ function(file) {
1748
+ suite.emit(EVENT_FILE_PRE_REQUIRE, global, file, self);
1749
+ },
1750
+ function(file, resultModule) {
1751
+ suite.emit(EVENT_FILE_REQUIRE, resultModule, file, self);
1752
+ suite.emit(EVENT_FILE_POST_REQUIRE, global, file, self);
1753
+ }
1754
+ );
1755
+ };
1756
+
1708
1757
  /**
1709
1758
  * Removes a previously loaded file from Node's `require` cache.
1710
1759
  *
@@ -1721,8 +1770,9 @@ Mocha.unloadFile = function(file) {
1721
1770
  * Unloads `files` from Node's `require` cache.
1722
1771
  *
1723
1772
  * @description
1724
- * This allows files to be "freshly" reloaded, providing the ability
1773
+ * This allows required files to be "freshly" reloaded, providing the ability
1725
1774
  * to reuse a Mocha instance programmatically.
1775
+ * Note: does not clear ESM module files from the cache
1726
1776
  *
1727
1777
  * <strong>Intended for consumers &mdash; not used internally</strong>
1728
1778
  *
@@ -2233,10 +2283,14 @@ Object.defineProperty(Mocha.prototype, 'version', {
2233
2283
  * @see {@link Mocha#unloadFiles}
2234
2284
  * @see {@link Runner#run}
2235
2285
  * @param {DoneCB} [fn] - Callback invoked when test execution completed.
2236
- * @return {Runner} runner instance
2286
+ * @returns {Runner} runner instance
2287
+ * @example
2288
+ *
2289
+ * // exit with non-zero status if there were test failures
2290
+ * mocha.run(failures => process.exitCode = failures ? 1 : 0);
2237
2291
  */
2238
2292
  Mocha.prototype.run = function(fn) {
2239
- if (this.files.length) {
2293
+ if (this.files.length && !this.loadAsync) {
2240
2294
  this.loadFiles();
2241
2295
  }
2242
2296
  var suite = this.suite;
@@ -2279,10 +2333,10 @@ Mocha.prototype.run = function(fn) {
2279
2333
  };
2280
2334
 
2281
2335
  }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2282
- },{"../package.json":90,"./context":5,"./errors":6,"./growl":2,"./hook":7,"./interfaces":11,"./mocharc.json":15,"./reporters":21,"./runnable":33,"./runner":34,"./stats-collector":35,"./suite":36,"./test":37,"./utils":38,"_process":69,"escape-string-regexp":49,"path":42}],15:[function(require,module,exports){
2336
+ },{"../package.json":90,"./context":5,"./errors":6,"./esm-utils":42,"./growl":2,"./hook":7,"./interfaces":11,"./mocharc.json":15,"./reporters":21,"./runnable":33,"./runner":34,"./stats-collector":35,"./suite":36,"./test":37,"./utils":38,"_process":69,"escape-string-regexp":49,"path":42}],15:[function(require,module,exports){
2283
2337
  module.exports={
2284
2338
  "diff": true,
2285
- "extension": ["js"],
2339
+ "extension": ["js", "cjs", "mjs"],
2286
2340
  "opts": "./test/mocha.opts",
2287
2341
  "package": "./package.json",
2288
2342
  "reporter": "spec",
@@ -5256,31 +5310,6 @@ Runnable.prototype.clearTimeout = function() {
5256
5310
  clearTimeout(this.timer);
5257
5311
  };
5258
5312
 
5259
- /**
5260
- * Inspect the runnable void of private properties.
5261
- *
5262
- * @private
5263
- * @return {string}
5264
- */
5265
- Runnable.prototype.inspect = function() {
5266
- return JSON.stringify(
5267
- this,
5268
- function(key, val) {
5269
- if (key[0] === '_') {
5270
- return;
5271
- }
5272
- if (key === 'parent') {
5273
- return '#<Suite>';
5274
- }
5275
- if (key === 'ctx') {
5276
- return '#<Context>';
5277
- }
5278
- return val;
5279
- },
5280
- 2
5281
- );
5282
- };
5283
-
5284
5313
  /**
5285
5314
  * Reset the timeout.
5286
5315
  *
@@ -5369,9 +5398,18 @@ Runnable.prototype.run = function(fn) {
5369
5398
  fn(err);
5370
5399
  }
5371
5400
 
5372
- // for .resetTimeout()
5401
+ // for .resetTimeout() and Runner#uncaught()
5373
5402
  this.callback = done;
5374
5403
 
5404
+ if (this.fn && typeof this.fn.call !== 'function') {
5405
+ done(
5406
+ new TypeError(
5407
+ 'A runnable must be passed a function as its second argument.'
5408
+ )
5409
+ );
5410
+ return;
5411
+ }
5412
+
5375
5413
  // explicit async with `done` argument
5376
5414
  if (this.async) {
5377
5415
  this.resetTimeout();
@@ -5552,7 +5590,6 @@ var EVENT_ROOT_SUITE_RUN = Suite.constants.EVENT_ROOT_SUITE_RUN;
5552
5590
  var STATE_FAILED = Runnable.constants.STATE_FAILED;
5553
5591
  var STATE_PASSED = Runnable.constants.STATE_PASSED;
5554
5592
  var dQuote = utils.dQuote;
5555
- var ngettext = utils.ngettext;
5556
5593
  var sQuote = utils.sQuote;
5557
5594
  var stackFilter = utils.stackTraceFilter();
5558
5595
  var stringify = utils.stringify;
@@ -5668,6 +5705,11 @@ function Runner(suite, delay) {
5668
5705
  this.total = suite.total();
5669
5706
  this.failures = 0;
5670
5707
  this.on(constants.EVENT_TEST_END, function(test) {
5708
+ if (test.type === 'test' && test.retriedTest() && test.parent) {
5709
+ var idx =
5710
+ test.parent.tests && test.parent.tests.indexOf(test.retriedTest());
5711
+ if (idx > -1) test.parent.tests[idx] = test;
5712
+ }
5671
5713
  self.checkGlobals(test);
5672
5714
  });
5673
5715
  this.on(constants.EVENT_HOOK_END, function(hook) {
@@ -5799,12 +5841,8 @@ Runner.prototype.checkGlobals = function(test) {
5799
5841
  this._globals = this._globals.concat(leaks);
5800
5842
 
5801
5843
  if (leaks.length) {
5802
- var format = ngettext(
5803
- leaks.length,
5804
- 'global leak detected: %s',
5805
- 'global leaks detected: %s'
5806
- );
5807
- var error = new Error(util.format(format, leaks.map(sQuote).join(', ')));
5844
+ var msg = 'global leak(s) detected: %s';
5845
+ var error = new Error(util.format(msg, leaks.map(sQuote).join(', ')));
5808
5846
  this.fail(test, error);
5809
5847
  }
5810
5848
  };
@@ -6187,7 +6225,7 @@ Runner.prototype.runTests = function(suite, fn) {
6187
6225
  self.emit(constants.EVENT_TEST_END, test);
6188
6226
  // skip inner afterEach hooks below errSuite level
6189
6227
  var origSuite = self.suite;
6190
- self.suite = errSuite;
6228
+ self.suite = errSuite || self.suite;
6191
6229
  return self.hookUp(HOOK_TYPE_AFTER_EACH, function(e, eSuite) {
6192
6230
  self.suite = origSuite;
6193
6231
  next(e, eSuite);
@@ -6257,7 +6295,6 @@ Runner.prototype.runSuite = function(suite, fn) {
6257
6295
  var i = 0;
6258
6296
  var self = this;
6259
6297
  var total = this.grepTotal(suite);
6260
- var afterAllHookCalled = false;
6261
6298
 
6262
6299
  debug('run suite %s', suite.fullTitle());
6263
6300
 
@@ -6305,21 +6342,13 @@ Runner.prototype.runSuite = function(suite, fn) {
6305
6342
  self.suite = suite;
6306
6343
  self.nextSuite = next;
6307
6344
 
6308
- if (afterAllHookCalled) {
6309
- fn(errSuite);
6310
- } else {
6311
- // mark that the afterAll block has been called once
6312
- // and so can be skipped if there is an error in it.
6313
- afterAllHookCalled = true;
6345
+ // remove reference to test
6346
+ delete self.test;
6314
6347
 
6315
- // remove reference to test
6316
- delete self.test;
6317
-
6318
- self.hook(HOOK_TYPE_AFTER_ALL, function() {
6319
- self.emit(constants.EVENT_SUITE_END, suite);
6320
- fn(errSuite);
6321
- });
6322
- }
6348
+ self.hook(HOOK_TYPE_AFTER_ALL, function() {
6349
+ self.emit(constants.EVENT_SUITE_END, suite);
6350
+ fn(errSuite);
6351
+ });
6323
6352
  }
6324
6353
 
6325
6354
  this.nextSuite = next;
@@ -6333,7 +6362,7 @@ Runner.prototype.runSuite = function(suite, fn) {
6333
6362
  };
6334
6363
 
6335
6364
  /**
6336
- * Handle uncaught exceptions.
6365
+ * Handle uncaught exceptions within runner.
6337
6366
  *
6338
6367
  * @param {Error} err
6339
6368
  * @private
@@ -6342,7 +6371,8 @@ Runner.prototype.uncaught = function(err) {
6342
6371
  if (err instanceof Pending) {
6343
6372
  return;
6344
6373
  }
6345
- if (this.allowUncaught) {
6374
+ // browser does not exit script when throwing in global.onerror()
6375
+ if (this.allowUncaught && !process.browser) {
6346
6376
  throw err;
6347
6377
  }
6348
6378
 
@@ -6394,36 +6424,24 @@ Runner.prototype.uncaught = function(err) {
6394
6424
 
6395
6425
  // we cannot recover gracefully if a Runnable has already passed
6396
6426
  // then fails asynchronously
6397
- var alreadyPassed = runnable.isPassed();
6398
- // this will change the state to "failed" regardless of the current value
6399
- this.fail(runnable, err);
6400
- if (!alreadyPassed) {
6401
- // recover from test
6402
- if (runnable.type === constants.EVENT_TEST_BEGIN) {
6403
- this.emit(constants.EVENT_TEST_END, runnable);
6404
- this.hookUp(HOOK_TYPE_AFTER_EACH, this.next);
6405
- return;
6406
- }
6427
+ if (runnable.isPassed()) {
6428
+ this.fail(runnable, err);
6429
+ this.abort();
6430
+ } else {
6407
6431
  debug(runnable);
6408
-
6409
- // recover from hooks
6410
- var errSuite = this.suite;
6411
-
6412
- // XXX how about a less awful way to determine this?
6413
- // if hook failure is in afterEach block
6414
- if (runnable.fullTitle().indexOf('after each') > -1) {
6415
- return this.hookErr(err, errSuite, true);
6416
- }
6417
- // if hook failure is in beforeEach block
6418
- if (runnable.fullTitle().indexOf('before each') > -1) {
6419
- return this.hookErr(err, errSuite, false);
6420
- }
6421
- // if hook failure is in after or before blocks
6422
- return this.nextSuite(errSuite);
6432
+ return runnable.callback(err);
6423
6433
  }
6434
+ };
6424
6435
 
6425
- // bail
6426
- this.abort();
6436
+ /**
6437
+ * Handle uncaught exceptions after runner's end event.
6438
+ *
6439
+ * @param {Error} err
6440
+ * @private
6441
+ */
6442
+ Runner.prototype.uncaughtEnd = function uncaughtEnd(err) {
6443
+ if (err instanceof Pending) return;
6444
+ throw err;
6427
6445
  };
6428
6446
 
6429
6447
  /**
@@ -6473,16 +6491,12 @@ Runner.prototype.run = function(fn) {
6473
6491
  this.on(constants.EVENT_RUN_END, function() {
6474
6492
  debug(constants.EVENT_RUN_END);
6475
6493
  process.removeListener('uncaughtException', uncaught);
6476
- process.on('uncaughtException', function(err) {
6477
- if (err instanceof Pending) {
6478
- return;
6479
- }
6480
- throw err;
6481
- });
6494
+ process.on('uncaughtException', self.uncaughtEnd);
6482
6495
  fn(self.failures);
6483
6496
  });
6484
6497
 
6485
6498
  // uncaught exception
6499
+ process.removeListener('uncaughtException', self.uncaughtEnd);
6486
6500
  process.on('uncaughtException', uncaught);
6487
6501
 
6488
6502
  if (this._delay) {
@@ -6491,7 +6505,9 @@ Runner.prototype.run = function(fn) {
6491
6505
  this.emit(constants.EVENT_DELAY_BEGIN, rootSuite);
6492
6506
  rootSuite.once(EVENT_ROOT_SUITE_RUN, start);
6493
6507
  } else {
6494
- start();
6508
+ Runner.immediately(function() {
6509
+ start();
6510
+ });
6495
6511
  }
6496
6512
 
6497
6513
  return this;
@@ -7359,6 +7375,18 @@ function Test(title, fn) {
7359
7375
  */
7360
7376
  utils.inherits(Test, Runnable);
7361
7377
 
7378
+ /**
7379
+ * Set or get retried test
7380
+ *
7381
+ * @private
7382
+ */
7383
+ Test.prototype.retriedTest = function(n) {
7384
+ if (!arguments.length) {
7385
+ return this._retriedTest;
7386
+ }
7387
+ this._retriedTest = n;
7388
+ };
7389
+
7362
7390
  Test.prototype.clone = function() {
7363
7391
  var test = new Test(this.title, this.fn);
7364
7392
  test.timeout(this.timeout());
@@ -7366,6 +7394,7 @@ Test.prototype.clone = function() {
7366
7394
  test.enableTimeouts(this.enableTimeouts());
7367
7395
  test.retries(this.retries());
7368
7396
  test.currentRetry(this.currentRetry());
7397
+ test.retriedTest(this.retriedTest() || this);
7369
7398
  test.globals(this.globals());
7370
7399
  test.parent = this.parent;
7371
7400
  test.file = this.file;
@@ -8130,38 +8159,6 @@ exports.dQuote = function(str) {
8130
8159
  return '"' + str + '"';
8131
8160
  };
8132
8161
 
8133
- /**
8134
- * Provides simplistic message translation for dealing with plurality.
8135
- *
8136
- * @description
8137
- * Use this to create messages which need to be singular or plural.
8138
- * Some languages have several plural forms, so _complete_ message clauses
8139
- * are preferable to generating the message on the fly.
8140
- *
8141
- * @private
8142
- * @param {number} n - Non-negative integer
8143
- * @param {string} msg1 - Message to be used in English for `n = 1`
8144
- * @param {string} msg2 - Message to be used in English for `n = 0, 2, 3, ...`
8145
- * @returns {string} message corresponding to value of `n`
8146
- * @example
8147
- * var sprintf = require('util').format;
8148
- * var pkgs = ['one', 'two'];
8149
- * var msg = sprintf(
8150
- * ngettext(
8151
- * pkgs.length,
8152
- * 'cannot load package: %s',
8153
- * 'cannot load packages: %s'
8154
- * ),
8155
- * pkgs.map(sQuote).join(', ')
8156
- * );
8157
- * console.log(msg); // => cannot load packages: 'one', 'two'
8158
- */
8159
- exports.ngettext = function(n, msg1, msg2) {
8160
- if (typeof n === 'number' && n >= 0) {
8161
- return n === 1 ? msg1 : msg2;
8162
- }
8163
- };
8164
-
8165
8162
  /**
8166
8163
  * It's a noop.
8167
8164
  * @public
@@ -8209,6 +8206,28 @@ exports.defineConstants = function(obj) {
8209
8206
  return Object.freeze(exports.createMap(obj));
8210
8207
  };
8211
8208
 
8209
+ /**
8210
+ * Whether current version of Node support ES modules
8211
+ *
8212
+ * @description
8213
+ * Versions prior to 10 did not support ES Modules, and version 10 has an old incompatibile version of ESM.
8214
+ * This function returns whether Node.JS has ES Module supports that is compatible with Mocha's needs,
8215
+ * which is version >=12.11.
8216
+ *
8217
+ * @returns {Boolean} whether the current version of Node.JS supports ES Modules in a way that is compatible with Mocha
8218
+ */
8219
+ exports.supportsEsModules = function() {
8220
+ if (!process.browser && process.versions && process.versions.node) {
8221
+ var versionFields = process.versions.node.split('.');
8222
+ var major = +versionFields[0];
8223
+ var minor = +versionFields[1];
8224
+
8225
+ if (major >= 13 || (major === 12 && minor >= 11)) {
8226
+ return true;
8227
+ }
8228
+ }
8229
+ };
8230
+
8212
8231
  }).call(this,require('_process'),require("buffer").Buffer)
8213
8232
  },{"./errors":6,"_process":69,"buffer":43,"fs":42,"glob":42,"he":54,"object.assign":65,"path":42,"util":89}],39:[function(require,module,exports){
8214
8233
  'use strict'
@@ -13759,7 +13778,6 @@ module.exports = Array.isArray || function (arr) {
13759
13778
  };
13760
13779
 
13761
13780
  },{}],59:[function(require,module,exports){
13762
- (function (process){
13763
13781
  var path = require('path');
13764
13782
  var fs = require('fs');
13765
13783
  var _0777 = parseInt('0777', 8);
@@ -13779,7 +13797,7 @@ function mkdirP (p, opts, f, made) {
13779
13797
  var xfs = opts.fs || fs;
13780
13798
 
13781
13799
  if (mode === undefined) {
13782
- mode = _0777 & (~process.umask());
13800
+ mode = _0777
13783
13801
  }
13784
13802
  if (!made) made = null;
13785
13803
 
@@ -13793,6 +13811,7 @@ function mkdirP (p, opts, f, made) {
13793
13811
  }
13794
13812
  switch (er.code) {
13795
13813
  case 'ENOENT':
13814
+ if (path.dirname(p) === p) return cb(er);
13796
13815
  mkdirP(path.dirname(p), opts, function (er, made) {
13797
13816
  if (er) cb(er, made);
13798
13817
  else mkdirP(p, opts, cb, made);
@@ -13823,7 +13842,7 @@ mkdirP.sync = function sync (p, opts, made) {
13823
13842
  var xfs = opts.fs || fs;
13824
13843
 
13825
13844
  if (mode === undefined) {
13826
- mode = _0777 & (~process.umask());
13845
+ mode = _0777
13827
13846
  }
13828
13847
  if (!made) made = null;
13829
13848
 
@@ -13859,8 +13878,7 @@ mkdirP.sync = function sync (p, opts, made) {
13859
13878
  return made;
13860
13879
  };
13861
13880
 
13862
- }).call(this,require('_process'))
13863
- },{"_process":69,"fs":42,"path":42}],60:[function(require,module,exports){
13881
+ },{"fs":42,"path":42}],60:[function(require,module,exports){
13864
13882
  /**
13865
13883
  * Helpers.
13866
13884
  */
@@ -18090,7 +18108,7 @@ function hasOwnProperty(obj, prop) {
18090
18108
  },{"./support/isBuffer":88,"_process":69,"inherits":56}],90:[function(require,module,exports){
18091
18109
  module.exports={
18092
18110
  "name": "mocha",
18093
- "version": "7.0.0",
18111
+ "version": "7.1.2",
18094
18112
  "homepage": "https://mochajs.org/",
18095
18113
  "notifyLogo": "https://ibin.co/4QuRuGjXvl36.png"
18096
18114
  }