@rstest/core 0.6.7 → 0.6.9

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~122.js CHANGED
@@ -89,6 +89,8 @@ const createForksPool = (poolOptions)=>{
89
89
  };
90
90
  };
91
91
  const external_node_os_ = __webpack_require__("node:os");
92
+ const picocolors = __webpack_require__("../../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js");
93
+ var picocolors_default = /*#__PURE__*/ __webpack_require__.n(picocolors);
92
94
  const getNumCpus = ()=>external_node_os_["default"].availableParallelism?.() ?? external_node_os_["default"].cpus().length;
93
95
  const parseWorkers = (maxWorkers)=>{
94
96
  const parsed = Number.parseInt(maxWorkers.toString(), 10);
@@ -168,6 +170,7 @@ const createPool = async ({ context, recommendWorkerCount = 1 / 0 })=>{
168
170
  });
169
171
  const rpcMethods = {
170
172
  onTestCaseStart: async (test)=>{
173
+ context.stateManager.onTestCaseStart(test);
171
174
  Promise.all(reporters.map((reporter)=>reporter.onTestCaseStart?.(test)));
172
175
  },
173
176
  onTestCaseResult: async (result)=>{
@@ -216,6 +219,26 @@ const createPool = async ({ context, recommendWorkerCount = 1 / 0 })=>{
216
219
  }
217
220
  }).catch((err)=>{
218
221
  err.fullStack = true;
222
+ if (err instanceof Error) {
223
+ if (err.message.includes('Worker exited unexpectedly')) delete err.stack;
224
+ const runningModule = context.stateManager.runningModules.get(entryInfo.testPath);
225
+ if (runningModule?.runningTests.length) {
226
+ const getCaseName = (test)=>`"${test.name}"${test.parentNames?.length ? ` (Under suite: ${test.parentNames?.join(' > ')})` : ''}`;
227
+ if (runningModule?.runningTests.length === 1) err.message += `\n\n${picocolors_default().white(`Maybe relevant test case: ${getCaseName(runningModule.runningTests[0])} which is running when the error occurs.`)}`;
228
+ else err.message += `\n\n${picocolors_default().white(`The below test cases may be relevant, as they were running when the error occurred:\n - ${runningModule.runningTests.map((t)=>getCaseName(t)).join('\n - ')}`)}`;
229
+ }
230
+ return {
231
+ testId: '0',
232
+ project: projectName,
233
+ testPath: entryInfo.testPath,
234
+ status: 'fail',
235
+ name: '',
236
+ results: runningModule?.results || [],
237
+ errors: [
238
+ err
239
+ ]
240
+ };
241
+ }
219
242
  return {
220
243
  testId: '0',
221
244
  project: projectName,
@@ -454,7 +477,7 @@ const autoExternalNodeModules = ({ context, request, dependencyType, getResolve
454
477
  if (!resolver) return callback();
455
478
  resolver(context, request, (err, resolvePath)=>{
456
479
  if (err) return callback();
457
- if (resolvePath && /node_modules/.test(resolvePath)) return doExternal(resolvePath);
480
+ if (resolvePath && resolvePath.includes('node_modules') && !/\.(?:ts|tsx|jsx|mts|cts)$/.test(resolvePath)) return doExternal(resolvePath);
458
481
  return callback();
459
482
  });
460
483
  };
package/dist/155.js CHANGED
@@ -500,7 +500,7 @@ 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.7");
503
+ src_logger.greet(" Rstest v0.6.9");
504
504
  src_logger.log('');
505
505
  }
506
506
  const applyCommonOptions = (cli)=>{
@@ -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.7");
547
+ cli.version("0.6.9");
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();
@@ -745,12 +745,7 @@ const withDefaultConfig = (config)=>{
745
745
  includeSource: merged.includeSource.map((p)=>formatRootStr(p, merged.root))
746
746
  };
747
747
  };
748
- async function resolveConfig(options) {
749
- const { content: config, filePath: configFilePath } = await config_loadConfig({
750
- cwd: options.root,
751
- path: options.config,
752
- configLoader: options.configLoader
753
- });
748
+ function mergeWithCLIOptions(config, options) {
754
749
  const keys = [
755
750
  'root',
756
751
  'globals',
@@ -783,8 +778,16 @@ async function resolveConfig(options) {
783
778
  }
784
779
  if (options.exclude) config.exclude = castArray(options.exclude);
785
780
  if (options.include) config.include = castArray(options.include);
781
+ return config;
782
+ }
783
+ async function resolveConfig(options) {
784
+ const { content: config, filePath: configFilePath } = await config_loadConfig({
785
+ cwd: options.root,
786
+ path: options.config,
787
+ configLoader: options.configLoader
788
+ });
786
789
  return {
787
- config,
790
+ config: mergeWithCLIOptions(config, options),
788
791
  configFilePath: configFilePath ?? void 0
789
792
  };
790
793
  }
@@ -796,7 +799,7 @@ async function resolveProjects({ config, root, options }) {
796
799
  if ('string' != typeof name || !name) return basename(dir);
797
800
  return name;
798
801
  };
799
- const globProjects = async (patterns)=>{
802
+ const globProjects = async (patterns, root)=>{
800
803
  const globOptions = {
801
804
  absolute: true,
802
805
  dot: true,
@@ -810,48 +813,60 @@ async function resolveProjects({ config, root, options }) {
810
813
  };
811
814
  return glob(patterns, globOptions);
812
815
  };
813
- const { projectPaths, projectPatterns, projectConfigs } = (config.projects || []).reduce((total, p)=>{
814
- if ('object' == typeof p) {
815
- const projectRoot = p.root ? formatRootStr(p.root, root) : root;
816
- total.projectConfigs.push({
817
- config: {
818
- root: projectRoot,
819
- name: p.name ? p.name : getDefaultProjectName(projectRoot),
820
- ...p
821
- },
822
- configFilePath: void 0
823
- });
816
+ const resolvedProjectPaths = new Set();
817
+ const getProjects = async (rstestConfig, root)=>{
818
+ const { projectPaths, projectPatterns, projectConfigs } = (rstestConfig.projects || []).reduce((total, p)=>{
819
+ if ('object' == typeof p) {
820
+ const projectRoot = p.root ? formatRootStr(p.root, root) : root;
821
+ total.projectConfigs.push({
822
+ config: mergeWithCLIOptions({
823
+ root: projectRoot,
824
+ ...p,
825
+ name: p.name ? p.name : getDefaultProjectName(projectRoot)
826
+ }, options),
827
+ configFilePath: void 0
828
+ });
829
+ return total;
830
+ }
831
+ const projectStr = formatRootStr(p, root);
832
+ if (isDynamicPattern(projectStr)) total.projectPatterns.push(projectStr);
833
+ else {
834
+ const absolutePath = getAbsolutePath(root, projectStr);
835
+ if (!(0, external_node_fs_.existsSync)(absolutePath)) throw `Can't resolve project "${p}", please make sure "${p}" is a existing file or a directory.`;
836
+ total.projectPaths.push(absolutePath);
837
+ }
824
838
  return total;
825
- }
826
- const projectStr = formatRootStr(p, root);
827
- if (isDynamicPattern(projectStr)) total.projectPatterns.push(projectStr);
828
- else {
829
- const absolutePath = getAbsolutePath(root, projectStr);
830
- if (!(0, external_node_fs_.existsSync)(absolutePath)) throw `Can't resolve project "${p}", please make sure "${p}" is a existing file or a directory.`;
831
- total.projectPaths.push(absolutePath);
832
- }
833
- return total;
834
- }, {
835
- projectPaths: [],
836
- projectPatterns: [],
837
- projectConfigs: []
838
- });
839
- projectPaths.push(...await globProjects(projectPatterns));
840
- const projects = await Promise.all(projectPaths.map(async (project)=>{
841
- const isDirectory = (0, external_node_fs_.statSync)(project).isDirectory();
842
- const root = isDirectory ? project : dirname(project);
843
- const { config, configFilePath } = await resolveConfig({
844
- ...options,
845
- config: isDirectory ? void 0 : project,
846
- root
839
+ }, {
840
+ projectPaths: [],
841
+ projectPatterns: [],
842
+ projectConfigs: []
847
843
  });
848
- config.name ??= getDefaultProjectName(root);
849
- if (config.projects?.length && config.root !== root) src_logger.warn(`Projects cannot have nested projects, the "projects" field in project "${config.name}" will be ignored.`);
850
- return {
851
- config,
852
- configFilePath
853
- };
854
- })).then((projects)=>filterProjects(projects.concat(projectConfigs), options));
844
+ projectPaths.push(...await globProjects(projectPatterns, root));
845
+ const projects = [];
846
+ await Promise.all(projectPaths.map(async (project)=>{
847
+ const isDirectory = (0, external_node_fs_.statSync)(project).isDirectory();
848
+ const projectRoot = isDirectory ? project : dirname(project);
849
+ const { config, configFilePath } = await resolveConfig({
850
+ ...options,
851
+ config: isDirectory ? void 0 : project,
852
+ root: projectRoot
853
+ });
854
+ if (configFilePath) {
855
+ if (resolvedProjectPaths.has(configFilePath)) return;
856
+ resolvedProjectPaths.add(configFilePath);
857
+ }
858
+ config.name ??= getDefaultProjectName(projectRoot);
859
+ if (config.projects?.length) {
860
+ const childProjects = await getProjects(config, projectRoot);
861
+ projects.push(...childProjects);
862
+ } else projects.push({
863
+ config,
864
+ configFilePath
865
+ });
866
+ }));
867
+ return projects.concat(projectConfigs);
868
+ };
869
+ const projects = await getProjects(config, root).then((p)=>filterProjects(p, options));
855
870
  if (!projects.length) {
856
871
  let errorMsg = `No projects found, please make sure you have at least one valid project.
857
872
  ${picocolors_default().gray('projects:')} ${JSON.stringify(config.projects, null, 2)}`;
@@ -1558,10 +1573,9 @@ function getRenderedRowCount(rows, columns) {
1558
1573
  class StatusRenderer {
1559
1574
  rootPath;
1560
1575
  renderer;
1561
- runningModules = new Map();
1562
- testModules = [];
1563
1576
  startTime = void 0;
1564
- constructor(rootPath){
1577
+ testState;
1578
+ constructor(rootPath, state){
1565
1579
  this.rootPath = rootPath;
1566
1580
  this.renderer = new WindowRenderer({
1567
1581
  getWindow: ()=>this.getContent(),
@@ -1571,13 +1585,16 @@ class StatusRenderer {
1571
1585
  getColumns: ()=>'columns' in process.stdout ? process.stdout.columns : 80
1572
1586
  }
1573
1587
  });
1588
+ this.testState = state;
1574
1589
  }
1575
1590
  getContent() {
1576
1591
  this.startTime ??= Date.now();
1577
1592
  const now = Date.now();
1578
1593
  const summary = [];
1594
+ const runningModules = this.testState.getRunningModules();
1595
+ const testModules = this.testState.getTestModules();
1579
1596
  const shouldDisplayRunningTests = (runningTests)=>runningTests[0]?.startTime && now - runningTests[0].startTime > 2000;
1580
- for (const [module, { runningTests }] of this.runningModules.entries()){
1597
+ for (const [module, { runningTests }] of runningModules.entries()){
1581
1598
  const relativePath = pathe_M_eThtNZ_relative(this.rootPath, module);
1582
1599
  summary.push(`${picocolors_default().bgYellow(picocolors_default().bold(' RUNS '))} ${prettyTestPath(relativePath)}`);
1583
1600
  if (runningTests.length && shouldDisplayRunningTests(runningTests)) {
@@ -1587,66 +1604,24 @@ class StatusRenderer {
1587
1604
  }
1588
1605
  }
1589
1606
  summary.push('');
1590
- if (0 === this.testModules.length) summary.push(`${TestFileSummaryLabel} ${this.runningModules.size} total`);
1591
- else summary.push(`${TestFileSummaryLabel} ${getSummaryStatusString(this.testModules, '', false)} ${picocolors_default().dim('|')} ${this.runningModules.size + this.testModules.length} total`);
1592
- const testResults = Array.from(this.runningModules.values()).flatMap(({ results })=>results).concat(this.testModules.flatMap((mod)=>mod.results));
1607
+ if (0 === testModules.length) summary.push(`${TestFileSummaryLabel} ${runningModules.size} total`);
1608
+ else summary.push(`${TestFileSummaryLabel} ${getSummaryStatusString(testModules, '', false)} ${picocolors_default().dim('|')} ${runningModules.size + testModules.length} total`);
1609
+ const testResults = Array.from(runningModules.values()).flatMap(({ results })=>results).concat(testModules.flatMap((mod)=>mod.results));
1593
1610
  if (testResults.length) summary.push(`${TestSummaryLabel} ${getSummaryStatusString(testResults, '', false)}`);
1594
1611
  summary.push(`${DurationLabel} ${prettyTime(Date.now() - this.startTime)}`);
1595
1612
  summary.push('');
1596
1613
  return summary;
1597
1614
  }
1598
- onTestFileStart(testPath) {
1599
- this.runningModules.set(testPath, {
1600
- runningTests: [],
1601
- results: []
1602
- });
1615
+ onTestFileStart() {
1603
1616
  this.renderer?.schedule();
1604
1617
  }
1605
- onTestCaseResult(result) {
1606
- const currentModule = this.runningModules.get(result.testPath);
1607
- if (currentModule) {
1608
- const filteredRunningTests = currentModule.runningTests.filter((t)=>t.testId !== result.testId);
1609
- this.runningModules.set(result.testPath, {
1610
- runningTests: filteredRunningTests,
1611
- results: [
1612
- ...currentModule.results,
1613
- result
1614
- ]
1615
- });
1616
- } else this.runningModules.set(result.testPath, {
1617
- runningTests: [],
1618
- results: [
1619
- result
1620
- ]
1621
- });
1618
+ onTestCaseResult() {
1622
1619
  this.renderer?.schedule();
1623
1620
  }
1624
- onTestCaseStart(test) {
1625
- const currentModule = this.runningModules.get(test.testPath);
1626
- if (currentModule) {
1627
- const filteredRunningTests = currentModule.runningTests.filter((t)=>t.testId !== test.testId);
1628
- this.runningModules.set(test.testPath, {
1629
- runningTests: [
1630
- ...filteredRunningTests,
1631
- test
1632
- ],
1633
- results: currentModule.results
1634
- });
1635
- } else this.runningModules.set(test.testPath, {
1636
- runningTests: [
1637
- test
1638
- ],
1639
- results: []
1640
- });
1641
- }
1642
- onTestFileResult(test) {
1643
- this.runningModules.delete(test.testPath);
1644
- this.testModules.push(test);
1621
+ onTestFileResult() {
1645
1622
  this.renderer?.schedule();
1646
1623
  }
1647
1624
  clear() {
1648
- this.testModules.length = 0;
1649
- this.runningModules.clear();
1650
1625
  this.startTime = void 0;
1651
1626
  this.renderer?.finish();
1652
1627
  }
@@ -1688,17 +1663,17 @@ class DefaultReporter {
1688
1663
  config;
1689
1664
  options = {};
1690
1665
  statusRenderer;
1691
- constructor({ rootPath, options, config }){
1666
+ constructor({ rootPath, options, config, testState }){
1692
1667
  this.rootPath = rootPath;
1693
1668
  this.config = config;
1694
1669
  this.options = options;
1695
- if (isTTY()) this.statusRenderer = new StatusRenderer(rootPath);
1670
+ if (isTTY()) this.statusRenderer = new StatusRenderer(rootPath, testState);
1696
1671
  }
1697
- onTestFileStart(test) {
1698
- this.statusRenderer?.onTestFileStart(test.testPath);
1672
+ onTestFileStart() {
1673
+ this.statusRenderer?.onTestFileStart();
1699
1674
  }
1700
1675
  onTestFileResult(test) {
1701
- this.statusRenderer?.onTestFileResult(test);
1676
+ this.statusRenderer?.onTestFileResult();
1702
1677
  const relativePath = pathe_M_eThtNZ_relative(this.rootPath, test.testPath);
1703
1678
  const { slowTestThreshold } = this.config;
1704
1679
  logFileTitle(test, relativePath);
@@ -1710,11 +1685,8 @@ class DefaultReporter {
1710
1685
  });
1711
1686
  }
1712
1687
  }
1713
- onTestCaseResult(result) {
1714
- this.statusRenderer?.onTestCaseResult(result);
1715
- }
1716
- onTestCaseStart(test) {
1717
- this.statusRenderer?.onTestCaseStart(test);
1688
+ onTestCaseResult() {
1689
+ this.statusRenderer?.onTestCaseResult();
1718
1690
  }
1719
1691
  onUserConsoleLog(log) {
1720
1692
  const shouldLog = this.config.onConsoleLog?.(log.content) ?? true;
@@ -2343,7 +2315,7 @@ class JUnitReporter {
2343
2315
  }
2344
2316
  class VerboseReporter extends DefaultReporter {
2345
2317
  onTestFileResult(test) {
2346
- this.statusRenderer?.onTestFileResult(test);
2318
+ this.statusRenderer?.onTestFileResult();
2347
2319
  const relativePath = pathe_M_eThtNZ_relative(this.rootPath, test.testPath);
2348
2320
  const { slowTestThreshold } = this.config;
2349
2321
  logFileTitle(test, relativePath, true);
@@ -2357,16 +2329,49 @@ class TestStateManager {
2357
2329
  runningModules = new Map();
2358
2330
  testModules = [];
2359
2331
  onTestFileStart(testPath) {
2360
- this.runningModules.set(testPath, []);
2332
+ this.runningModules.set(testPath, {
2333
+ runningTests: [],
2334
+ results: []
2335
+ });
2361
2336
  }
2362
2337
  onTestCaseResult(result) {
2363
- this.runningModules.set(result.testPath, [
2364
- ...this.runningModules.get(result.testPath) || [],
2365
- result
2366
- ]);
2338
+ const currentModule = this.runningModules.get(result.testPath);
2339
+ if (currentModule) {
2340
+ const filteredRunningTests = currentModule.runningTests.filter((t)=>t.testId !== result.testId);
2341
+ this.runningModules.set(result.testPath, {
2342
+ runningTests: filteredRunningTests,
2343
+ results: [
2344
+ ...currentModule.results,
2345
+ result
2346
+ ]
2347
+ });
2348
+ } else this.runningModules.set(result.testPath, {
2349
+ runningTests: [],
2350
+ results: [
2351
+ result
2352
+ ]
2353
+ });
2354
+ }
2355
+ onTestCaseStart(test) {
2356
+ const currentModule = this.runningModules.get(test.testPath);
2357
+ if (currentModule) {
2358
+ const filteredRunningTests = currentModule.runningTests.filter((t)=>t.testId !== test.testId);
2359
+ this.runningModules.set(test.testPath, {
2360
+ runningTests: [
2361
+ ...filteredRunningTests,
2362
+ test
2363
+ ],
2364
+ results: currentModule.results
2365
+ });
2366
+ } else this.runningModules.set(test.testPath, {
2367
+ runningTests: [
2368
+ test
2369
+ ],
2370
+ results: []
2371
+ });
2367
2372
  }
2368
2373
  getCountOfFailedTests() {
2369
- const testResults = Array.from(this.runningModules.values()).flat().concat(this.testModules.flatMap((mod)=>mod.results));
2374
+ const testResults = Array.from(this.runningModules.values()).flatMap(({ results })=>results).concat(this.testModules.flatMap((mod)=>mod.results));
2370
2375
  return testResults.filter((t)=>'fail' === t.status).length;
2371
2376
  }
2372
2377
  onTestFileResult(test) {
@@ -2397,6 +2402,10 @@ class Rstest {
2397
2402
  testResults: []
2398
2403
  };
2399
2404
  stateManager = new TestStateManager();
2405
+ testState = {
2406
+ getRunningModules: ()=>this.stateManager.runningModules,
2407
+ getTestModules: ()=>this.stateManager.testModules
2408
+ };
2400
2409
  projects = [];
2401
2410
  constructor({ cwd = process.cwd(), command, fileFilters, configFilePath, projects }, userConfig){
2402
2411
  this.cwd = cwd;
@@ -2410,14 +2419,15 @@ class Rstest {
2410
2419
  });
2411
2420
  const reporters = 'list' !== command ? createReporters(rstestConfig.reporters, {
2412
2421
  rootPath,
2413
- config: rstestConfig
2422
+ config: rstestConfig,
2423
+ testState: this.testState
2414
2424
  }) : [];
2415
2425
  const snapshotManager = new SnapshotManager({
2416
2426
  updateSnapshot: rstestConfig.update ? 'all' : T ? 'none' : 'new'
2417
2427
  });
2418
2428
  this.reporters = reporters;
2419
2429
  this.snapshotManager = snapshotManager;
2420
- this.version = "0.6.7";
2430
+ this.version = "0.6.9";
2421
2431
  this.rootPath = rootPath;
2422
2432
  this.originalConfig = userConfig;
2423
2433
  this.normalizedConfig = rstestConfig;
package/dist/362.js CHANGED
@@ -6656,7 +6656,7 @@ const formatTestError = (err, test)=>{
6656
6656
  message: rawError
6657
6657
  } : rawError;
6658
6658
  const errObj = {
6659
- ...error,
6659
+ fullStack: error.fullStack,
6660
6660
  message: error.message,
6661
6661
  name: error.name,
6662
6662
  stack: error.stack
@@ -6665,10 +6665,6 @@ const formatTestError = (err, test)=>{
6665
6665
  if (error.showDiff || void 0 === error.showDiff && void 0 !== error.expected && void 0 !== error.actual) errObj.diff = diff(err.expected, err.actual, {
6666
6666
  expand: false
6667
6667
  });
6668
- for (const key of [
6669
- 'actual',
6670
- 'expected'
6671
- ])if ('string' != typeof err[key]) errObj[key] = JSON.stringify(err[key], null, 10);
6672
6668
  return errObj;
6673
6669
  });
6674
6670
  };
package/dist/index.d.ts CHANGED
@@ -588,15 +588,15 @@ declare class DefaultReporter implements Reporter {
588
588
  protected config: NormalizedConfig;
589
589
  private options;
590
590
  protected statusRenderer: StatusRenderer | undefined;
591
- constructor({ rootPath, options, config, }: {
591
+ constructor({ rootPath, options, config, testState, }: {
592
592
  rootPath: string;
593
593
  config: NormalizedConfig;
594
594
  options: DefaultReporterOptions;
595
+ testState: RstestTestState;
595
596
  });
596
- onTestFileStart(test: TestFileInfo): void;
597
+ onTestFileStart(): void;
597
598
  onTestFileResult(test: TestFileResult): void;
598
- onTestCaseResult(result: TestResult): void;
599
- onTestCaseStart(test: TestCaseInfo): void;
599
+ onTestCaseResult(): void;
600
600
  onUserConsoleLog(log: UserConsoleLog): void;
601
601
  onExit(): Promise<void>;
602
602
  onTestRunEnd({ results, testResults, duration, getSourcemap, snapshotSummary, filterRerunTestPaths, }: {
@@ -633,7 +633,7 @@ export declare function defineConfig(config: RstestConfigExport): RstestConfigEx
633
633
  * This function helps you to autocomplete configuration types.
634
634
  * It accepts a Rstest project config object, or a function that returns a config.
635
635
  */
636
- export declare function defineProject(config: ProjectConfig): ProjectConfig;
636
+ export declare function defineProject(config: ProjectConfig | NestedProjectConfig): ProjectConfig | NestedProjectConfig;
637
637
 
638
638
  export declare function defineProject(config: ProjectConfigSyncFn): ProjectConfigSyncFn;
639
639
 
@@ -946,6 +946,18 @@ export declare function initCli(options: CommonOptions): Promise<{
946
946
  projects: Project[];
947
947
  }>;
948
948
 
949
+ /**
950
+ * A list of glob patterns or files that match your test projects.
951
+ *
952
+ * eg. ['packages/*', 'examples/node/rstest.config.ts']
953
+ */
954
+ /**
955
+ * Inline project config must include a name.
956
+ */
957
+ declare type InlineProjectConfig = ProjectConfig & {
958
+ name: string;
959
+ };
960
+
949
961
  declare interface InlineSnapshotMatcher<T> {
950
962
  <U extends {
951
963
  [P in keyof T]: any;
@@ -1900,6 +1912,10 @@ declare interface MockSettledResultRejected_2 {
1900
1912
 
1901
1913
  declare type NamesIndex = number;
1902
1914
 
1915
+ declare type NestedProjectConfig = {
1916
+ projects: (ProjectConfig | string)[];
1917
+ };
1918
+
1903
1919
  declare interface NewPlugin {
1904
1920
  serialize: (val: any, config: Config, indentation: string, depth: number, refs: Refs, printer: Printer) => string;
1905
1921
  test: Test;
@@ -2017,9 +2033,9 @@ declare type Project = {
2017
2033
 
2018
2034
  export declare type ProjectConfig = Omit<RstestConfig, 'projects' | 'reporters' | 'pool' | 'isolate' | 'coverage' | 'resolveSnapshotPath' | 'onConsoleLog' | 'hideSkippedTests' | 'bail'>;
2019
2035
 
2020
- declare type ProjectConfigAsyncFn = () => Promise<ProjectConfig>;
2036
+ declare type ProjectConfigAsyncFn = () => Promise<ProjectConfig | NestedProjectConfig>;
2021
2037
 
2022
- declare type ProjectConfigSyncFn = () => ProjectConfig;
2038
+ declare type ProjectConfigSyncFn = () => ProjectConfig | NestedProjectConfig;
2023
2039
 
2024
2040
  declare type ProjectContext = {
2025
2041
  name: string;
@@ -2375,6 +2391,10 @@ declare type RstestContext = {
2375
2391
  * Run tests from one or more projects.
2376
2392
  */
2377
2393
  projects: ProjectContext[];
2394
+ /**
2395
+ * The test state
2396
+ */
2397
+ testState: RstestTestState;
2378
2398
  /**
2379
2399
  * The command type.
2380
2400
  *
@@ -2407,6 +2427,11 @@ declare type RstestPoolOptions = {
2407
2427
 
2408
2428
  declare type RstestPoolType = 'forks';
2409
2429
 
2430
+ declare type RstestTestState = {
2431
+ getRunningModules: () => RunningModules;
2432
+ getTestModules: () => TestFileResult[];
2433
+ };
2434
+
2410
2435
  export declare interface RstestUtilities {
2411
2436
  /**
2412
2437
  * Creates a spy on a function.
@@ -2549,6 +2574,11 @@ declare type RunnerAPI = {
2549
2574
  onTestFailed: (fn: OnTestFailedHandler, timeout?: number) => void;
2550
2575
  };
2551
2576
 
2577
+ declare type RunningModules = Map<string, {
2578
+ runningTests: TestCaseInfo[];
2579
+ results: TestResult[];
2580
+ }>;
2581
+
2552
2582
  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'>;
2553
2583
 
2554
2584
  declare type RuntimeOptions = Partial<Pick<RuntimeConfig, 'testTimeout' | 'hookTimeout' | 'clearMocks' | 'resetMocks' | 'restoreMocks' | 'maxConcurrency' | 'retry'>>;
@@ -2726,15 +2756,13 @@ declare type SourcesIndex = number;
2726
2756
  declare class StatusRenderer {
2727
2757
  private rootPath;
2728
2758
  private renderer;
2729
- private runningModules;
2730
- private testModules;
2731
2759
  private startTime;
2732
- constructor(rootPath: string);
2760
+ private testState;
2761
+ constructor(rootPath: string, state: RstestTestState);
2733
2762
  getContent(): string[];
2734
- onTestFileStart(testPath: string): void;
2735
- onTestCaseResult(result: TestResult): void;
2736
- onTestCaseStart(test: TestCaseInfo): void;
2737
- onTestFileResult(test: TestFileResult): void;
2763
+ onTestFileStart(): void;
2764
+ onTestCaseResult(): void;
2765
+ onTestFileResult(): void;
2738
2766
  clear(): void;
2739
2767
  }
2740
2768
 
@@ -2829,12 +2857,7 @@ declare type TestForFn<ExtraContext = object> = <T>(cases: readonly T[]) => (des
2829
2857
  /** The test file original path */
2830
2858
  declare type TestPath = string;
2831
2859
 
2832
- /**
2833
- * A list of glob patterns or files that match your test projects.
2834
- *
2835
- * eg. ['packages/*', 'examples/node/rstest.config.ts']
2836
- */
2837
- declare type TestProject = string | ProjectConfig;
2860
+ declare type TestProject = string | InlineProjectConfig;
2838
2861
 
2839
2862
  export declare type TestResult = {
2840
2863
  testId: string;
@@ -2852,10 +2875,14 @@ export declare type TestResult = {
2852
2875
  declare type TestResultStatus = 'skip' | 'pass' | 'fail' | 'todo';
2853
2876
 
2854
2877
  declare class TestStateManager {
2855
- runningModules: Map<string, TestResult[]>;
2878
+ runningModules: Map<string, {
2879
+ runningTests: TestCaseInfo[];
2880
+ results: TestResult[];
2881
+ }>;
2856
2882
  testModules: TestFileResult[];
2857
2883
  onTestFileStart(testPath: string): void;
2858
2884
  onTestCaseResult(result: TestResult): void;
2885
+ onTestCaseStart(test: TestCaseInfo): void;
2859
2886
  getCountOfFailedTests(): number;
2860
2887
  onTestFileResult(test: TestFileResult): void;
2861
2888
  reset(): void;
package/dist/worker.d.ts CHANGED
@@ -494,15 +494,15 @@ declare class DefaultReporter implements Reporter {
494
494
  protected config: NormalizedConfig;
495
495
  private options;
496
496
  protected statusRenderer: StatusRenderer | undefined;
497
- constructor({ rootPath, options, config, }: {
497
+ constructor({ rootPath, options, config, testState, }: {
498
498
  rootPath: string;
499
499
  config: NormalizedConfig;
500
500
  options: DefaultReporterOptions;
501
+ testState: RstestTestState;
501
502
  });
502
- onTestFileStart(test: TestFileInfo): void;
503
+ onTestFileStart(): void;
503
504
  onTestFileResult(test: TestFileResult): void;
504
- onTestCaseResult(result: TestResult): void;
505
- onTestCaseStart(test: TestCaseInfo): void;
505
+ onTestCaseResult(): void;
506
506
  onUserConsoleLog(log: UserConsoleLog): void;
507
507
  onExit(): Promise<void>;
508
508
  onTestRunEnd({ results, testResults, duration, getSourcemap, snapshotSummary, filterRerunTestPaths, }: {
@@ -770,6 +770,18 @@ declare interface HtmlSpaOptions extends HtmlOptions {
770
770
 
771
771
  declare type Indent = (arg0: string) => string;
772
772
 
773
+ /**
774
+ * A list of glob patterns or files that match your test projects.
775
+ *
776
+ * eg. ['packages/*', 'examples/node/rstest.config.ts']
777
+ */
778
+ /**
779
+ * Inline project config must include a name.
780
+ */
781
+ declare type InlineProjectConfig = ProjectConfig & {
782
+ name: string;
783
+ };
784
+
773
785
  declare interface InlineSnapshotMatcher<T> {
774
786
  <U extends {
775
787
  [P in keyof T]: any;
@@ -2006,6 +2018,10 @@ declare type RstestContext = {
2006
2018
  * Run tests from one or more projects.
2007
2019
  */
2008
2020
  projects: ProjectContext[];
2021
+ /**
2022
+ * The test state
2023
+ */
2024
+ testState: RstestTestState;
2009
2025
  /**
2010
2026
  * The command type.
2011
2027
  *
@@ -2034,6 +2050,11 @@ declare type RstestPoolOptions = {
2034
2050
 
2035
2051
  declare type RstestPoolType = 'forks';
2036
2052
 
2053
+ declare type RstestTestState = {
2054
+ getRunningModules: () => RunningModules;
2055
+ getTestModules: () => TestFileResult[];
2056
+ };
2057
+
2037
2058
  declare const runInPool: (options: RunWorkerOptions["options"]) => Promise<{
2038
2059
  tests: Test_2[];
2039
2060
  testPath: string;
@@ -2052,6 +2073,11 @@ declare type RunnerAPI = {
2052
2073
  onTestFailed: (fn: OnTestFailedHandler, timeout?: number) => void;
2053
2074
  };
2054
2075
 
2076
+ declare type RunningModules = Map<string, {
2077
+ runningTests: TestCaseInfo[];
2078
+ results: TestResult[];
2079
+ }>;
2080
+
2055
2081
  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'>;
2056
2082
 
2057
2083
  /** Runtime to Server */
@@ -2257,15 +2283,13 @@ declare type SourcesIndex = number;
2257
2283
  declare class StatusRenderer {
2258
2284
  private rootPath;
2259
2285
  private renderer;
2260
- private runningModules;
2261
- private testModules;
2262
2286
  private startTime;
2263
- constructor(rootPath: string);
2287
+ private testState;
2288
+ constructor(rootPath: string, state: RstestTestState);
2264
2289
  getContent(): string[];
2265
- onTestFileStart(testPath: string): void;
2266
- onTestCaseResult(result: TestResult): void;
2267
- onTestCaseStart(test: TestCaseInfo): void;
2268
- onTestFileResult(test: TestFileResult): void;
2290
+ onTestFileStart(): void;
2291
+ onTestCaseResult(): void;
2292
+ onTestFileResult(): void;
2269
2293
  clear(): void;
2270
2294
  }
2271
2295
 
@@ -2402,12 +2426,7 @@ declare type TestForFn<ExtraContext = object> = <T>(cases: readonly T[]) => (des
2402
2426
  /** The test file original path */
2403
2427
  declare type TestPath = string;
2404
2428
 
2405
- /**
2406
- * A list of glob patterns or files that match your test projects.
2407
- *
2408
- * eg. ['packages/*', 'examples/node/rstest.config.ts']
2409
- */
2410
- declare type TestProject = string | ProjectConfig;
2429
+ declare type TestProject = string | InlineProjectConfig;
2411
2430
 
2412
2431
  declare type TestResult = {
2413
2432
  testId: string;
@@ -2427,10 +2446,14 @@ declare type TestResultStatus = 'skip' | 'pass' | 'fail' | 'todo';
2427
2446
  declare type TestRunMode = 'run' | 'skip' | 'todo' | 'only';
2428
2447
 
2429
2448
  declare class TestStateManager {
2430
- runningModules: Map<string, TestResult[]>;
2449
+ runningModules: Map<string, {
2450
+ runningTests: TestCaseInfo[];
2451
+ results: TestResult[];
2452
+ }>;
2431
2453
  testModules: TestFileResult[];
2432
2454
  onTestFileStart(testPath: string): void;
2433
2455
  onTestCaseResult(result: TestResult): void;
2456
+ onTestCaseStart(test: TestCaseInfo): void;
2434
2457
  getCountOfFailedTests(): number;
2435
2458
  onTestFileResult(test: TestFileResult): void;
2436
2459
  reset(): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rstest/core",
3
- "version": "0.6.7",
3
+ "version": "0.6.9",
4
4
  "description": "The Rsbuild-based test tool.",
5
5
  "bugs": {
6
6
  "url": "https://github.com/web-infra-dev/rstest/issues"