mocha-compat 3.6.4 → 10.8.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/LICENSE +1 -1
- package/README.md +61 -110
- package/bin/_mocha +10 -0
- package/bin/mocha.js +142 -0
- package/browser-entry.js +61 -22
- package/lib/browser/highlight-tags.js +39 -0
- package/lib/browser/parse-query.js +24 -0
- package/lib/{template.html → browser/template.html} +7 -5
- package/lib/cli/cli.js +89 -0
- package/lib/cli/collect-files.js +137 -0
- package/lib/cli/commands.js +14 -0
- package/lib/cli/config.js +100 -0
- package/lib/cli/index.js +3 -0
- package/lib/cli/init.js +36 -0
- package/lib/cli/lookup-files.js +150 -0
- package/lib/cli/node-flags.js +85 -0
- package/lib/cli/one-and-dones.js +69 -0
- package/lib/cli/options.js +284 -0
- package/lib/cli/run-helpers.js +304 -0
- package/lib/cli/run-option-metadata.js +116 -0
- package/lib/cli/run.js +380 -0
- package/lib/cli/watch-run.js +377 -0
- package/lib/context.js +16 -42
- package/lib/errors.js +563 -0
- package/lib/hook.js +50 -9
- package/lib/interfaces/bdd.js +28 -29
- package/lib/interfaces/common.js +56 -21
- package/lib/interfaces/exports.js +4 -7
- package/lib/interfaces/qunit.js +10 -11
- package/lib/interfaces/tdd.js +15 -15
- package/lib/mocha.js +1073 -292
- package/lib/mocharc.json +10 -0
- package/lib/nodejs/buffered-worker-pool.js +188 -0
- package/lib/nodejs/esm-utils.js +106 -0
- package/lib/nodejs/file-unloader.js +15 -0
- package/lib/nodejs/parallel-buffered-runner.js +433 -0
- package/lib/nodejs/reporters/parallel-buffered.js +165 -0
- package/lib/nodejs/serializer.js +414 -0
- package/lib/nodejs/worker.js +151 -0
- package/lib/pending.js +3 -3
- package/lib/plugin-loader.js +286 -0
- package/lib/reporters/base.js +305 -205
- package/lib/reporters/doc.js +52 -21
- package/lib/reporters/dot.js +31 -18
- package/lib/reporters/html.js +153 -81
- package/lib/reporters/json-stream.js +53 -24
- package/lib/reporters/json.js +88 -18
- package/lib/reporters/landing.js +38 -16
- package/lib/reporters/list.js +34 -19
- package/lib/reporters/markdown.js +28 -15
- package/lib/reporters/min.js +22 -8
- package/lib/reporters/nyan.js +62 -58
- package/lib/reporters/progress.js +32 -19
- package/lib/reporters/spec.js +41 -23
- package/lib/reporters/tap.js +255 -32
- package/lib/reporters/xunit.js +89 -39
- package/lib/runnable.js +233 -148
- package/lib/runner.js +679 -380
- package/lib/stats-collector.js +83 -0
- package/lib/suite.js +376 -112
- package/lib/test.js +82 -21
- package/lib/utils.js +364 -477
- package/mocha.css +183 -54
- package/mocha.js +19840 -15846
- package/mocha.js.map +1 -0
- package/package.json +163 -336
- package/{lib/to-iso-string → vendor/serialize-javascript}/LICENSE +8 -6
- package/vendor/serialize-javascript/README.md +10 -0
- package/vendor/serialize-javascript/index.js +349 -0
- package/bin/_mocha-compat +0 -572
- package/bin/mocha-compat +0 -87
- package/bin/options.js +0 -41
- package/bower.json +0 -38
- package/images/error.png +0 -0
- package/images/ok.png +0 -0
- package/lib/browser/.eslintrc.yaml +0 -4
- package/lib/browser/debug.js +0 -7
- package/lib/browser/events.js +0 -195
- package/lib/browser/progress.js +0 -119
- package/lib/browser/tty.js +0 -13
- package/lib/ms.js +0 -130
- package/lib/to-iso-string/index.js +0 -37
- package/vendor/glob/LICENSE +0 -15
- package/vendor/glob/README.md +0 -399
- package/vendor/glob/common.js +0 -244
- package/vendor/glob/glob.js +0 -788
- package/vendor/glob/package.json +0 -55
- package/vendor/glob/sync.js +0 -486
- package/vendor/inflight/LICENSE +0 -15
- package/vendor/inflight/README.md +0 -37
- package/vendor/inflight/inflight.js +0 -54
- package/vendor/inflight/package.json +0 -29
package/lib/mocharc.json
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A wrapper around a third-party child process worker pool implementation.
|
|
3
|
+
* Used by {@link module:buffered-runner}.
|
|
4
|
+
* @private
|
|
5
|
+
* @module buffered-worker-pool
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
const serializeJavascript = require('../../vendor/serialize-javascript');
|
|
11
|
+
const workerpool = require('workerpool');
|
|
12
|
+
const {deserialize} = require('./serializer');
|
|
13
|
+
const debug = require('debug')('mocha:parallel:buffered-worker-pool');
|
|
14
|
+
const {createInvalidArgumentTypeError} = require('../errors');
|
|
15
|
+
|
|
16
|
+
const WORKER_PATH = require.resolve('./worker.js');
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* A mapping of Mocha `Options` objects to serialized values.
|
|
20
|
+
*
|
|
21
|
+
* This is helpful because we tend to same the same options over and over
|
|
22
|
+
* over IPC.
|
|
23
|
+
* @type {WeakMap<Options,string>}
|
|
24
|
+
*/
|
|
25
|
+
let optionsCache = new WeakMap();
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* These options are passed into the [workerpool](https://npm.im/workerpool) module.
|
|
29
|
+
* @type {Partial<WorkerPoolOptions>}
|
|
30
|
+
*/
|
|
31
|
+
const WORKER_POOL_DEFAULT_OPTS = {
|
|
32
|
+
// use child processes, not worker threads!
|
|
33
|
+
workerType: 'process',
|
|
34
|
+
// ensure the same flags sent to `node` for this `mocha` invocation are passed
|
|
35
|
+
// along to children
|
|
36
|
+
forkOpts: {execArgv: process.execArgv},
|
|
37
|
+
maxWorkers: workerpool.cpus - 1
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* A wrapper around a third-party worker pool implementation.
|
|
42
|
+
* @private
|
|
43
|
+
*/
|
|
44
|
+
class BufferedWorkerPool {
|
|
45
|
+
/**
|
|
46
|
+
* Creates an underlying worker pool instance; determines max worker count
|
|
47
|
+
* @param {Partial<WorkerPoolOptions>} [opts] - Options
|
|
48
|
+
*/
|
|
49
|
+
constructor(opts = {}) {
|
|
50
|
+
const maxWorkers = Math.max(
|
|
51
|
+
1,
|
|
52
|
+
typeof opts.maxWorkers === 'undefined'
|
|
53
|
+
? WORKER_POOL_DEFAULT_OPTS.maxWorkers
|
|
54
|
+
: opts.maxWorkers
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
/* istanbul ignore next */
|
|
58
|
+
if (workerpool.cpus < 2) {
|
|
59
|
+
// TODO: decide whether we should warn
|
|
60
|
+
debug(
|
|
61
|
+
'not enough CPU cores available to run multiple jobs; avoid --parallel on this machine'
|
|
62
|
+
);
|
|
63
|
+
} else if (maxWorkers >= workerpool.cpus) {
|
|
64
|
+
// TODO: decide whether we should warn
|
|
65
|
+
debug(
|
|
66
|
+
'%d concurrent job(s) requested, but only %d core(s) available',
|
|
67
|
+
maxWorkers,
|
|
68
|
+
workerpool.cpus
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
/* istanbul ignore next */
|
|
72
|
+
debug(
|
|
73
|
+
'run(): starting worker pool of max size %d, using node args: %s',
|
|
74
|
+
maxWorkers,
|
|
75
|
+
process.execArgv.join(' ')
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
let counter = 0;
|
|
79
|
+
const onCreateWorker = ({forkOpts}) => {
|
|
80
|
+
return {
|
|
81
|
+
forkOpts: {
|
|
82
|
+
...forkOpts,
|
|
83
|
+
// adds an incremental id to all workers, which can be useful to allocate resources for each process
|
|
84
|
+
env: {...process.env, MOCHA_WORKER_ID: counter++}
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
this.options = {
|
|
90
|
+
...WORKER_POOL_DEFAULT_OPTS,
|
|
91
|
+
...opts,
|
|
92
|
+
maxWorkers,
|
|
93
|
+
onCreateWorker
|
|
94
|
+
};
|
|
95
|
+
this._pool = workerpool.pool(WORKER_PATH, this.options);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Terminates all workers in the pool.
|
|
100
|
+
* @param {boolean} [force] - Whether to force-kill workers. By default, lets workers finish their current task before termination.
|
|
101
|
+
* @private
|
|
102
|
+
* @returns {Promise<void>}
|
|
103
|
+
*/
|
|
104
|
+
async terminate(force = false) {
|
|
105
|
+
/* istanbul ignore next */
|
|
106
|
+
debug('terminate(): terminating with force = %s', force);
|
|
107
|
+
return this._pool.terminate(force);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Adds a test file run to the worker pool queue for execution by a worker process.
|
|
112
|
+
*
|
|
113
|
+
* Handles serialization/deserialization.
|
|
114
|
+
*
|
|
115
|
+
* @param {string} filepath - Filepath of test
|
|
116
|
+
* @param {Options} [options] - Options for Mocha instance
|
|
117
|
+
* @private
|
|
118
|
+
* @returns {Promise<SerializedWorkerResult>}
|
|
119
|
+
*/
|
|
120
|
+
async run(filepath, options = {}) {
|
|
121
|
+
if (!filepath || typeof filepath !== 'string') {
|
|
122
|
+
throw createInvalidArgumentTypeError(
|
|
123
|
+
'Expected a non-empty filepath',
|
|
124
|
+
'filepath',
|
|
125
|
+
'string'
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
const serializedOptions = BufferedWorkerPool.serializeOptions(options);
|
|
129
|
+
const result = await this._pool.exec('run', [filepath, serializedOptions]);
|
|
130
|
+
return deserialize(result);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Returns stats about the state of the worker processes in the pool.
|
|
135
|
+
*
|
|
136
|
+
* Used for debugging.
|
|
137
|
+
*
|
|
138
|
+
* @private
|
|
139
|
+
*/
|
|
140
|
+
stats() {
|
|
141
|
+
return this._pool.stats();
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Instantiates a {@link WorkerPool}.
|
|
146
|
+
* @private
|
|
147
|
+
*/
|
|
148
|
+
static create(...args) {
|
|
149
|
+
return new BufferedWorkerPool(...args);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Given Mocha options object `opts`, serialize into a format suitable for
|
|
154
|
+
* transmission over IPC.
|
|
155
|
+
*
|
|
156
|
+
* @param {Options} [opts] - Mocha options
|
|
157
|
+
* @private
|
|
158
|
+
* @returns {string} Serialized options
|
|
159
|
+
*/
|
|
160
|
+
static serializeOptions(opts = {}) {
|
|
161
|
+
if (!optionsCache.has(opts)) {
|
|
162
|
+
const serialized = serializeJavascript(opts, {
|
|
163
|
+
unsafe: true, // this means we don't care about XSS
|
|
164
|
+
ignoreFunction: true // do not serialize functions
|
|
165
|
+
});
|
|
166
|
+
optionsCache.set(opts, serialized);
|
|
167
|
+
/* istanbul ignore next */
|
|
168
|
+
debug(
|
|
169
|
+
'serializeOptions(): serialized options %O to: %s',
|
|
170
|
+
opts,
|
|
171
|
+
serialized
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
return optionsCache.get(opts);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Resets internal cache of serialized options objects.
|
|
179
|
+
*
|
|
180
|
+
* For testing/debugging
|
|
181
|
+
* @private
|
|
182
|
+
*/
|
|
183
|
+
static resetOptionsCache() {
|
|
184
|
+
optionsCache = new WeakMap();
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
exports.BufferedWorkerPool = BufferedWorkerPool;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const url = require('url');
|
|
3
|
+
|
|
4
|
+
const forward = x => x;
|
|
5
|
+
|
|
6
|
+
const formattedImport = async (file, esmDecorator = forward) => {
|
|
7
|
+
if (path.isAbsolute(file)) {
|
|
8
|
+
try {
|
|
9
|
+
return await exports.doImport(esmDecorator(url.pathToFileURL(file)));
|
|
10
|
+
} catch (err) {
|
|
11
|
+
// This is a hack created because ESM in Node.js (at least in Node v15.5.1) does not emit
|
|
12
|
+
// the location of the syntax error in the error thrown.
|
|
13
|
+
// This is problematic because the user can't see what file has the problem,
|
|
14
|
+
// so we add the file location to the error.
|
|
15
|
+
// TODO: remove once Node.js fixes the problem.
|
|
16
|
+
if (
|
|
17
|
+
err instanceof SyntaxError &&
|
|
18
|
+
err.message &&
|
|
19
|
+
err.stack &&
|
|
20
|
+
!err.stack.includes(file)
|
|
21
|
+
) {
|
|
22
|
+
const newErrorWithFilename = new SyntaxError(err.message);
|
|
23
|
+
newErrorWithFilename.stack = err.stack.replace(
|
|
24
|
+
/^SyntaxError/,
|
|
25
|
+
`SyntaxError[ @${file} ]`
|
|
26
|
+
);
|
|
27
|
+
throw newErrorWithFilename;
|
|
28
|
+
}
|
|
29
|
+
throw err;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return exports.doImport(esmDecorator(file));
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
exports.doImport = async file => import(file);
|
|
36
|
+
|
|
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
|
+
) {
|
|
49
|
+
try {
|
|
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) {
|
|
55
|
+
if (
|
|
56
|
+
requireErr.code === 'ERR_REQUIRE_ESM' ||
|
|
57
|
+
(requireErr instanceof SyntaxError &&
|
|
58
|
+
requireErr
|
|
59
|
+
.toString()
|
|
60
|
+
.includes('Cannot use import statement outside a module'))
|
|
61
|
+
) {
|
|
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.
|
|
73
|
+
throw err;
|
|
74
|
+
} else {
|
|
75
|
+
throw requireErr;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
} else {
|
|
79
|
+
throw err;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
function dealWithExports(module) {
|
|
85
|
+
if (module.default) {
|
|
86
|
+
return module.default;
|
|
87
|
+
} else {
|
|
88
|
+
return {...module, default: undefined};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
exports.loadFilesAsync = async (
|
|
93
|
+
files,
|
|
94
|
+
preLoadFunc,
|
|
95
|
+
postLoadFunc,
|
|
96
|
+
esmDecorator
|
|
97
|
+
) => {
|
|
98
|
+
for (const file of files) {
|
|
99
|
+
preLoadFunc(file);
|
|
100
|
+
const result = await exports.requireOrImport(
|
|
101
|
+
path.resolve(file),
|
|
102
|
+
esmDecorator
|
|
103
|
+
);
|
|
104
|
+
postLoadFunc(file, result);
|
|
105
|
+
}
|
|
106
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* This module should not be in the browser bundle, so it's here.
|
|
5
|
+
* @private
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Deletes a file from the `require` cache.
|
|
11
|
+
* @param {string} file - File
|
|
12
|
+
*/
|
|
13
|
+
exports.unloadFile = file => {
|
|
14
|
+
delete require.cache[require.resolve(file)];
|
|
15
|
+
};
|