mocha 12.0.0-beta-3 → 12.0.0-beta-5
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/README.md +2 -2
- package/lib/cli/config.js +4 -2
- package/lib/cli/run-option-metadata.js +1 -0
- package/lib/cli/run.js +5 -0
- package/lib/mocha.js +15 -0
- package/lib/nodejs/esm-utils.js +1 -1
- package/lib/runner.js +118 -1
- package/mocha.js +2024 -3359
- package/mocha.js.map +1 -1
- package/mocha.mjs +2 -3
- package/package.json +16 -27
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img src="
|
|
2
|
+
<img src="docs-next/src/components/mocha-logo.svg" alt="Mocha test framework logo"/>
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
|
-
<p align="center">☕️
|
|
5
|
+
<p align="center">☕️ Classic, reliable, trusted test framework for Node.js and the browser ☕️</p>
|
|
6
6
|
|
|
7
7
|
<div align="center">
|
|
8
8
|
|
package/lib/cli/config.js
CHANGED
|
@@ -24,6 +24,7 @@ const utils = require("../utils");
|
|
|
24
24
|
exports.CONFIG_FILES = [
|
|
25
25
|
".mocharc.cjs",
|
|
26
26
|
".mocharc.js",
|
|
27
|
+
".mocharc.mjs",
|
|
27
28
|
".mocharc.yaml",
|
|
28
29
|
".mocharc.yml",
|
|
29
30
|
".mocharc.jsonc",
|
|
@@ -72,8 +73,9 @@ exports.loadConfig = (filepath) => {
|
|
|
72
73
|
try {
|
|
73
74
|
if (ext === ".yml" || ext === ".yaml") {
|
|
74
75
|
config = parsers.yaml(filepath);
|
|
75
|
-
} else if (ext === ".js" || ext === ".cjs") {
|
|
76
|
-
|
|
76
|
+
} else if (ext === ".js" || ext === ".cjs" || ext === ".mjs") {
|
|
77
|
+
const parsedConfig = parsers.js(filepath);
|
|
78
|
+
config = parsedConfig.default ?? parsedConfig;
|
|
77
79
|
} else {
|
|
78
80
|
config = parsers.json(filepath);
|
|
79
81
|
}
|
package/lib/cli/run.js
CHANGED
|
@@ -104,6 +104,11 @@ exports.builder = (yargs) =>
|
|
|
104
104
|
description: "Not fail test run if tests were failed",
|
|
105
105
|
group: GROUPS.RULES,
|
|
106
106
|
},
|
|
107
|
+
"fail-hook-affected-tests": {
|
|
108
|
+
description:
|
|
109
|
+
"Report tests as failed when affected by hook failures (before/beforeEach)",
|
|
110
|
+
group: GROUPS.RULES,
|
|
111
|
+
},
|
|
107
112
|
"fail-zero": {
|
|
108
113
|
description: "Fail test run if no test(s) encountered",
|
|
109
114
|
group: GROUPS.RULES,
|
package/lib/mocha.js
CHANGED
|
@@ -846,6 +846,20 @@ Mocha.prototype.dryRun = function (dryRun) {
|
|
|
846
846
|
return this;
|
|
847
847
|
};
|
|
848
848
|
|
|
849
|
+
/**
|
|
850
|
+
* Reports tests as failed when they are skipped due to a hook failure.
|
|
851
|
+
*
|
|
852
|
+
* @public
|
|
853
|
+
* @see [CLI option](../#-fail-hook-affected-tests)
|
|
854
|
+
* @param {boolean} [failHookAffectedTests=true] - Whether to fail tests affected by hook failures.
|
|
855
|
+
* @return {Mocha} this
|
|
856
|
+
* @chainable
|
|
857
|
+
*/
|
|
858
|
+
Mocha.prototype.failHookAffectedTests = function (failHookAffectedTests) {
|
|
859
|
+
this.options.failHookAffectedTests = failHookAffectedTests !== false;
|
|
860
|
+
return this;
|
|
861
|
+
};
|
|
862
|
+
|
|
849
863
|
/**
|
|
850
864
|
* Fails test run if no tests encountered with exit-code 1.
|
|
851
865
|
*
|
|
@@ -974,6 +988,7 @@ Mocha.prototype.run = function (fn) {
|
|
|
974
988
|
cleanReferencesAfterRun: this._cleanReferencesAfterRun,
|
|
975
989
|
delay: options.delay,
|
|
976
990
|
dryRun: options.dryRun,
|
|
991
|
+
failHookAffectedTests: options.failHookAffectedTests,
|
|
977
992
|
failZero: options.failZero,
|
|
978
993
|
});
|
|
979
994
|
createStatsCollector(runner);
|
package/lib/nodejs/esm-utils.js
CHANGED
|
@@ -98,7 +98,7 @@ const requireModule = async (file, esmDecorator) => {
|
|
|
98
98
|
return require(file);
|
|
99
99
|
} catch (requireErr) {
|
|
100
100
|
debug("requireModule caught err: %O", requireErr.message);
|
|
101
|
-
if (requireErr.name ===
|
|
101
|
+
if (requireErr.name === "TSError") {
|
|
102
102
|
throw requireErr;
|
|
103
103
|
}
|
|
104
104
|
try {
|
package/lib/runner.js
CHANGED
|
@@ -182,6 +182,7 @@ class Runner extends EventEmitter {
|
|
|
182
182
|
* @param {boolean} [opts.delay] - Whether to delay execution of root suite until ready.
|
|
183
183
|
* @param {boolean} [opts.dryRun] - Whether to report tests without running them.
|
|
184
184
|
* @param {boolean} [opts.failZero] - Whether to fail test run if zero tests encountered.
|
|
185
|
+
* @param {boolean} [opts.failHookAffectedTests] - Whether to fail all tests affected by hook failures.
|
|
185
186
|
*/
|
|
186
187
|
constructor(suite, opts = {}) {
|
|
187
188
|
super();
|
|
@@ -441,6 +442,73 @@ Runner.prototype.checkGlobals = function (test) {
|
|
|
441
442
|
}
|
|
442
443
|
};
|
|
443
444
|
|
|
445
|
+
/**
|
|
446
|
+
* Create an error object for a test that was skipped due to a hook failure.
|
|
447
|
+
*
|
|
448
|
+
* @private
|
|
449
|
+
* @param {string} hookTitle - The title of the failed hook
|
|
450
|
+
* @param {*} hookError - The error from the failed hook (may not be an Error object)
|
|
451
|
+
* @returns {Error} The error object for the skipped test
|
|
452
|
+
*/
|
|
453
|
+
function createHookSkipError(hookTitle, hookError) {
|
|
454
|
+
// Handle falsy or undefined exceptions
|
|
455
|
+
if (!hookError) {
|
|
456
|
+
hookError = createInvalidExceptionError(
|
|
457
|
+
'Hook "' + hookTitle + '" failed with exception: ' + hookError,
|
|
458
|
+
hookError,
|
|
459
|
+
);
|
|
460
|
+
}
|
|
461
|
+
// Convert non-Error objects to Error
|
|
462
|
+
else if (!isError(hookError)) {
|
|
463
|
+
hookError = thrown2Error(hookError);
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
var errorMessage =
|
|
467
|
+
'Test skipped due to failure in hook "' +
|
|
468
|
+
hookTitle +
|
|
469
|
+
'": ' +
|
|
470
|
+
hookError.message;
|
|
471
|
+
var testError = new Error(errorMessage);
|
|
472
|
+
testError.stack = hookError.stack;
|
|
473
|
+
return testError;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Fail all tests that are affected by a hook failure.
|
|
478
|
+
* This is used when the `failHookAffectedTests` option is enabled.
|
|
479
|
+
*
|
|
480
|
+
* @private
|
|
481
|
+
* @param {Suite} suite - The suite containing the affected tests
|
|
482
|
+
* @param {Error} hookError - The error from the failed hook
|
|
483
|
+
* @param {string} hookTitle - The title of the failed hook
|
|
484
|
+
*/
|
|
485
|
+
Runner.prototype.failAffectedTests = function (suite, hookError, hookTitle) {
|
|
486
|
+
if (!this._opts.failHookAffectedTests) {
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
var self = this;
|
|
491
|
+
var testError = createHookSkipError(hookTitle, hookError);
|
|
492
|
+
|
|
493
|
+
// Recursively fail all tests in this suite and its child suites
|
|
494
|
+
function failTestsInSuite(s) {
|
|
495
|
+
s.tests.forEach(function (test) {
|
|
496
|
+
// Only fail tests that haven't been executed yet
|
|
497
|
+
if (!test.state) {
|
|
498
|
+
test.state = STATE_FAILED;
|
|
499
|
+
self.failures++;
|
|
500
|
+
self.emit(constants.EVENT_TEST_BEGIN, test);
|
|
501
|
+
self.emit(constants.EVENT_TEST_FAIL, test, testError);
|
|
502
|
+
self.emit(constants.EVENT_TEST_END, test);
|
|
503
|
+
}
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
s.suites.forEach(failTestsInSuite);
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
failTestsInSuite(suite);
|
|
510
|
+
};
|
|
511
|
+
|
|
444
512
|
/**
|
|
445
513
|
* Fail the given `test`.
|
|
446
514
|
*
|
|
@@ -583,6 +651,28 @@ Runner.prototype.hook = function (name, fn) {
|
|
|
583
651
|
}
|
|
584
652
|
} else if (err) {
|
|
585
653
|
self.fail(hook, err);
|
|
654
|
+
// If failHookAffectedTests is enabled, mark affected tests as failed
|
|
655
|
+
if (self._opts.failHookAffectedTests) {
|
|
656
|
+
if (name === HOOK_TYPE_BEFORE_ALL) {
|
|
657
|
+
self.failAffectedTests(self.suite, err, hook.title);
|
|
658
|
+
} else if (name === HOOK_TYPE_BEFORE_EACH) {
|
|
659
|
+
// Fail the current test
|
|
660
|
+
if (self.test && !self.test.state) {
|
|
661
|
+
var testError = createHookSkipError(hook.title, err);
|
|
662
|
+
|
|
663
|
+
self.test.state = STATE_FAILED;
|
|
664
|
+
self.failures++;
|
|
665
|
+
self.emit(constants.EVENT_TEST_BEGIN, self.test);
|
|
666
|
+
self.emit(constants.EVENT_TEST_FAIL, self.test, testError);
|
|
667
|
+
self.emit(constants.EVENT_TEST_END, self.test);
|
|
668
|
+
}
|
|
669
|
+
// Store the hook error info for remaining tests
|
|
670
|
+
self._failedBeforeEachHook = {
|
|
671
|
+
error: err,
|
|
672
|
+
title: hook.title,
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
}
|
|
586
676
|
// stop executing hooks, notify callee of hook err
|
|
587
677
|
return fn(err);
|
|
588
678
|
}
|
|
@@ -734,10 +824,37 @@ Runner.prototype.runTests = function (suite, fn) {
|
|
|
734
824
|
var tests = suite.tests.slice();
|
|
735
825
|
var test;
|
|
736
826
|
|
|
737
|
-
function hookErr(
|
|
827
|
+
function hookErr(err, errSuite, after) {
|
|
738
828
|
// before/after Each hook for errSuite failed:
|
|
739
829
|
var orig = self.suite;
|
|
740
830
|
|
|
831
|
+
// If failHookAffectedTests is enabled and this is a beforeEach failure,
|
|
832
|
+
// mark remaining tests as failed
|
|
833
|
+
if (
|
|
834
|
+
self._opts.failHookAffectedTests &&
|
|
835
|
+
!after &&
|
|
836
|
+
self._failedBeforeEachHook
|
|
837
|
+
) {
|
|
838
|
+
// Fail all remaining tests in the suite
|
|
839
|
+
var remainingTests = tests.slice();
|
|
840
|
+
remainingTests.forEach(function (t) {
|
|
841
|
+
if (!t.state) {
|
|
842
|
+
var testError = createHookSkipError(
|
|
843
|
+
self._failedBeforeEachHook.title,
|
|
844
|
+
self._failedBeforeEachHook.error,
|
|
845
|
+
);
|
|
846
|
+
|
|
847
|
+
t.state = STATE_FAILED;
|
|
848
|
+
self.failures++;
|
|
849
|
+
self.emit(constants.EVENT_TEST_BEGIN, t);
|
|
850
|
+
self.emit(constants.EVENT_TEST_FAIL, t, testError);
|
|
851
|
+
self.emit(constants.EVENT_TEST_END, t);
|
|
852
|
+
}
|
|
853
|
+
});
|
|
854
|
+
// Clear the stored hook info
|
|
855
|
+
delete self._failedBeforeEachHook;
|
|
856
|
+
}
|
|
857
|
+
|
|
741
858
|
// for failed 'after each' hook start from errSuite parent,
|
|
742
859
|
// otherwise start from errSuite itself
|
|
743
860
|
self.suite = after ? errSuite.parent : errSuite;
|