mocha 8.4.0 → 9.0.3

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 CHANGED
@@ -1,3 +1,62 @@
1
+ # 9.0.3 / 2021-07-25
2
+
3
+ ## :bug: Fixes
4
+
5
+ - [#4702](https://github.com/mochajs/mocha/issues/4702): Error rethrow from cwd-relative path while loading `.mocharc.js` ([**@kirill-golovan**](https://github.com/kirill-golovan))
6
+
7
+ - [#4688](https://github.com/mochajs/mocha/issues/4688): Usage of custom interface in parallel mode ([**@juergba**](https://github.com/juergba))
8
+
9
+ - [#4687](https://github.com/mochajs/mocha/issues/4687): ESM: don't swallow `MODULE_NOT_FOUND` errors in case of `type:module` ([**@giltayar**](https://github.com/giltayar))
10
+
11
+ # 9.0.2 / 2021-07-03
12
+
13
+ ## :bug: Fixes
14
+
15
+ - [#4668](https://github.com/mochajs/mocha/issues/4668): ESM: make `--require <dir>` work with new `import`-first loading ([**@giltayar**](https://github.com/giltayar))
16
+
17
+ ## :nut_and_bolt: Other
18
+
19
+ - [#4674](https://github.com/mochajs/mocha/issues/4674): Update production dependencies ([**@juergba**](https://github.com/juergba))
20
+
21
+ # 9.0.1 / 2021-06-18
22
+
23
+ ## :nut_and_bolt: Other
24
+
25
+ - [#4657](https://github.com/mochajs/mocha/issues/4657): Browser: add separate bundle for modern browsers ([**@juergba**](https://github.com/juergba))
26
+
27
+ We added a separate browser bundle `mocha-es2018.js` in javascript ES2018, as we skipped the transpilation down to ES5. This is an **experimental step towards freezing Mocha's support of IE11**.
28
+
29
+ - [#4653](https://github.com/mochajs/mocha/issues/4653): ESM: proper version check in `hasStableEsmImplementation` ([**@alexander-fenster**](https://github.com/alexander-fenster))
30
+
31
+ # 9.0.0 / 2021-06-07
32
+
33
+ ## :boom: Breaking Changes
34
+
35
+ - [#4633](https://github.com/mochajs/mocha/issues/4633): **Drop Node.js v10.x support** ([**@juergba**](https://github.com/juergba))
36
+
37
+ - [#4635](https://github.com/mochajs/mocha/issues/4635): `import`-first loading of test files ([**@giltayar**](https://github.com/giltayar))
38
+
39
+ **Mocha is going ESM-first!** This means that it will now use ESM `import(test_file)` to load the test files, instead of the CommonJS `require(test_file)`. This is not a problem, as `import` can also load most files that `require` does. In the rare cases where this fails, it will fallback to `require(...)`. This ESM-first approach is the next step in Mocha's ESM migration, and allows ESM loaders to load and transform the test file.
40
+
41
+ - [#4636](https://github.com/mochajs/mocha/issues/4636): Remove deprecated `utils.lookupFiles()` ([**@juergba**](https://github.com/juergba))
42
+
43
+ - [#4638](https://github.com/mochajs/mocha/issues/4638): Limit the size of `actual`/`expected` for `diff` generation ([**@juergba**](https://github.com/juergba))
44
+
45
+ - [#4389](https://github.com/mochajs/mocha/issues/4389): Refactoring: Consuming log-symbols alternate to code for win32 in reporters/base ([**@MoonSupport**](https://github.com/MoonSupport))
46
+
47
+ ## :tada: Enhancements
48
+
49
+ - [#4640](https://github.com/mochajs/mocha/issues/4640): Add new option `--dry-run` ([**@juergba**](https://github.com/juergba))
50
+
51
+ ## :bug: Fixes
52
+
53
+ - [#4128](https://github.com/mochajs/mocha/issues/4128): Fix: control stringification of error message ([**@syeutyu**](https://github.com/syeutyu))
54
+
55
+ ## :nut_and_bolt: Other
56
+
57
+ - [#4646](https://github.com/mochajs/mocha/issues/4646): Deprecate `Runner(suite: Suite, delay: boolean)` signature ([**@juergba**](https://github.com/juergba))
58
+ - [#4643](https://github.com/mochajs/mocha/issues/4643): Update production dependencies ([**@juergba**](https://github.com/juergba))
59
+
1
60
  # 8.4.0 / 2021-05-07
2
61
 
3
62
  ## :tada: Enhancements
package/lib/cli/config.js CHANGED
@@ -31,7 +31,7 @@ exports.CONFIG_FILES = [
31
31
  ];
32
32
 
33
33
  const isModuleNotFoundError = err =>
34
- err.code !== 'MODULE_NOT_FOUND' ||
34
+ err.code === 'MODULE_NOT_FOUND' ||
35
35
  err.message.indexOf('Cannot find module') !== -1;
36
36
 
37
37
  /**
@@ -8,11 +8,9 @@
8
8
  var fs = require('fs');
9
9
  var path = require('path');
10
10
  var glob = require('glob');
11
- var {format} = require('util');
12
11
  var errors = require('../errors');
13
12
  var createNoFilesMatchPatternError = errors.createNoFilesMatchPatternError;
14
13
  var createMissingArgumentError = errors.createMissingArgumentError;
15
- var {sQuote, dQuote} = require('../utils');
16
14
  const debug = require('debug')('mocha:cli:lookup-files');
17
15
 
18
16
  /**
@@ -91,7 +89,7 @@ module.exports = function lookupFiles(
91
89
  files.push(...glob.sync(pattern, {nodir: true}));
92
90
  if (!files.length) {
93
91
  throw createNoFilesMatchPatternError(
94
- 'Cannot find any files matching pattern ' + dQuote(filepath),
92
+ `Cannot find any files matching pattern "${filepath}"`,
95
93
  filepath
96
94
  );
97
95
  }
@@ -127,11 +125,7 @@ module.exports = function lookupFiles(
127
125
  }
128
126
  if (!extensions.length) {
129
127
  throw createMissingArgumentError(
130
- format(
131
- 'Argument %s required when argument %s is a directory',
132
- sQuote('extensions'),
133
- sQuote('filepath')
134
- ),
128
+ `Argument '${extensions}' required when argument '${filepath}' is a directory`,
135
129
  'extensions',
136
130
  'array'
137
131
  );
@@ -195,10 +195,10 @@ exports.runMocha = async (mocha, options) => {
195
195
  * it actually exists. This must be run _after_ requires are processed (see
196
196
  * {@link handleRequires}), as it'll prevent interfaces from loading otherwise.
197
197
  * @param {Object} opts - Options object
198
- * @param {"reporter"|"interface"} pluginType - Type of plugin.
199
- * @param {Object} [map] - An object perhaps having key `key`. Used as a cache
200
- * of sorts; `Mocha.reporters` is one, where each key corresponds to a reporter
201
- * name
198
+ * @param {"reporter"|"ui"} pluginType - Type of plugin.
199
+ * @param {Object} [map] - Used as a cache of sorts;
200
+ * `Mocha.reporters` where each key corresponds to a reporter name,
201
+ * `Mocha.interfaces` where each key corresponds to an interface name.
202
202
  * @private
203
203
  */
204
204
  exports.validateLegacyPlugin = (opts, pluginType, map = {}) => {
@@ -226,12 +226,12 @@ exports.validateLegacyPlugin = (opts, pluginType, map = {}) => {
226
226
  // if this exists, then it's already loaded, so nothing more to do.
227
227
  if (!map[pluginId]) {
228
228
  try {
229
- opts[pluginType] = require(pluginId);
229
+ map[pluginId] = require(pluginId);
230
230
  } catch (err) {
231
231
  if (err.code === 'MODULE_NOT_FOUND') {
232
232
  // Try to load reporters from a path (absolute or relative)
233
233
  try {
234
- opts[pluginType] = require(path.resolve(pluginId));
234
+ map[pluginId] = require(path.resolve(pluginId));
235
235
  } catch (err) {
236
236
  throw createUnknownError(err);
237
237
  }
@@ -32,6 +32,7 @@ const TYPES = (exports.types = {
32
32
  'color',
33
33
  'delay',
34
34
  'diff',
35
+ 'dry-run',
35
36
  'exit',
36
37
  'forbid-only',
37
38
  'forbid-pending',
package/lib/cli/run.js CHANGED
@@ -83,6 +83,10 @@ exports.builder = yargs =>
83
83
  description: 'Show diff on failure',
84
84
  group: GROUPS.OUTPUT
85
85
  },
86
+ 'dry-run': {
87
+ description: 'Report tests without executing them',
88
+ group: GROUPS.RULES
89
+ },
86
90
  exit: {
87
91
  description: 'Force Mocha to quit after tests complete',
88
92
  group: GROUPS.RULES
package/lib/errors.js CHANGED
@@ -328,7 +328,7 @@ function createFatalError(message, value) {
328
328
  /**
329
329
  * Dynamically creates a plugin-type-specific error based on plugin type
330
330
  * @param {string} message - Error message
331
- * @param {"reporter"|"interface"} pluginType - Plugin type. Future: expand as needed
331
+ * @param {"reporter"|"ui"} pluginType - Plugin type. Future: expand as needed
332
332
  * @param {string} [pluginId] - Name/path of plugin, if any
333
333
  * @throws When `pluginType` is not known
334
334
  * @public
@@ -339,7 +339,7 @@ function createInvalidLegacyPluginError(message, pluginType, pluginId) {
339
339
  switch (pluginType) {
340
340
  case 'reporter':
341
341
  return createInvalidReporterError(message, pluginId);
342
- case 'interface':
342
+ case 'ui':
343
343
  return createInvalidInterfaceError(message, pluginId);
344
344
  default:
345
345
  throw new Error('unknown pluginType "' + pluginType + '"');
package/lib/esm-utils.js CHANGED
@@ -30,14 +30,73 @@ const formattedImport = async file => {
30
30
  return import(file);
31
31
  };
32
32
 
33
- exports.requireOrImport = async file => {
33
+ const hasStableEsmImplementation = (() => {
34
+ const [major, minor] = process.version.split('.');
35
+ // ESM is stable from v12.22.0 onward
36
+ // https://nodejs.org/api/esm.html#esm_modules_ecmascript_modules
37
+ const majorNumber = parseInt(major.slice(1), 10);
38
+ const minorNumber = parseInt(minor, 10);
39
+ return majorNumber > 12 || (majorNumber === 12 && minorNumber >= 22);
40
+ })();
41
+
42
+ exports.requireOrImport = hasStableEsmImplementation
43
+ ? async file => {
44
+ if (path.extname(file) === '.mjs') {
45
+ return formattedImport(file);
46
+ }
47
+ try {
48
+ return dealWithExports(await formattedImport(file));
49
+ } catch (err) {
50
+ if (
51
+ err.code === 'ERR_MODULE_NOT_FOUND' ||
52
+ err.code === 'ERR_UNKNOWN_FILE_EXTENSION' ||
53
+ err.code === 'ERR_UNSUPPORTED_DIR_IMPORT'
54
+ ) {
55
+ try {
56
+ return require(file);
57
+ } catch (requireErr) {
58
+ if (requireErr.code === 'ERR_REQUIRE_ESM') {
59
+ // This happens when the test file is a JS file, but via type:module is actually ESM,
60
+ // AND has an import to a file that doesn't exist.
61
+ // This throws an `ERR_MODULE_NOT_FOUND` // error above,
62
+ // and when we try to `require` it here, it throws an `ERR_REQUIRE_ESM`.
63
+ // What we want to do is throw the original error (the `ERR_MODULE_NOT_FOUND`),
64
+ // and not the `ERR_REQUIRE_ESM` error, which is a red herring.
65
+ throw err;
66
+ } else {
67
+ throw requireErr;
68
+ }
69
+ }
70
+ } else {
71
+ throw err;
72
+ }
73
+ }
74
+ }
75
+ : implementationOfRequireOrImportForUnstableEsm;
76
+
77
+ function dealWithExports(module) {
78
+ if (module.default) {
79
+ return module.default;
80
+ } else {
81
+ return {...module, default: undefined};
82
+ }
83
+ }
84
+
85
+ exports.loadFilesAsync = async (files, preLoadFunc, postLoadFunc) => {
86
+ for (const file of files) {
87
+ preLoadFunc(file);
88
+ const result = await exports.requireOrImport(path.resolve(file));
89
+ postLoadFunc(file, result);
90
+ }
91
+ };
92
+
93
+ /* istanbul ignore next */
94
+ async function implementationOfRequireOrImportForUnstableEsm(file) {
34
95
  if (path.extname(file) === '.mjs') {
35
96
  return formattedImport(file);
36
97
  }
37
- // This is currently the only known way of figuring out whether a file is CJS or ESM.
38
- // If Node.js or the community establish a better procedure for that, we can fix this code.
39
- // Another option here would be to always use `import()`, as this also supports CJS, but I would be
40
- // wary of using it for _all_ existing test files, till ESM is fully stable.
98
+ // This is currently the only known way of figuring out whether a file is CJS or ESM in
99
+ // Node.js that doesn't necessitate calling `import` first.
41
100
  try {
42
101
  return require(file);
43
102
  } catch (err) {
@@ -47,12 +106,4 @@ exports.requireOrImport = async file => {
47
106
  throw err;
48
107
  }
49
108
  }
50
- };
51
-
52
- exports.loadFilesAsync = async (files, preLoadFunc, postLoadFunc) => {
53
- for (const file of files) {
54
- preLoadFunc(file);
55
- const result = await exports.requireOrImport(path.resolve(file));
56
- postLoadFunc(file, result);
57
- }
58
- };
109
+ }
package/lib/mocha.js CHANGED
@@ -30,7 +30,6 @@ const {
30
30
  EVENT_FILE_POST_REQUIRE,
31
31
  EVENT_FILE_REQUIRE
32
32
  } = Suite.constants;
33
- var sQuote = utils.sQuote;
34
33
  var debug = require('debug')('mocha:mocha');
35
34
 
36
35
  exports = module.exports = Mocha;
@@ -164,6 +163,7 @@ exports.run = function(...args) {
164
163
  * @param {boolean} [options.color] - Color TTY output from reporter?
165
164
  * @param {boolean} [options.delay] - Delay root suite execution?
166
165
  * @param {boolean} [options.diff] - Show diff on failure?
166
+ * @param {boolean} [options.dryRun] - Report tests without running them?
167
167
  * @param {string} [options.fgrep] - Test filter given string.
168
168
  * @param {boolean} [options.forbidOnly] - Tests marked `only` fail the suite?
169
169
  * @param {boolean} [options.forbidPending] - Pending tests fail the suite?
@@ -200,7 +200,7 @@ function Mocha(options = {}) {
200
200
  .ui(options.ui)
201
201
  .reporter(
202
202
  options.reporter,
203
- options.reporterOption || options.reporterOptions // reporterOptions was previously the only way to specify options to reporter
203
+ options.reporterOption || options.reporterOptions // for backwards compability
204
204
  )
205
205
  .slow(options.slow)
206
206
  .global(options.global);
@@ -222,6 +222,7 @@ function Mocha(options = {}) {
222
222
  'color',
223
223
  'delay',
224
224
  'diff',
225
+ 'dryRun',
225
226
  'forbidOnly',
226
227
  'forbidPending',
227
228
  'fullTrace',
@@ -346,23 +347,19 @@ Mocha.prototype.reporter = function(reporterName, reporterOptions) {
346
347
  reporter = require(path.resolve(utils.cwd(), reporterName));
347
348
  } catch (_err) {
348
349
  _err.code === 'MODULE_NOT_FOUND'
349
- ? warn(sQuote(reporterName) + ' reporter not found')
350
+ ? warn(`'${reporterName}' reporter not found`)
350
351
  : warn(
351
- sQuote(reporterName) +
352
- ' reporter blew up with error:\n' +
353
- err.stack
352
+ `'${reporterName}' reporter blew up with error:\n ${err.stack}`
354
353
  );
355
354
  }
356
355
  } else {
357
- warn(
358
- sQuote(reporterName) + ' reporter blew up with error:\n' + err.stack
359
- );
356
+ warn(`'${reporterName}' reporter blew up with error:\n ${err.stack}`);
360
357
  }
361
358
  }
362
359
  }
363
360
  if (!reporter) {
364
361
  throw createInvalidReporterError(
365
- 'invalid reporter ' + sQuote(reporterName),
362
+ `invalid reporter '${reporterName}'`,
366
363
  reporterName
367
364
  );
368
365
  }
@@ -396,10 +393,7 @@ Mocha.prototype.ui = function(ui) {
396
393
  try {
397
394
  bindInterface = require(ui);
398
395
  } catch (err) {
399
- throw createInvalidInterfaceError(
400
- 'invalid interface ' + sQuote(ui),
401
- ui
402
- );
396
+ throw createInvalidInterfaceError(`invalid interface '${ui}'`, ui);
403
397
  }
404
398
  }
405
399
  }
@@ -784,6 +778,20 @@ Mocha.prototype.diff = function(diff) {
784
778
  return this;
785
779
  };
786
780
 
781
+ /**
782
+ * Enables or disables running tests in dry-run mode.
783
+ *
784
+ * @public
785
+ * @see [CLI option](../#-dry-run)
786
+ * @param {boolean} [dryRun=true] - Whether to activate dry-run mode.
787
+ * @return {Mocha} this
788
+ * @chainable
789
+ */
790
+ Mocha.prototype.dryRun = function(dryRun) {
791
+ this.options.dryRun = dryRun !== false;
792
+ return this;
793
+ };
794
+
787
795
  /**
788
796
  * @summary
789
797
  * Sets timeout threshold value.
@@ -1016,6 +1024,7 @@ Mocha.prototype.run = function(fn) {
1016
1024
  options.files = this.files;
1017
1025
  const runner = new this._runnerClass(suite, {
1018
1026
  delay: options.delay,
1027
+ dryRun: options.dryRun,
1019
1028
  cleanReferencesAfterRun: this._cleanReferencesAfterRun
1020
1029
  });
1021
1030
  createStatsCollector(runner);
@@ -10,6 +10,7 @@ var diff = require('diff');
10
10
  var milliseconds = require('ms');
11
11
  var utils = require('../utils');
12
12
  var supportsColor = require('supports-color');
13
+ var symbols = require('log-symbols');
13
14
  var constants = require('../runner').constants;
14
15
  var EVENT_TEST_PASS = constants.EVENT_TEST_PASS;
15
16
  var EVENT_TEST_FAIL = constants.EVENT_TEST_FAIL;
@@ -88,20 +89,13 @@ exports.colors = {
88
89
  */
89
90
 
90
91
  exports.symbols = {
91
- ok: '✓',
92
- err: '✖',
93
- dot: '',
92
+ ok: symbols.success,
93
+ err: symbols.err,
94
+ dot: '.',
94
95
  comma: ',',
95
96
  bang: '!'
96
97
  };
97
98
 
98
- // With node.js on Windows: use symbols available in terminal default fonts
99
- if (process.platform === 'win32') {
100
- exports.symbols.ok = '\u221A';
101
- exports.symbols.err = '\u00D7';
102
- exports.symbols.dot = '.';
103
- }
104
-
105
99
  /**
106
100
  * Color `str` with the given `type`,
107
101
  * allowing colors to be disabled,
@@ -196,6 +190,13 @@ function stringifyDiffObjs(err) {
196
190
  */
197
191
  var generateDiff = (exports.generateDiff = function(actual, expected) {
198
192
  try {
193
+ const diffSize = 2048;
194
+ if (actual.length > diffSize) {
195
+ actual = actual.substring(0, diffSize) + ' ... Lines skipped';
196
+ }
197
+ if (expected.length > diffSize) {
198
+ expected = expected.substring(0, diffSize) + ' ... Lines skipped';
199
+ }
199
200
  return exports.inlineDiffs
200
201
  ? inlineDiff(actual, expected)
201
202
  : unifiedDiff(actual, expected);
@@ -242,10 +243,10 @@ exports.list = function(failures) {
242
243
  err = test.err;
243
244
  }
244
245
  var message;
245
- if (err.message && typeof err.message.toString === 'function') {
246
- message = err.message + '';
247
- } else if (typeof err.inspect === 'function') {
246
+ if (typeof err.inspect === 'function') {
248
247
  message = err.inspect() + '';
248
+ } else if (err.message && typeof err.message.toString === 'function') {
249
+ message = err.message + '';
249
250
  } else {
250
251
  message = '';
251
252
  }
package/lib/runner.js CHANGED
@@ -4,7 +4,6 @@
4
4
  * Module dependencies.
5
5
  * @private
6
6
  */
7
- var util = require('util');
8
7
  var EventEmitter = require('events').EventEmitter;
9
8
  var Pending = require('./pending');
10
9
  var utils = require('./utils');
@@ -19,8 +18,6 @@ var EVENT_ROOT_SUITE_RUN = Suite.constants.EVENT_ROOT_SUITE_RUN;
19
18
  var STATE_FAILED = Runnable.constants.STATE_FAILED;
20
19
  var STATE_PASSED = Runnable.constants.STATE_PASSED;
21
20
  var STATE_PENDING = Runnable.constants.STATE_PENDING;
22
- var dQuote = utils.dQuote;
23
- var sQuote = utils.sQuote;
24
21
  var stackFilter = utils.stackTraceFilter();
25
22
  var stringify = utils.stringify;
26
23
 
@@ -138,8 +135,9 @@ class Runner extends EventEmitter {
138
135
  * @public
139
136
  * @class
140
137
  * @param {Suite} suite - Root suite
141
- * @param {Object|boolean} [opts] - Options. If `boolean`, whether or not to delay execution of root suite until ready (for backwards compatibility).
138
+ * @param {Object|boolean} [opts] - Options. If `boolean` (deprecated), whether or not to delay execution of root suite until ready.
142
139
  * @param {boolean} [opts.delay] - Whether to delay execution of root suite until ready.
140
+ * @param {boolean} [opts.dryRun] - Whether to report tests without running them.
143
141
  * @param {boolean} [opts.cleanReferencesAfterRun] - Whether to clean references to test fns and hooks when a suite is done.
144
142
  */
145
143
  constructor(suite, opts) {
@@ -148,7 +146,10 @@ class Runner extends EventEmitter {
148
146
  opts = {};
149
147
  }
150
148
  if (typeof opts === 'boolean') {
151
- // TODO: deprecate this
149
+ // TODO: remove this
150
+ require('./errors').deprecate(
151
+ '"Runner(suite: Suite, delay: boolean)" is deprecated. Use "Runner(suite: Suite, {delay: boolean})" instead.'
152
+ );
152
153
  this._delay = opts;
153
154
  opts = {};
154
155
  } else {
@@ -407,9 +408,8 @@ Runner.prototype.checkGlobals = function(test) {
407
408
  this._globals = this._globals.concat(leaks);
408
409
 
409
410
  if (leaks.length) {
410
- var msg = 'global leak(s) detected: %s';
411
- var error = new Error(util.format(msg, leaks.map(sQuote).join(', ')));
412
- this.fail(test, error);
411
+ var msg = `global leak(s) detected: ${leaks.map(e => `'${e}'`).join(', ')}`;
412
+ this.fail(test, new Error(msg));
413
413
  }
414
414
  };
415
415
 
@@ -476,6 +476,8 @@ Runner.prototype.fail = function(test, err, force) {
476
476
  */
477
477
 
478
478
  Runner.prototype.hook = function(name, fn) {
479
+ if (this._opts.dryRun) return fn();
480
+
479
481
  var suite = this.suite;
480
482
  var hooks = suite.getHooks(name);
481
483
  var self = this;
@@ -554,8 +556,7 @@ Runner.prototype.hook = function(name, fn) {
554
556
  function setHookTitle(hook) {
555
557
  hook.originalTitle = hook.originalTitle || hook.title;
556
558
  if (hook.ctx && hook.ctx.currentTest) {
557
- hook.title =
558
- hook.originalTitle + ' for ' + dQuote(hook.ctx.currentTest.title);
559
+ hook.title = `${hook.originalTitle} for "${hook.ctx.currentTest.title}"`;
559
560
  } else {
560
561
  var parentTitle;
561
562
  if (hook.parent.title) {
@@ -563,7 +564,7 @@ Runner.prototype.hook = function(name, fn) {
563
564
  } else {
564
565
  parentTitle = hook.parent.root ? '{root}' : '';
565
566
  }
566
- hook.title = hook.originalTitle + ' in ' + dQuote(parentTitle);
567
+ hook.title = `${hook.originalTitle} in "${parentTitle}"`;
567
568
  }
568
569
  }
569
570
  }
@@ -609,7 +610,7 @@ Runner.prototype.hooks = function(name, suites, fn) {
609
610
  };
610
611
 
611
612
  /**
612
- * Run hooks from the top level down.
613
+ * Run 'afterEach' hooks from bottom up.
613
614
  *
614
615
  * @param {String} name
615
616
  * @param {Function} fn
@@ -621,7 +622,7 @@ Runner.prototype.hookUp = function(name, fn) {
621
622
  };
622
623
 
623
624
  /**
624
- * Run hooks from the bottom up.
625
+ * Run 'beforeEach' hooks from top level down.
625
626
  *
626
627
  * @param {String} name
627
628
  * @param {Function} fn
@@ -656,6 +657,8 @@ Runner.prototype.parents = function() {
656
657
  * @private
657
658
  */
658
659
  Runner.prototype.runTest = function(fn) {
660
+ if (this._opts.dryRun) return fn();
661
+
659
662
  var self = this;
660
663
  var test = this.test;
661
664
 
@@ -701,7 +704,6 @@ Runner.prototype.runTests = function(suite, fn) {
701
704
  self.suite = after ? errSuite.parent : errSuite;
702
705
 
703
706
  if (self.suite) {
704
- // call hookUp afterEach
705
707
  self.hookUp(HOOK_TYPE_AFTER_EACH, function(err2, errSuite2) {
706
708
  self.suite = orig;
707
709
  // some hooks may fail even now
package/lib/utils.js CHANGED
@@ -13,7 +13,6 @@ const {nanoid} = require('nanoid/non-secure');
13
13
  var path = require('path');
14
14
  var util = require('util');
15
15
  var he = require('he');
16
- const errors = require('./errors');
17
16
 
18
17
  const MOCHA_ID_PROP_NAME = '__mocha_id__';
19
18
 
@@ -519,44 +518,6 @@ exports.clamp = function clamp(value, range) {
519
518
  return Math.min(Math.max(value, range[0]), range[1]);
520
519
  };
521
520
 
522
- /**
523
- * Single quote text by combining with undirectional ASCII quotation marks.
524
- *
525
- * @description
526
- * Provides a simple means of markup for quoting text to be used in output.
527
- * Use this to quote names of variables, methods, and packages.
528
- *
529
- * <samp>package 'foo' cannot be found</samp>
530
- *
531
- * @private
532
- * @param {string} str - Value to be quoted.
533
- * @returns {string} quoted value
534
- * @example
535
- * sQuote('n') // => 'n'
536
- */
537
- exports.sQuote = function(str) {
538
- return "'" + str + "'";
539
- };
540
-
541
- /**
542
- * Double quote text by combining with undirectional ASCII quotation marks.
543
- *
544
- * @description
545
- * Provides a simple means of markup for quoting text to be used in output.
546
- * Use this to quote names of datatypes, classes, pathnames, and strings.
547
- *
548
- * <samp>argument 'value' must be "string" or "number"</samp>
549
- *
550
- * @private
551
- * @param {string} str - Value to be quoted.
552
- * @returns {string} quoted value
553
- * @example
554
- * dQuote('number') // => "number"
555
- */
556
- exports.dQuote = function(str) {
557
- return '"' + str + '"';
558
- };
559
-
560
521
  /**
561
522
  * It's a noop.
562
523
  * @public
@@ -650,35 +611,6 @@ exports.isBrowser = function isBrowser() {
650
611
  return Boolean(process.browser);
651
612
  };
652
613
 
653
- /**
654
- * Lookup file names at the given `path`.
655
- *
656
- * @description
657
- * Filenames are returned in _traversal_ order by the OS/filesystem.
658
- * **Make no assumption that the names will be sorted in any fashion.**
659
- *
660
- * @public
661
- * @alias module:lib/cli.lookupFiles
662
- * @param {string} filepath - Base path to start searching from.
663
- * @param {string[]} [extensions=[]] - File extensions to look for.
664
- * @param {boolean} [recursive=false] - Whether to recurse into subdirectories.
665
- * @return {string[]} An array of paths.
666
- * @throws {Error} if no files match pattern.
667
- * @throws {TypeError} if `filepath` is directory and `extensions` not provided.
668
- * @deprecated Moved to {@link module:lib/cli.lookupFiles}
669
- */
670
- exports.lookupFiles = (...args) => {
671
- if (exports.isBrowser()) {
672
- throw errors.createUnsupportedError(
673
- 'lookupFiles() is only supported in Node.js!'
674
- );
675
- }
676
- errors.deprecate(
677
- '`lookupFiles()` in module `mocha/lib/utils` has moved to module `mocha/lib/cli` and will be removed in the next major revision of Mocha'
678
- );
679
- return require('./cli').lookupFiles(...args);
680
- };
681
-
682
614
  /*
683
615
  * Casts `value` to an array; useful for optionally accepting array parameters
684
616
  *