@rstest/core 0.6.3 → 0.6.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/dist/0~470.js +1 -0
- package/dist/0~764.js +9 -1
- package/dist/0~814.js +8 -2
- package/dist/0~971.js +59 -27
- package/dist/index.js +41 -12
- package/dist/worker.js +10 -2
- package/dist-types/index.d.ts +46 -20
- package/dist-types/worker.d.ts +29 -3
- package/package.json +1 -1
package/dist/0~470.js
CHANGED
|
@@ -198,6 +198,7 @@ async function runTests(context) {
|
|
|
198
198
|
let testStart;
|
|
199
199
|
const currentEntries = [];
|
|
200
200
|
const currentDeletedEntries = [];
|
|
201
|
+
context.stateManager.reset();
|
|
201
202
|
const returns = await Promise.all(context.projects.map(async (p)=>{
|
|
202
203
|
const { assetNames, entries, setupEntries, getAssetFiles, getSourceMaps, affectedEntries, deletedEntries } = await getRsbuildStats({
|
|
203
204
|
environmentName: p.environmentName,
|
package/dist/0~764.js
CHANGED
|
@@ -11767,6 +11767,9 @@ use(JestExtend);
|
|
|
11767
11767
|
use(JestChaiExpect);
|
|
11768
11768
|
use(SnapshotPlugin);
|
|
11769
11769
|
use(JestAsymmetricMatchers);
|
|
11770
|
+
function setupChaiConfig(config) {
|
|
11771
|
+
Object.assign(chai_config, config);
|
|
11772
|
+
}
|
|
11770
11773
|
function createExpect({ getCurrentTest, workerState }) {
|
|
11771
11774
|
const expect = (value, message)=>{
|
|
11772
11775
|
const { assertionCalls } = getState(expect);
|
|
@@ -12081,7 +12084,7 @@ class TestRunner {
|
|
|
12081
12084
|
workerState;
|
|
12082
12085
|
async runTests({ tests, testPath, state, hooks, api }) {
|
|
12083
12086
|
this.workerState = state;
|
|
12084
|
-
const { runtimeConfig: { passWithNoTests, retry, maxConcurrency }, project, snapshotOptions } = state;
|
|
12087
|
+
const { runtimeConfig: { passWithNoTests, retry, maxConcurrency, bail }, project, snapshotOptions } = state;
|
|
12085
12088
|
const results = [];
|
|
12086
12089
|
const errors = [];
|
|
12087
12090
|
let defaultStatus = 'pass';
|
|
@@ -12226,6 +12229,10 @@ class TestRunner {
|
|
|
12226
12229
|
}
|
|
12227
12230
|
};
|
|
12228
12231
|
const runTest = async (test, parentHooks)=>{
|
|
12232
|
+
if (bail && await hooks.getCountOfFailedTests() >= bail) {
|
|
12233
|
+
defaultStatus = 'skip';
|
|
12234
|
+
return;
|
|
12235
|
+
}
|
|
12229
12236
|
if ('suite' === test.type) {
|
|
12230
12237
|
if (0 === test.tests.length) {
|
|
12231
12238
|
if ([
|
|
@@ -13258,6 +13265,7 @@ const createRstestRuntime = (workerState)=>{
|
|
|
13258
13265
|
const { runner, api: runnerAPI } = createRunner({
|
|
13259
13266
|
workerState
|
|
13260
13267
|
});
|
|
13268
|
+
if (workerState.runtimeConfig.chaiConfig) setupChaiConfig(workerState.runtimeConfig.chaiConfig);
|
|
13261
13269
|
const expect = createExpect({
|
|
13262
13270
|
workerState,
|
|
13263
13271
|
getCurrentTest: ()=>runner.getCurrentTest()
|
package/dist/0~814.js
CHANGED
|
@@ -100,7 +100,7 @@ const parseWorkers = (maxWorkers)=>{
|
|
|
100
100
|
return parsed > 0 ? parsed : 1;
|
|
101
101
|
};
|
|
102
102
|
const getRuntimeConfig = (context)=>{
|
|
103
|
-
const { testNamePattern, testTimeout, passWithNoTests, retry, globals, clearMocks, resetMocks, restoreMocks, unstubEnvs, unstubGlobals, maxConcurrency, printConsoleTrace, disableConsoleIntercept, testEnvironment, hookTimeout, isolate, coverage, snapshotFormat, env, logHeapUsage } = context.normalizedConfig;
|
|
103
|
+
const { testNamePattern, testTimeout, passWithNoTests, retry, globals, clearMocks, resetMocks, restoreMocks, unstubEnvs, unstubGlobals, maxConcurrency, printConsoleTrace, disableConsoleIntercept, testEnvironment, hookTimeout, isolate, coverage, snapshotFormat, env, logHeapUsage, bail, chaiConfig } = context.normalizedConfig;
|
|
104
104
|
return {
|
|
105
105
|
env,
|
|
106
106
|
testNamePattern,
|
|
@@ -121,7 +121,9 @@ const getRuntimeConfig = (context)=>{
|
|
|
121
121
|
isolate,
|
|
122
122
|
coverage,
|
|
123
123
|
snapshotFormat,
|
|
124
|
-
logHeapUsage
|
|
124
|
+
logHeapUsage,
|
|
125
|
+
bail,
|
|
126
|
+
chaiConfig
|
|
125
127
|
};
|
|
126
128
|
};
|
|
127
129
|
const filterAssetsByEntry = async (entryInfo, getAssetFiles, getSourceMaps, setupAssets)=>{
|
|
@@ -166,12 +168,15 @@ const createPool = async ({ context, recommendWorkerCount = 1 / 0 })=>{
|
|
|
166
168
|
});
|
|
167
169
|
const rpcMethods = {
|
|
168
170
|
onTestCaseResult: async (result)=>{
|
|
171
|
+
context.stateManager.onTestCaseResult(result);
|
|
169
172
|
await Promise.all(reporters.map((reporter)=>reporter.onTestCaseResult?.(result)));
|
|
170
173
|
},
|
|
174
|
+
getCountOfFailedTests: async ()=>context.stateManager.getCountOfFailedTests(),
|
|
171
175
|
onConsoleLog: async (log)=>{
|
|
172
176
|
await Promise.all(reporters.map((reporter)=>reporter.onUserConsoleLog?.(log)));
|
|
173
177
|
},
|
|
174
178
|
onTestFileStart: async (test)=>{
|
|
179
|
+
context.stateManager.onTestFileStart(test.testPath);
|
|
175
180
|
await Promise.all(reporters.map((reporter)=>reporter.onTestFileStart?.(test)));
|
|
176
181
|
},
|
|
177
182
|
resolveSnapshotPath: (testPath)=>{
|
|
@@ -219,6 +224,7 @@ const createPool = async ({ context, recommendWorkerCount = 1 / 0 })=>{
|
|
|
219
224
|
]
|
|
220
225
|
};
|
|
221
226
|
});
|
|
227
|
+
context.stateManager.onTestFileResult(result);
|
|
222
228
|
reporters.map((reporter)=>reporter.onTestFileResult?.(result));
|
|
223
229
|
return result;
|
|
224
230
|
}));
|
package/dist/0~971.js
CHANGED
|
@@ -7,23 +7,7 @@ const external_node_fs_ = __webpack_require__("node:fs");
|
|
|
7
7
|
const external_node_path_ = __webpack_require__("node:path");
|
|
8
8
|
const picocolors = __webpack_require__("../../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js");
|
|
9
9
|
var picocolors_default = /*#__PURE__*/ __webpack_require__.n(picocolors);
|
|
10
|
-
async
|
|
11
|
-
const { rootPath } = context;
|
|
12
|
-
const testEntries = {};
|
|
13
|
-
const globTestSourceEntries = async (name)=>{
|
|
14
|
-
if (testEntries[name]) return testEntries[name];
|
|
15
|
-
const { include, exclude, includeSource, root } = context.projects.find((p)=>p.environmentName === name).normalizedConfig;
|
|
16
|
-
const entries = await getTestEntries({
|
|
17
|
-
include,
|
|
18
|
-
exclude: exclude.patterns,
|
|
19
|
-
rootPath,
|
|
20
|
-
projectRoot: root,
|
|
21
|
-
fileFilters: context.fileFilters || [],
|
|
22
|
-
includeSource
|
|
23
|
-
});
|
|
24
|
-
testEntries[name] = entries;
|
|
25
|
-
return entries;
|
|
26
|
-
};
|
|
10
|
+
const collectTests = async ({ context, globTestSourceEntries })=>{
|
|
27
11
|
const setupFiles = Object.fromEntries(context.projects.map((project)=>{
|
|
28
12
|
const { environmentName, rootPath, normalizedConfig: { setupFiles } } = project;
|
|
29
13
|
return [
|
|
@@ -40,7 +24,7 @@ async function listTests(context, { filesOnly, json }) {
|
|
|
40
24
|
},
|
|
41
25
|
setupFiles,
|
|
42
26
|
rsbuildInstance,
|
|
43
|
-
rootPath
|
|
27
|
+
rootPath: context.rootPath
|
|
44
28
|
});
|
|
45
29
|
const pool = await createPool({
|
|
46
30
|
context
|
|
@@ -64,7 +48,60 @@ async function listTests(context, { filesOnly, json }) {
|
|
|
64
48
|
assetNames
|
|
65
49
|
};
|
|
66
50
|
}));
|
|
67
|
-
|
|
51
|
+
return {
|
|
52
|
+
list: returns.flatMap((r)=>r.list),
|
|
53
|
+
getSourceMap: async (name)=>{
|
|
54
|
+
const resource = returns.find((r)=>r.assetNames.includes(name));
|
|
55
|
+
return (await resource?.getSourceMaps([
|
|
56
|
+
name
|
|
57
|
+
]))?.[name];
|
|
58
|
+
},
|
|
59
|
+
close: async ()=>{
|
|
60
|
+
await closeServer();
|
|
61
|
+
await pool.close();
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
const collectTestFiles = async ({ context, globTestSourceEntries })=>{
|
|
66
|
+
const list = [];
|
|
67
|
+
for (const project of context.projects){
|
|
68
|
+
const files = await globTestSourceEntries(project.environmentName);
|
|
69
|
+
list.push(...Object.values(files).map((testPath)=>({
|
|
70
|
+
testPath,
|
|
71
|
+
project: project.name,
|
|
72
|
+
tests: []
|
|
73
|
+
})));
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
close: async ()=>{},
|
|
77
|
+
list,
|
|
78
|
+
getSourceMap: async (_name)=>null
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
async function listTests(context, { filesOnly, json }) {
|
|
82
|
+
const { rootPath } = context;
|
|
83
|
+
const testEntries = {};
|
|
84
|
+
const globTestSourceEntries = async (name)=>{
|
|
85
|
+
if (testEntries[name]) return testEntries[name];
|
|
86
|
+
const { include, exclude, includeSource, root } = context.projects.find((p)=>p.environmentName === name).normalizedConfig;
|
|
87
|
+
const entries = await getTestEntries({
|
|
88
|
+
include,
|
|
89
|
+
exclude: exclude.patterns,
|
|
90
|
+
rootPath,
|
|
91
|
+
projectRoot: root,
|
|
92
|
+
fileFilters: context.fileFilters || [],
|
|
93
|
+
includeSource
|
|
94
|
+
});
|
|
95
|
+
testEntries[name] = entries;
|
|
96
|
+
return entries;
|
|
97
|
+
};
|
|
98
|
+
const { list, close, getSourceMap } = filesOnly ? await collectTestFiles({
|
|
99
|
+
context,
|
|
100
|
+
globTestSourceEntries
|
|
101
|
+
}) : await collectTests({
|
|
102
|
+
context,
|
|
103
|
+
globTestSourceEntries
|
|
104
|
+
});
|
|
68
105
|
const tests = [];
|
|
69
106
|
const traverseTests = (test)=>{
|
|
70
107
|
if ([
|
|
@@ -94,16 +131,12 @@ async function listTests(context, { filesOnly, json }) {
|
|
|
94
131
|
if (file.errors?.length) {
|
|
95
132
|
src_logger.log(`${picocolors_default().bgRed(' FAIL ')} ${relativePath}`);
|
|
96
133
|
for (const error of file.errors)await printError(error, async (name)=>{
|
|
97
|
-
const
|
|
98
|
-
const sourceMap = (await resource?.getSourceMaps([
|
|
99
|
-
name
|
|
100
|
-
]))?.[name];
|
|
134
|
+
const sourceMap = await getSourceMap(name);
|
|
101
135
|
return sourceMap ? JSON.parse(sourceMap) : null;
|
|
102
136
|
}, rootPath);
|
|
103
137
|
}
|
|
104
138
|
}
|
|
105
|
-
await
|
|
106
|
-
await pool.close();
|
|
139
|
+
await close();
|
|
107
140
|
return;
|
|
108
141
|
}
|
|
109
142
|
for (const file of list){
|
|
@@ -132,7 +165,6 @@ async function listTests(context, { filesOnly, json }) {
|
|
|
132
165
|
const shortPath = (0, external_node_path_.relative)(rootPath, test.file);
|
|
133
166
|
src_logger.log(test.name ? `${picocolors_default().dim(`${shortPath} > `)}${test.name}` : prettyTestPath(shortPath));
|
|
134
167
|
}
|
|
135
|
-
await
|
|
136
|
-
await pool.close();
|
|
168
|
+
await close();
|
|
137
169
|
}
|
|
138
170
|
export { listTests };
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import 'module';
|
|
|
3
3
|
import { __webpack_require__ } from "./rslib-runtime.js";
|
|
4
4
|
import { EventEmitter } from "events";
|
|
5
5
|
import { createRsbuild, loadConfig, logger, mergeRsbuildConfig } from "@rsbuild/core";
|
|
6
|
-
import { basename, DEFAULT_CONFIG_EXTENSIONS, TS_CONFIG_FILE,
|
|
6
|
+
import { basename, DEFAULT_CONFIG_EXTENSIONS, TS_CONFIG_FILE, isTTY, dirname, posix, resolve as pathe_M_eThtNZ_resolve, pathe_M_eThtNZ_relative, DEFAULT_CONFIG_NAME, globalApis, formatTestPath, getAbsolutePath, filterProjects, join, formatRootStr, isDynamicPattern, glob, writeFile, castArray, src_logger, prettyTestPath, prettyTime, isDebug, isAbsolute, getTaskNameWithPrefix, formatError, normalize, TEMP_RSTEST_OUTPUT_DIR_GLOB } from "./857.js";
|
|
7
7
|
import { decode } from "./597.js";
|
|
8
8
|
function toArr(any) {
|
|
9
9
|
return null == any ? [] : Array.isArray(any) ? any : [
|
|
@@ -500,13 +500,13 @@ function prepareCli() {
|
|
|
500
500
|
if (!npm_execpath || npm_execpath.includes('npx-cli.js') || npm_execpath.includes('.bun')) console.log();
|
|
501
501
|
}
|
|
502
502
|
function showRstest() {
|
|
503
|
-
src_logger.greet(" Rstest v0.6.
|
|
503
|
+
src_logger.greet(" Rstest v0.6.5");
|
|
504
504
|
src_logger.log('');
|
|
505
505
|
}
|
|
506
506
|
const applyCommonOptions = (cli)=>{
|
|
507
507
|
cli.option('-c, --config <config>', 'Specify the configuration file, can be a relative or absolute path').option('--config-loader <loader>', 'Specify the loader to load the config file, can be `jiti` or `native`', {
|
|
508
508
|
default: 'jiti'
|
|
509
|
-
}).option('-r, --root <root>', 'Specify the project root directory, can be an absolute path or a path relative to cwd').option('--globals', 'Provide global APIs').option('--isolate', 'Run tests in an isolated environment').option('--include <include>', 'Match test files').option('--exclude <exclude>', 'Exclude files from test').option('-u, --update', 'Update snapshot files').option('--coverage', 'Enable code coverage collection').option('--project <name>', 'Run only projects that match the name, can be a full name or wildcards pattern').option('--passWithNoTests', 'Allows the test suite to pass when no files are found').option('--printConsoleTrace', 'Print console traces when calling any console method').option('--disableConsoleIntercept', 'Disable console intercept').option('--logHeapUsage', 'Log heap usage after each test').option('--slowTestThreshold <value>', 'The number of milliseconds after which a test or suite is considered slow').option('--reporter <reporter>', 'Specify the reporter to use').option('-t, --testNamePattern <value>', 'Run only tests with a name that matches the regex').option('--testEnvironment <name>', 'The environment that will be used for testing').option('--testTimeout <value>', 'Timeout of a test in milliseconds').option('--hookTimeout <value>', 'Timeout of hook in milliseconds').option('--hideSkippedTests', 'Hide skipped tests from the output').option('--retry <retry>', 'Number of times to retry a test if it fails').option('--maxConcurrency <value>', 'Maximum number of concurrent tests').option('--clearMocks', 'Automatically clear mock calls, instances, contexts and results before every test').option('--resetMocks', 'Automatically reset mock state before every test').option('--restoreMocks', 'Automatically restore mock state and implementation before every test').option('--unstubGlobals', 'Restores all global variables that were changed with `rstest.stubGlobal` before every test').option('--unstubEnvs', 'Restores all `process.env` values that were changed with `rstest.stubEnv` before every test');
|
|
509
|
+
}).option('-r, --root <root>', 'Specify the project root directory, can be an absolute path or a path relative to cwd').option('--globals', 'Provide global APIs').option('--isolate', 'Run tests in an isolated environment').option('--include <include>', 'Match test files').option('--exclude <exclude>', 'Exclude files from test').option('-u, --update', 'Update snapshot files').option('--coverage', 'Enable code coverage collection').option('--project <name>', 'Run only projects that match the name, can be a full name or wildcards pattern').option('--passWithNoTests', 'Allows the test suite to pass when no files are found').option('--printConsoleTrace', 'Print console traces when calling any console method').option('--disableConsoleIntercept', 'Disable console intercept').option('--logHeapUsage', 'Log heap usage after each test').option('--slowTestThreshold <value>', 'The number of milliseconds after which a test or suite is considered slow').option('--reporter <reporter>', 'Specify the reporter to use').option('-t, --testNamePattern <value>', 'Run only tests with a name that matches the regex').option('--testEnvironment <name>', 'The environment that will be used for testing').option('--testTimeout <value>', 'Timeout of a test in milliseconds').option('--hookTimeout <value>', 'Timeout of hook in milliseconds').option('--hideSkippedTests', 'Hide skipped tests from the output').option('--retry <retry>', 'Number of times to retry a test if it fails').option('--bail <number>', 'Stop running tests after n failures. Set to 0 to run all tests regardless of failures').option('--maxConcurrency <value>', 'Maximum number of concurrent tests').option('--clearMocks', 'Automatically clear mock calls, instances, contexts and results before every test').option('--resetMocks', 'Automatically reset mock state before every test').option('--restoreMocks', 'Automatically restore mock state and implementation before every test').option('--unstubGlobals', 'Restores all global variables that were changed with `rstest.stubGlobal` before every test').option('--unstubEnvs', 'Restores all `process.env` values that were changed with `rstest.stubEnv` before every test');
|
|
510
510
|
};
|
|
511
511
|
const runRest = async ({ options, filters, command })=>{
|
|
512
512
|
let rstest;
|
|
@@ -544,7 +544,7 @@ const runRest = async ({ options, filters, command })=>{
|
|
|
544
544
|
function setupCommands() {
|
|
545
545
|
const cli = dist('rstest');
|
|
546
546
|
cli.help();
|
|
547
|
-
cli.version("0.6.
|
|
547
|
+
cli.version("0.6.5");
|
|
548
548
|
applyCommonOptions(cli);
|
|
549
549
|
cli.command('[...filters]', 'run tests').option('-w, --watch', 'Run tests in watch mode').action(async (filters, options)=>{
|
|
550
550
|
showRstest();
|
|
@@ -697,6 +697,7 @@ const createDefaultConfig = ()=>({
|
|
|
697
697
|
env: {},
|
|
698
698
|
hideSkippedTests: false,
|
|
699
699
|
logHeapUsage: false,
|
|
700
|
+
bail: 0,
|
|
700
701
|
coverage: {
|
|
701
702
|
exclude: [
|
|
702
703
|
'**/node_modules/**',
|
|
@@ -707,9 +708,9 @@ const createDefaultConfig = ()=>({
|
|
|
707
708
|
'**/__mocks__/**',
|
|
708
709
|
'**/*.d.ts',
|
|
709
710
|
'**/*.{test,spec}.[jt]s',
|
|
710
|
-
'**/*.{test,spec}.[
|
|
711
|
+
'**/*.{test,spec}.[cm][jt]s',
|
|
711
712
|
'**/*.{test,spec}.[jt]sx',
|
|
712
|
-
'**/*.{test,spec}.[
|
|
713
|
+
'**/*.{test,spec}.[cm][jt]sx'
|
|
713
714
|
],
|
|
714
715
|
enabled: false,
|
|
715
716
|
provider: 'istanbul',
|
|
@@ -771,7 +772,8 @@ async function resolveConfig(options) {
|
|
|
771
772
|
'disableConsoleIntercept',
|
|
772
773
|
'testEnvironment',
|
|
773
774
|
'hideSkippedTests',
|
|
774
|
-
'logHeapUsage'
|
|
775
|
+
'logHeapUsage',
|
|
776
|
+
'bail'
|
|
775
777
|
];
|
|
776
778
|
for (const key of keys)if (void 0 !== options[key]) config[key] = options[key];
|
|
777
779
|
if (options.reporter) config.reporters = castArray(options.reporter);
|
|
@@ -1650,7 +1652,7 @@ class DefaultReporter {
|
|
|
1650
1652
|
this.rootPath = rootPath;
|
|
1651
1653
|
this.config = config;
|
|
1652
1654
|
this.options = options;
|
|
1653
|
-
if (
|
|
1655
|
+
if (isTTY()) this.statusRenderer = new StatusRenderer(rootPath);
|
|
1654
1656
|
}
|
|
1655
1657
|
onTestFileStart(test) {
|
|
1656
1658
|
this.statusRenderer?.onTestFileStart(test.testPath);
|
|
@@ -2308,6 +2310,31 @@ class VerboseReporter extends DefaultReporter {
|
|
|
2308
2310
|
});
|
|
2309
2311
|
}
|
|
2310
2312
|
}
|
|
2313
|
+
class TestStateManager {
|
|
2314
|
+
runningModules = new Map();
|
|
2315
|
+
testModules = [];
|
|
2316
|
+
onTestFileStart(testPath) {
|
|
2317
|
+
this.runningModules.set(testPath, []);
|
|
2318
|
+
}
|
|
2319
|
+
onTestCaseResult(result) {
|
|
2320
|
+
this.runningModules.set(result.testPath, [
|
|
2321
|
+
...this.runningModules.get(result.testPath) || [],
|
|
2322
|
+
result
|
|
2323
|
+
]);
|
|
2324
|
+
}
|
|
2325
|
+
getCountOfFailedTests() {
|
|
2326
|
+
const testResults = Array.from(this.runningModules.values()).flat().concat(this.testModules.flatMap((mod)=>mod.results));
|
|
2327
|
+
return testResults.filter((t)=>'fail' === t.status).length;
|
|
2328
|
+
}
|
|
2329
|
+
onTestFileResult(test) {
|
|
2330
|
+
this.runningModules.delete(test.testPath);
|
|
2331
|
+
this.testModules.push(test);
|
|
2332
|
+
}
|
|
2333
|
+
reset() {
|
|
2334
|
+
this.runningModules.clear();
|
|
2335
|
+
this.testModules = [];
|
|
2336
|
+
}
|
|
2337
|
+
}
|
|
2311
2338
|
function formatEnvironmentName(name) {
|
|
2312
2339
|
return name.replace(/[^a-zA-Z0-9\-_$]/g, '_');
|
|
2313
2340
|
}
|
|
@@ -2322,11 +2349,11 @@ class Rstest {
|
|
|
2322
2349
|
rootPath;
|
|
2323
2350
|
originalConfig;
|
|
2324
2351
|
normalizedConfig;
|
|
2325
|
-
idMap = new Map();
|
|
2326
2352
|
reporterResults = {
|
|
2327
2353
|
results: [],
|
|
2328
2354
|
testResults: []
|
|
2329
2355
|
};
|
|
2356
|
+
stateManager = new TestStateManager();
|
|
2330
2357
|
projects = [];
|
|
2331
2358
|
constructor({ cwd = process.cwd(), command, fileFilters, configFilePath, projects }, userConfig){
|
|
2332
2359
|
this.cwd = cwd;
|
|
@@ -2347,7 +2374,7 @@ class Rstest {
|
|
|
2347
2374
|
});
|
|
2348
2375
|
this.reporters = reporters;
|
|
2349
2376
|
this.snapshotManager = snapshotManager;
|
|
2350
|
-
this.version = "0.6.
|
|
2377
|
+
this.version = "0.6.5";
|
|
2351
2378
|
this.rootPath = rootPath;
|
|
2352
2379
|
this.originalConfig = userConfig;
|
|
2353
2380
|
this.normalizedConfig = rstestConfig;
|
|
@@ -2355,9 +2382,11 @@ class Rstest {
|
|
|
2355
2382
|
project.config.root = getAbsolutePath(rootPath, project.config.root);
|
|
2356
2383
|
const config = withDefaultConfig(project.config);
|
|
2357
2384
|
config.isolate = rstestConfig.isolate;
|
|
2358
|
-
config.source ??= {};
|
|
2359
2385
|
config.coverage = rstestConfig.coverage;
|
|
2360
|
-
|
|
2386
|
+
config.bail = rstestConfig.bail;
|
|
2387
|
+
config.source ??= {};
|
|
2388
|
+
if (config.source.tsconfigPath) config.source.tsconfigPath = getAbsolutePath(config.root, config.source.tsconfigPath);
|
|
2389
|
+
else {
|
|
2361
2390
|
const tsconfigPath = join(config.root, TS_CONFIG_FILE);
|
|
2362
2391
|
if ((0, external_node_fs_.existsSync)(tsconfigPath)) config.source.tsconfigPath = tsconfigPath;
|
|
2363
2392
|
}
|
package/dist/worker.js
CHANGED
|
@@ -7129,7 +7129,7 @@ const loadFiles = async ({ setupEntries, assetFiles, rstestContext, distPath, te
|
|
|
7129
7129
|
};
|
|
7130
7130
|
const runInPool = async (options)=>{
|
|
7131
7131
|
isTeardown = false;
|
|
7132
|
-
const { entryInfo: { distPath, testPath }, setupEntries, assets, type, context: { project, runtimeConfig: { isolate } } } = options;
|
|
7132
|
+
const { entryInfo: { distPath, testPath }, setupEntries, assets, type, context: { project, runtimeConfig: { isolate, bail } } } = options;
|
|
7133
7133
|
const cleanups = [];
|
|
7134
7134
|
const exit = process.exit.bind(process);
|
|
7135
7135
|
process.exit = (code = process.exitCode || 0)=>{
|
|
@@ -7182,6 +7182,13 @@ const runInPool = async (options)=>{
|
|
|
7182
7182
|
}
|
|
7183
7183
|
try {
|
|
7184
7184
|
const { rstestContext, runner, rpc, api, cleanup, unhandledErrors, interopDefault } = await preparePool(options);
|
|
7185
|
+
if (bail && await rpc.getCountOfFailedTests() >= bail) return {
|
|
7186
|
+
project,
|
|
7187
|
+
testPath,
|
|
7188
|
+
status: 'skip',
|
|
7189
|
+
name: '',
|
|
7190
|
+
results: []
|
|
7191
|
+
};
|
|
7185
7192
|
const coverageProvider = await createCoverageProvider(options.context.runtimeConfig.coverage || {}, options.context.rootPath);
|
|
7186
7193
|
if (coverageProvider) coverageProvider.init();
|
|
7187
7194
|
const { assetFiles, sourceMaps: sourceMapsFromAssets } = assets || await rpc.getAssetsByEntry();
|
|
@@ -7202,7 +7209,8 @@ const runInPool = async (options)=>{
|
|
|
7202
7209
|
const results = await runner.runTests(testPath, {
|
|
7203
7210
|
onTestCaseResult: async (result)=>{
|
|
7204
7211
|
await rpc.onTestCaseResult(result);
|
|
7205
|
-
}
|
|
7212
|
+
},
|
|
7213
|
+
getCountOfFailedTests: async ()=>rpc.getCountOfFailedTests()
|
|
7206
7214
|
}, api);
|
|
7207
7215
|
if (unhandledErrors.length > 0) {
|
|
7208
7216
|
results.status = 'fail';
|
package/dist-types/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { assert as assert_2 } from 'chai';
|
|
2
|
+
import type { config } from 'chai';
|
|
2
3
|
import { LoadConfigOptions } from '@rsbuild/core';
|
|
3
4
|
import type { RsbuildConfig } from '@rsbuild/core';
|
|
4
5
|
import type { RsbuildPlugin } from '@rsbuild/core';
|
|
@@ -272,6 +273,8 @@ declare type BuiltinReporterOptions = {
|
|
|
272
273
|
default: DefaultReporterOptions;
|
|
273
274
|
};
|
|
274
275
|
|
|
276
|
+
declare type ChaiConfig = Partial<Omit<typeof config, 'useProxy' | 'proxyExcludedKeys' | 'deepEqual'>>;
|
|
277
|
+
|
|
275
278
|
declare interface CloverOptions extends FileOptions, ProjectOptions {}
|
|
276
279
|
|
|
277
280
|
declare interface CoberturaOptions extends FileOptions, ProjectOptions {}
|
|
@@ -334,6 +337,7 @@ declare type CommonOptions = {
|
|
|
334
337
|
maxConcurrency?: number;
|
|
335
338
|
slowTestThreshold?: number;
|
|
336
339
|
hideSkippedTests?: boolean;
|
|
340
|
+
bail?: number;
|
|
337
341
|
};
|
|
338
342
|
|
|
339
343
|
declare type CompareKeys = ((a: string, b: string) => number) | null | undefined;
|
|
@@ -634,20 +638,20 @@ export declare function defineProject(config: ProjectConfigSyncFn): ProjectConfi
|
|
|
634
638
|
|
|
635
639
|
export declare function defineProject(config: ProjectConfigAsyncFn): ProjectConfigAsyncFn;
|
|
636
640
|
|
|
637
|
-
export declare
|
|
638
|
-
|
|
639
|
-
declare type DescribeAPI = DescribeFn & {
|
|
641
|
+
export declare type Describe = DescribeFn & {
|
|
640
642
|
each: DescribeEachFn;
|
|
641
643
|
for: DescribeForFn;
|
|
642
|
-
only:
|
|
643
|
-
skip:
|
|
644
|
-
runIf: (condition: boolean) =>
|
|
645
|
-
skipIf: (condition: boolean) =>
|
|
646
|
-
todo:
|
|
647
|
-
concurrent:
|
|
648
|
-
sequential:
|
|
644
|
+
only: Describe;
|
|
645
|
+
skip: Describe;
|
|
646
|
+
runIf: (condition: boolean) => Describe;
|
|
647
|
+
skipIf: (condition: boolean) => Describe;
|
|
648
|
+
todo: Describe;
|
|
649
|
+
concurrent: Describe;
|
|
650
|
+
sequential: Describe;
|
|
649
651
|
};
|
|
650
652
|
|
|
653
|
+
export declare const describe: Rstest['describe'];
|
|
654
|
+
|
|
651
655
|
declare interface DescribeEachFn {
|
|
652
656
|
<T extends Record<string, unknown>>(cases: readonly T[]): (description: string, fn?: (param: T) => MaybePromise<void>) => void;
|
|
653
657
|
<T extends readonly [unknown, ...unknown[]]>(cases: readonly T[]): (description: string, fn: (...args: [...T]) => MaybePromise<void>) => void;
|
|
@@ -712,6 +716,8 @@ declare interface EncodedSourceMap extends SourceMapV3 {
|
|
|
712
716
|
|
|
713
717
|
declare type EncodedSourceMapXInput = EncodedSourceMap & XInput;
|
|
714
718
|
|
|
719
|
+
export declare type Expect = ExpectStatic;
|
|
720
|
+
|
|
715
721
|
export declare const expect: Rstest['expect'];
|
|
716
722
|
|
|
717
723
|
declare type ExpectationResult = SyncExpectationResult | AsyncExpectationResult;
|
|
@@ -1950,7 +1956,7 @@ declare type OnTestFinishedHandler = (params: {
|
|
|
1950
1956
|
};
|
|
1951
1957
|
}) => MaybePromise<void>;
|
|
1952
1958
|
|
|
1953
|
-
declare type OptionalKeys = 'testNamePattern' | 'plugins' | 'source' | 'resolve' | 'output' | 'performance' | 'tools' | 'dev' | 'onConsoleLog' | 'resolveSnapshotPath';
|
|
1959
|
+
declare type OptionalKeys = 'testNamePattern' | 'plugins' | 'source' | 'resolve' | 'output' | 'performance' | 'tools' | 'dev' | 'onConsoleLog' | 'chaiConfig' | 'resolveSnapshotPath';
|
|
1954
1960
|
|
|
1955
1961
|
declare type OptionsReceived = PrettyFormatOptions;
|
|
1956
1962
|
|
|
@@ -2007,7 +2013,7 @@ declare type Project = {
|
|
|
2007
2013
|
configFilePath?: string;
|
|
2008
2014
|
};
|
|
2009
2015
|
|
|
2010
|
-
export declare type ProjectConfig = Omit<RstestConfig, 'projects' | 'reporters' | 'pool' | 'isolate' | 'coverage' | 'resolveSnapshotPath' | 'onConsoleLog' | 'hideSkippedTests'>;
|
|
2016
|
+
export declare type ProjectConfig = Omit<RstestConfig, 'projects' | 'reporters' | 'pool' | 'isolate' | 'coverage' | 'resolveSnapshotPath' | 'onConsoleLog' | 'hideSkippedTests' | 'bail'>;
|
|
2011
2017
|
|
|
2012
2018
|
declare type ProjectConfigAsyncFn = () => Promise<ProjectConfig>;
|
|
2013
2019
|
|
|
@@ -2129,8 +2135,8 @@ export declare const rs: RstestUtilities;
|
|
|
2129
2135
|
|
|
2130
2136
|
export { RsbuildPlugin }
|
|
2131
2137
|
|
|
2132
|
-
declare type Rstest = RunnerAPI & {
|
|
2133
|
-
expect:
|
|
2138
|
+
export declare type Rstest = RunnerAPI & {
|
|
2139
|
+
expect: Expect;
|
|
2134
2140
|
assert: typeof assert_2;
|
|
2135
2141
|
rstest: RstestUtilities;
|
|
2136
2142
|
rs: RstestUtilities;
|
|
@@ -2219,6 +2225,13 @@ export declare interface RstestConfig {
|
|
|
2219
2225
|
* @default 'node'
|
|
2220
2226
|
*/
|
|
2221
2227
|
testEnvironment?: 'node' | 'jsdom' | 'happy-dom';
|
|
2228
|
+
/**
|
|
2229
|
+
* Stop running tests after n failures.
|
|
2230
|
+
* Set to 0 to run all tests regardless of failures.
|
|
2231
|
+
*
|
|
2232
|
+
* @default 0
|
|
2233
|
+
*/
|
|
2234
|
+
bail?: number;
|
|
2222
2235
|
/**
|
|
2223
2236
|
* print console traces when calling any console method.
|
|
2224
2237
|
*
|
|
@@ -2320,6 +2333,10 @@ export declare interface RstestConfig {
|
|
|
2320
2333
|
* Coverage options
|
|
2321
2334
|
*/
|
|
2322
2335
|
coverage?: CoverageOptions;
|
|
2336
|
+
/**
|
|
2337
|
+
* chai configuration options
|
|
2338
|
+
*/
|
|
2339
|
+
chaiConfig?: ChaiConfig;
|
|
2323
2340
|
plugins?: RsbuildConfig['plugins'];
|
|
2324
2341
|
source?: Pick<NonNullable<RsbuildConfig['source']>, 'define' | 'tsconfigPath' | 'decorators' | 'include' | 'exclude'>;
|
|
2325
2342
|
performance?: Pick<NonNullable<RsbuildConfig['performance']>, 'bundleAnalyze'>;
|
|
@@ -2362,10 +2379,9 @@ declare type RstestContext = {
|
|
|
2362
2379
|
command: RstestCommand;
|
|
2363
2380
|
reporters: Reporter[];
|
|
2364
2381
|
snapshotManager: SnapshotManager;
|
|
2382
|
+
stateManager: TestStateManager;
|
|
2365
2383
|
};
|
|
2366
2384
|
|
|
2367
|
-
declare type RstestExpect = ExpectStatic;
|
|
2368
|
-
|
|
2369
2385
|
declare type RstestInstance = {
|
|
2370
2386
|
context: RstestContext;
|
|
2371
2387
|
runTests: () => Promise<void>;
|
|
@@ -2385,7 +2401,7 @@ declare type RstestPoolOptions = {
|
|
|
2385
2401
|
|
|
2386
2402
|
declare type RstestPoolType = 'forks';
|
|
2387
2403
|
|
|
2388
|
-
declare interface RstestUtilities {
|
|
2404
|
+
export declare interface RstestUtilities {
|
|
2389
2405
|
/**
|
|
2390
2406
|
* Creates a spy on a function.
|
|
2391
2407
|
*/
|
|
@@ -2512,7 +2528,7 @@ declare interface RstestUtilities {
|
|
|
2512
2528
|
export declare function runCLI(): Promise<void>;
|
|
2513
2529
|
|
|
2514
2530
|
declare type RunnerAPI = {
|
|
2515
|
-
describe:
|
|
2531
|
+
describe: Describe;
|
|
2516
2532
|
it: TestAPIs;
|
|
2517
2533
|
test: TestAPIs;
|
|
2518
2534
|
beforeAll: (fn: BeforeAllListener, timeout?: number) => MaybePromise<void>;
|
|
@@ -2523,7 +2539,7 @@ declare type RunnerAPI = {
|
|
|
2523
2539
|
onTestFailed: (fn: OnTestFailedHandler, timeout?: number) => void;
|
|
2524
2540
|
};
|
|
2525
2541
|
|
|
2526
|
-
declare type RuntimeConfig = Pick<RstestContext['normalizedConfig'], 'testTimeout' | 'testNamePattern' | 'globals' | 'passWithNoTests' | 'retry' | 'clearMocks' | 'resetMocks' | 'restoreMocks' | 'unstubEnvs' | 'unstubGlobals' | 'maxConcurrency' | 'printConsoleTrace' | 'disableConsoleIntercept' | 'testEnvironment' | 'isolate' | 'hookTimeout' | 'coverage' | 'snapshotFormat' | 'env' | 'logHeapUsage'>;
|
|
2542
|
+
declare type RuntimeConfig = Pick<RstestContext['normalizedConfig'], 'testTimeout' | 'testNamePattern' | 'globals' | 'passWithNoTests' | 'retry' | 'clearMocks' | 'resetMocks' | 'restoreMocks' | 'unstubEnvs' | 'unstubGlobals' | 'maxConcurrency' | 'printConsoleTrace' | 'disableConsoleIntercept' | 'testEnvironment' | 'isolate' | 'hookTimeout' | 'coverage' | 'snapshotFormat' | 'env' | 'logHeapUsage' | 'bail' | 'chaiConfig'>;
|
|
2527
2543
|
|
|
2528
2544
|
declare type RuntimeOptions = Partial<Pick<RuntimeConfig, 'testTimeout' | 'hookTimeout' | 'clearMocks' | 'resetMocks' | 'restoreMocks' | 'maxConcurrency' | 'retry'>>;
|
|
2529
2545
|
|
|
@@ -2758,7 +2774,7 @@ declare type TestAPIs<ExtraContext = object> = TestAPI<ExtraContext> & {
|
|
|
2758
2774
|
declare type TestCallbackFn<ExtraContext = object> = (context: TestContext & ExtraContext) => MaybePromise<void>;
|
|
2759
2775
|
|
|
2760
2776
|
declare type TestContext = {
|
|
2761
|
-
expect:
|
|
2777
|
+
expect: Expect;
|
|
2762
2778
|
onTestFinished: RunnerAPI['onTestFinished'];
|
|
2763
2779
|
onTestFailed: RunnerAPI['onTestFailed'];
|
|
2764
2780
|
};
|
|
@@ -2813,6 +2829,16 @@ export declare type TestResult = {
|
|
|
2813
2829
|
|
|
2814
2830
|
declare type TestResultStatus = 'skip' | 'pass' | 'fail' | 'todo';
|
|
2815
2831
|
|
|
2832
|
+
declare class TestStateManager {
|
|
2833
|
+
runningModules: Map<string, TestResult[]>;
|
|
2834
|
+
testModules: TestFileResult[];
|
|
2835
|
+
onTestFileStart(testPath: string): void;
|
|
2836
|
+
onTestCaseResult(result: TestResult): void;
|
|
2837
|
+
getCountOfFailedTests(): number;
|
|
2838
|
+
onTestFileResult(test: TestFileResult): void;
|
|
2839
|
+
reset(): void;
|
|
2840
|
+
}
|
|
2841
|
+
|
|
2816
2842
|
declare type TextLcovOptions = ProjectOptions;
|
|
2817
2843
|
|
|
2818
2844
|
declare interface TextOptions extends FileOptions {
|
package/dist-types/worker.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { config } from 'chai';
|
|
1
2
|
import type { RsbuildConfig } from '@rsbuild/core';
|
|
2
3
|
|
|
3
4
|
/**
|
|
@@ -259,6 +260,8 @@ declare type BuiltinReporterOptions = {
|
|
|
259
260
|
default: DefaultReporterOptions;
|
|
260
261
|
};
|
|
261
262
|
|
|
263
|
+
declare type ChaiConfig = Partial<Omit<typeof config, 'useProxy' | 'proxyExcludedKeys' | 'deepEqual'>>;
|
|
264
|
+
|
|
262
265
|
declare interface CloverOptions extends FileOptions, ProjectOptions {}
|
|
263
266
|
|
|
264
267
|
declare interface CoberturaOptions extends FileOptions, ProjectOptions {}
|
|
@@ -1614,7 +1617,7 @@ declare type OnTestFinishedHandler = (params: {
|
|
|
1614
1617
|
};
|
|
1615
1618
|
}) => MaybePromise<void>;
|
|
1616
1619
|
|
|
1617
|
-
declare type OptionalKeys = 'testNamePattern' | 'plugins' | 'source' | 'resolve' | 'output' | 'performance' | 'tools' | 'dev' | 'onConsoleLog' | 'resolveSnapshotPath';
|
|
1620
|
+
declare type OptionalKeys = 'testNamePattern' | 'plugins' | 'source' | 'resolve' | 'output' | 'performance' | 'tools' | 'dev' | 'onConsoleLog' | 'chaiConfig' | 'resolveSnapshotPath';
|
|
1618
1621
|
|
|
1619
1622
|
declare type OptionsReceived = PrettyFormatOptions;
|
|
1620
1623
|
|
|
@@ -1664,7 +1667,7 @@ declare function printWithType<T>(name: string, value: T, print: (value: T) => s
|
|
|
1664
1667
|
|
|
1665
1668
|
declare type Procedure = (...args: any[]) => any;
|
|
1666
1669
|
|
|
1667
|
-
declare type ProjectConfig = Omit<RstestConfig, 'projects' | 'reporters' | 'pool' | 'isolate' | 'coverage' | 'resolveSnapshotPath' | 'onConsoleLog' | 'hideSkippedTests'>;
|
|
1670
|
+
declare type ProjectConfig = Omit<RstestConfig, 'projects' | 'reporters' | 'pool' | 'isolate' | 'coverage' | 'resolveSnapshotPath' | 'onConsoleLog' | 'hideSkippedTests' | 'bail'>;
|
|
1668
1671
|
|
|
1669
1672
|
declare type ProjectContext = {
|
|
1670
1673
|
name: string;
|
|
@@ -1859,6 +1862,13 @@ declare interface RstestConfig {
|
|
|
1859
1862
|
* @default 'node'
|
|
1860
1863
|
*/
|
|
1861
1864
|
testEnvironment?: 'node' | 'jsdom' | 'happy-dom';
|
|
1865
|
+
/**
|
|
1866
|
+
* Stop running tests after n failures.
|
|
1867
|
+
* Set to 0 to run all tests regardless of failures.
|
|
1868
|
+
*
|
|
1869
|
+
* @default 0
|
|
1870
|
+
*/
|
|
1871
|
+
bail?: number;
|
|
1862
1872
|
/**
|
|
1863
1873
|
* print console traces when calling any console method.
|
|
1864
1874
|
*
|
|
@@ -1960,6 +1970,10 @@ declare interface RstestConfig {
|
|
|
1960
1970
|
* Coverage options
|
|
1961
1971
|
*/
|
|
1962
1972
|
coverage?: CoverageOptions;
|
|
1973
|
+
/**
|
|
1974
|
+
* chai configuration options
|
|
1975
|
+
*/
|
|
1976
|
+
chaiConfig?: ChaiConfig;
|
|
1963
1977
|
plugins?: RsbuildConfig['plugins'];
|
|
1964
1978
|
source?: Pick<NonNullable<RsbuildConfig['source']>, 'define' | 'tsconfigPath' | 'decorators' | 'include' | 'exclude'>;
|
|
1965
1979
|
performance?: Pick<NonNullable<RsbuildConfig['performance']>, 'bundleAnalyze'>;
|
|
@@ -1996,6 +2010,7 @@ declare type RstestContext = {
|
|
|
1996
2010
|
command: RstestCommand;
|
|
1997
2011
|
reporters: Reporter[];
|
|
1998
2012
|
snapshotManager: SnapshotManager;
|
|
2013
|
+
stateManager: TestStateManager;
|
|
1999
2014
|
};
|
|
2000
2015
|
|
|
2001
2016
|
declare type RstestExpect = ExpectStatic;
|
|
@@ -2031,7 +2046,7 @@ declare type RunnerAPI = {
|
|
|
2031
2046
|
onTestFailed: (fn: OnTestFailedHandler, timeout?: number) => void;
|
|
2032
2047
|
};
|
|
2033
2048
|
|
|
2034
|
-
declare type RuntimeConfig = Pick<RstestContext['normalizedConfig'], 'testTimeout' | 'testNamePattern' | 'globals' | 'passWithNoTests' | 'retry' | 'clearMocks' | 'resetMocks' | 'restoreMocks' | 'unstubEnvs' | 'unstubGlobals' | 'maxConcurrency' | 'printConsoleTrace' | 'disableConsoleIntercept' | 'testEnvironment' | 'isolate' | 'hookTimeout' | 'coverage' | 'snapshotFormat' | 'env' | 'logHeapUsage'>;
|
|
2049
|
+
declare type RuntimeConfig = Pick<RstestContext['normalizedConfig'], 'testTimeout' | 'testNamePattern' | 'globals' | 'passWithNoTests' | 'retry' | 'clearMocks' | 'resetMocks' | 'restoreMocks' | 'unstubEnvs' | 'unstubGlobals' | 'maxConcurrency' | 'printConsoleTrace' | 'disableConsoleIntercept' | 'testEnvironment' | 'isolate' | 'hookTimeout' | 'coverage' | 'snapshotFormat' | 'env' | 'logHeapUsage' | 'bail' | 'chaiConfig'>;
|
|
2035
2050
|
|
|
2036
2051
|
/** Runtime to Server */
|
|
2037
2052
|
declare type RuntimeRPC = {
|
|
@@ -2041,6 +2056,7 @@ declare type RuntimeRPC = {
|
|
|
2041
2056
|
sourceMaps: Record<string, string>;
|
|
2042
2057
|
}>;
|
|
2043
2058
|
onTestCaseResult: (result: TestResult) => Promise<void>;
|
|
2059
|
+
getCountOfFailedTests: () => Promise<number>;
|
|
2044
2060
|
onConsoleLog: (log: UserConsoleLog) => void;
|
|
2045
2061
|
resolveSnapshotPath: (filepath: string) => string;
|
|
2046
2062
|
};
|
|
@@ -2396,6 +2412,16 @@ declare type TestResultStatus = 'skip' | 'pass' | 'fail' | 'todo';
|
|
|
2396
2412
|
|
|
2397
2413
|
declare type TestRunMode = 'run' | 'skip' | 'todo' | 'only';
|
|
2398
2414
|
|
|
2415
|
+
declare class TestStateManager {
|
|
2416
|
+
runningModules: Map<string, TestResult[]>;
|
|
2417
|
+
testModules: TestFileResult[];
|
|
2418
|
+
onTestFileStart(testPath: string): void;
|
|
2419
|
+
onTestCaseResult(result: TestResult): void;
|
|
2420
|
+
getCountOfFailedTests(): number;
|
|
2421
|
+
onTestFileResult(test: TestFileResult): void;
|
|
2422
|
+
reset(): void;
|
|
2423
|
+
}
|
|
2424
|
+
|
|
2399
2425
|
declare type TestSuite = {
|
|
2400
2426
|
name: string;
|
|
2401
2427
|
parentNames?: string[];
|