mocha 8.2.1 → 8.3.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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,28 @@
1
+ # 8.3.0 / 2021-02-11
2
+
3
+ ## :tada: Enhancements
4
+
5
+ - [#4506](https://github.com/mochajs/mocha/issues/4506): Add error code for test timeout errors ([**@boneskull**](https://github.com/boneskull))
6
+ - [#4112](https://github.com/mochajs/mocha/issues/4112): Add BigInt support to stringify util function ([**@JosejeSinohui**](https://github.com/JosejeSinohui))
7
+
8
+ ## :bug: Fixes
9
+
10
+ - [#4557](https://github.com/mochajs/mocha/issues/4557): Add file location when SyntaxError happens in ESM ([**@giltayar**](https://github.com/giltayar))
11
+ - [#4521](https://github.com/mochajs/mocha/issues/4521): Fix `require` error when bundling Mocha with Webpack ([**@devhazem**](https://github.com/devhazem))
12
+
13
+ ## :book: Documentation
14
+
15
+ - [#4507](https://github.com/mochajs/mocha/issues/4507): Add support for typescript-style docstrings ([**@boneskull**](https://github.com/boneskull))
16
+ - [#4503](https://github.com/mochajs/mocha/issues/4503): Add GH Actions workflow status badge ([**@outsideris**](https://github.com/outsideris))
17
+ - [#4494](https://github.com/mochajs/mocha/issues/4494): Add example of generating tests dynamically with a closure ([**@maxwellgerber**](https://github.com/maxwellgerber))
18
+
19
+ ## :nut_and_bolt: Other
20
+
21
+ - [#4556](https://github.com/mochajs/mocha/issues/4556): Upgrade all dependencies to latest stable ([**@AviVahl**](https://github.com/AviVahl))
22
+ - [#4543](https://github.com/mochajs/mocha/issues/4543): Update dependencies yargs and yargs-parser ([**@juergba**](https://github.com/juergba))
23
+
24
+ Also thanks to [**@outsideris**](https://github.com/outsideris) and [**@HyunSangHan**](https://github.com/HyunSangHan) for various fixes to our website and documentation.
25
+
1
26
  # 8.2.1 / 2020-11-02
2
27
 
3
28
  Fixed stuff.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  (The MIT License)
2
2
 
3
- Copyright (c) 2011-2020 OpenJS Foundation and contributors, https://openjsf.org
3
+ Copyright (c) 2011-2021 OpenJS Foundation and contributors, https://openjsf.org
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining
6
6
  a copy of this software and associated documentation files (the
package/README.md CHANGED
@@ -4,10 +4,19 @@
4
4
 
5
5
  <p align="center">☕️ Simple, flexible, fun JavaScript test framework for Node.js & The Browser ☕️</p>
6
6
 
7
- <p align="center"><a href="http://travis-ci.org/mochajs/mocha"><img src="https://api.travis-ci.org/mochajs/mocha.svg?branch=master" alt="Build Status"></a> <a href="https://coveralls.io/github/mochajs/mocha"><img src="https://coveralls.io/repos/github/mochajs/mocha/badge.svg" alt="Coverage Status"></a> <a href="https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fmochajs%2Fmocha?ref=badge_shield"><img src="https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fmochajs%2Fmocha.svg?type=shield" alt="FOSSA Status"></a> <a href="https://gitter.im/mochajs/mocha?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"><img src="https://badges.gitter.im/Join%20Chat.svg" alt="Gitter"></a> <a href="https://github.com/mochajs/mocha#backers"><img src="https://opencollective.com/mochajs/backers/badge.svg" alt="OpenCollective"></a> <a href="https://github.com/mochajs/mocha#sponsors"><img src="https://opencollective.com/mochajs/sponsors/badge.svg" alt="OpenCollective"></a>
7
+ <p align="center">
8
+ <a href="https://github.com/mochajs/mocha/actions?query=workflow%3ATests+branch%3Amaster"><img src="https://github.com/mochajs/mocha/workflows/Tests/badge.svg?branch=master" alt="GitHub Actions Build Status"></a>
9
+ <a href="https://coveralls.io/github/mochajs/mocha"><img src="https://coveralls.io/repos/github/mochajs/mocha/badge.svg" alt="Coverage Status"></a>
10
+ <a href="https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fmochajs%2Fmocha?ref=badge_shield"><img src="https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fmochajs%2Fmocha.svg?type=shield" alt="FOSSA Status"></a>
11
+ <a href="https://gitter.im/mochajs/mocha?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"><img src="https://badges.gitter.im/Join%20Chat.svg" alt="Gitter"></a>
12
+ <a href="https://github.com/mochajs/mocha#backers"><img src="https://opencollective.com/mochajs/backers/badge.svg" alt="OpenCollective"></a>
13
+ <a href="https://github.com/mochajs/mocha#sponsors"><img src="https://opencollective.com/mochajs/sponsors/badge.svg" alt="OpenCollective"></a>
8
14
  </p>
9
15
 
10
- <p align="center"><a href="https://www.npmjs.com/package/mocha"><img src="https://img.shields.io/npm/v/mocha.svg" alt="NPM Version"></a> <a href="https://github.com/mochajs/mocha"><img src="https://img.shields.io/node/v/mocha.svg" alt="Node Version"></a></p>
16
+ <p align="center">
17
+ <a href="https://www.npmjs.com/package/mocha"><img src="https://img.shields.io/npm/v/mocha.svg" alt="NPM Version"></a>
18
+ <a href="https://github.com/mochajs/mocha"><img src="https://img.shields.io/node/v/mocha.svg" alt="Node Version"></a>
19
+ </p>
11
20
 
12
21
  <p align="center"><br><img alt="Mocha Browser Support h/t SauceLabs" src="https://saucelabs.com/browser-matrix/mochajs.svg" width="354"></p>
13
22
 
@@ -102,6 +111,6 @@ Finally, come [chat with the maintainers](https://gitter.im/mochajs/contributors
102
111
 
103
112
  ## License
104
113
 
105
- Copyright 2011-2020 OpenJS Foundation and contributors. Licensed [MIT](https://github.com/mochajs/mocha/blob/master/LICENSE).
114
+ Copyright 2011-2021 OpenJS Foundation and contributors. Licensed [MIT](https://github.com/mochajs/mocha/blob/master/LICENSE).
106
115
 
107
116
  [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fmochajs%2Fmocha.svg?type=large)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fmochajs%2Fmocha?ref=badge_large)
package/bin/mocha CHANGED
@@ -36,8 +36,6 @@ const disableTimeouts = value => {
36
36
  if (impliesNoTimeouts(value)) {
37
37
  debug('option %s disabled timeouts', value);
38
38
  mochaArgs.timeout = 0;
39
- delete mochaArgs.timeouts;
40
- delete mochaArgs.t;
41
39
  }
42
40
  };
43
41
 
@@ -93,7 +91,6 @@ if (mochaArgs.require && mochaArgs.require.includes('esm')) {
93
91
  if (!mochaArgs.require.length) {
94
92
  delete mochaArgs.require;
95
93
  }
96
- delete mochaArgs.r;
97
94
  }
98
95
 
99
96
  if (Object.keys(nodeArgs).length) {
@@ -125,7 +125,7 @@ function display(runner) {
125
125
  cross: '\u274C',
126
126
  tick: '\u2705'
127
127
  };
128
- var logo = require('../../package').notifyLogo;
128
+ var logo = require('../../package.json').notifyLogo;
129
129
  var _message;
130
130
  var message;
131
131
  var title;
@@ -6,6 +6,7 @@ const debug = require('debug')('mocha:cli:run:helpers');
6
6
  const minimatch = require('minimatch');
7
7
  const {NO_FILES_MATCH_PATTERN} = require('../errors').constants;
8
8
  const lookupFiles = require('./lookup-files');
9
+ const {castArray} = require('../utils');
9
10
 
10
11
  /**
11
12
  * Exports a function that collects test files from CLI parameters.
@@ -21,45 +22,44 @@ const lookupFiles = require('./lookup-files');
21
22
  * @returns {string[]} List of files to test
22
23
  * @private
23
24
  */
24
- module.exports = ({ignore, extension, file, recursive, sort, spec} = {}) => {
25
- let files = [];
25
+ module.exports = ({
26
+ ignore,
27
+ extension,
28
+ file: fileArgs,
29
+ recursive,
30
+ sort,
31
+ spec
32
+ } = {}) => {
26
33
  const unmatched = [];
27
- spec.forEach(arg => {
28
- let newFiles;
34
+ const specFiles = spec.reduce((specFiles, arg) => {
29
35
  try {
30
- newFiles = lookupFiles(arg, extension, recursive);
36
+ const moreSpecFiles = castArray(lookupFiles(arg, extension, recursive))
37
+ .filter(filename =>
38
+ ignore.every(pattern => !minimatch(filename, pattern))
39
+ )
40
+ .map(filename => path.resolve(filename));
41
+ return [...specFiles, ...moreSpecFiles];
31
42
  } catch (err) {
32
43
  if (err.code === NO_FILES_MATCH_PATTERN) {
33
44
  unmatched.push({message: err.message, pattern: err.pattern});
34
- return;
45
+ return specFiles;
35
46
  }
36
47
 
37
48
  throw err;
38
49
  }
39
-
40
- if (typeof newFiles !== 'undefined') {
41
- if (typeof newFiles === 'string') {
42
- newFiles = [newFiles];
43
- }
44
- newFiles = newFiles.filter(fileName =>
45
- ignore.every(pattern => !minimatch(fileName, pattern))
46
- );
47
- }
48
-
49
- files = files.concat(newFiles);
50
- });
51
-
52
- const fileArgs = file.map(filepath => path.resolve(filepath));
53
- files = files.map(filepath => path.resolve(filepath));
50
+ }, []);
54
51
 
55
52
  // ensure we don't sort the stuff from fileArgs; order is important!
56
53
  if (sort) {
57
- files.sort();
54
+ specFiles.sort();
58
55
  }
59
56
 
60
57
  // add files given through --file to be ran first
61
- files = fileArgs.concat(files);
62
- debug('files (in order): ', files);
58
+ const files = [
59
+ ...fileArgs.map(filepath => path.resolve(filepath)),
60
+ ...specFiles
61
+ ];
62
+ debug('test files (in order): ', files);
63
63
 
64
64
  if (!files.length) {
65
65
  // give full message details when only 1 file is missing
@@ -70,7 +70,7 @@ module.exports = ({ignore, extension, file, recursive, sort, spec} = {}) => {
70
70
  console.error(ansi.red(noneFoundMsg));
71
71
  process.exit(1);
72
72
  } else {
73
- // print messages as an warning
73
+ // print messages as a warning
74
74
  unmatched.forEach(warning => {
75
75
  console.warn(ansi.yellow(`Warning: ${warning.message}`));
76
76
  });
package/lib/cli/config.js CHANGED
@@ -38,8 +38,7 @@ const isModuleNotFoundError = err =>
38
38
  * returns an object (but could throw)
39
39
  */
40
40
  const parsers = (exports.parsers = {
41
- yaml: filepath =>
42
- require('js-yaml').safeLoad(fs.readFileSync(filepath, 'utf8')),
41
+ yaml: filepath => require('js-yaml').load(fs.readFileSync(filepath, 'utf8')),
43
42
  js: filepath => {
44
43
  const cwdFilepath = path.resolve(filepath);
45
44
  try {
@@ -38,7 +38,8 @@ const {isNodeFlag} = require('./node-flags');
38
38
  const YARGS_PARSER_CONFIG = {
39
39
  'combine-arrays': true,
40
40
  'short-option-groups': false,
41
- 'dot-notation': false
41
+ 'dot-notation': false,
42
+ 'strip-aliased': true
42
43
  };
43
44
 
44
45
  /**
package/lib/errors.js CHANGED
@@ -17,6 +17,7 @@ const emitWarning = (msg, type) => {
17
17
  if (process.emitWarning) {
18
18
  process.emitWarning(msg, type);
19
19
  } else {
20
+ /* istanbul ignore next */
20
21
  process.nextTick(function() {
21
22
  console.warn(type + ': ' + msg);
22
23
  });
@@ -53,88 +54,129 @@ const warn = msg => {
53
54
  };
54
55
 
55
56
  /**
56
- * When Mocha throw exceptions (or otherwise errors), it attempts to assign a
57
- * `code` property to the `Error` object, for easier handling. These are the
58
- * potential values of `code`.
57
+ * When Mocha throws exceptions (or rejects `Promise`s), it attempts to assign a `code` property to the `Error` object, for easier handling. These are the potential values of `code`.
58
+ * @public
59
+ * @namespace
60
+ * @memberof module:lib/errors
59
61
  */
60
62
  var constants = {
61
63
  /**
62
64
  * An unrecoverable error.
65
+ * @constant
66
+ * @default
63
67
  */
64
68
  FATAL: 'ERR_MOCHA_FATAL',
65
69
 
66
70
  /**
67
71
  * The type of an argument to a function call is invalid
72
+ * @constant
73
+ * @default
68
74
  */
69
75
  INVALID_ARG_TYPE: 'ERR_MOCHA_INVALID_ARG_TYPE',
70
76
 
71
77
  /**
72
78
  * The value of an argument to a function call is invalid
79
+ * @constant
80
+ * @default
73
81
  */
74
82
  INVALID_ARG_VALUE: 'ERR_MOCHA_INVALID_ARG_VALUE',
75
83
 
76
84
  /**
77
85
  * Something was thrown, but it wasn't an `Error`
86
+ * @constant
87
+ * @default
78
88
  */
79
89
  INVALID_EXCEPTION: 'ERR_MOCHA_INVALID_EXCEPTION',
80
90
 
81
91
  /**
82
92
  * An interface (e.g., `Mocha.interfaces`) is unknown or invalid
93
+ * @constant
94
+ * @default
83
95
  */
84
96
  INVALID_INTERFACE: 'ERR_MOCHA_INVALID_INTERFACE',
85
97
 
86
98
  /**
87
99
  * A reporter (.e.g, `Mocha.reporters`) is unknown or invalid
100
+ * @constant
101
+ * @default
88
102
  */
89
103
  INVALID_REPORTER: 'ERR_MOCHA_INVALID_REPORTER',
90
104
 
91
105
  /**
92
106
  * `done()` was called twice in a `Test` or `Hook` callback
107
+ * @constant
108
+ * @default
93
109
  */
94
110
  MULTIPLE_DONE: 'ERR_MOCHA_MULTIPLE_DONE',
95
111
 
96
112
  /**
97
113
  * No files matched the pattern provided by the user
114
+ * @constant
115
+ * @default
98
116
  */
99
117
  NO_FILES_MATCH_PATTERN: 'ERR_MOCHA_NO_FILES_MATCH_PATTERN',
100
118
 
101
119
  /**
102
120
  * Known, but unsupported behavior of some kind
121
+ * @constant
122
+ * @default
103
123
  */
104
124
  UNSUPPORTED: 'ERR_MOCHA_UNSUPPORTED',
105
125
 
106
126
  /**
107
127
  * Invalid state transition occurring in `Mocha` instance
128
+ * @constant
129
+ * @default
108
130
  */
109
131
  INSTANCE_ALREADY_RUNNING: 'ERR_MOCHA_INSTANCE_ALREADY_RUNNING',
110
132
 
111
133
  /**
112
134
  * Invalid state transition occurring in `Mocha` instance
135
+ * @constant
136
+ * @default
113
137
  */
114
138
  INSTANCE_ALREADY_DISPOSED: 'ERR_MOCHA_INSTANCE_ALREADY_DISPOSED',
115
139
 
116
140
  /**
117
141
  * Use of `only()` w/ `--forbid-only` results in this error.
142
+ * @constant
143
+ * @default
118
144
  */
119
145
  FORBIDDEN_EXCLUSIVITY: 'ERR_MOCHA_FORBIDDEN_EXCLUSIVITY',
120
146
 
121
147
  /**
122
148
  * To be thrown when a user-defined plugin implementation (e.g., `mochaHooks`) is invalid
149
+ * @constant
150
+ * @default
123
151
  */
124
152
  INVALID_PLUGIN_IMPLEMENTATION: 'ERR_MOCHA_INVALID_PLUGIN_IMPLEMENTATION',
125
153
 
126
154
  /**
127
155
  * To be thrown when a builtin or third-party plugin definition (the _definition_ of `mochaHooks`) is invalid
156
+ * @constant
157
+ * @default
128
158
  */
129
- INVALID_PLUGIN_DEFINITION: 'ERR_MOCHA_INVALID_PLUGIN_DEFINITION'
159
+ INVALID_PLUGIN_DEFINITION: 'ERR_MOCHA_INVALID_PLUGIN_DEFINITION',
160
+
161
+ /**
162
+ * When a runnable exceeds its allowed run time.
163
+ * @constant
164
+ * @default
165
+ */
166
+ TIMEOUT: 'ERR_MOCHA_TIMEOUT'
130
167
  };
131
168
 
169
+ /**
170
+ * A set containing all string values of all Mocha error constants, for use by {@link isMochaError}.
171
+ * @private
172
+ */
132
173
  const MOCHA_ERRORS = new Set(Object.values(constants));
133
174
 
134
175
  /**
135
176
  * Creates an error object to be thrown when no files to be tested could be found using specified pattern.
136
177
  *
137
178
  * @public
179
+ * @static
138
180
  * @param {string} message - Error message to be displayed.
139
181
  * @param {string} pattern - User-specified argument value.
140
182
  * @returns {Error} instance detailing the error condition
@@ -165,6 +207,7 @@ function createInvalidReporterError(message, reporter) {
165
207
  * Creates an error object to be thrown when the interface specified in the options was not found.
166
208
  *
167
209
  * @public
210
+ * @static
168
211
  * @param {string} message - Error message to be displayed.
169
212
  * @param {string} ui - User-specified interface value.
170
213
  * @returns {Error} instance detailing the error condition
@@ -180,6 +223,7 @@ function createInvalidInterfaceError(message, ui) {
180
223
  * Creates an error object to be thrown when a behavior, option, or parameter is unsupported.
181
224
  *
182
225
  * @public
226
+ * @static
183
227
  * @param {string} message - Error message to be displayed.
184
228
  * @returns {Error} instance detailing the error condition
185
229
  */
@@ -193,6 +237,7 @@ function createUnsupportedError(message) {
193
237
  * Creates an error object to be thrown when an argument is missing.
194
238
  *
195
239
  * @public
240
+ * @static
196
241
  * @param {string} message - Error message to be displayed.
197
242
  * @param {string} argument - Argument name.
198
243
  * @param {string} expected - Expected argument datatype.
@@ -206,6 +251,7 @@ function createMissingArgumentError(message, argument, expected) {
206
251
  * Creates an error object to be thrown when an argument did not use the supported type
207
252
  *
208
253
  * @public
254
+ * @static
209
255
  * @param {string} message - Error message to be displayed.
210
256
  * @param {string} argument - Argument name.
211
257
  * @param {string} expected - Expected argument datatype.
@@ -224,6 +270,7 @@ function createInvalidArgumentTypeError(message, argument, expected) {
224
270
  * Creates an error object to be thrown when an argument did not use the supported value
225
271
  *
226
272
  * @public
273
+ * @static
227
274
  * @param {string} message - Error message to be displayed.
228
275
  * @param {string} argument - Argument name.
229
276
  * @param {string} value - Argument value.
@@ -243,6 +290,7 @@ function createInvalidArgumentValueError(message, argument, value, reason) {
243
290
  * Creates an error object to be thrown when an exception was caught, but the `Error` is falsy or undefined.
244
291
  *
245
292
  * @public
293
+ * @static
246
294
  * @param {string} message - Error message to be displayed.
247
295
  * @returns {Error} instance detailing the error condition
248
296
  */
@@ -258,6 +306,7 @@ function createInvalidExceptionError(message, value) {
258
306
  * Creates an error object to be thrown when an unrecoverable error occurs.
259
307
  *
260
308
  * @public
309
+ * @static
261
310
  * @param {string} message - Error message to be displayed.
262
311
  * @returns {Error} instance detailing the error condition
263
312
  */
@@ -276,6 +325,7 @@ function createFatalError(message, value) {
276
325
  * @param {string} [pluginId] - Name/path of plugin, if any
277
326
  * @throws When `pluginType` is not known
278
327
  * @public
328
+ * @static
279
329
  * @returns {Error}
280
330
  */
281
331
  function createInvalidLegacyPluginError(message, pluginType, pluginId) {
@@ -297,6 +347,7 @@ function createInvalidLegacyPluginError(message, pluginType, pluginId) {
297
347
  * @param {string} [pluginId] - Name/path of plugin, if any
298
348
  * @throws When `pluginType` is not known
299
349
  * @public
350
+ * @static
300
351
  * @returns {Error}
301
352
  */
302
353
  function createInvalidPluginError(...args) {
@@ -309,6 +360,7 @@ function createInvalidPluginError(...args) {
309
360
  * @param {string} message The error message to be displayed.
310
361
  * @param {boolean} cleanReferencesAfterRun the value of `cleanReferencesAfterRun`
311
362
  * @param {Mocha} instance the mocha instance that throw this error
363
+ * @static
312
364
  */
313
365
  function createMochaInstanceAlreadyDisposedError(
314
366
  message,
@@ -325,6 +377,8 @@ function createMochaInstanceAlreadyDisposedError(
325
377
  /**
326
378
  * Creates an error object to be thrown when a mocha object's `run` method is called while a test run is in progress.
327
379
  * @param {string} message The error message to be displayed.
380
+ * @static
381
+ * @public
328
382
  */
329
383
  function createMochaInstanceAlreadyRunningError(message, instance) {
330
384
  var err = new Error(message);
@@ -333,13 +387,14 @@ function createMochaInstanceAlreadyRunningError(message, instance) {
333
387
  return err;
334
388
  }
335
389
 
336
- /*
390
+ /**
337
391
  * Creates an error object to be thrown when done() is called multiple times in a test
338
392
  *
339
393
  * @public
340
394
  * @param {Runnable} runnable - Original runnable
341
395
  * @param {Error} [originalErr] - Original error, if any
342
396
  * @returns {Error} instance detailing the error condition
397
+ * @static
343
398
  */
344
399
  function createMultipleDoneError(runnable, originalErr) {
345
400
  var title;
@@ -373,6 +428,7 @@ function createMultipleDoneError(runnable, originalErr) {
373
428
  /**
374
429
  * Creates an error object to be thrown when `.only()` is used with
375
430
  * `--forbid-only`.
431
+ * @static
376
432
  * @public
377
433
  * @param {Mocha} mocha - Mocha instance
378
434
  * @returns {Error} Error with code {@link constants.FORBIDDEN_EXCLUSIVITY}
@@ -389,6 +445,7 @@ function createForbiddenExclusivityError(mocha) {
389
445
 
390
446
  /**
391
447
  * Creates an error object to be thrown when a plugin definition is invalid
448
+ * @static
392
449
  * @param {string} msg - Error message
393
450
  * @param {PluginDefinition} [pluginDef] - Problematic plugin definition
394
451
  * @public
@@ -403,6 +460,7 @@ function createInvalidPluginDefinitionError(msg, pluginDef) {
403
460
 
404
461
  /**
405
462
  * Creates an error object to be thrown when a plugin implementation (user code) is invalid
463
+ * @static
406
464
  * @param {string} msg - Error message
407
465
  * @param {Object} [opts] - Plugin definition and user-supplied implementation
408
466
  * @param {PluginDefinition} [opts.pluginDef] - Plugin Definition
@@ -421,9 +479,26 @@ function createInvalidPluginImplementationError(
421
479
  return err;
422
480
  }
423
481
 
482
+ /**
483
+ * Creates an error object to be thrown when a runnable exceeds its allowed run time.
484
+ * @static
485
+ * @param {string} msg - Error message
486
+ * @param {number} [timeout] - Timeout in ms
487
+ * @param {string} [file] - File, if given
488
+ * @returns {MochaTimeoutError}
489
+ */
490
+ function createTimeoutError(msg, timeout, file) {
491
+ const err = new Error(msg);
492
+ err.code = constants.TIMEOUT;
493
+ err.timeout = timeout;
494
+ err.file = file;
495
+ return err;
496
+ }
497
+
424
498
  /**
425
499
  * Returns `true` if an error came out of Mocha.
426
500
  * _Can suffer from false negatives, but not false positives._
501
+ * @static
427
502
  * @public
428
503
  * @param {*} err - Error, or anything
429
504
  * @returns {boolean}
@@ -449,8 +524,18 @@ module.exports = {
449
524
  createMochaInstanceAlreadyRunningError,
450
525
  createMultipleDoneError,
451
526
  createNoFilesMatchPatternError,
527
+ createTimeoutError,
452
528
  createUnsupportedError,
453
529
  deprecate,
454
530
  isMochaError,
455
531
  warn
456
532
  };
533
+
534
+ /**
535
+ * The error thrown when a Runnable times out
536
+ * @memberof module:lib/errors
537
+ * @typedef {Error} MochaTimeoutError
538
+ * @property {constants.TIMEOUT} code - Error code
539
+ * @property {number?} timeout Timeout in ms
540
+ * @property {string?} file Filepath, if given
541
+ */
package/lib/esm-utils.js CHANGED
@@ -3,7 +3,29 @@ const url = require('url');
3
3
 
4
4
  const formattedImport = async file => {
5
5
  if (path.isAbsolute(file)) {
6
- return import(url.pathToFileURL(file));
6
+ try {
7
+ return await import(url.pathToFileURL(file));
8
+ } catch (err) {
9
+ // This is a hack created because ESM in Node.js (at least in Node v15.5.1) does not emit
10
+ // the location of the syntax error in the error thrown.
11
+ // This is problematic because the user can't see what file has the problem,
12
+ // so we add the file location to the error.
13
+ // This `if` should be removed once Node.js fixes the problem.
14
+ if (
15
+ err instanceof SyntaxError &&
16
+ err.message &&
17
+ err.stack &&
18
+ !err.stack.includes(file)
19
+ ) {
20
+ const newErrorWithFilename = new SyntaxError(err.message);
21
+ newErrorWithFilename.stack = err.stack.replace(
22
+ /^SyntaxError/,
23
+ `SyntaxError[ @${file} ]`
24
+ );
25
+ throw newErrorWithFilename;
26
+ }
27
+ throw err;
28
+ }
7
29
  }
8
30
  return import(file);
9
31
  };
package/lib/runnable.js CHANGED
@@ -5,9 +5,11 @@ var Pending = require('./pending');
5
5
  var debug = require('debug')('mocha:runnable');
6
6
  var milliseconds = require('ms');
7
7
  var utils = require('./utils');
8
- var errors = require('./errors');
9
- var createInvalidExceptionError = errors.createInvalidExceptionError;
10
- var createMultipleDoneError = errors.createMultipleDoneError;
8
+ const {
9
+ createInvalidExceptionError,
10
+ createMultipleDoneError,
11
+ createTimeoutError
12
+ } = require('./errors');
11
13
 
12
14
  /**
13
15
  * Save timer references to avoid Sinon interfering (see GH-237).
@@ -422,14 +424,11 @@ Runnable.prototype.run = function(fn) {
422
424
  * @private
423
425
  */
424
426
  Runnable.prototype._timeoutError = function(ms) {
425
- var msg =
426
- 'Timeout of ' +
427
- ms +
428
- 'ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.';
427
+ let msg = `Timeout of ${ms}ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.`;
429
428
  if (this.file) {
430
429
  msg += ' (' + this.file + ')';
431
430
  }
432
- return new Error(msg);
431
+ return createTimeoutError(msg, ms, this.file);
433
432
  };
434
433
 
435
434
  var constants = utils.defineConstants(
package/lib/utils.js CHANGED
@@ -298,6 +298,9 @@ function jsonStringify(object, spaces, depth) {
298
298
  ? '-0'
299
299
  : val.toString();
300
300
  break;
301
+ case 'bigint':
302
+ val = val.toString() + 'n';
303
+ break;
301
304
  case 'date':
302
305
  var sDate = isNaN(val.getTime()) ? val.toString() : val.toISOString();
303
306
  val = '[Date: ' + sDate + ']';