mocha 8.2.0 → 8.3.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/CHANGELOG.md CHANGED
@@ -1,4 +1,59 @@
1
- # 8.2.0 / 2020-10-15
1
+ # 8.3.2 / 2021-03-12
2
+
3
+ ## :bug: Fixes
4
+
5
+ - [#4599](https://github.com/mochajs/mocha/issues/4599): Fix regression in `require` interface ([**@alexander-fenster**](https://github.com/alexander-fenster))
6
+
7
+ ## :book: Documentation
8
+
9
+ - [#4601](https://github.com/mochajs/mocha/issues/4601): Add build to GH actions run ([**@christian-bromann**](https://github.com/christian-bromann))
10
+ - [#4596](https://github.com/mochajs/mocha/issues/4596): Filter active sponsors/backers ([**@juergba**](https://github.com/juergba))
11
+ - [#4225](https://github.com/mochajs/mocha/issues/4225): Update config file examples ([**@pkuczynski**](https://github.com/pkuczynski))
12
+
13
+ # 8.3.1 / 2021-03-06
14
+
15
+ ## :bug: Fixes
16
+
17
+ - [#4577](https://github.com/mochajs/mocha/issues/4577): Browser: fix `EvalError` caused by regenerator-runtime ([**@snoack**](https://github.com/snoack))
18
+ - [#4574](https://github.com/mochajs/mocha/issues/4574): ESM: allow `import` from mocha in parallel mode ([**@nicojs**](https://github.com/nicojs))
19
+
20
+ # 8.3.0 / 2021-02-11
21
+
22
+ ## :tada: Enhancements
23
+
24
+ - [#4506](https://github.com/mochajs/mocha/issues/4506): Add error code for test timeout errors ([**@boneskull**](https://github.com/boneskull))
25
+ - [#4112](https://github.com/mochajs/mocha/issues/4112): Add BigInt support to stringify util function ([**@JosejeSinohui**](https://github.com/JosejeSinohui))
26
+
27
+ ## :bug: Fixes
28
+
29
+ - [#4557](https://github.com/mochajs/mocha/issues/4557): Add file location when SyntaxError happens in ESM ([**@giltayar**](https://github.com/giltayar))
30
+ - [#4521](https://github.com/mochajs/mocha/issues/4521): Fix `require` error when bundling Mocha with Webpack ([**@devhazem**](https://github.com/devhazem))
31
+
32
+ ## :book: Documentation
33
+
34
+ - [#4507](https://github.com/mochajs/mocha/issues/4507): Add support for typescript-style docstrings ([**@boneskull**](https://github.com/boneskull))
35
+ - [#4503](https://github.com/mochajs/mocha/issues/4503): Add GH Actions workflow status badge ([**@outsideris**](https://github.com/outsideris))
36
+ - [#4494](https://github.com/mochajs/mocha/issues/4494): Add example of generating tests dynamically with a closure ([**@maxwellgerber**](https://github.com/maxwellgerber))
37
+
38
+ ## :nut_and_bolt: Other
39
+
40
+ - [#4556](https://github.com/mochajs/mocha/issues/4556): Upgrade all dependencies to latest stable ([**@AviVahl**](https://github.com/AviVahl))
41
+ - [#4543](https://github.com/mochajs/mocha/issues/4543): Update dependencies yargs and yargs-parser ([**@juergba**](https://github.com/juergba))
42
+
43
+ Also thanks to [**@outsideris**](https://github.com/outsideris) and [**@HyunSangHan**](https://github.com/HyunSangHan) for various fixes to our website and documentation.
44
+
45
+ # 8.2.1 / 2020-11-02
46
+
47
+ Fixed stuff.
48
+
49
+ ## :bug: Fixes
50
+
51
+ - [#4489](https://github.com/mochajs/mocha/issues/4489): Fix problematic handling of otherwise-unhandled `Promise` rejections and erroneous "`done()` called twice" errors ([**@boneskull**](https://github.com/boneskull))
52
+ - [#4496](https://github.com/mochajs/mocha/issues/4496): Avoid `MaxListenersExceededWarning` in watch mode ([**@boneskull**](https://github.com/boneskull))
53
+
54
+ Also thanks to [**@akeating**](https://github.com/akeating) for a documentation fix!
55
+
56
+ # 8.2.0 / 2020-10-16
2
57
 
3
58
  The major feature added in v8.2.0 is addition of support for [_global fixtures_](https://mochajs.org/#global-fixtures).
4
59
 
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
  /**
@@ -41,6 +41,9 @@ exports.watchParallelRun = (
41
41
  // I don't know why we're cloning the root suite.
42
42
  const rootSuite = mocha.suite.clone();
43
43
 
44
+ // ensure we aren't leaking event listeners
45
+ mocha.dispose();
46
+
44
47
  // this `require` is needed because the require cache has been cleared. the dynamic
45
48
  // exports set via the below call to `mocha.ui()` won't work properly if a
46
49
  // test depends on this module (see `required-tokens.spec.js`).
@@ -100,6 +103,9 @@ exports.watchRun = (mocha, {watchFiles, watchIgnore}, fileCollectParams) => {
100
103
  // I don't know why we're cloning the root suite.
101
104
  const rootSuite = mocha.suite.clone();
102
105
 
106
+ // ensure we aren't leaking event listeners
107
+ mocha.dispose();
108
+
103
109
  // this `require` is needed because the require cache has been cleared. the dynamic
104
110
  // exports set via the below call to `mocha.ui()` won't work properly if a
105
111
  // test depends on this module (see `required-tokens.spec.js`).
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,86 +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
158
+ */
159
+ INVALID_PLUGIN_DEFINITION: 'ERR_MOCHA_INVALID_PLUGIN_DEFINITION',
160
+
161
+ /**
162
+ * When a runnable exceeds its allowed run time.
163
+ * @constant
164
+ * @default
128
165
  */
129
- INVALID_PLUGIN_DEFINITION: 'ERR_MOCHA_INVALID_PLUGIN_DEFINITION'
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
+ */
173
+ const MOCHA_ERRORS = new Set(Object.values(constants));
174
+
132
175
  /**
133
176
  * Creates an error object to be thrown when no files to be tested could be found using specified pattern.
134
177
  *
135
178
  * @public
179
+ * @static
136
180
  * @param {string} message - Error message to be displayed.
137
181
  * @param {string} pattern - User-specified argument value.
138
182
  * @returns {Error} instance detailing the error condition
@@ -163,6 +207,7 @@ function createInvalidReporterError(message, reporter) {
163
207
  * Creates an error object to be thrown when the interface specified in the options was not found.
164
208
  *
165
209
  * @public
210
+ * @static
166
211
  * @param {string} message - Error message to be displayed.
167
212
  * @param {string} ui - User-specified interface value.
168
213
  * @returns {Error} instance detailing the error condition
@@ -178,6 +223,7 @@ function createInvalidInterfaceError(message, ui) {
178
223
  * Creates an error object to be thrown when a behavior, option, or parameter is unsupported.
179
224
  *
180
225
  * @public
226
+ * @static
181
227
  * @param {string} message - Error message to be displayed.
182
228
  * @returns {Error} instance detailing the error condition
183
229
  */
@@ -191,6 +237,7 @@ function createUnsupportedError(message) {
191
237
  * Creates an error object to be thrown when an argument is missing.
192
238
  *
193
239
  * @public
240
+ * @static
194
241
  * @param {string} message - Error message to be displayed.
195
242
  * @param {string} argument - Argument name.
196
243
  * @param {string} expected - Expected argument datatype.
@@ -204,6 +251,7 @@ function createMissingArgumentError(message, argument, expected) {
204
251
  * Creates an error object to be thrown when an argument did not use the supported type
205
252
  *
206
253
  * @public
254
+ * @static
207
255
  * @param {string} message - Error message to be displayed.
208
256
  * @param {string} argument - Argument name.
209
257
  * @param {string} expected - Expected argument datatype.
@@ -222,6 +270,7 @@ function createInvalidArgumentTypeError(message, argument, expected) {
222
270
  * Creates an error object to be thrown when an argument did not use the supported value
223
271
  *
224
272
  * @public
273
+ * @static
225
274
  * @param {string} message - Error message to be displayed.
226
275
  * @param {string} argument - Argument name.
227
276
  * @param {string} value - Argument value.
@@ -241,6 +290,7 @@ function createInvalidArgumentValueError(message, argument, value, reason) {
241
290
  * Creates an error object to be thrown when an exception was caught, but the `Error` is falsy or undefined.
242
291
  *
243
292
  * @public
293
+ * @static
244
294
  * @param {string} message - Error message to be displayed.
245
295
  * @returns {Error} instance detailing the error condition
246
296
  */
@@ -256,6 +306,7 @@ function createInvalidExceptionError(message, value) {
256
306
  * Creates an error object to be thrown when an unrecoverable error occurs.
257
307
  *
258
308
  * @public
309
+ * @static
259
310
  * @param {string} message - Error message to be displayed.
260
311
  * @returns {Error} instance detailing the error condition
261
312
  */
@@ -274,6 +325,7 @@ function createFatalError(message, value) {
274
325
  * @param {string} [pluginId] - Name/path of plugin, if any
275
326
  * @throws When `pluginType` is not known
276
327
  * @public
328
+ * @static
277
329
  * @returns {Error}
278
330
  */
279
331
  function createInvalidLegacyPluginError(message, pluginType, pluginId) {
@@ -295,6 +347,7 @@ function createInvalidLegacyPluginError(message, pluginType, pluginId) {
295
347
  * @param {string} [pluginId] - Name/path of plugin, if any
296
348
  * @throws When `pluginType` is not known
297
349
  * @public
350
+ * @static
298
351
  * @returns {Error}
299
352
  */
300
353
  function createInvalidPluginError(...args) {
@@ -307,6 +360,7 @@ function createInvalidPluginError(...args) {
307
360
  * @param {string} message The error message to be displayed.
308
361
  * @param {boolean} cleanReferencesAfterRun the value of `cleanReferencesAfterRun`
309
362
  * @param {Mocha} instance the mocha instance that throw this error
363
+ * @static
310
364
  */
311
365
  function createMochaInstanceAlreadyDisposedError(
312
366
  message,
@@ -323,6 +377,8 @@ function createMochaInstanceAlreadyDisposedError(
323
377
  /**
324
378
  * Creates an error object to be thrown when a mocha object's `run` method is called while a test run is in progress.
325
379
  * @param {string} message The error message to be displayed.
380
+ * @static
381
+ * @public
326
382
  */
327
383
  function createMochaInstanceAlreadyRunningError(message, instance) {
328
384
  var err = new Error(message);
@@ -331,13 +387,14 @@ function createMochaInstanceAlreadyRunningError(message, instance) {
331
387
  return err;
332
388
  }
333
389
 
334
- /*
390
+ /**
335
391
  * Creates an error object to be thrown when done() is called multiple times in a test
336
392
  *
337
393
  * @public
338
394
  * @param {Runnable} runnable - Original runnable
339
395
  * @param {Error} [originalErr] - Original error, if any
340
396
  * @returns {Error} instance detailing the error condition
397
+ * @static
341
398
  */
342
399
  function createMultipleDoneError(runnable, originalErr) {
343
400
  var title;
@@ -371,6 +428,7 @@ function createMultipleDoneError(runnable, originalErr) {
371
428
  /**
372
429
  * Creates an error object to be thrown when `.only()` is used with
373
430
  * `--forbid-only`.
431
+ * @static
374
432
  * @public
375
433
  * @param {Mocha} mocha - Mocha instance
376
434
  * @returns {Error} Error with code {@link constants.FORBIDDEN_EXCLUSIVITY}
@@ -387,6 +445,7 @@ function createForbiddenExclusivityError(mocha) {
387
445
 
388
446
  /**
389
447
  * Creates an error object to be thrown when a plugin definition is invalid
448
+ * @static
390
449
  * @param {string} msg - Error message
391
450
  * @param {PluginDefinition} [pluginDef] - Problematic plugin definition
392
451
  * @public
@@ -401,6 +460,7 @@ function createInvalidPluginDefinitionError(msg, pluginDef) {
401
460
 
402
461
  /**
403
462
  * Creates an error object to be thrown when a plugin implementation (user code) is invalid
463
+ * @static
404
464
  * @param {string} msg - Error message
405
465
  * @param {Object} [opts] - Plugin definition and user-supplied implementation
406
466
  * @param {PluginDefinition} [opts.pluginDef] - Plugin Definition
@@ -419,6 +479,33 @@ function createInvalidPluginImplementationError(
419
479
  return err;
420
480
  }
421
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
+
498
+ /**
499
+ * Returns `true` if an error came out of Mocha.
500
+ * _Can suffer from false negatives, but not false positives._
501
+ * @static
502
+ * @public
503
+ * @param {*} err - Error, or anything
504
+ * @returns {boolean}
505
+ */
506
+ const isMochaError = err =>
507
+ Boolean(err && typeof err === 'object' && MOCHA_ERRORS.has(err.code));
508
+
422
509
  module.exports = {
423
510
  constants,
424
511
  createFatalError,
@@ -437,7 +524,18 @@ module.exports = {
437
524
  createMochaInstanceAlreadyRunningError,
438
525
  createMultipleDoneError,
439
526
  createNoFilesMatchPatternError,
527
+ createTimeoutError,
440
528
  createUnsupportedError,
441
529
  deprecate,
530
+ isMochaError,
442
531
  warn
443
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
  };