mocha 6.2.3 → 7.1.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 +102 -1347
- package/LICENSE +1 -1
- package/README.md +6 -6
- package/bin/mocha +12 -41
- package/browser-entry.js +2 -2
- package/lib/cli/config.js +2 -1
- package/lib/cli/node-flags.js +1 -1
- package/lib/cli/one-and-dones.js +2 -2
- package/lib/cli/options.js +4 -35
- package/lib/cli/run-helpers.js +12 -10
- package/lib/cli/run-option-metadata.js +6 -5
- package/lib/cli/run.js +32 -14
- package/lib/cli/watch-run.js +116 -31
- package/lib/esm-utils.js +31 -0
- package/lib/mocha.js +194 -103
- package/lib/mocharc.json +3 -2
- package/lib/reporters/base.js +15 -5
- package/lib/reporters/xunit.js +3 -3
- package/lib/runnable.js +26 -18
- package/lib/runner.js +99 -87
- package/lib/test.js +13 -0
- package/lib/utils.js +22 -74
- package/mocha.js +483 -452
- package/package.json +25 -504
- package/bin/options.js +0 -10
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
(The MIT License)
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2011-
|
|
3
|
+
Copyright (c) 2011-2020 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
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<img src="https://cldup.com/xFVFxOioAU.svg" alt="Mocha test framework"/>
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
|
-
<p align="center"
|
|
5
|
+
<p align="center">☕️ Simple, flexible, fun JavaScript test framework for Node.js & The Browser ☕️</p>
|
|
6
6
|
|
|
7
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>
|
|
8
8
|
</p>
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
|
|
57
57
|
## Sponsors
|
|
58
58
|
|
|
59
|
-
Does your company use Mocha?
|
|
59
|
+
Does your company use Mocha? Ask your manager or marketing team if your company would be interested in supporting our project. Support will allow the maintainers to dedicate more time for maintenance and new features for everyone. Also, your company's logo will show [on GitHub](https://github.com/mochajs/mocha#readme) and on [our site](https://mochajs.org) - who doesn't want a little extra exposure? [Here's the info](https://opencollective.com/mochajs#sponsor).
|
|
60
60
|
|
|
61
61
|
[](https://opencollective.com/mochajs/sponsor/0/website)
|
|
62
62
|
[](https://opencollective.com/mochajs/sponsor/1/website)
|
|
@@ -83,12 +83,12 @@ Does your company use Mocha? Ask your manager or marketing team if your company
|
|
|
83
83
|
|
|
84
84
|
You might want to know that:
|
|
85
85
|
|
|
86
|
-
- Mocha is the
|
|
87
|
-
- Mocha is an
|
|
86
|
+
- Mocha is the _most-depended-upon_ module on npm (source: [libraries.io](https://libraries.io/search?order=desc&platforms=NPM&sort=dependents_count)), and
|
|
87
|
+
- Mocha is an _independent_ open-source project, maintained exclusively by volunteers.
|
|
88
88
|
|
|
89
89
|
You might want to help:
|
|
90
90
|
|
|
91
|
-
- New to contributing to Mocha?
|
|
91
|
+
- New to contributing to Mocha? Check out this list of [good first issues](https://github.com/mochajs/mocha/issues?q=is%3Aissue+is%3Aopen+label%3Agood-first-issue)
|
|
92
92
|
- Mocha could use a hand with [these issues](https://github.com/mochajs/mocha/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22)
|
|
93
93
|
- The [maintainer's handbook](https://github.com/mochajs/mocha/blob/master/MAINTAINERS.md) explains how things get done
|
|
94
94
|
|
|
@@ -100,6 +100,6 @@ Finally, come [chat with the maintainers](https://gitter.im/mochajs/contributors
|
|
|
100
100
|
|
|
101
101
|
## License
|
|
102
102
|
|
|
103
|
-
[MIT](LICENSE)
|
|
103
|
+
Copyright 2011-2020 OpenJS Foundation and contributors. Licensed [MIT](https://github.com/mochajs/mocha/blob/master/LICENSE).
|
|
104
104
|
|
|
105
105
|
[](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fmochajs%2Fmocha?ref=badge_large)
|
package/bin/mocha
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* @private
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
const {deprecate
|
|
13
|
+
const {deprecate} = require('../lib/utils');
|
|
14
14
|
const {loadOptions} = require('../lib/cli/options');
|
|
15
15
|
const {
|
|
16
16
|
unparseNodeFlags,
|
|
@@ -20,7 +20,6 @@ const {
|
|
|
20
20
|
const unparse = require('yargs-unparser');
|
|
21
21
|
const debug = require('debug')('mocha:cli:mocha');
|
|
22
22
|
const {aliases} = require('../lib/cli/run-option-metadata');
|
|
23
|
-
const nodeEnv = require('node-environment-flags');
|
|
24
23
|
|
|
25
24
|
const mochaArgs = {};
|
|
26
25
|
const nodeArgs = {};
|
|
@@ -55,57 +54,29 @@ const trimV8Option = value =>
|
|
|
55
54
|
Object.keys(opts).forEach(opt => {
|
|
56
55
|
if (isNodeFlag(opt)) {
|
|
57
56
|
nodeArgs[trimV8Option(opt)] = opts[opt];
|
|
58
|
-
disableTimeouts(opt);
|
|
59
57
|
} else {
|
|
60
58
|
mochaArgs[opt] = opts[opt];
|
|
61
59
|
}
|
|
62
60
|
});
|
|
63
61
|
|
|
62
|
+
// disable 'timeout' for debugFlags
|
|
63
|
+
Object.keys(nodeArgs).forEach(opt => disableTimeouts(opt));
|
|
64
|
+
|
|
64
65
|
// Native debugger handling
|
|
65
66
|
// see https://nodejs.org/api/debugger.html#debugger_debugger
|
|
66
|
-
// look for '
|
|
67
|
+
// look for 'inspect' or 'debug' that would launch this debugger,
|
|
67
68
|
// remove it from Mocha's opts and prepend it to Node's opts.
|
|
68
|
-
// also coerce depending on Node.js version.
|
|
69
69
|
// A deprecation warning will be printed by node, if applicable.
|
|
70
70
|
// (mochaArgs._ are "positional" arguments, not prefixed with - or --)
|
|
71
|
-
if (
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
.
|
|
77
|
-
|
|
78
|
-
warn(`command "${command}" provided; --${opt} ignored`);
|
|
79
|
-
delete nodeArgs[opt];
|
|
80
|
-
delete mochaArgs[opt];
|
|
81
|
-
});
|
|
82
|
-
nodeArgs._ = [
|
|
83
|
-
parseInt(
|
|
84
|
-
process.version
|
|
85
|
-
.slice(1)
|
|
86
|
-
.split('.')
|
|
87
|
-
.shift(),
|
|
88
|
-
10
|
|
89
|
-
) >= 8
|
|
90
|
-
? 'inspect'
|
|
91
|
-
: 'debug'
|
|
92
|
-
];
|
|
71
|
+
if (mochaArgs._) {
|
|
72
|
+
const i = mochaArgs._.findIndex(val => val === 'inspect' || val === 'debug');
|
|
73
|
+
if (i > -1) {
|
|
74
|
+
const [command] = mochaArgs._.splice(i, 1);
|
|
75
|
+
disableTimeouts('inspect');
|
|
76
|
+
nodeArgs._ = [command];
|
|
77
|
+
}
|
|
93
78
|
}
|
|
94
79
|
|
|
95
|
-
// allow --debug to invoke --inspect on Node.js v8 or newer.
|
|
96
|
-
['debug', 'debug-brk']
|
|
97
|
-
.filter(opt => opt in nodeArgs && !nodeEnv.has(opt))
|
|
98
|
-
.forEach(opt => {
|
|
99
|
-
const newOpt = opt === 'debug' ? 'inspect' : 'inspect-brk';
|
|
100
|
-
warn(
|
|
101
|
-
`"--${opt}" is not available in Node.js ${process.version}; use "--${newOpt}" instead.`
|
|
102
|
-
);
|
|
103
|
-
nodeArgs[newOpt] = nodeArgs[opt];
|
|
104
|
-
mochaArgs.timeout = false;
|
|
105
|
-
debug(`--${opt} -> ${newOpt}`);
|
|
106
|
-
delete nodeArgs[opt];
|
|
107
|
-
});
|
|
108
|
-
|
|
109
80
|
// historical
|
|
110
81
|
if (nodeArgs.gc) {
|
|
111
82
|
deprecate(
|
package/browser-entry.js
CHANGED
|
@@ -60,7 +60,7 @@ process.on = function(e, fn) {
|
|
|
60
60
|
if (e === 'uncaughtException') {
|
|
61
61
|
global.onerror = function(err, url, line) {
|
|
62
62
|
fn(new Error(err + ' (' + url + ':' + line + ')'));
|
|
63
|
-
return !mocha.allowUncaught;
|
|
63
|
+
return !mocha.options.allowUncaught;
|
|
64
64
|
};
|
|
65
65
|
uncaughtExceptionHandlers.push(fn);
|
|
66
66
|
}
|
|
@@ -129,7 +129,7 @@ mocha.setup = function(opts) {
|
|
|
129
129
|
opts = {ui: opts};
|
|
130
130
|
}
|
|
131
131
|
for (var opt in opts) {
|
|
132
|
-
if (
|
|
132
|
+
if (Object.prototype.hasOwnProperty.call(opts, opt)) {
|
|
133
133
|
this[opt](opts[opt]);
|
|
134
134
|
}
|
|
135
135
|
}
|
package/lib/cli/config.js
CHANGED
|
@@ -21,6 +21,7 @@ const findUp = require('find-up');
|
|
|
21
21
|
* @private
|
|
22
22
|
*/
|
|
23
23
|
exports.CONFIG_FILES = [
|
|
24
|
+
'.mocharc.cjs',
|
|
24
25
|
'.mocharc.js',
|
|
25
26
|
'.mocharc.yaml',
|
|
26
27
|
'.mocharc.yml',
|
|
@@ -75,7 +76,7 @@ exports.loadConfig = filepath => {
|
|
|
75
76
|
try {
|
|
76
77
|
if (ext === '.yml' || ext === '.yaml') {
|
|
77
78
|
config = parsers.yaml(filepath);
|
|
78
|
-
} else if (ext === '.js') {
|
|
79
|
+
} else if (ext === '.js' || ext === '.cjs') {
|
|
79
80
|
config = parsers.js(filepath);
|
|
80
81
|
} else {
|
|
81
82
|
config = parsers.json(filepath);
|
package/lib/cli/node-flags.js
CHANGED
|
@@ -14,7 +14,7 @@ const unparse = require('yargs-unparser');
|
|
|
14
14
|
* @see {@link impliesNoTimeouts}
|
|
15
15
|
* @private
|
|
16
16
|
*/
|
|
17
|
-
const debugFlags = new Set(['
|
|
17
|
+
const debugFlags = new Set(['inspect', 'inspect-brk']);
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Mocha has historical support for various `node` and V8 flags which might not
|
package/lib/cli/one-and-dones.js
CHANGED
|
@@ -48,14 +48,14 @@ exports.ONE_AND_DONES = {
|
|
|
48
48
|
* Dump list of built-in interfaces
|
|
49
49
|
* @private
|
|
50
50
|
*/
|
|
51
|
-
interfaces: () => {
|
|
51
|
+
'list-interfaces': () => {
|
|
52
52
|
showKeys(Mocha.interfaces);
|
|
53
53
|
},
|
|
54
54
|
/**
|
|
55
55
|
* Dump list of built-in reporters
|
|
56
56
|
* @private
|
|
57
57
|
*/
|
|
58
|
-
reporters: () => {
|
|
58
|
+
'list-reporters': () => {
|
|
59
59
|
showKeys(Mocha.reporters);
|
|
60
60
|
}
|
|
61
61
|
};
|
package/lib/cli/options.js
CHANGED
|
@@ -163,40 +163,6 @@ const parseMochaOpts = content =>
|
|
|
163
163
|
.filter(Boolean)
|
|
164
164
|
.map(value => value.replace(/%20/g, ' '));
|
|
165
165
|
|
|
166
|
-
/**
|
|
167
|
-
* Prepends options from run-control file to the command line arguments.
|
|
168
|
-
*
|
|
169
|
-
* @deprecated Deprecated in v6.0.0; This function is no longer used internally and will be removed in a future version.
|
|
170
|
-
* @public
|
|
171
|
-
* @alias module:lib/cli/options
|
|
172
|
-
* @see {@link https://mochajs.org/#mochaopts|mocha.opts}
|
|
173
|
-
*/
|
|
174
|
-
module.exports = function getOptions() {
|
|
175
|
-
deprecate(
|
|
176
|
-
'getOptions() is DEPRECATED and will be removed from a future version of Mocha. Use loadOptions() instead'
|
|
177
|
-
);
|
|
178
|
-
if (process.argv.length === 3 && ONE_AND_DONE_ARGS.has(process.argv[2])) {
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
const optsPath =
|
|
183
|
-
process.argv.indexOf('--opts') === -1
|
|
184
|
-
? mocharc.opts
|
|
185
|
-
: process.argv[process.argv.indexOf('--opts') + 1];
|
|
186
|
-
|
|
187
|
-
try {
|
|
188
|
-
const options = parseMochaOpts(fs.readFileSync(optsPath, 'utf8'));
|
|
189
|
-
|
|
190
|
-
process.argv = process.argv
|
|
191
|
-
.slice(0, 2)
|
|
192
|
-
.concat(options.concat(process.argv.slice(2)));
|
|
193
|
-
} catch (ignore) {
|
|
194
|
-
// NOTE: should console.error() and throw the error
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
process.env.LOADED_MOCHA_OPTS = true;
|
|
198
|
-
};
|
|
199
|
-
|
|
200
166
|
/**
|
|
201
167
|
* Given filepath in `args.opts`, attempt to load and parse a `mocha.opts` file.
|
|
202
168
|
* @param {Object} [args] - Arguments object
|
|
@@ -231,6 +197,9 @@ const loadMochaOpts = (args = {}) => {
|
|
|
231
197
|
// if there's an exception to catch here, I'm not sure what it is.
|
|
232
198
|
// by attaching the `no-opts` arg, we avoid re-parsing of `mocha.opts`.
|
|
233
199
|
if (mochaOpts) {
|
|
200
|
+
deprecate(
|
|
201
|
+
'Configuration via mocha.opts is DEPRECATED and will be removed from a future version of Mocha. Use RC files or package.json instead.'
|
|
202
|
+
);
|
|
234
203
|
result = parse(parseMochaOpts(mochaOpts));
|
|
235
204
|
debug(`${filepath} parsed succesfully`);
|
|
236
205
|
}
|
|
@@ -296,7 +265,7 @@ module.exports.loadPkgRc = loadPkgRc;
|
|
|
296
265
|
* Priority list:
|
|
297
266
|
*
|
|
298
267
|
* 1. Command-line args
|
|
299
|
-
* 2. RC file (`.mocharc.js`, `.mocharc.ya?ml`, `mocharc.json`)
|
|
268
|
+
* 2. RC file (`.mocharc.c?js`, `.mocharc.ya?ml`, `mocharc.json`)
|
|
300
269
|
* 3. `mocha` prop of `package.json`
|
|
301
270
|
* 4. `mocha.opts`
|
|
302
271
|
* 5. default configuration (`lib/mocharc.json`)
|
package/lib/cli/run-helpers.js
CHANGED
|
@@ -15,8 +15,6 @@ const collectFiles = require('./collect-files');
|
|
|
15
15
|
|
|
16
16
|
const cwd = (exports.cwd = process.cwd());
|
|
17
17
|
|
|
18
|
-
exports.watchRun = watchRun;
|
|
19
|
-
|
|
20
18
|
/**
|
|
21
19
|
* Exits Mocha when tests + code under test has finished execution (default)
|
|
22
20
|
* @param {number} code - Exit code; typically # of failures
|
|
@@ -92,19 +90,21 @@ exports.handleRequires = (requires = []) => {
|
|
|
92
90
|
};
|
|
93
91
|
|
|
94
92
|
/**
|
|
95
|
-
* Collect test files
|
|
93
|
+
* Collect and load test files, then run mocha instance.
|
|
96
94
|
* @param {Mocha} mocha - Mocha instance
|
|
97
95
|
* @param {Options} [opts] - Command line options
|
|
98
96
|
* @param {boolean} [opts.exit] - Whether or not to force-exit after tests are complete
|
|
99
97
|
* @param {Object} fileCollectParams - Parameters that control test
|
|
100
98
|
* file collection. See `lib/cli/collect-files.js`.
|
|
101
|
-
* @returns {Runner}
|
|
99
|
+
* @returns {Promise<Runner>}
|
|
102
100
|
* @private
|
|
103
101
|
*/
|
|
104
|
-
|
|
102
|
+
const singleRun = async (mocha, {exit}, fileCollectParams) => {
|
|
105
103
|
const files = collectFiles(fileCollectParams);
|
|
106
104
|
debug('running tests with files', files);
|
|
107
105
|
mocha.files = files;
|
|
106
|
+
|
|
107
|
+
await mocha.loadFilesAsync();
|
|
108
108
|
return mocha.run(exit ? exitMocha : exitMochaLater);
|
|
109
109
|
};
|
|
110
110
|
|
|
@@ -113,18 +113,20 @@ exports.singleRun = (mocha, {exit}, fileCollectParams) => {
|
|
|
113
113
|
* @param {Mocha} mocha - Mocha instance
|
|
114
114
|
* @param {Object} opts - Command line options
|
|
115
115
|
* @private
|
|
116
|
+
* @returns {Promise}
|
|
116
117
|
*/
|
|
117
|
-
exports.runMocha = (mocha, options) => {
|
|
118
|
+
exports.runMocha = async (mocha, options) => {
|
|
118
119
|
const {
|
|
119
120
|
watch = false,
|
|
120
121
|
extension = [],
|
|
121
|
-
ui = 'bdd',
|
|
122
122
|
exit = false,
|
|
123
123
|
ignore = [],
|
|
124
124
|
file = [],
|
|
125
125
|
recursive = false,
|
|
126
126
|
sort = false,
|
|
127
|
-
spec = []
|
|
127
|
+
spec = [],
|
|
128
|
+
watchFiles,
|
|
129
|
+
watchIgnore
|
|
128
130
|
} = options;
|
|
129
131
|
|
|
130
132
|
const fileCollectParams = {
|
|
@@ -137,9 +139,9 @@ exports.runMocha = (mocha, options) => {
|
|
|
137
139
|
};
|
|
138
140
|
|
|
139
141
|
if (watch) {
|
|
140
|
-
watchRun(mocha, {
|
|
142
|
+
watchRun(mocha, {watchFiles, watchIgnore}, fileCollectParams);
|
|
141
143
|
} else {
|
|
142
|
-
|
|
144
|
+
await singleRun(mocha, {exit}, fileCollectParams);
|
|
143
145
|
}
|
|
144
146
|
};
|
|
145
147
|
|
|
@@ -18,9 +18,11 @@ exports.types = {
|
|
|
18
18
|
'file',
|
|
19
19
|
'global',
|
|
20
20
|
'ignore',
|
|
21
|
-
'require',
|
|
22
21
|
'reporter-option',
|
|
23
|
-
'
|
|
22
|
+
'require',
|
|
23
|
+
'spec',
|
|
24
|
+
'watch-files',
|
|
25
|
+
'watch-ignore'
|
|
24
26
|
],
|
|
25
27
|
boolean: [
|
|
26
28
|
'allow-uncaught',
|
|
@@ -36,11 +38,11 @@ exports.types = {
|
|
|
36
38
|
'full-trace',
|
|
37
39
|
'growl',
|
|
38
40
|
'inline-diffs',
|
|
39
|
-
'interfaces',
|
|
40
41
|
'invert',
|
|
42
|
+
'list-interfaces',
|
|
43
|
+
'list-reporters',
|
|
41
44
|
'no-colors',
|
|
42
45
|
'recursive',
|
|
43
|
-
'reporters',
|
|
44
46
|
'sort',
|
|
45
47
|
'watch'
|
|
46
48
|
],
|
|
@@ -68,7 +70,6 @@ exports.aliases = {
|
|
|
68
70
|
'async-only': ['A'],
|
|
69
71
|
bail: ['b'],
|
|
70
72
|
color: ['c', 'colors'],
|
|
71
|
-
extension: ['watch-extensions'],
|
|
72
73
|
fgrep: ['f'],
|
|
73
74
|
global: ['globals'],
|
|
74
75
|
grep: ['g'],
|
package/lib/cli/run.js
CHANGED
|
@@ -38,7 +38,7 @@ const GROUPS = {
|
|
|
38
38
|
CONFIG: 'Configuration'
|
|
39
39
|
};
|
|
40
40
|
|
|
41
|
-
exports.command = ['$0 [spec..]', '
|
|
41
|
+
exports.command = ['$0 [spec..]', 'inspect'];
|
|
42
42
|
|
|
43
43
|
exports.describe = 'Run tests with Mocha';
|
|
44
44
|
|
|
@@ -87,8 +87,7 @@ exports.builder = yargs =>
|
|
|
87
87
|
},
|
|
88
88
|
extension: {
|
|
89
89
|
default: defaults.extension,
|
|
90
|
-
|
|
91
|
-
description: 'File extension(s) to load and/or watch',
|
|
90
|
+
description: 'File extension(s) to load',
|
|
92
91
|
group: GROUPS.FILES,
|
|
93
92
|
requiresArg: true,
|
|
94
93
|
coerce: list
|
|
@@ -147,14 +146,18 @@ exports.builder = yargs =>
|
|
|
147
146
|
'Display actual/expected differences inline within each string',
|
|
148
147
|
group: GROUPS.OUTPUT
|
|
149
148
|
},
|
|
150
|
-
interfaces: {
|
|
151
|
-
conflicts: Array.from(ONE_AND_DONE_ARGS),
|
|
152
|
-
description: 'List built-in user interfaces & exit'
|
|
153
|
-
},
|
|
154
149
|
invert: {
|
|
155
150
|
description: 'Inverts --grep and --fgrep matches',
|
|
156
151
|
group: GROUPS.FILTERS
|
|
157
152
|
},
|
|
153
|
+
'list-interfaces': {
|
|
154
|
+
conflicts: Array.from(ONE_AND_DONE_ARGS),
|
|
155
|
+
description: 'List built-in user interfaces & exit'
|
|
156
|
+
},
|
|
157
|
+
'list-reporters': {
|
|
158
|
+
conflicts: Array.from(ONE_AND_DONE_ARGS),
|
|
159
|
+
description: 'List built-in reporters & exit'
|
|
160
|
+
},
|
|
158
161
|
'no-colors': {
|
|
159
162
|
description: 'Force-disable color output',
|
|
160
163
|
group: GROUPS.OUTPUT,
|
|
@@ -162,7 +165,7 @@ exports.builder = yargs =>
|
|
|
162
165
|
},
|
|
163
166
|
opts: {
|
|
164
167
|
default: defaults.opts,
|
|
165
|
-
description: 'Path to `mocha.opts`',
|
|
168
|
+
description: 'Path to `mocha.opts` (DEPRECATED)',
|
|
166
169
|
group: GROUPS.CONFIG,
|
|
167
170
|
normalize: true,
|
|
168
171
|
requiresArg: true
|
|
@@ -183,10 +186,6 @@ exports.builder = yargs =>
|
|
|
183
186
|
group: GROUPS.OUTPUT,
|
|
184
187
|
requiresArg: true
|
|
185
188
|
},
|
|
186
|
-
reporters: {
|
|
187
|
-
conflicts: Array.from(ONE_AND_DONE_ARGS),
|
|
188
|
-
description: 'List built-in reporters & exit'
|
|
189
|
-
},
|
|
190
189
|
'reporter-option': {
|
|
191
190
|
coerce: opts =>
|
|
192
191
|
list(opts).reduce((acc, opt) => {
|
|
@@ -241,6 +240,19 @@ exports.builder = yargs =>
|
|
|
241
240
|
watch: {
|
|
242
241
|
description: 'Watch files in the current working directory for changes',
|
|
243
242
|
group: GROUPS.FILES
|
|
243
|
+
},
|
|
244
|
+
'watch-files': {
|
|
245
|
+
description: 'List of paths or globs to watch',
|
|
246
|
+
group: GROUPS.FILES,
|
|
247
|
+
requiresArg: true,
|
|
248
|
+
coerce: list
|
|
249
|
+
},
|
|
250
|
+
'watch-ignore': {
|
|
251
|
+
description: 'List of paths or globs to exclude from watching',
|
|
252
|
+
group: GROUPS.FILES,
|
|
253
|
+
requiresArg: true,
|
|
254
|
+
coerce: list,
|
|
255
|
+
default: defaults['watch-ignore']
|
|
244
256
|
}
|
|
245
257
|
})
|
|
246
258
|
.positional('spec', {
|
|
@@ -286,8 +298,14 @@ exports.builder = yargs =>
|
|
|
286
298
|
.number(types.number)
|
|
287
299
|
.alias(aliases);
|
|
288
300
|
|
|
289
|
-
exports.handler = argv
|
|
301
|
+
exports.handler = async function(argv) {
|
|
290
302
|
debug('post-yargs config', argv);
|
|
291
303
|
const mocha = new Mocha(argv);
|
|
292
|
-
|
|
304
|
+
|
|
305
|
+
try {
|
|
306
|
+
await runMocha(mocha, argv);
|
|
307
|
+
} catch (err) {
|
|
308
|
+
console.error('\n' + (err.stack || `Error: ${err.message || err}`));
|
|
309
|
+
process.exit(1);
|
|
310
|
+
}
|
|
293
311
|
};
|
package/lib/cli/watch-run.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const chokidar = require('chokidar');
|
|
4
5
|
const Context = require('../context');
|
|
5
|
-
const Mocha = require('../mocha');
|
|
6
6
|
const collectFiles = require('./collect-files');
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -16,36 +16,88 @@ const collectFiles = require('./collect-files');
|
|
|
16
16
|
* Run Mocha in "watch" mode
|
|
17
17
|
* @param {Mocha} mocha - Mocha instance
|
|
18
18
|
* @param {Object} opts - Options
|
|
19
|
-
* @param {string} opts.
|
|
19
|
+
* @param {string[]} [opts.watchFiles] - List of paths and patterns to
|
|
20
|
+
* watch. If not provided all files with an extension included in
|
|
21
|
+
* `fileColletionParams.extension` are watched. See first argument of
|
|
22
|
+
* `chokidar.watch`.
|
|
23
|
+
* @param {string[]} opts.watchIgnore - List of paths and patterns to
|
|
24
|
+
* exclude from watching. See `ignored` option of `chokidar`.
|
|
20
25
|
* @param {Object} fileCollectParams - Parameters that control test
|
|
21
26
|
* file collection. See `lib/cli/collect-files.js`.
|
|
22
|
-
* @param {string[]} fileCollectParams.extension - List of extensions
|
|
27
|
+
* @param {string[]} fileCollectParams.extension - List of extensions
|
|
28
|
+
* to watch if `opts.watchFiles` is not given.
|
|
23
29
|
* @private
|
|
24
30
|
*/
|
|
25
|
-
module.exports = (mocha, {
|
|
26
|
-
|
|
27
|
-
|
|
31
|
+
module.exports = (mocha, {watchFiles, watchIgnore}, fileCollectParams) => {
|
|
32
|
+
if (!watchFiles) {
|
|
33
|
+
watchFiles = fileCollectParams.extension.map(ext => `**/*.${ext}`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const watcher = chokidar.watch(watchFiles, {
|
|
37
|
+
ignored: watchIgnore,
|
|
38
|
+
ignoreInitial: true
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const rerunner = createRerunner(mocha, () => {
|
|
42
|
+
getWatchedFiles(watcher).forEach(file => {
|
|
43
|
+
delete require.cache[file];
|
|
44
|
+
});
|
|
45
|
+
mocha.files = collectFiles(fileCollectParams);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
watcher.on('ready', () => {
|
|
49
|
+
rerunner.run();
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
watcher.on('all', () => {
|
|
53
|
+
rerunner.scheduleRun();
|
|
54
|
+
});
|
|
28
55
|
|
|
29
56
|
console.log();
|
|
30
57
|
hideCursor();
|
|
58
|
+
process.on('exit', () => {
|
|
59
|
+
showCursor();
|
|
60
|
+
});
|
|
31
61
|
process.on('SIGINT', () => {
|
|
32
62
|
showCursor();
|
|
33
63
|
console.log('\n');
|
|
34
|
-
// By UNIX/Posix convention this indicates that the process was
|
|
35
|
-
// killed by SIGINT which has portable number 2.
|
|
36
64
|
process.exit(128 + 2);
|
|
37
65
|
});
|
|
38
66
|
|
|
39
|
-
|
|
40
|
-
|
|
67
|
+
// Keyboard shortcut for restarting when "rs\n" is typed (ala Nodemon)
|
|
68
|
+
process.stdin.resume();
|
|
69
|
+
process.stdin.setEncoding('utf8');
|
|
70
|
+
process.stdin.on('data', data => {
|
|
71
|
+
const str = data
|
|
72
|
+
.toString()
|
|
73
|
+
.trim()
|
|
74
|
+
.toLowerCase();
|
|
75
|
+
if (str === 'rs') rerunner.scheduleRun();
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Create an object that allows you to rerun tests on the mocha
|
|
81
|
+
* instance. `beforeRun` is called everytime before `mocha.run()` is
|
|
82
|
+
* called.
|
|
83
|
+
*
|
|
84
|
+
* @param {Mocha} mocha - Mocha instance
|
|
85
|
+
* @param {function} beforeRun - Called just before `mocha.run()`
|
|
86
|
+
*/
|
|
87
|
+
const createRerunner = (mocha, beforeRun) => {
|
|
88
|
+
// Set to a `Runner` when mocha is running. Set to `null` when mocha is not
|
|
89
|
+
// running.
|
|
90
|
+
let runner = null;
|
|
41
91
|
|
|
42
|
-
|
|
92
|
+
let rerunScheduled = false;
|
|
93
|
+
|
|
94
|
+
const run = () => {
|
|
43
95
|
try {
|
|
44
|
-
|
|
45
|
-
|
|
96
|
+
beforeRun();
|
|
97
|
+
resetMocha(mocha);
|
|
46
98
|
runner = mocha.run(() => {
|
|
47
99
|
runner = null;
|
|
48
|
-
if (
|
|
100
|
+
if (rerunScheduled) {
|
|
49
101
|
rerun();
|
|
50
102
|
}
|
|
51
103
|
});
|
|
@@ -54,29 +106,62 @@ module.exports = (mocha, {ui}, fileCollectParams) => {
|
|
|
54
106
|
}
|
|
55
107
|
};
|
|
56
108
|
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
loadAndRun();
|
|
62
|
-
|
|
63
|
-
const rerun = () => {
|
|
64
|
-
purge();
|
|
65
|
-
eraseLine();
|
|
66
|
-
mocha.suite = mocha.suite.clone();
|
|
67
|
-
mocha.suite.ctx = new Context();
|
|
68
|
-
mocha.ui(ui);
|
|
69
|
-
loadAndRun();
|
|
70
|
-
};
|
|
109
|
+
const scheduleRun = () => {
|
|
110
|
+
if (rerunScheduled) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
71
113
|
|
|
72
|
-
|
|
73
|
-
runAgain = true;
|
|
114
|
+
rerunScheduled = true;
|
|
74
115
|
if (runner) {
|
|
75
116
|
runner.abort();
|
|
76
117
|
} else {
|
|
77
118
|
rerun();
|
|
78
119
|
}
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
const rerun = () => {
|
|
123
|
+
rerunScheduled = false;
|
|
124
|
+
eraseLine();
|
|
125
|
+
run();
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
return {
|
|
129
|
+
scheduleRun,
|
|
130
|
+
run
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Return the list of absolute paths watched by a chokidar watcher.
|
|
136
|
+
*
|
|
137
|
+
* @param watcher - Instance of a chokidar watcher
|
|
138
|
+
* @return {string[]} - List of absolute paths
|
|
139
|
+
*/
|
|
140
|
+
const getWatchedFiles = watcher => {
|
|
141
|
+
const watchedDirs = watcher.getWatched();
|
|
142
|
+
let watchedFiles = [];
|
|
143
|
+
Object.keys(watchedDirs).forEach(dir => {
|
|
144
|
+
watchedFiles = watchedFiles.concat(
|
|
145
|
+
watchedDirs[dir].map(file => path.join(dir, file))
|
|
146
|
+
);
|
|
79
147
|
});
|
|
148
|
+
return watchedFiles;
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Reset the internal state of the mocha instance so that tests can be rerun.
|
|
153
|
+
*
|
|
154
|
+
* @param {Mocha} mocha - Mocha instance
|
|
155
|
+
* @private
|
|
156
|
+
*/
|
|
157
|
+
const resetMocha = mocha => {
|
|
158
|
+
mocha.unloadFiles();
|
|
159
|
+
mocha.suite = mocha.suite.clone();
|
|
160
|
+
mocha.suite.ctx = new Context();
|
|
161
|
+
// Registers a callback on `mocha.suite` that wires new context to the DSL
|
|
162
|
+
// (e.g. `describe`) that is exposed as globals when the test files are
|
|
163
|
+
// reloaded.
|
|
164
|
+
mocha.ui(mocha.options.ui);
|
|
80
165
|
};
|
|
81
166
|
|
|
82
167
|
/**
|