mocha 6.1.4 → 6.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 +40 -0
- package/bin/mocha +32 -26
- package/lib/cli/cli.js +6 -1
- package/lib/cli/collect-files.js +85 -0
- package/lib/cli/options.js +24 -10
- package/lib/cli/run-helpers.js +35 -193
- package/lib/cli/run-option-metadata.js +14 -3
- package/lib/cli/run.js +7 -11
- package/lib/cli/watch-run.js +106 -0
- package/lib/mocha.js +10 -3
- package/lib/reporters/base.js +15 -8
- package/lib/reporters/doc.js +14 -10
- package/lib/reporters/dot.js +1 -1
- package/lib/reporters/landing.js +1 -1
- package/lib/reporters/list.js +4 -4
- package/lib/reporters/progress.js +2 -2
- package/lib/reporters/spec.js +7 -7
- package/lib/reporters/xunit.js +1 -1
- package/lib/utils.js +26 -16
- package/mocha.css +0 -1
- package/mocha.js +82 -54
- package/package.json +34 -25
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const utils = require('../utils');
|
|
4
|
+
const Context = require('../context');
|
|
5
|
+
const Mocha = require('../mocha');
|
|
6
|
+
const collectFiles = require('./collect-files');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Exports the `watchRun` function that runs mocha in "watch" mode.
|
|
10
|
+
* @see module:lib/cli/run-helpers
|
|
11
|
+
* @module
|
|
12
|
+
* @private
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Run Mocha in "watch" mode
|
|
17
|
+
* @param {Mocha} mocha - Mocha instance
|
|
18
|
+
* @param {Object} opts - Options
|
|
19
|
+
* @param {string} opts.ui - User interface
|
|
20
|
+
* @param {Object} fileCollectParams - Parameters that control test
|
|
21
|
+
* file collection. See `lib/cli/collect-files.js`.
|
|
22
|
+
* @param {string[]} fileCollectParams.extension - List of extensions to watch
|
|
23
|
+
* @private
|
|
24
|
+
*/
|
|
25
|
+
module.exports = (mocha, {ui}, fileCollectParams) => {
|
|
26
|
+
let runner;
|
|
27
|
+
const files = collectFiles(fileCollectParams);
|
|
28
|
+
|
|
29
|
+
console.log();
|
|
30
|
+
hideCursor();
|
|
31
|
+
process.on('SIGINT', () => {
|
|
32
|
+
showCursor();
|
|
33
|
+
console.log('\n');
|
|
34
|
+
// By UNIX/Posix convention this indicates that the process was
|
|
35
|
+
// killed by SIGINT which has portable number 2.
|
|
36
|
+
process.exit(128 + 2);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
const watchFiles = utils.files(process.cwd(), fileCollectParams.extension);
|
|
40
|
+
let runAgain = false;
|
|
41
|
+
|
|
42
|
+
const loadAndRun = () => {
|
|
43
|
+
try {
|
|
44
|
+
mocha.files = files;
|
|
45
|
+
runAgain = false;
|
|
46
|
+
runner = mocha.run(() => {
|
|
47
|
+
runner = null;
|
|
48
|
+
if (runAgain) {
|
|
49
|
+
rerun();
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
} catch (e) {
|
|
53
|
+
console.log(e.stack);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const purge = () => {
|
|
58
|
+
watchFiles.forEach(Mocha.unloadFile);
|
|
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
|
+
};
|
|
71
|
+
|
|
72
|
+
utils.watch(watchFiles, () => {
|
|
73
|
+
runAgain = true;
|
|
74
|
+
if (runner) {
|
|
75
|
+
runner.abort();
|
|
76
|
+
} else {
|
|
77
|
+
rerun();
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Hide the cursor.
|
|
84
|
+
* @ignore
|
|
85
|
+
* @private
|
|
86
|
+
*/
|
|
87
|
+
const hideCursor = () => {
|
|
88
|
+
process.stdout.write('\u001b[?25l');
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Show the cursor.
|
|
93
|
+
* @ignore
|
|
94
|
+
* @private
|
|
95
|
+
*/
|
|
96
|
+
const showCursor = () => {
|
|
97
|
+
process.stdout.write('\u001b[?25h');
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Erases the line on stdout
|
|
102
|
+
* @private
|
|
103
|
+
*/
|
|
104
|
+
const eraseLine = () => {
|
|
105
|
+
process.stdout.write('\u001b[2K');
|
|
106
|
+
};
|
package/lib/mocha.js
CHANGED
|
@@ -106,6 +106,10 @@ function Mocha(options) {
|
|
|
106
106
|
options.color = 'color' in options ? options.color : options.useColors;
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
+
// Globals are passed in as options.global, with options.globals for backward compatibility.
|
|
110
|
+
options.globals = options.global || options.globals || [];
|
|
111
|
+
delete options.global;
|
|
112
|
+
|
|
109
113
|
this.grep(options.grep)
|
|
110
114
|
.fgrep(options.fgrep)
|
|
111
115
|
.ui(options.ui)
|
|
@@ -540,7 +544,7 @@ Mocha.prototype._growl = growl.notify;
|
|
|
540
544
|
* Specifies whitelist of variable names to be expected in global scope.
|
|
541
545
|
*
|
|
542
546
|
* @public
|
|
543
|
-
* @see {@link https://mochajs.org
|
|
547
|
+
* @see {@link https://mochajs.org/#-global-variable-name|CLI option}
|
|
544
548
|
* @see {@link Mocha#checkLeaks}
|
|
545
549
|
* @param {String[]|String} globals - Accepted global variable name(s).
|
|
546
550
|
* @return {Mocha} this
|
|
@@ -551,9 +555,12 @@ Mocha.prototype._growl = growl.notify;
|
|
|
551
555
|
* mocha.globals(['jQuery', 'MyLib']);
|
|
552
556
|
*/
|
|
553
557
|
Mocha.prototype.globals = function(globals) {
|
|
554
|
-
this.options.globals =
|
|
558
|
+
this.options.globals = this.options.globals
|
|
555
559
|
.concat(globals)
|
|
556
|
-
.filter(Boolean)
|
|
560
|
+
.filter(Boolean)
|
|
561
|
+
.filter(function(elt, idx, arr) {
|
|
562
|
+
return arr.indexOf(elt) === idx;
|
|
563
|
+
});
|
|
557
564
|
return this;
|
|
558
565
|
};
|
|
559
566
|
|
package/lib/reporters/base.js
CHANGED
|
@@ -27,6 +27,11 @@ exports = module.exports = Base;
|
|
|
27
27
|
|
|
28
28
|
var isatty = tty.isatty(1) && tty.isatty(2);
|
|
29
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Save log references to avoid tests interfering (see GH-3604).
|
|
32
|
+
*/
|
|
33
|
+
var consoleLog = console.log;
|
|
34
|
+
|
|
30
35
|
/**
|
|
31
36
|
* Enable coloring by default, except in the browser interface.
|
|
32
37
|
*/
|
|
@@ -192,7 +197,7 @@ var generateDiff = (exports.generateDiff = function(actual, expected) {
|
|
|
192
197
|
* Error property
|
|
193
198
|
*/
|
|
194
199
|
exports.list = function(failures) {
|
|
195
|
-
|
|
200
|
+
Base.consoleLog();
|
|
196
201
|
failures.forEach(function(test, i) {
|
|
197
202
|
// format
|
|
198
203
|
var fmt =
|
|
@@ -253,7 +258,7 @@ exports.list = function(failures) {
|
|
|
253
258
|
testTitle += str;
|
|
254
259
|
});
|
|
255
260
|
|
|
256
|
-
|
|
261
|
+
Base.consoleLog(fmt, i + 1, testTitle, msg, stack);
|
|
257
262
|
});
|
|
258
263
|
};
|
|
259
264
|
|
|
@@ -308,7 +313,7 @@ Base.prototype.epilogue = function() {
|
|
|
308
313
|
var stats = this.stats;
|
|
309
314
|
var fmt;
|
|
310
315
|
|
|
311
|
-
|
|
316
|
+
Base.consoleLog();
|
|
312
317
|
|
|
313
318
|
// passes
|
|
314
319
|
fmt =
|
|
@@ -316,26 +321,26 @@ Base.prototype.epilogue = function() {
|
|
|
316
321
|
color('green', ' %d passing') +
|
|
317
322
|
color('light', ' (%s)');
|
|
318
323
|
|
|
319
|
-
|
|
324
|
+
Base.consoleLog(fmt, stats.passes || 0, milliseconds(stats.duration));
|
|
320
325
|
|
|
321
326
|
// pending
|
|
322
327
|
if (stats.pending) {
|
|
323
328
|
fmt = color('pending', ' ') + color('pending', ' %d pending');
|
|
324
329
|
|
|
325
|
-
|
|
330
|
+
Base.consoleLog(fmt, stats.pending);
|
|
326
331
|
}
|
|
327
332
|
|
|
328
333
|
// failures
|
|
329
334
|
if (stats.failures) {
|
|
330
335
|
fmt = color('fail', ' %d failing');
|
|
331
336
|
|
|
332
|
-
|
|
337
|
+
Base.consoleLog(fmt, stats.failures);
|
|
333
338
|
|
|
334
339
|
Base.list(this.failures);
|
|
335
|
-
|
|
340
|
+
Base.consoleLog();
|
|
336
341
|
}
|
|
337
342
|
|
|
338
|
-
|
|
343
|
+
Base.consoleLog();
|
|
339
344
|
};
|
|
340
345
|
|
|
341
346
|
/**
|
|
@@ -488,4 +493,6 @@ function sameType(a, b) {
|
|
|
488
493
|
return objToString.call(a) === objToString.call(b);
|
|
489
494
|
}
|
|
490
495
|
|
|
496
|
+
Base.consoleLog = consoleLog;
|
|
497
|
+
|
|
491
498
|
Base.abstract = true;
|
package/lib/reporters/doc.js
CHANGED
|
@@ -44,41 +44,45 @@ function Doc(runner, options) {
|
|
|
44
44
|
return;
|
|
45
45
|
}
|
|
46
46
|
++indents;
|
|
47
|
-
|
|
47
|
+
Base.consoleLog('%s<section class="suite">', indent());
|
|
48
48
|
++indents;
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
Base.consoleLog('%s<h1>%s</h1>', indent(), utils.escape(suite.title));
|
|
50
|
+
Base.consoleLog('%s<dl>', indent());
|
|
51
51
|
});
|
|
52
52
|
|
|
53
53
|
runner.on(EVENT_SUITE_END, function(suite) {
|
|
54
54
|
if (suite.root) {
|
|
55
55
|
return;
|
|
56
56
|
}
|
|
57
|
-
|
|
57
|
+
Base.consoleLog('%s</dl>', indent());
|
|
58
58
|
--indents;
|
|
59
|
-
|
|
59
|
+
Base.consoleLog('%s</section>', indent());
|
|
60
60
|
--indents;
|
|
61
61
|
});
|
|
62
62
|
|
|
63
63
|
runner.on(EVENT_TEST_PASS, function(test) {
|
|
64
|
-
|
|
64
|
+
Base.consoleLog('%s <dt>%s</dt>', indent(), utils.escape(test.title));
|
|
65
65
|
var code = utils.escape(utils.clean(test.body));
|
|
66
|
-
|
|
66
|
+
Base.consoleLog('%s <dd><pre><code>%s</code></pre></dd>', indent(), code);
|
|
67
67
|
});
|
|
68
68
|
|
|
69
69
|
runner.on(EVENT_TEST_FAIL, function(test, err) {
|
|
70
|
-
|
|
70
|
+
Base.consoleLog(
|
|
71
71
|
'%s <dt class="error">%s</dt>',
|
|
72
72
|
indent(),
|
|
73
73
|
utils.escape(test.title)
|
|
74
74
|
);
|
|
75
75
|
var code = utils.escape(utils.clean(test.body));
|
|
76
|
-
|
|
76
|
+
Base.consoleLog(
|
|
77
77
|
'%s <dd class="error"><pre><code>%s</code></pre></dd>',
|
|
78
78
|
indent(),
|
|
79
79
|
code
|
|
80
80
|
);
|
|
81
|
-
|
|
81
|
+
Base.consoleLog(
|
|
82
|
+
'%s <dd class="error">%s</dd>',
|
|
83
|
+
indent(),
|
|
84
|
+
utils.escape(err)
|
|
85
|
+
);
|
|
82
86
|
});
|
|
83
87
|
}
|
|
84
88
|
|
package/lib/reporters/dot.js
CHANGED
package/lib/reporters/landing.js
CHANGED
package/lib/reporters/list.js
CHANGED
|
@@ -41,7 +41,7 @@ function List(runner, options) {
|
|
|
41
41
|
var n = 0;
|
|
42
42
|
|
|
43
43
|
runner.on(EVENT_RUN_BEGIN, function() {
|
|
44
|
-
|
|
44
|
+
Base.consoleLog();
|
|
45
45
|
});
|
|
46
46
|
|
|
47
47
|
runner.on(EVENT_TEST_BEGIN, function(test) {
|
|
@@ -50,7 +50,7 @@ function List(runner, options) {
|
|
|
50
50
|
|
|
51
51
|
runner.on(EVENT_TEST_PENDING, function(test) {
|
|
52
52
|
var fmt = color('checkmark', ' -') + color('pending', ' %s');
|
|
53
|
-
|
|
53
|
+
Base.consoleLog(fmt, test.fullTitle());
|
|
54
54
|
});
|
|
55
55
|
|
|
56
56
|
runner.on(EVENT_TEST_PASS, function(test) {
|
|
@@ -59,12 +59,12 @@ function List(runner, options) {
|
|
|
59
59
|
color('pass', ' %s: ') +
|
|
60
60
|
color(test.speed, '%dms');
|
|
61
61
|
cursor.CR();
|
|
62
|
-
|
|
62
|
+
Base.consoleLog(fmt, test.fullTitle(), test.duration);
|
|
63
63
|
});
|
|
64
64
|
|
|
65
65
|
runner.on(EVENT_TEST_FAIL, function(test) {
|
|
66
66
|
cursor.CR();
|
|
67
|
-
|
|
67
|
+
Base.consoleLog(color('fail', ' %d) %s'), ++n, test.fullTitle());
|
|
68
68
|
});
|
|
69
69
|
|
|
70
70
|
runner.once(EVENT_RUN_END, self.epilogue.bind(self));
|
|
@@ -58,7 +58,7 @@ function Progress(runner, options) {
|
|
|
58
58
|
|
|
59
59
|
// tests started
|
|
60
60
|
runner.on(EVENT_RUN_BEGIN, function() {
|
|
61
|
-
|
|
61
|
+
process.stdout.write('\n');
|
|
62
62
|
cursor.hide();
|
|
63
63
|
});
|
|
64
64
|
|
|
@@ -91,7 +91,7 @@ function Progress(runner, options) {
|
|
|
91
91
|
// and the failures if any
|
|
92
92
|
runner.once(EVENT_RUN_END, function() {
|
|
93
93
|
cursor.show();
|
|
94
|
-
|
|
94
|
+
process.stdout.write('\n');
|
|
95
95
|
self.epilogue();
|
|
96
96
|
});
|
|
97
97
|
}
|
package/lib/reporters/spec.js
CHANGED
|
@@ -46,24 +46,24 @@ function Spec(runner, options) {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
runner.on(EVENT_RUN_BEGIN, function() {
|
|
49
|
-
|
|
49
|
+
Base.consoleLog();
|
|
50
50
|
});
|
|
51
51
|
|
|
52
52
|
runner.on(EVENT_SUITE_BEGIN, function(suite) {
|
|
53
53
|
++indents;
|
|
54
|
-
|
|
54
|
+
Base.consoleLog(color('suite', '%s%s'), indent(), suite.title);
|
|
55
55
|
});
|
|
56
56
|
|
|
57
57
|
runner.on(EVENT_SUITE_END, function() {
|
|
58
58
|
--indents;
|
|
59
59
|
if (indents === 1) {
|
|
60
|
-
|
|
60
|
+
Base.consoleLog();
|
|
61
61
|
}
|
|
62
62
|
});
|
|
63
63
|
|
|
64
64
|
runner.on(EVENT_TEST_PENDING, function(test) {
|
|
65
65
|
var fmt = indent() + color('pending', ' - %s');
|
|
66
|
-
|
|
66
|
+
Base.consoleLog(fmt, test.title);
|
|
67
67
|
});
|
|
68
68
|
|
|
69
69
|
runner.on(EVENT_TEST_PASS, function(test) {
|
|
@@ -73,19 +73,19 @@ function Spec(runner, options) {
|
|
|
73
73
|
indent() +
|
|
74
74
|
color('checkmark', ' ' + Base.symbols.ok) +
|
|
75
75
|
color('pass', ' %s');
|
|
76
|
-
|
|
76
|
+
Base.consoleLog(fmt, test.title);
|
|
77
77
|
} else {
|
|
78
78
|
fmt =
|
|
79
79
|
indent() +
|
|
80
80
|
color('checkmark', ' ' + Base.symbols.ok) +
|
|
81
81
|
color('pass', ' %s') +
|
|
82
82
|
color(test.speed, ' (%dms)');
|
|
83
|
-
|
|
83
|
+
Base.consoleLog(fmt, test.title, test.duration);
|
|
84
84
|
}
|
|
85
85
|
});
|
|
86
86
|
|
|
87
87
|
runner.on(EVENT_TEST_FAIL, function(test) {
|
|
88
|
-
|
|
88
|
+
Base.consoleLog(indent() + color('fail', ' %d) %s'), ++n, test.title);
|
|
89
89
|
});
|
|
90
90
|
|
|
91
91
|
runner.once(EVENT_RUN_END, self.epilogue.bind(self));
|
package/lib/reporters/xunit.js
CHANGED
package/lib/utils.js
CHANGED
|
@@ -562,32 +562,41 @@ function isHiddenOnUnix(pathname) {
|
|
|
562
562
|
*
|
|
563
563
|
* @public
|
|
564
564
|
* @memberof Mocha.utils
|
|
565
|
-
* @todo Fix extension handling
|
|
566
565
|
* @param {string} filepath - Base path to start searching from.
|
|
567
|
-
* @param {string[]} extensions - File extensions to look for.
|
|
568
|
-
* @param {boolean} recursive - Whether to recurse into subdirectories.
|
|
566
|
+
* @param {string[]} [extensions=[]] - File extensions to look for.
|
|
567
|
+
* @param {boolean} [recursive=false] - Whether to recurse into subdirectories.
|
|
569
568
|
* @return {string[]} An array of paths.
|
|
570
569
|
* @throws {Error} if no files match pattern.
|
|
571
570
|
* @throws {TypeError} if `filepath` is directory and `extensions` not provided.
|
|
572
571
|
*/
|
|
573
572
|
exports.lookupFiles = function lookupFiles(filepath, extensions, recursive) {
|
|
573
|
+
extensions = extensions || [];
|
|
574
|
+
recursive = recursive || false;
|
|
574
575
|
var files = [];
|
|
575
576
|
var stat;
|
|
576
577
|
|
|
577
578
|
if (!fs.existsSync(filepath)) {
|
|
578
|
-
|
|
579
|
-
|
|
579
|
+
var pattern;
|
|
580
|
+
if (glob.hasMagic(filepath)) {
|
|
581
|
+
// Handle glob as is without extensions
|
|
582
|
+
pattern = filepath;
|
|
580
583
|
} else {
|
|
581
|
-
//
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
584
|
+
// glob pattern e.g. 'filepath+(.js|.ts)'
|
|
585
|
+
var strExtensions = extensions
|
|
586
|
+
.map(function(v) {
|
|
587
|
+
return '.' + v;
|
|
588
|
+
})
|
|
589
|
+
.join('|');
|
|
590
|
+
pattern = filepath + '+(' + strExtensions + ')';
|
|
591
|
+
}
|
|
592
|
+
files = glob.sync(pattern, {nodir: true});
|
|
593
|
+
if (!files.length) {
|
|
594
|
+
throw createNoFilesMatchPatternError(
|
|
595
|
+
'Cannot find any files matching pattern ' + exports.dQuote(filepath),
|
|
596
|
+
filepath
|
|
597
|
+
);
|
|
590
598
|
}
|
|
599
|
+
return files;
|
|
591
600
|
}
|
|
592
601
|
|
|
593
602
|
// Handle file
|
|
@@ -618,7 +627,7 @@ exports.lookupFiles = function lookupFiles(filepath, extensions, recursive) {
|
|
|
618
627
|
// ignore error
|
|
619
628
|
return;
|
|
620
629
|
}
|
|
621
|
-
if (!extensions) {
|
|
630
|
+
if (!extensions.length) {
|
|
622
631
|
throw createMissingArgumentError(
|
|
623
632
|
util.format(
|
|
624
633
|
'Argument %s required when argument %s is a directory',
|
|
@@ -714,7 +723,8 @@ exports.stackTraceFilter = function() {
|
|
|
714
723
|
function isMochaInternal(line) {
|
|
715
724
|
return (
|
|
716
725
|
~line.indexOf('node_modules' + slash + 'mocha' + slash) ||
|
|
717
|
-
~line.indexOf(slash + 'mocha.js')
|
|
726
|
+
~line.indexOf(slash + 'mocha.js') ||
|
|
727
|
+
~line.indexOf(slash + 'mocha.min.js')
|
|
718
728
|
);
|
|
719
729
|
}
|
|
720
730
|
|