mocha 7.0.1 → 7.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.
- package/CHANGELOG.md +86 -2
- package/bin/mocha +7 -2
- package/browser-entry.js +13 -2
- package/lib/cli/cli.js +4 -1
- package/lib/cli/collect-files.js +2 -1
- package/lib/cli/config.js +8 -6
- package/lib/cli/options.js +4 -4
- package/lib/cli/run-helpers.js +93 -33
- package/lib/cli/run.js +23 -5
- package/lib/errors.js +179 -9
- package/lib/esm-utils.js +31 -0
- package/lib/hook.js +8 -0
- package/lib/interfaces/common.js +6 -3
- package/lib/mocha.js +226 -16
- package/lib/mocharc.json +1 -1
- package/lib/reporters/doc.js +6 -0
- package/lib/reporters/json-stream.js +1 -0
- package/lib/reporters/json.js +1 -0
- package/lib/reporters/landing.js +8 -0
- package/lib/runnable.js +21 -42
- package/lib/runner.js +173 -63
- package/lib/suite.js +29 -3
- package/lib/test.js +33 -2
- package/lib/utils.js +36 -35
- package/mocha.js +749 -185
- package/package.json +56 -549
package/lib/errors.js
CHANGED
|
@@ -1,10 +1,73 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
+
|
|
3
|
+
var format = require('util').format;
|
|
4
|
+
|
|
2
5
|
/**
|
|
6
|
+
* Factory functions to create throwable error objects
|
|
3
7
|
* @module Errors
|
|
4
8
|
*/
|
|
9
|
+
|
|
5
10
|
/**
|
|
6
|
-
*
|
|
11
|
+
* When Mocha throw exceptions (or otherwise errors), it attempts to assign a
|
|
12
|
+
* `code` property to the `Error` object, for easier handling. These are the
|
|
13
|
+
* potential values of `code`.
|
|
7
14
|
*/
|
|
15
|
+
var constants = {
|
|
16
|
+
/**
|
|
17
|
+
* An unrecoverable error.
|
|
18
|
+
*/
|
|
19
|
+
FATAL: 'ERR_MOCHA_FATAL',
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The type of an argument to a function call is invalid
|
|
23
|
+
*/
|
|
24
|
+
INVALID_ARG_TYPE: 'ERR_MOCHA_INVALID_ARG_TYPE',
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* The value of an argument to a function call is invalid
|
|
28
|
+
*/
|
|
29
|
+
INVALID_ARG_VALUE: 'ERR_MOCHA_INVALID_ARG_VALUE',
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Something was thrown, but it wasn't an `Error`
|
|
33
|
+
*/
|
|
34
|
+
INVALID_EXCEPTION: 'ERR_MOCHA_INVALID_EXCEPTION',
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* An interface (e.g., `Mocha.interfaces`) is unknown or invalid
|
|
38
|
+
*/
|
|
39
|
+
INVALID_INTERFACE: 'ERR_MOCHA_INVALID_INTERFACE',
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* A reporter (.e.g, `Mocha.reporters`) is unknown or invalid
|
|
43
|
+
*/
|
|
44
|
+
INVALID_REPORTER: 'ERR_MOCHA_INVALID_REPORTER',
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* `done()` was called twice in a `Test` or `Hook` callback
|
|
48
|
+
*/
|
|
49
|
+
MULTIPLE_DONE: 'ERR_MOCHA_MULTIPLE_DONE',
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* No files matched the pattern provided by the user
|
|
53
|
+
*/
|
|
54
|
+
NO_FILES_MATCH_PATTERN: 'ERR_MOCHA_NO_FILES_MATCH_PATTERN',
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Known, but unsupported behavior of some kind
|
|
58
|
+
*/
|
|
59
|
+
UNSUPPORTED: 'ERR_MOCHA_UNSUPPORTED',
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Invalid state transition occuring in `Mocha` instance
|
|
63
|
+
*/
|
|
64
|
+
INSTANCE_ALREADY_RUNNING: 'ERR_MOCHA_INSTANCE_ALREADY_RUNNING',
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Invalid state transition occuring in `Mocha` instance
|
|
68
|
+
*/
|
|
69
|
+
INSTANCE_ALREADY_DISPOSED: 'ERR_MOCHA_INSTANCE_ALREADY_DISPOSED'
|
|
70
|
+
};
|
|
8
71
|
|
|
9
72
|
/**
|
|
10
73
|
* Creates an error object to be thrown when no files to be tested could be found using specified pattern.
|
|
@@ -16,7 +79,7 @@
|
|
|
16
79
|
*/
|
|
17
80
|
function createNoFilesMatchPatternError(message, pattern) {
|
|
18
81
|
var err = new Error(message);
|
|
19
|
-
err.code =
|
|
82
|
+
err.code = constants.NO_FILES_MATCH_PATTERN;
|
|
20
83
|
err.pattern = pattern;
|
|
21
84
|
return err;
|
|
22
85
|
}
|
|
@@ -31,7 +94,7 @@ function createNoFilesMatchPatternError(message, pattern) {
|
|
|
31
94
|
*/
|
|
32
95
|
function createInvalidReporterError(message, reporter) {
|
|
33
96
|
var err = new TypeError(message);
|
|
34
|
-
err.code =
|
|
97
|
+
err.code = constants.INVALID_REPORTER;
|
|
35
98
|
err.reporter = reporter;
|
|
36
99
|
return err;
|
|
37
100
|
}
|
|
@@ -46,7 +109,7 @@ function createInvalidReporterError(message, reporter) {
|
|
|
46
109
|
*/
|
|
47
110
|
function createInvalidInterfaceError(message, ui) {
|
|
48
111
|
var err = new Error(message);
|
|
49
|
-
err.code =
|
|
112
|
+
err.code = constants.INVALID_INTERFACE;
|
|
50
113
|
err.interface = ui;
|
|
51
114
|
return err;
|
|
52
115
|
}
|
|
@@ -60,7 +123,7 @@ function createInvalidInterfaceError(message, ui) {
|
|
|
60
123
|
*/
|
|
61
124
|
function createUnsupportedError(message) {
|
|
62
125
|
var err = new Error(message);
|
|
63
|
-
err.code =
|
|
126
|
+
err.code = constants.UNSUPPORTED;
|
|
64
127
|
return err;
|
|
65
128
|
}
|
|
66
129
|
|
|
@@ -88,7 +151,7 @@ function createMissingArgumentError(message, argument, expected) {
|
|
|
88
151
|
*/
|
|
89
152
|
function createInvalidArgumentTypeError(message, argument, expected) {
|
|
90
153
|
var err = new TypeError(message);
|
|
91
|
-
err.code =
|
|
154
|
+
err.code = constants.INVALID_ARG_TYPE;
|
|
92
155
|
err.argument = argument;
|
|
93
156
|
err.expected = expected;
|
|
94
157
|
err.actual = typeof argument;
|
|
@@ -107,7 +170,7 @@ function createInvalidArgumentTypeError(message, argument, expected) {
|
|
|
107
170
|
*/
|
|
108
171
|
function createInvalidArgumentValueError(message, argument, value, reason) {
|
|
109
172
|
var err = new TypeError(message);
|
|
110
|
-
err.code =
|
|
173
|
+
err.code = constants.INVALID_ARG_VALUE;
|
|
111
174
|
err.argument = argument;
|
|
112
175
|
err.value = value;
|
|
113
176
|
err.reason = typeof reason !== 'undefined' ? reason : 'is invalid';
|
|
@@ -123,12 +186,113 @@ function createInvalidArgumentValueError(message, argument, value, reason) {
|
|
|
123
186
|
*/
|
|
124
187
|
function createInvalidExceptionError(message, value) {
|
|
125
188
|
var err = new Error(message);
|
|
126
|
-
err.code =
|
|
189
|
+
err.code = constants.INVALID_EXCEPTION;
|
|
190
|
+
err.valueType = typeof value;
|
|
191
|
+
err.value = value;
|
|
192
|
+
return err;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Creates an error object to be thrown when an unrecoverable error occurs.
|
|
197
|
+
*
|
|
198
|
+
* @public
|
|
199
|
+
* @param {string} message - Error message to be displayed.
|
|
200
|
+
* @returns {Error} instance detailing the error condition
|
|
201
|
+
*/
|
|
202
|
+
function createFatalError(message, value) {
|
|
203
|
+
var err = new Error(message);
|
|
204
|
+
err.code = constants.FATAL;
|
|
127
205
|
err.valueType = typeof value;
|
|
128
206
|
err.value = value;
|
|
129
207
|
return err;
|
|
130
208
|
}
|
|
131
209
|
|
|
210
|
+
/**
|
|
211
|
+
* Dynamically creates a plugin-type-specific error based on plugin type
|
|
212
|
+
* @param {string} message - Error message
|
|
213
|
+
* @param {"reporter"|"interface"} pluginType - Plugin type. Future: expand as needed
|
|
214
|
+
* @param {string} [pluginId] - Name/path of plugin, if any
|
|
215
|
+
* @throws When `pluginType` is not known
|
|
216
|
+
* @public
|
|
217
|
+
* @returns {Error}
|
|
218
|
+
*/
|
|
219
|
+
function createInvalidPluginError(message, pluginType, pluginId) {
|
|
220
|
+
switch (pluginType) {
|
|
221
|
+
case 'reporter':
|
|
222
|
+
return createInvalidReporterError(message, pluginId);
|
|
223
|
+
case 'interface':
|
|
224
|
+
return createInvalidInterfaceError(message, pluginId);
|
|
225
|
+
default:
|
|
226
|
+
throw new Error('unknown pluginType "' + pluginType + '"');
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Creates an error object to be thrown when a mocha object's `run` method is executed while it is already disposed.
|
|
232
|
+
* @param {string} message The error message to be displayed.
|
|
233
|
+
* @param {boolean} cleanReferencesAfterRun the value of `cleanReferencesAfterRun`
|
|
234
|
+
* @param {Mocha} instance the mocha instance that throw this error
|
|
235
|
+
*/
|
|
236
|
+
function createMochaInstanceAlreadyDisposedError(
|
|
237
|
+
message,
|
|
238
|
+
cleanReferencesAfterRun,
|
|
239
|
+
instance
|
|
240
|
+
) {
|
|
241
|
+
var err = new Error(message);
|
|
242
|
+
err.code = constants.INSTANCE_ALREADY_DISPOSED;
|
|
243
|
+
err.cleanReferencesAfterRun = cleanReferencesAfterRun;
|
|
244
|
+
err.instance = instance;
|
|
245
|
+
return err;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Creates an error object to be thrown when a mocha object's `run` method is called while a test run is in progress.
|
|
250
|
+
* @param {string} message The error message to be displayed.
|
|
251
|
+
*/
|
|
252
|
+
function createMochaInstanceAlreadyRunningError(message, instance) {
|
|
253
|
+
var err = new Error(message);
|
|
254
|
+
err.code = constants.INSTANCE_ALREADY_RUNNING;
|
|
255
|
+
err.instance = instance;
|
|
256
|
+
return err;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/*
|
|
260
|
+
* Creates an error object to be thrown when done() is called multiple times in a test
|
|
261
|
+
*
|
|
262
|
+
* @public
|
|
263
|
+
* @param {Runnable} runnable - Original runnable
|
|
264
|
+
* @param {Error} [originalErr] - Original error, if any
|
|
265
|
+
* @returns {Error} instance detailing the error condition
|
|
266
|
+
*/
|
|
267
|
+
function createMultipleDoneError(runnable, originalErr) {
|
|
268
|
+
var title;
|
|
269
|
+
try {
|
|
270
|
+
title = format('<%s>', runnable.fullTitle());
|
|
271
|
+
if (runnable.parent.root) {
|
|
272
|
+
title += ' (of root suite)';
|
|
273
|
+
}
|
|
274
|
+
} catch (ignored) {
|
|
275
|
+
title = format('<%s> (of unknown suite)', runnable.title);
|
|
276
|
+
}
|
|
277
|
+
var message = format(
|
|
278
|
+
'done() called multiple times in %s %s',
|
|
279
|
+
runnable.type ? runnable.type : 'unknown runnable',
|
|
280
|
+
title
|
|
281
|
+
);
|
|
282
|
+
if (runnable.file) {
|
|
283
|
+
message += format(' of file %s', runnable.file);
|
|
284
|
+
}
|
|
285
|
+
if (originalErr) {
|
|
286
|
+
message += format('; in addition, done() received error: %s', originalErr);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
var err = new Error(message);
|
|
290
|
+
err.code = constants.MULTIPLE_DONE;
|
|
291
|
+
err.valueType = typeof originalErr;
|
|
292
|
+
err.value = originalErr;
|
|
293
|
+
return err;
|
|
294
|
+
}
|
|
295
|
+
|
|
132
296
|
module.exports = {
|
|
133
297
|
createInvalidArgumentTypeError: createInvalidArgumentTypeError,
|
|
134
298
|
createInvalidArgumentValueError: createInvalidArgumentValueError,
|
|
@@ -137,5 +301,11 @@ module.exports = {
|
|
|
137
301
|
createInvalidReporterError: createInvalidReporterError,
|
|
138
302
|
createMissingArgumentError: createMissingArgumentError,
|
|
139
303
|
createNoFilesMatchPatternError: createNoFilesMatchPatternError,
|
|
140
|
-
createUnsupportedError: createUnsupportedError
|
|
304
|
+
createUnsupportedError: createUnsupportedError,
|
|
305
|
+
createInvalidPluginError: createInvalidPluginError,
|
|
306
|
+
createMochaInstanceAlreadyDisposedError: createMochaInstanceAlreadyDisposedError,
|
|
307
|
+
createMochaInstanceAlreadyRunningError: createMochaInstanceAlreadyRunningError,
|
|
308
|
+
createFatalError: createFatalError,
|
|
309
|
+
createMultipleDoneError: createMultipleDoneError,
|
|
310
|
+
constants: constants
|
|
141
311
|
};
|
package/lib/esm-utils.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const url = require('url');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const requireOrImport = async file => {
|
|
5
|
+
file = path.resolve(file);
|
|
6
|
+
|
|
7
|
+
if (path.extname(file) === '.mjs') {
|
|
8
|
+
return import(url.pathToFileURL(file));
|
|
9
|
+
}
|
|
10
|
+
// This is currently the only known way of figuring out whether a file is CJS or ESM.
|
|
11
|
+
// If Node.js or the community establish a better procedure for that, we can fix this code.
|
|
12
|
+
// Another option here would be to always use `import()`, as this also supports CJS, but I would be
|
|
13
|
+
// wary of using it for _all_ existing test files, till ESM is fully stable.
|
|
14
|
+
try {
|
|
15
|
+
return require(file);
|
|
16
|
+
} catch (err) {
|
|
17
|
+
if (err.code === 'ERR_REQUIRE_ESM') {
|
|
18
|
+
return import(url.pathToFileURL(file));
|
|
19
|
+
} else {
|
|
20
|
+
throw err;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
exports.loadFilesAsync = async (files, preLoadFunc, postLoadFunc) => {
|
|
26
|
+
for (const file of files) {
|
|
27
|
+
preLoadFunc(file);
|
|
28
|
+
const result = await requireOrImport(file);
|
|
29
|
+
postLoadFunc(file, result);
|
|
30
|
+
}
|
|
31
|
+
};
|
package/lib/hook.js
CHANGED
|
@@ -27,6 +27,14 @@ function Hook(title, fn) {
|
|
|
27
27
|
*/
|
|
28
28
|
inherits(Hook, Runnable);
|
|
29
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Resets the state for a next run.
|
|
32
|
+
*/
|
|
33
|
+
Hook.prototype.reset = function() {
|
|
34
|
+
Runnable.prototype.reset.call(this);
|
|
35
|
+
delete this._error;
|
|
36
|
+
};
|
|
37
|
+
|
|
30
38
|
/**
|
|
31
39
|
* Get or set the test `err`.
|
|
32
40
|
*
|
package/lib/interfaces/common.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
var Suite = require('../suite');
|
|
4
4
|
var errors = require('../errors');
|
|
5
5
|
var createMissingArgumentError = errors.createMissingArgumentError;
|
|
6
|
+
var createUnsupportedError = errors.createUnsupportedError;
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Functions common to more than one interface.
|
|
@@ -126,14 +127,14 @@ module.exports = function(suites, context, mocha) {
|
|
|
126
127
|
suites.unshift(suite);
|
|
127
128
|
if (opts.isOnly) {
|
|
128
129
|
if (mocha.options.forbidOnly && shouldBeTested(suite)) {
|
|
129
|
-
throw
|
|
130
|
+
throw createUnsupportedError('`.only` forbidden');
|
|
130
131
|
}
|
|
131
132
|
|
|
132
133
|
suite.parent.appendOnlySuite(suite);
|
|
133
134
|
}
|
|
134
135
|
if (suite.pending) {
|
|
135
136
|
if (mocha.options.forbidPending && shouldBeTested(suite)) {
|
|
136
|
-
throw
|
|
137
|
+
throw createUnsupportedError('Pending test forbidden');
|
|
137
138
|
}
|
|
138
139
|
}
|
|
139
140
|
if (typeof opts.fn === 'function') {
|
|
@@ -165,7 +166,9 @@ module.exports = function(suites, context, mocha) {
|
|
|
165
166
|
* @returns {*}
|
|
166
167
|
*/
|
|
167
168
|
only: function(mocha, test) {
|
|
168
|
-
|
|
169
|
+
if (mocha.options.forbidOnly)
|
|
170
|
+
throw createUnsupportedError('`.only` forbidden');
|
|
171
|
+
test.markOnly();
|
|
169
172
|
return test;
|
|
170
173
|
},
|
|
171
174
|
|