mocha 9.2.2 → 10.2.0

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.
File without changes
@@ -86,6 +86,20 @@ Progress.prototype.update = function (n) {
86
86
  */
87
87
  Progress.prototype.draw = function (ctx) {
88
88
  try {
89
+ var darkMatcher = window.matchMedia('(prefers-color-scheme: dark)');
90
+ var isDarkMode = !!darkMatcher.matches;
91
+ var lightColors = {
92
+ outerCircle: '#9f9f9f',
93
+ innerCircle: '#eee',
94
+ text: '#000'
95
+ };
96
+ var darkColors = {
97
+ outerCircle: '#888',
98
+ innerCircle: '#444',
99
+ text: '#fff'
100
+ };
101
+ var colors = isDarkMode ? darkColors : lightColors;
102
+
89
103
  var percent = Math.min(this.percent, 100);
90
104
  var size = this._size;
91
105
  var half = size / 2;
@@ -100,13 +114,13 @@ Progress.prototype.draw = function (ctx) {
100
114
  ctx.clearRect(0, 0, size, size);
101
115
 
102
116
  // outer circle
103
- ctx.strokeStyle = '#9f9f9f';
117
+ ctx.strokeStyle = colors.outerCircle;
104
118
  ctx.beginPath();
105
119
  ctx.arc(x, y, rad, 0, angle, false);
106
120
  ctx.stroke();
107
121
 
108
122
  // inner circle
109
- ctx.strokeStyle = '#eee';
123
+ ctx.strokeStyle = colors.innerCircle;
110
124
  ctx.beginPath();
111
125
  ctx.arc(x, y, rad - 1, 0, angle, true);
112
126
  ctx.stroke();
@@ -115,6 +129,7 @@ Progress.prototype.draw = function (ctx) {
115
129
  var text = this._text || (percent | 0) + '%';
116
130
  var w = ctx.measureText(text).width;
117
131
 
132
+ ctx.fillStyle = colors.text;
118
133
  ctx.fillText(text, x - w / 2 + 1, y + fontSize / 2 - 1);
119
134
  } catch (ignore) {
120
135
  // don't fail if we can't render progress
@@ -2,7 +2,7 @@
2
2
 
3
3
  /**
4
4
  * Exports Yargs commands
5
- * @see https://git.io/fpJ0G
5
+ * @see https://github.com/yargs/yargs/blob/main/docs/advanced.md
6
6
  * @private
7
7
  * @module
8
8
  */
@@ -39,7 +39,6 @@ const TYPES = (exports.types = {
39
39
  'forbid-only',
40
40
  'forbid-pending',
41
41
  'full-trace',
42
- 'growl',
43
42
  'inline-diffs',
44
43
  'invert',
45
44
  'list-interfaces',
@@ -76,7 +75,6 @@ exports.aliases = {
76
75
  fgrep: ['f'],
77
76
  global: ['globals'],
78
77
  grep: ['g'],
79
- growl: ['G'],
80
78
  ignore: ['exclude'],
81
79
  invert: ['i'],
82
80
  jobs: ['j'],
package/lib/cli/run.js CHANGED
@@ -141,10 +141,6 @@ exports.builder = yargs =>
141
141
  group: GROUPS.FILTERS,
142
142
  requiresArg: true
143
143
  },
144
- growl: {
145
- description: 'Enable Growl notifications',
146
- group: GROUPS.OUTPUT
147
- },
148
144
  ignore: {
149
145
  defaultDescription: '(none)',
150
146
  description: 'Ignore file(s) or glob pattern(s)',
@@ -333,7 +329,7 @@ exports.builder = yargs =>
333
329
  if (argv.compilers) {
334
330
  throw createUnsupportedError(
335
331
  `--compilers is DEPRECATED and no longer supported.
336
- See https://git.io/vdcSr for migration information.`
332
+ See https://github.com/mochajs/mocha/wiki/compilers-deprecation for migration information.`
337
333
  );
338
334
  }
339
335
 
@@ -40,9 +40,9 @@ module.exports = function bddInterface(suite) {
40
40
 
41
41
  context.describe = context.context = function (title, fn) {
42
42
  return common.suite.create({
43
- title: title,
44
- file: file,
45
- fn: fn
43
+ title,
44
+ file,
45
+ fn
46
46
  });
47
47
  };
48
48
 
@@ -55,9 +55,9 @@ module.exports = function bddInterface(suite) {
55
55
  context.describe.skip =
56
56
  function (title, fn) {
57
57
  return common.suite.skip({
58
- title: title,
59
- file: file,
60
- fn: fn
58
+ title,
59
+ file,
60
+ fn
61
61
  });
62
62
  };
63
63
 
@@ -67,9 +67,9 @@ module.exports = function bddInterface(suite) {
67
67
 
68
68
  context.describe.only = function (title, fn) {
69
69
  return common.suite.only({
70
- title: title,
71
- file: file,
72
- fn: fn
70
+ title,
71
+ file,
72
+ fn
73
73
  });
74
74
  };
75
75
 
@@ -49,8 +49,8 @@ module.exports = function qUnitInterface(suite) {
49
49
  suites.shift();
50
50
  }
51
51
  return common.suite.create({
52
- title: title,
53
- file: file,
52
+ title,
53
+ file,
54
54
  fn: false
55
55
  });
56
56
  };
@@ -64,8 +64,8 @@ module.exports = function qUnitInterface(suite) {
64
64
  suites.shift();
65
65
  }
66
66
  return common.suite.only({
67
- title: title,
68
- file: file,
67
+ title,
68
+ file,
69
69
  fn: false
70
70
  });
71
71
  };
@@ -47,9 +47,9 @@ module.exports = function (suite) {
47
47
  */
48
48
  context.suite = function (title, fn) {
49
49
  return common.suite.create({
50
- title: title,
51
- file: file,
52
- fn: fn
50
+ title,
51
+ file,
52
+ fn
53
53
  });
54
54
  };
55
55
 
@@ -58,9 +58,9 @@ module.exports = function (suite) {
58
58
  */
59
59
  context.suite.skip = function (title, fn) {
60
60
  return common.suite.skip({
61
- title: title,
62
- file: file,
63
- fn: fn
61
+ title,
62
+ file,
63
+ fn
64
64
  });
65
65
  };
66
66
 
@@ -69,9 +69,9 @@ module.exports = function (suite) {
69
69
  */
70
70
  context.suite.only = function (title, fn) {
71
71
  return common.suite.only({
72
- title: title,
73
- file: file,
74
- fn: fn
72
+ title,
73
+ file,
74
+ fn
75
75
  });
76
76
  };
77
77
 
package/lib/mocha.js CHANGED
@@ -9,7 +9,6 @@
9
9
  var escapeRe = require('escape-string-regexp');
10
10
  var path = require('path');
11
11
  var builtinReporters = require('./reporters');
12
- var growl = require('./nodejs/growl');
13
12
  var utils = require('./utils');
14
13
  var mocharc = require('./mocharc.json');
15
14
  var Suite = require('./suite');
@@ -165,7 +164,6 @@ exports.run = function (...args) {
165
164
  * @param {boolean} [options.fullTrace] - Full stacktrace upon failure?
166
165
  * @param {string[]} [options.global] - Variables expected in global scope.
167
166
  * @param {RegExp|string} [options.grep] - Test filter given regular expression.
168
- * @param {boolean} [options.growl] - Enable desktop notifications?
169
167
  * @param {boolean} [options.inlineDiffs] - Display inline diffs?
170
168
  * @param {boolean} [options.invert] - Invert test filter matches?
171
169
  * @param {boolean} [options.noHighlighting] - Disable syntax highlighting?
@@ -195,7 +193,7 @@ function Mocha(options = {}) {
195
193
  .ui(options.ui)
196
194
  .reporter(
197
195
  options.reporter,
198
- options.reporterOption || options.reporterOptions // for backwards compability
196
+ options.reporterOption || options.reporterOptions // for backwards compatibility
199
197
  )
200
198
  .slow(options.slow)
201
199
  .global(options.global);
@@ -222,7 +220,6 @@ function Mocha(options = {}) {
222
220
  'forbidOnly',
223
221
  'forbidPending',
224
222
  'fullTrace',
225
- 'growl',
226
223
  'inlineDiffs',
227
224
  'invert'
228
225
  ].forEach(function (opt) {
@@ -432,6 +429,8 @@ Mocha.prototype.loadFiles = function (fn) {
432
429
  * @see {@link Mocha#addFile}
433
430
  * @see {@link Mocha#run}
434
431
  * @see {@link Mocha#unloadFiles}
432
+ * @param {Object} [options] - Settings object.
433
+ * @param {Function} [options.esmDecorator] - Function invoked on esm module name right before importing it. By default will passthrough as is.
435
434
  * @returns {Promise}
436
435
  * @example
437
436
  *
@@ -440,7 +439,7 @@ Mocha.prototype.loadFiles = function (fn) {
440
439
  * .then(() => mocha.run(failures => process.exitCode = failures ? 1 : 0))
441
440
  * .catch(() => process.exitCode = 1);
442
441
  */
443
- Mocha.prototype.loadFilesAsync = function () {
442
+ Mocha.prototype.loadFilesAsync = function ({esmDecorator} = {}) {
444
443
  var self = this;
445
444
  var suite = this.suite;
446
445
  this.lazyLoadFiles(true);
@@ -453,7 +452,8 @@ Mocha.prototype.loadFilesAsync = function () {
453
452
  function (file, resultModule) {
454
453
  suite.emit(EVENT_FILE_REQUIRE, resultModule, file, self);
455
454
  suite.emit(EVENT_FILE_POST_REQUIRE, global, file, self);
456
- }
455
+ },
456
+ esmDecorator
457
457
  );
458
458
  };
459
459
 
@@ -468,7 +468,7 @@ Mocha.prototype.loadFilesAsync = function () {
468
468
  Mocha.unloadFile = function (file) {
469
469
  if (utils.isBrowser()) {
470
470
  throw createUnsupportedError(
471
- 'unloadFile() is only suported in a Node.js environment'
471
+ 'unloadFile() is only supported in a Node.js environment'
472
472
  );
473
473
  }
474
474
  return require('./nodejs/file-unloader').unloadFile(file);
@@ -647,49 +647,6 @@ Mocha.prototype.fullTrace = function (fullTrace) {
647
647
  return this;
648
648
  };
649
649
 
650
- /**
651
- * Enables desktop notification support if prerequisite software installed.
652
- *
653
- * @public
654
- * @see [CLI option](../#-growl-g)
655
- * @return {Mocha} this
656
- * @chainable
657
- */
658
- Mocha.prototype.growl = function () {
659
- this.options.growl = this.isGrowlCapable();
660
- if (!this.options.growl) {
661
- var detail = utils.isBrowser()
662
- ? 'notification support not available in this browser...'
663
- : 'notification support prerequisites not installed...';
664
- console.error(detail + ' cannot enable!');
665
- }
666
- return this;
667
- };
668
-
669
- /**
670
- * @summary
671
- * Determines if Growl support seems likely.
672
- *
673
- * @description
674
- * <strong>Not available when run in browser.</strong>
675
- *
676
- * @private
677
- * @see {@link Growl#isCapable}
678
- * @see {@link Mocha#growl}
679
- * @return {boolean} whether Growl support can be expected
680
- */
681
- Mocha.prototype.isGrowlCapable = growl.isCapable;
682
-
683
- /**
684
- * Implements desktop notifications using a pseudo-reporter.
685
- *
686
- * @private
687
- * @see {@link Mocha#growl}
688
- * @see {@link Growl#notify}
689
- * @param {Runner} runner - Runner instance.
690
- */
691
- Mocha.prototype._growl = growl.notify;
692
-
693
650
  /**
694
651
  * Specifies whitelist of variable names to be expected in global scope.
695
652
  *
@@ -713,7 +670,7 @@ Mocha.prototype.global = function (global) {
713
670
  });
714
671
  return this;
715
672
  };
716
- // for backwards compability, 'globals' is an alias of 'global'
673
+ // for backwards compatibility, 'globals' is an alias of 'global'
717
674
  Mocha.prototype.globals = Mocha.prototype.global;
718
675
 
719
676
  /**
@@ -1037,9 +994,6 @@ Mocha.prototype.run = function (fn) {
1037
994
  if (options.global) {
1038
995
  runner.globals(options.global);
1039
996
  }
1040
- if (options.growl) {
1041
- this._growl(runner);
1042
- }
1043
997
  if (options.color !== undefined) {
1044
998
  exports.reporters.Base.useColors = options.color;
1045
999
  }
@@ -1,16 +1,18 @@
1
1
  const path = require('path');
2
2
  const url = require('url');
3
3
 
4
- const formattedImport = async file => {
4
+ const forward = x => x;
5
+
6
+ const formattedImport = async (file, esmDecorator = forward) => {
5
7
  if (path.isAbsolute(file)) {
6
8
  try {
7
- return await import(url.pathToFileURL(file));
9
+ return await exports.doImport(esmDecorator(url.pathToFileURL(file)));
8
10
  } catch (err) {
9
11
  // This is a hack created because ESM in Node.js (at least in Node v15.5.1) does not emit
10
12
  // the location of the syntax error in the error thrown.
11
13
  // This is problematic because the user can't see what file has the problem,
12
14
  // so we add the file location to the error.
13
- // This `if` should be removed once Node.js fixes the problem.
15
+ // TODO: remove once Node.js fixes the problem.
14
16
  if (
15
17
  err instanceof SyntaxError &&
16
18
  err.message &&
@@ -27,67 +29,57 @@ const formattedImport = async file => {
27
29
  throw err;
28
30
  }
29
31
  }
30
- return import(file);
32
+ return exports.doImport(esmDecorator(file));
31
33
  };
32
34
 
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
- })();
35
+ exports.doImport = async file => import(file);
41
36
 
42
- exports.requireOrImport = hasStableEsmImplementation
43
- ? async file => {
44
- if (path.extname(file) === '.mjs') {
45
- return formattedImport(file);
46
- }
37
+ exports.requireOrImport = async (file, esmDecorator) => {
38
+ if (path.extname(file) === '.mjs') {
39
+ return formattedImport(file, esmDecorator);
40
+ }
41
+ try {
42
+ return dealWithExports(await formattedImport(file, esmDecorator));
43
+ } catch (err) {
44
+ if (
45
+ err.code === 'ERR_MODULE_NOT_FOUND' ||
46
+ err.code === 'ERR_UNKNOWN_FILE_EXTENSION' ||
47
+ err.code === 'ERR_UNSUPPORTED_DIR_IMPORT'
48
+ ) {
47
49
  try {
48
- return dealWithExports(await formattedImport(file));
49
- } catch (err) {
50
+ // Importing a file usually works, but the resolution of `import` is the ESM
51
+ // resolution algorithm, and not the CJS resolution algorithm. We may have
52
+ // failed because we tried the ESM resolution, so we try to `require` it.
53
+ return require(file);
54
+ } catch (requireErr) {
50
55
  if (
51
- err.code === 'ERR_MODULE_NOT_FOUND' ||
52
- err.code === 'ERR_UNKNOWN_FILE_EXTENSION' ||
53
- err.code === 'ERR_UNSUPPORTED_DIR_IMPORT'
56
+ requireErr.code === 'ERR_REQUIRE_ESM' ||
57
+ (requireErr instanceof SyntaxError &&
58
+ requireErr
59
+ .toString()
60
+ .includes('Cannot use import statement outside a module'))
54
61
  ) {
55
- try {
56
- // Importing a file usually works, but the resolution of `import` is the ESM
57
- // resolution algorithm, and not the CJS resolution algorithm. So in this case
58
- // if we fail, we may have failed because we tried the ESM resolution and failed
59
- // So we try to `require` it
60
- return require(file);
61
- } catch (requireErr) {
62
- if (
63
- requireErr.code === 'ERR_REQUIRE_ESM' ||
64
- (requireErr instanceof SyntaxError &&
65
- requireErr
66
- .toString()
67
- .includes('Cannot use import statement outside a module'))
68
- ) {
69
- // ERR_REQUIRE_ESM happens when the test file is a JS file, but via type:module is actually ESM,
70
- // AND has an import to a file that doesn't exist.
71
- // This throws an `ERR_MODULE_NOT_FOUND` error above,
72
- // and when we try to `require` it here, it throws an `ERR_REQUIRE_ESM`.
73
- // What we want to do is throw the original error (the `ERR_MODULE_NOT_FOUND`),
74
- // and not the `ERR_REQUIRE_ESM` error, which is a red herring.
75
- //
76
- // SyntaxError happens when in an edge case: when we're using an ESM loader that loads
77
- // a `test.ts` file (i.e. unrecognized extension), and that file includes an unknown
78
- // import (which thows an ERR_MODULE_NOT_FOUND). require-ing it will throw the
79
- // syntax error, because we cannot require a file that has import-s.
80
- throw err;
81
- } else {
82
- throw requireErr;
83
- }
84
- }
85
- } else {
62
+ // ERR_REQUIRE_ESM happens when the test file is a JS file, but via type:module is actually ESM,
63
+ // AND has an import to a file that doesn't exist.
64
+ // This throws an `ERR_MODULE_NOT_FOUND` error above,
65
+ // and when we try to `require` it here, it throws an `ERR_REQUIRE_ESM`.
66
+ // What we want to do is throw the original error (the `ERR_MODULE_NOT_FOUND`),
67
+ // and not the `ERR_REQUIRE_ESM` error, which is a red herring.
68
+ //
69
+ // SyntaxError happens when in an edge case: when we're using an ESM loader that loads
70
+ // a `test.ts` file (i.e. unrecognized extension), and that file includes an unknown
71
+ // import (which throws an ERR_MODULE_NOT_FOUND). `require`-ing it will throw the
72
+ // syntax error, because we cannot require a file that has `import`-s.
86
73
  throw err;
74
+ } else {
75
+ throw requireErr;
87
76
  }
88
77
  }
78
+ } else {
79
+ throw err;
89
80
  }
90
- : implementationOfRequireOrImportForUnstableEsm;
81
+ }
82
+ };
91
83
 
92
84
  function dealWithExports(module) {
93
85
  if (module.default) {
@@ -97,28 +89,18 @@ function dealWithExports(module) {
97
89
  }
98
90
  }
99
91
 
100
- exports.loadFilesAsync = async (files, preLoadFunc, postLoadFunc) => {
92
+ exports.loadFilesAsync = async (
93
+ files,
94
+ preLoadFunc,
95
+ postLoadFunc,
96
+ esmDecorator
97
+ ) => {
101
98
  for (const file of files) {
102
99
  preLoadFunc(file);
103
- const result = await exports.requireOrImport(path.resolve(file));
100
+ const result = await exports.requireOrImport(
101
+ path.resolve(file),
102
+ esmDecorator
103
+ );
104
104
  postLoadFunc(file, result);
105
105
  }
106
106
  };
107
-
108
- /* istanbul ignore next */
109
- async function implementationOfRequireOrImportForUnstableEsm(file) {
110
- if (path.extname(file) === '.mjs') {
111
- return formattedImport(file);
112
- }
113
- // This is currently the only known way of figuring out whether a file is CJS or ESM in
114
- // Node.js that doesn't necessitate calling `import` first.
115
- try {
116
- return require(file);
117
- } catch (err) {
118
- if (err.code === 'ERR_REQUIRE_ESM') {
119
- return formattedImport(file);
120
- } else {
121
- throw err;
122
- }
123
- }
124
- }
@@ -6,7 +6,6 @@
6
6
 
7
7
  'use strict';
8
8
 
9
- const allSettled = require('@ungap/promise-all-settled').bind(Promise);
10
9
  const Runner = require('../runner');
11
10
  const {EVENT_RUN_BEGIN, EVENT_RUN_END} = Runner.constants;
12
11
  const debug = require('debug')('mocha:parallel:parallel-buffered-runner');
@@ -271,8 +270,9 @@ class ParallelBufferedRunner extends Runner {
271
270
  *
272
271
  * @param {Function} callback - Called with an exit code corresponding to
273
272
  * number of test failures.
274
- * @param {{files: string[], options: Options}} opts - Files to run and
275
- * command-line options, respectively.
273
+ * @param {Object} [opts] - options
274
+ * @param {string[]} opts.files - Files to run
275
+ * @param {Options} opts.options - command-line options
276
276
  */
277
277
  run(callback, {files, options = {}} = {}) {
278
278
  /**
@@ -321,7 +321,7 @@ class ParallelBufferedRunner extends Runner {
321
321
  delete options[opt];
322
322
  });
323
323
 
324
- const results = await allSettled(
324
+ const results = await Promise.allSettled(
325
325
  files.map(this._createFileRunner(pool, options))
326
326
  );
327
327
 
@@ -181,7 +181,7 @@ function HTML(runner, options) {
181
181
  if (indexOfMessage === -1) {
182
182
  stackString = test.err.stack;
183
183
  } else {
184
- stackString = test.err.stack.substr(
184
+ stackString = test.err.stack.slice(
185
185
  test.err.message.length + indexOfMessage
186
186
  );
187
187
  }
@@ -36,7 +36,7 @@ function JSONStream(runner, options) {
36
36
  var total = runner.total;
37
37
 
38
38
  runner.once(EVENT_RUN_BEGIN, function () {
39
- writeEvent(['start', {total: total}]);
39
+ writeEvent(['start', {total}]);
40
40
  });
41
41
 
42
42
  runner.on(EVENT_TEST_PASS, function (test) {
@@ -50,7 +50,7 @@ function Markdown(runner, options) {
50
50
  var ret = obj;
51
51
  var key = SUITE_PREFIX + suite.title;
52
52
 
53
- obj = obj[key] = obj[key] || {suite: suite};
53
+ obj = obj[key] = obj[key] || {suite};
54
54
  suite.suites.forEach(function (suite) {
55
55
  mapTOC(suite, obj);
56
56
  });
package/lib/runner.js CHANGED
@@ -135,27 +135,15 @@ class Runner extends EventEmitter {
135
135
  * @public
136
136
  * @class
137
137
  * @param {Suite} suite - Root suite
138
- * @param {Object|boolean} [opts] - Options. If `boolean` (deprecated), whether to delay execution of root suite until ready.
138
+ * @param {Object} [opts] - Settings object
139
139
  * @param {boolean} [opts.cleanReferencesAfterRun] - Whether to clean references to test fns and hooks when a suite is done.
140
140
  * @param {boolean} [opts.delay] - Whether to delay execution of root suite until ready.
141
141
  * @param {boolean} [opts.dryRun] - Whether to report tests without running them.
142
142
  * @param {boolean} [opts.failZero] - Whether to fail test run if zero tests encountered.
143
143
  */
144
- constructor(suite, opts) {
144
+ constructor(suite, opts = {}) {
145
145
  super();
146
- if (opts === undefined) {
147
- opts = {};
148
- }
149
- if (typeof opts === 'boolean') {
150
- // TODO: remove this
151
- require('./errors').deprecate(
152
- '"Runner(suite: Suite, delay: boolean)" is deprecated. Use "Runner(suite: Suite, {delay: boolean})" instead.'
153
- );
154
- this._delay = opts;
155
- opts = {};
156
- } else {
157
- this._delay = opts.delay;
158
- }
146
+
159
147
  var self = this;
160
148
  this._globals = [];
161
149
  this._abort = false;
@@ -1031,7 +1019,9 @@ Runner.prototype._uncaught = function (err) {
1031
1019
  * @public
1032
1020
  * @memberof Runner
1033
1021
  * @param {Function} fn - Callback when finished
1034
- * @param {{files: string[], options: Options}} [opts] - For subclasses
1022
+ * @param {Object} [opts] - For subclasses
1023
+ * @param {string[]} opts.files - Files to run
1024
+ * @param {Options} opts.options - command-line options
1035
1025
  * @returns {Runner} Runner instance.
1036
1026
  */
1037
1027
  Runner.prototype.run = function (fn, opts = {}) {
@@ -1064,7 +1054,7 @@ Runner.prototype.run = function (fn, opts = {}) {
1064
1054
  debug('run(): filtered exclusive Runnables');
1065
1055
  }
1066
1056
  this.state = constants.STATE_RUNNING;
1067
- if (this._delay) {
1057
+ if (this._opts.delay) {
1068
1058
  this.emit(constants.EVENT_DELAY_END);
1069
1059
  debug('run(): "delay" ended');
1070
1060
  }
@@ -1091,7 +1081,7 @@ Runner.prototype.run = function (fn, opts = {}) {
1091
1081
  this._addEventListener(process, 'uncaughtException', this.uncaught);
1092
1082
  this._addEventListener(process, 'unhandledRejection', this.unhandled);
1093
1083
 
1094
- if (this._delay) {
1084
+ if (this._opts.delay) {
1095
1085
  // for reporters, I guess.
1096
1086
  // might be nice to debounce some dots while we wait.
1097
1087
  this.emit(constants.EVENT_DELAY_BEGIN, rootSuite);
package/lib/utils.js CHANGED
@@ -76,7 +76,7 @@ exports.clean = function (str) {
76
76
  .replace(/^\uFEFF/, '')
77
77
  // (traditional)-> space/name parameters body (lambda)-> parameters body multi-statement/single keep body content
78
78
  .replace(
79
- /^function(?:\s*|\s+[^(]*)\([^)]*\)\s*\{((?:.|\n)*?)\s*\}$|^\([^)]*\)\s*=>\s*(?:\{((?:.|\n)*?)\s*\}|((?:.|\n)*))$/,
79
+ /^function(?:\s*|\s[^(]*)\([^)]*\)\s*\{((?:.|\n)*?)\}$|^\([^)]*\)\s*=>\s*(?:\{((?:.|\n)*?)\}|((?:.|\n)*))$/,
80
80
  '$1$2$3'
81
81
  );
82
82