@rstest/core 0.1.2 → 0.1.3

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/285.js CHANGED
@@ -25,7 +25,7 @@ export const __webpack_modules__ = {
25
25
  const globTestSourceEntries = async ()=>testEntries;
26
26
  const setupFiles = (0, _utils__WEBPACK_IMPORTED_MODULE_3__.aA)(setups, rootPath);
27
27
  const rsbuildInstance = await (0, _rsbuild__WEBPACK_IMPORTED_MODULE_4__.z)(context, globTestSourceEntries, setupFiles);
28
- const getRsbuildStats = await (0, _rsbuild__WEBPACK_IMPORTED_MODULE_4__.r)({
28
+ const { getRsbuildStats, closeServer } = await (0, _rsbuild__WEBPACK_IMPORTED_MODULE_4__.r)({
29
29
  name,
30
30
  globTestSourceEntries,
31
31
  normalizedConfig: context.normalizedConfig,
@@ -33,15 +33,17 @@ export const __webpack_modules__ = {
33
33
  rsbuildInstance,
34
34
  rootPath
35
35
  });
36
- const { entries, setupEntries, assetFiles, sourceMaps, close, getSourcemap } = await getRsbuildStats();
36
+ const { entries, setupEntries, assetFiles, sourceMaps, getSourcemap } = await getRsbuildStats();
37
37
  const pool = await (0, _pool__WEBPACK_IMPORTED_MODULE_2__.K)({
38
+ context
39
+ });
40
+ const list = await pool.collectTests({
38
41
  entries,
39
42
  sourceMaps,
40
43
  setupEntries,
41
44
  assetFiles,
42
- context
45
+ updateSnapshot: context.snapshotManager.options.updateSnapshot
43
46
  });
44
- const list = await pool.collectTests();
45
47
  const tests = [];
46
48
  const traverseTests = (test)=>{
47
49
  if ([
@@ -68,7 +70,7 @@ export const __webpack_modules__ = {
68
70
  for (const error of file.errors)await printError(error, getSourcemap, rootPath);
69
71
  }
70
72
  }
71
- await close();
73
+ await closeServer();
72
74
  await pool.close();
73
75
  return;
74
76
  }
@@ -94,7 +96,7 @@ export const __webpack_modules__ = {
94
96
  const shortPath = (0, node_path__WEBPACK_IMPORTED_MODULE_1__.relative)(rootPath, test.file);
95
97
  _utils__WEBPACK_IMPORTED_MODULE_3__.kg.log(test.name ? `${_utils__WEBPACK_IMPORTED_MODULE_3__.$_.dim(`${shortPath} > `)}${test.name}` : (0, _utils__WEBPACK_IMPORTED_MODULE_3__.aj)(shortPath));
96
98
  }
97
- await close();
99
+ await closeServer();
98
100
  await pool.close();
99
101
  }
100
102
  }
package/dist/359.js CHANGED
@@ -256,7 +256,7 @@ export const __webpack_modules__ = {
256
256
  this.windowHeight = 0;
257
257
  }
258
258
  interceptStream(stream, type) {
259
- const original = stream.write;
259
+ const original = stream.write.bind(stream);
260
260
  stream.write = (chunk, _, callback)=>{
261
261
  if (chunk) if (this.finished) this.write(chunk.toString(), type);
262
262
  else this.buffer.push({
@@ -411,7 +411,7 @@ export const __webpack_modules__ = {
411
411
  };
412
412
  const logFileTitle = (test, relativePath, slowTestThreshold, alwaysShowTime = false)=>{
413
413
  let title = ` ${utils.$_.bold(statusColorfulStr[test.status])} ${(0, utils.aj)(relativePath)}`;
414
- const formatDuration = (duration)=>utils.$_[duration > slowTestThreshold ? 'yellow' : 'green'](`${(0, utils.AS)(duration)}`);
414
+ const formatDuration = (duration)=>utils.$_[duration > slowTestThreshold ? 'yellow' : 'green']((0, utils.AS)(duration));
415
415
  title += ` ${utils.$_.gray(`(${test.results.length})`)}`;
416
416
  const isTooSlow = test.duration && test.duration > slowTestThreshold;
417
417
  if (alwaysShowTime || isTooSlow) title += ` ${formatDuration(test.duration)}`;
@@ -581,7 +581,7 @@ export const __webpack_modules__ = {
581
581
  });
582
582
  return {
583
583
  command,
584
- version: "0.1.2",
584
+ version: "0.1.3",
585
585
  rootPath,
586
586
  reporters,
587
587
  snapshotManager,
@@ -597,7 +597,7 @@ export const __webpack_modules__ = {
597
597
  const runTests = async ()=>{
598
598
  const { runTests } = await Promise.all([
599
599
  __webpack_require__.e("854"),
600
- __webpack_require__.e("629")
600
+ __webpack_require__.e("920")
601
601
  ]).then(__webpack_require__.bind(__webpack_require__, "./src/core/runTests.ts"));
602
602
  await runTests(context, fileFilters);
603
603
  };
package/dist/854.js CHANGED
@@ -9,7 +9,6 @@ export const __webpack_modules__ = {
9
9
  r: ()=>createRsbuildServer,
10
10
  z: ()=>prepareRsbuild
11
11
  });
12
- var external_node_fs_ = __webpack_require__("fs");
13
12
  var core_ = __webpack_require__("@rsbuild/core");
14
13
  var external_pathe_ = __webpack_require__("pathe");
15
14
  var utils = __webpack_require__("./src/utils/index.ts");
@@ -508,12 +507,15 @@ global.__rstest_clean_core_cache__ = __rstest_clean_core_cache__;
508
507
  rstest: normalizedConfig
509
508
  }
510
509
  });
511
- const outputFileSystem = (isMultiCompiler(rspackCompiler) ? rspackCompiler.compilers[0].outputFileSystem : rspackCompiler.outputFileSystem) || external_node_fs_["default"];
512
- const getRsbuildStats = async ()=>{
510
+ if (!rspackCompiler) throw new Error('rspackCompiler was not initialized');
511
+ const outputFileSystem = isMultiCompiler(rspackCompiler) ? rspackCompiler.compilers[0].outputFileSystem : rspackCompiler.outputFileSystem;
512
+ if (!outputFileSystem) throw new Error(`Expect outputFileSystem to be defined, but got ${outputFileSystem}`);
513
+ const getRsbuildStats = async ({ fileFilters } = {})=>{
513
514
  const stats = await devServer.environments[name].getStats();
514
515
  const manifest = devServer.environments[name].context.manifest;
515
- const { entrypoints, outputPath, assets, time: buildTime } = stats.toJson({
516
+ const { entrypoints, outputPath, assets, hash, time: buildTime } = stats.toJson({
516
517
  all: false,
518
+ hash: true,
517
519
  entrypoints: true,
518
520
  outputPath: true,
519
521
  assets: true,
@@ -548,11 +550,14 @@ global.__rstest_clean_core_cache__ = __rstest_clean_core_cache__;
548
550
  testPath: setupFiles[entry],
549
551
  files: entryFiles[entry]
550
552
  });
551
- else if (sourceEntries[entry]) entries.push({
552
- distPath,
553
- testPath: sourceEntries[entry],
554
- files: entryFiles[entry]
555
- });
553
+ else if (sourceEntries[entry]) {
554
+ if (fileFilters?.length && !fileFilters.includes(sourceEntries[entry])) continue;
555
+ entries.push({
556
+ distPath,
557
+ testPath: sourceEntries[entry],
558
+ files: entryFiles[entry]
559
+ });
560
+ }
556
561
  }
557
562
  const inlineSourceMap = 'inline-source-map' === stats.compilation.options.devtool;
558
563
  const sourceMaps = Object.fromEntries((await Promise.all(assets.map(async (asset)=>{
@@ -579,6 +584,7 @@ global.__rstest_clean_core_cache__ = __rstest_clean_core_cache__;
579
584
  ];
580
585
  }))).filter((asset)=>null !== asset[1]));
581
586
  return {
587
+ hash,
582
588
  entries,
583
589
  setupEntries,
584
590
  buildTime: buildTime,
@@ -590,11 +596,13 @@ global.__rstest_clean_core_cache__ = __rstest_clean_core_cache__;
590
596
  ];
591
597
  }))),
592
598
  sourceMaps,
593
- getSourcemap: (sourcePath)=>sourceMaps[sourcePath] || null,
594
- close: devServer.close
599
+ getSourcemap: (sourcePath)=>sourceMaps[sourcePath] || null
595
600
  };
596
601
  };
597
- return getRsbuildStats;
602
+ return {
603
+ closeServer: devServer.close,
604
+ getRsbuildStats
605
+ };
598
606
  };
599
607
  },
600
608
  "./src/pool/index.ts": function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
@@ -689,12 +697,41 @@ global.__rstest_clean_core_cache__ = __rstest_clean_core_cache__;
689
697
  }
690
698
  return parsed > 0 ? parsed : 1;
691
699
  };
692
- const createPool = async ({ entries, context, assetFiles, setupEntries, sourceMaps })=>{
700
+ const getRuntimeConfig = (context)=>{
701
+ const { testNamePattern, testTimeout, passWithNoTests, retry, globals, clearMocks, resetMocks, restoreMocks, unstubEnvs, unstubGlobals, maxConcurrency, printConsoleTrace, disableConsoleIntercept, testEnvironment, hookTimeout, isolate } = context.normalizedConfig;
702
+ return {
703
+ testNamePattern,
704
+ testTimeout,
705
+ hookTimeout,
706
+ passWithNoTests,
707
+ retry,
708
+ globals,
709
+ clearMocks,
710
+ resetMocks,
711
+ restoreMocks,
712
+ unstubEnvs,
713
+ unstubGlobals,
714
+ maxConcurrency,
715
+ printConsoleTrace,
716
+ disableConsoleIntercept,
717
+ testEnvironment,
718
+ isolate
719
+ };
720
+ };
721
+ const filterAssetsByEntry = (entryInfo, assetFiles, setupAssets, sourceMaps, entryLength)=>{
722
+ const neededFiles = entryLength > 1 && entryInfo.files ? Object.fromEntries(Object.entries(assetFiles).filter(([key])=>entryInfo.files.includes(key) || setupAssets.includes(key))) : assetFiles;
723
+ const neededSourceMaps = entryLength > 1 ? Object.fromEntries(Object.entries(sourceMaps).filter(([key])=>neededFiles[key])) : sourceMaps;
724
+ return {
725
+ assetFiles: neededFiles,
726
+ sourceMaps: neededSourceMaps
727
+ };
728
+ };
729
+ const createPool = async ({ context, recommendWorkerCount = 1 / 0 })=>{
693
730
  const execArgv = process.execArgv.filter((execArg)=>execArg.startsWith('--perf') || execArg.startsWith('--cpu-prof') || execArg.startsWith('--heap-prof') || execArg.startsWith('--diagnostic-dir'));
694
731
  const numCpus = getNumCpus();
695
732
  const { normalizedConfig: { pool: poolOptions, isolate }, reporters } = context;
696
733
  const threadsCount = 'watch' === context.command ? Math.max(Math.floor(numCpus / 2), 1) : Math.max(numCpus - 1, 1);
697
- const recommendCount = 'watch' === context.command ? threadsCount : Math.min(Object.keys(entries).length, threadsCount);
734
+ const recommendCount = 'watch' === context.command ? threadsCount : Math.min(recommendWorkerCount, threadsCount);
698
735
  const maxWorkers = poolOptions.maxWorkers ? parseWorkers(poolOptions.maxWorkers) : recommendCount;
699
736
  const minWorkers = poolOptions.minWorkers ? parseWorkers(poolOptions.minWorkers) : maxWorkers < recommendCount ? maxWorkers : recommendCount;
700
737
  if (maxWorkers < minWorkers) throw `Invalid pool configuration: maxWorkers(${maxWorkers}) cannot be less than minWorkers(${minWorkers}).`;
@@ -717,26 +754,7 @@ global.__rstest_clean_core_cache__ = __rstest_clean_core_cache__;
717
754
  ...process.env
718
755
  }
719
756
  });
720
- const { updateSnapshot } = context.snapshotManager.options;
721
- const { testNamePattern, testTimeout, passWithNoTests, retry, globals, clearMocks, resetMocks, restoreMocks, unstubEnvs, unstubGlobals, maxConcurrency, printConsoleTrace, disableConsoleIntercept, testEnvironment, hookTimeout } = context.normalizedConfig;
722
- const runtimeConfig = {
723
- testNamePattern,
724
- testTimeout,
725
- hookTimeout,
726
- passWithNoTests,
727
- retry,
728
- globals,
729
- clearMocks,
730
- resetMocks,
731
- restoreMocks,
732
- unstubEnvs,
733
- unstubGlobals,
734
- maxConcurrency,
735
- printConsoleTrace,
736
- disableConsoleIntercept,
737
- testEnvironment,
738
- isolate
739
- };
757
+ const runtimeConfig = getRuntimeConfig(context);
740
758
  const rpcMethods = {
741
759
  onTestCaseResult: async (result)=>{
742
760
  await Promise.all(reporters.map((reporter)=>reporter.onTestCaseResult?.(result)));
@@ -751,30 +769,22 @@ global.__rstest_clean_core_cache__ = __rstest_clean_core_cache__;
751
769
  await Promise.all(reporters.map((reporter)=>reporter.onTestFileResult?.(test)));
752
770
  }
753
771
  };
754
- const setupAssets = setupEntries.flatMap((entry)=>entry.files);
755
- const entryLength = Object.keys(entries).length;
756
- const filterAssetsByEntry = (entryInfo)=>{
757
- const neededFiles = entryLength > 1 && entryInfo.files ? Object.fromEntries(Object.entries(assetFiles).filter(([key])=>entryInfo.files.includes(key) || setupAssets.includes(key))) : assetFiles;
758
- const neededSourceMaps = entryLength > 1 ? Object.fromEntries(Object.entries(sourceMaps).filter(([key])=>neededFiles[key])) : sourceMaps;
759
- return {
760
- assetFiles: neededFiles,
761
- sourceMaps: neededSourceMaps
762
- };
763
- };
764
772
  return {
765
- runTests: async ()=>{
773
+ runTests: async ({ entries, assetFiles, setupEntries, sourceMaps, updateSnapshot })=>{
774
+ const setupAssets = setupEntries.flatMap((entry)=>entry.files || []);
775
+ const entryLength = Object.keys(entries).length;
766
776
  const results = await Promise.all(entries.map((entryInfo)=>{
767
- const { assetFiles, sourceMaps } = filterAssetsByEntry(entryInfo);
777
+ const { assetFiles: neededFiles, sourceMaps: neededSourceMaps } = filterAssetsByEntry(entryInfo, assetFiles, setupAssets, sourceMaps, entryLength);
768
778
  return pool.runTest({
769
779
  options: {
770
780
  entryInfo,
771
- assetFiles,
781
+ assetFiles: neededFiles,
772
782
  context: {
773
783
  rootPath: context.rootPath,
774
784
  runtimeConfig: (0, utils.v8)(runtimeConfig)
775
785
  },
776
786
  type: 'run',
777
- sourceMaps,
787
+ sourceMaps: neededSourceMaps,
778
788
  setupEntries,
779
789
  updateSnapshot
780
790
  },
@@ -799,18 +809,21 @@ global.__rstest_clean_core_cache__ = __rstest_clean_core_cache__;
799
809
  testResults
800
810
  };
801
811
  },
802
- collectTests: async ()=>Promise.all(entries.map((entryInfo)=>{
803
- const { assetFiles, sourceMaps } = filterAssetsByEntry(entryInfo);
812
+ collectTests: async ({ entries, assetFiles, setupEntries, sourceMaps, updateSnapshot })=>{
813
+ const setupAssets = setupEntries.flatMap((entry)=>entry.files || []);
814
+ const entryLength = Object.keys(entries).length;
815
+ return Promise.all(entries.map((entryInfo)=>{
816
+ const { assetFiles: neededFiles, sourceMaps: neededSourceMaps } = filterAssetsByEntry(entryInfo, assetFiles, setupAssets, sourceMaps, entryLength);
804
817
  return pool.collectTests({
805
818
  options: {
806
819
  entryInfo,
807
- assetFiles,
820
+ assetFiles: neededFiles,
808
821
  context: {
809
822
  rootPath: context.rootPath,
810
823
  runtimeConfig: (0, utils.v8)(runtimeConfig)
811
824
  },
812
825
  type: 'collect',
813
- sourceMaps,
826
+ sourceMaps: neededSourceMaps,
814
827
  setupEntries,
815
828
  updateSnapshot
816
829
  },
@@ -825,7 +838,8 @@ global.__rstest_clean_core_cache__ = __rstest_clean_core_cache__;
825
838
  ]
826
839
  };
827
840
  });
828
- })),
841
+ }));
842
+ },
829
843
  close: ()=>pool.close()
830
844
  };
831
845
  };
package/dist/920.js ADDED
@@ -0,0 +1,208 @@
1
+ import 'module';
2
+ /*#__PURE__*/ import.meta.url;
3
+ export const __webpack_ids__ = [
4
+ "920"
5
+ ];
6
+ export const __webpack_modules__ = {
7
+ "./src/core/runTests.ts": function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
8
+ __webpack_require__.d(__webpack_exports__, {
9
+ runTests: ()=>runTests
10
+ });
11
+ var src_pool = __webpack_require__("./src/pool/index.ts");
12
+ var utils = __webpack_require__("./src/utils/index.ts");
13
+ const isCliShortcutsEnabled = ()=>(0, utils._l)('stdin');
14
+ async function setupCliShortcuts({ closeServer, runAll, updateSnapshot, runFailedTests }) {
15
+ const shortcuts = [
16
+ {
17
+ key: 'c',
18
+ description: `${utils.$_.bold('c')} ${utils.$_.dim('clear console')}`,
19
+ action: ()=>{
20
+ console.clear();
21
+ }
22
+ },
23
+ {
24
+ key: 'f',
25
+ description: `${utils.$_.bold('f')} ${utils.$_.dim('rerun failed tests')}`,
26
+ action: async ()=>{
27
+ await runFailedTests();
28
+ }
29
+ },
30
+ {
31
+ key: 'a',
32
+ description: `${utils.$_.bold('a')} ${utils.$_.dim('rerun all tests')}`,
33
+ action: async ()=>{
34
+ await runAll();
35
+ }
36
+ },
37
+ {
38
+ key: 'u',
39
+ description: `${utils.$_.bold('u')} ${utils.$_.dim('update snapshot')}`,
40
+ action: async ()=>{
41
+ await updateSnapshot();
42
+ }
43
+ },
44
+ {
45
+ key: 'q',
46
+ description: `${utils.$_.bold('q')} ${utils.$_.dim('quit process')}`,
47
+ action: async ()=>{
48
+ try {
49
+ await closeServer();
50
+ } finally{
51
+ process.exit(0);
52
+ }
53
+ }
54
+ }
55
+ ];
56
+ const { createInterface } = await import("node:readline");
57
+ const rl = createInterface({
58
+ input: process.stdin,
59
+ output: process.stdout
60
+ });
61
+ process.stdin.setRawMode(true);
62
+ process.stdin.resume();
63
+ process.stdin.setEncoding('utf8');
64
+ const handleKeypress = (str, key)=>{
65
+ if (key.ctrl && 'c' === key.name) process.exit(0);
66
+ for (const shortcut of shortcuts)if (str === shortcut.key) return void shortcut.action();
67
+ if ('h' === str) {
68
+ let message = `\n ${utils.$_.bold(utils.$_.blue('Shortcuts:'))}\n`;
69
+ for (const shortcut of shortcuts)message += ` ${shortcut.description}\n`;
70
+ utils.kg.log(message);
71
+ }
72
+ };
73
+ process.stdin.on('keypress', handleKeypress);
74
+ return ()=>{
75
+ process.stdin.setRawMode(false);
76
+ process.stdin.pause();
77
+ rl.close();
78
+ };
79
+ }
80
+ var rsbuild = __webpack_require__("./src/core/rsbuild.ts");
81
+ async function runTests(context, fileFilters) {
82
+ const { normalizedConfig: { include, exclude, root, name, setupFiles: setups, includeSource }, rootPath, reporters, snapshotManager, command } = context;
83
+ const entriesCache = new Map();
84
+ const globTestSourceEntries = async ()=>{
85
+ const entries = await (0, utils.GL)({
86
+ include,
87
+ exclude,
88
+ includeSource,
89
+ root,
90
+ fileFilters
91
+ });
92
+ entriesCache.set(name, entries);
93
+ if (!Object.keys(entries).length) {
94
+ utils.kg.log(utils.$_.red('No test files found.'));
95
+ utils.kg.log('');
96
+ if (fileFilters.length) utils.kg.log(utils.$_.gray('filter: '), fileFilters.join(utils.$_.gray(', ')));
97
+ utils.kg.log(utils.$_.gray('include:'), include.join(utils.$_.gray(', ')));
98
+ utils.kg.log(utils.$_.gray('exclude:'), exclude.join(utils.$_.gray(', ')));
99
+ utils.kg.log('');
100
+ }
101
+ return entries;
102
+ };
103
+ const setupFiles = (0, utils.aA)(setups, rootPath);
104
+ const rsbuildInstance = await (0, rsbuild.z)(context, globTestSourceEntries, setupFiles);
105
+ const { getRsbuildStats, closeServer } = await (0, rsbuild.r)({
106
+ name,
107
+ normalizedConfig: context.normalizedConfig,
108
+ globTestSourceEntries: 'watch' === command ? globTestSourceEntries : async ()=>{
109
+ if (entriesCache.has(name)) return entriesCache.get(name);
110
+ return globTestSourceEntries();
111
+ },
112
+ setupFiles,
113
+ rsbuildInstance,
114
+ rootPath
115
+ });
116
+ const recommendWorkerCount = 'watch' === command ? 1 / 0 : Array.from(entriesCache.values()).reduce((acc, entries)=>acc + Object.keys(entries).length, 0);
117
+ const pool = await (0, src_pool.K)({
118
+ context,
119
+ recommendWorkerCount
120
+ });
121
+ let testFileResult = [];
122
+ let buildHash;
123
+ const run = async ({ fileFilters } = {})=>{
124
+ const { entries, setupEntries, assetFiles, sourceMaps, getSourcemap, buildTime, hash } = await getRsbuildStats({
125
+ fileFilters
126
+ });
127
+ const testStart = Date.now();
128
+ const { results, testResults } = await pool.runTests({
129
+ entries,
130
+ sourceMaps,
131
+ setupEntries,
132
+ assetFiles,
133
+ updateSnapshot: snapshotManager.options.updateSnapshot
134
+ });
135
+ const actualBuildTime = buildHash === hash ? 0 : buildTime;
136
+ const testTime = Date.now() - testStart;
137
+ const duration = {
138
+ totalTime: testTime + actualBuildTime,
139
+ buildTime: actualBuildTime,
140
+ testTime
141
+ };
142
+ buildHash = hash;
143
+ testFileResult = results;
144
+ if (results.some((r)=>'fail' === r.status)) process.exitCode = 1;
145
+ for (const reporter of reporters)await reporter.onTestRunEnd?.({
146
+ results,
147
+ testResults,
148
+ snapshotSummary: snapshotManager.summary,
149
+ duration,
150
+ getSourcemap
151
+ });
152
+ };
153
+ if ('watch' === command) {
154
+ const enableCliShortcuts = isCliShortcutsEnabled();
155
+ const afterTestsWatchRun = ()=>{
156
+ utils.kg.log(utils.$_.green(' Waiting for file changes...'));
157
+ if (enableCliShortcuts) if (snapshotManager.summary.unmatched) utils.kg.log(` ${utils.$_.dim('press')} ${utils.$_.yellow(utils.$_.bold('u'))} ${utils.$_.dim('to update snapshot')}${utils.$_.dim(', press')} ${utils.$_.bold('h')} ${utils.$_.dim('to show help')}\n`);
158
+ else utils.kg.log(` ${utils.$_.dim('press')} ${utils.$_.bold('h')} ${utils.$_.dim('to show help')}${utils.$_.dim(', press')} ${utils.$_.bold('q')} ${utils.$_.dim('to quit')}\n`);
159
+ };
160
+ const clearLogs = ()=>{
161
+ console.clear();
162
+ };
163
+ rsbuildInstance.onDevCompileDone(async ({ isFirstCompile })=>{
164
+ if (!isFirstCompile) clearLogs();
165
+ snapshotManager.clear();
166
+ await run();
167
+ if (isFirstCompile && enableCliShortcuts) await setupCliShortcuts({
168
+ closeServer: async ()=>{
169
+ await pool.close();
170
+ await closeServer();
171
+ },
172
+ runAll: async ()=>{
173
+ clearLogs();
174
+ snapshotManager.clear();
175
+ await run();
176
+ afterTestsWatchRun();
177
+ },
178
+ runFailedTests: async ()=>{
179
+ const failedTests = testFileResult.filter((result)=>'fail' === result.status).map((r)=>r.testPath);
180
+ if (!failedTests.length) return void utils.kg.log(utils.$_.yellow('\nNo failed tests were found that needed to be rerun.'));
181
+ clearLogs();
182
+ snapshotManager.clear();
183
+ await run({
184
+ fileFilters: failedTests
185
+ });
186
+ afterTestsWatchRun();
187
+ },
188
+ updateSnapshot: async ()=>{
189
+ if (!snapshotManager.summary.unmatched) return void utils.kg.log(utils.$_.yellow('\nNo snapshots were found that needed to be updated.'));
190
+ clearLogs();
191
+ const originalUpdateSnapshot = snapshotManager.options.updateSnapshot;
192
+ snapshotManager.clear();
193
+ snapshotManager.options.updateSnapshot = 'all';
194
+ await run();
195
+ afterTestsWatchRun();
196
+ snapshotManager.options.updateSnapshot = originalUpdateSnapshot;
197
+ }
198
+ });
199
+ afterTestsWatchRun();
200
+ });
201
+ } else {
202
+ await run();
203
+ await pool.close();
204
+ await closeServer();
205
+ }
206
+ }
207
+ }
208
+ };
package/dist/cli.js CHANGED
@@ -2302,6 +2302,7 @@ var __webpack_modules__ = {
2302
2302
  Yz: ()=>getTaskNameWithPrefix,
2303
2303
  Z: ()=>formatError,
2304
2304
  ZY: ()=>getAbsolutePath,
2305
+ _l: ()=>isTTY,
2305
2306
  v8: ()=>serializableConfig
2306
2307
  });
2307
2308
  var pathe__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("pathe");
@@ -2443,12 +2444,14 @@ var __webpack_modules__ = {
2443
2444
  /^node:/,
2444
2445
  'pnpapi'
2445
2446
  ];
2447
+ const isTTY = (type = 'stdout')=>('stdin' === type ? process.stdin.isTTY : process.stdout.isTTY) && !process.env.CI;
2446
2448
  },
2447
2449
  "./src/utils/index.ts": function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
2448
2450
  __webpack_require__.d(__webpack_exports__, {
2449
2451
  F7: ()=>constants.F7,
2450
2452
  GL: ()=>getTestEntries,
2451
2453
  aj: ()=>prettyTestPath,
2454
+ _l: ()=>helper._l,
2452
2455
  aA: ()=>getSetupFiles,
2453
2456
  kg: ()=>logger.k,
2454
2457
  Io: ()=>constants.Io,
@@ -2639,6 +2642,7 @@ var __webpack_modules__ = {
2639
2642
  if ('TEAMCITY_VERSION' in env) return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
2640
2643
  if ('truecolor' === env.COLORTERM) return 3;
2641
2644
  if ('xterm-kitty' === env.TERM) return 3;
2645
+ if ('xterm-ghostty' === env.TERM) return 3;
2642
2646
  if ('TERM_PROGRAM' in env) {
2643
2647
  const version = Number.parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10);
2644
2648
  switch(env.TERM_PROGRAM){
@@ -2836,7 +2840,7 @@ var __webpack_modules__ = {
2836
2840
  src_logger.override({
2837
2841
  debug: (message, ...args)=>{
2838
2842
  if ('verbose' !== src_logger.level) return;
2839
- const time = helper.$_.gray(`${getTime()}`);
2843
+ const time = helper.$_.gray(getTime());
2840
2844
  console.log(` ${helper.$_.magenta('rstest')} ${time} ${message}`, ...args);
2841
2845
  }
2842
2846
  });
@@ -3694,7 +3698,7 @@ function prepareCli() {
3694
3698
  if (!npm_execpath || npm_execpath.includes('npx-cli.js') || npm_execpath.includes('.bun')) console.log();
3695
3699
  }
3696
3700
  function showRstest() {
3697
- logger.k.greet(" Rstest v0.1.2");
3701
+ logger.k.greet(" Rstest v0.1.3");
3698
3702
  logger.k.log('');
3699
3703
  }
3700
3704
  const applyCommonOptions = (cli)=>{
@@ -3743,7 +3747,7 @@ async function initCli(options) {
3743
3747
  function setupCommands() {
3744
3748
  const cli = dist('rstest');
3745
3749
  cli.help();
3746
- cli.version("0.1.2");
3750
+ cli.version("0.1.3");
3747
3751
  applyCommonOptions(cli);
3748
3752
  cli.command('[...filters]', 'run tests').option('--watch', 'Run tests in watch mode').action(async (filters, options)=>{
3749
3753
  showRstest();
package/dist/worker.js CHANGED
@@ -5200,6 +5200,7 @@ var __webpack_modules__ = {
5200
5200
  if ('TEAMCITY_VERSION' in env) return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
5201
5201
  if ('truecolor' === env.COLORTERM) return 3;
5202
5202
  if ('xterm-kitty' === env.TERM) return 3;
5203
+ if ('xterm-ghostty' === env.TERM) return 3;
5203
5204
  if ('TERM_PROGRAM' in env) {
5204
5205
  const version = Number.parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10);
5205
5206
  switch(env.TERM_PROGRAM){
@@ -5397,7 +5398,7 @@ var __webpack_modules__ = {
5397
5398
  src_logger.override({
5398
5399
  debug: (message, ...args)=>{
5399
5400
  if ('verbose' !== src_logger.level) return;
5400
- const time = helper.$_.gray(`${getTime()}`);
5401
+ const time = helper.$_.gray(getTime());
5401
5402
  console.log(` ${helper.$_.magenta('rstest')} ${time} ${message}`, ...args);
5402
5403
  }
5403
5404
  });
@@ -5576,7 +5577,7 @@ var external_node_path_ = __webpack_require__("node:path");
5576
5577
  var external_pathe_ = __webpack_require__("pathe");
5577
5578
  var logger = __webpack_require__("./src/utils/logger.ts");
5578
5579
  const shouldInterop = ({ interopDefault = true, modulePath, mod })=>{
5579
- if (false === interopDefault) return false;
5580
+ if (!interopDefault) return false;
5580
5581
  return !modulePath.endsWith('.mjs') && 'default' in mod;
5581
5582
  };
5582
5583
  const isPrimitive = (v)=>v !== Object(v);
@@ -5650,7 +5651,7 @@ const createRequire = (filename, distPath, rstestContext, assetFiles, interopDef
5650
5651
  return require;
5651
5652
  };
5652
5653
  const defineRstestDynamicImport = ({ testPath, interopDefault, returnModule = false })=>async (specifier, importAttributes)=>{
5653
- const resolvedPath = (0, external_node_path_.isAbsolute)(specifier) ? pathToFileURL(specifier) : await import.meta.resolve(specifier, pathToFileURL(testPath));
5654
+ const resolvedPath = (0, external_node_path_.isAbsolute)(specifier) ? pathToFileURL(specifier) : import.meta.resolve(specifier, pathToFileURL(testPath));
5654
5655
  const modulePath = 'string' == typeof resolvedPath ? resolvedPath : resolvedPath.pathname;
5655
5656
  if (importAttributes?.with?.rstest) delete importAttributes.with.rstest;
5656
5657
  const importedModule = await import(modulePath, importAttributes);
@@ -5885,7 +5886,7 @@ const preparePool = async ({ entryInfo: { distPath, testPath }, sourceMaps, upda
5885
5886
  {
5886
5887
  const { environment } = await __webpack_require__.e("44").then(__webpack_require__.bind(__webpack_require__, "./src/runtime/worker/env/happyDom.ts"));
5887
5888
  const { teardown } = await environment.setup(global, {});
5888
- cleanupFns.push(async ()=>await teardown(global));
5889
+ cleanupFns.push(async ()=>teardown(global));
5889
5890
  break;
5890
5891
  }
5891
5892
  default:
@@ -5948,7 +5949,7 @@ const runInPool = async (options)=>{
5948
5949
  isTeardown = false;
5949
5950
  const { entryInfo: { distPath, testPath }, setupEntries, assetFiles, type, context: { runtimeConfig: { isolate } } } = options;
5950
5951
  const cleanups = [];
5951
- const exit = process.exit;
5952
+ const exit = process.exit.bind(process);
5952
5953
  process.exit = (code = process.exitCode || 0)=>{
5953
5954
  throw new Error(`process.exit unexpectedly called with "${code}"`);
5954
5955
  };
@@ -430,13 +430,13 @@ declare type DescribeAPI = DescribeFn & {
430
430
  };
431
431
 
432
432
  declare interface DescribeEachFn {
433
- <T extends Record<string, unknown>>(cases: ReadonlyArray<T>): (description: string, fn?: (param: T) => MaybePromise<void>) => void;
434
- <T extends readonly [unknown, ...Array<unknown>]>(cases: ReadonlyArray<T>): (description: string, fn: (...args: [...T]) => MaybePromise<void>) => void;
433
+ <T extends Record<string, unknown>>(cases: readonly T[]): (description: string, fn?: (param: T) => MaybePromise<void>) => void;
434
+ <T extends readonly [unknown, ...unknown[]]>(cases: readonly T[]): (description: string, fn: (...args: [...T]) => MaybePromise<void>) => void;
435
435
  }
436
436
 
437
437
  declare type DescribeFn = (description: string, fn?: () => void) => void;
438
438
 
439
- declare type DescribeForFn = <T>(cases: ReadonlyArray<T>) => (description: string, fn?: (param: T) => MaybePromise<void>) => void;
439
+ declare type DescribeForFn = <T>(cases: readonly T[]) => (description: string, fn?: (param: T) => MaybePromise<void>) => void;
440
440
 
441
441
  /**
442
442
  * @param a Expected value
@@ -514,7 +514,7 @@ declare interface ExpectStatic extends ExpectStatic_2 {
514
514
  unreachable: (message?: string) => never;
515
515
  soft: <T>(actual: T, message?: string) => Assertion<T>;
516
516
  poll: <T>(actual: () => T, options?: ExpectPollOptions) => Omit<PromisifyAssertion_2<Awaited<T>>, 'rejects' | 'resolves' | 'toThrow' | 'toThrowError' | 'throw' | 'throws' | 'matchSnapshot' | 'toMatchSnapshot' | 'toMatchInlineSnapshot' | 'toThrowErrorMatchingSnapshot' | 'toThrowErrorMatchingInlineSnapshot'>;
517
- addEqualityTesters: (testers: Array<Tester>) => void;
517
+ addEqualityTesters: (testers: Tester[]) => void;
518
518
  assertions: (expected: number) => void;
519
519
  hasAssertions: () => void;
520
520
  addSnapshotSerializer: typeof addSerializer;
@@ -1225,21 +1225,21 @@ declare type MockContext_2<T extends FunctionLike = FunctionLike> = {
1225
1225
  /**
1226
1226
  * List of the call arguments of all calls that have been made to the mock.
1227
1227
  */
1228
- calls: Array<Parameters<T>>;
1228
+ calls: Parameters<T>[];
1229
1229
  /**
1230
1230
  * List of all the object instances that have been instantiated from the mock.
1231
1231
  */
1232
- instances: Array<ReturnType<T>>;
1232
+ instances: ReturnType<T>[];
1233
1233
  /**
1234
1234
  * List of all the function contexts that have been applied to calls to the mock.
1235
1235
  */
1236
- contexts: Array<ThisParameterType<T>>;
1236
+ contexts: ThisParameterType<T>[];
1237
1237
  /**
1238
1238
  * The order of mock's execution.
1239
1239
  * This returns an array of numbers which are shared between all defined mocks.
1240
1240
  * The index is starting with `1`.
1241
1241
  */
1242
- invocationCallOrder: Array<number>;
1242
+ invocationCallOrder: number[];
1243
1243
  /**
1244
1244
  * List of the call arguments of the last call that was made to the mock.
1245
1245
  * If the function was not called, it will return `undefined`.
@@ -1248,7 +1248,7 @@ declare type MockContext_2<T extends FunctionLike = FunctionLike> = {
1248
1248
  /**
1249
1249
  * List of the results of all calls that have been made to the mock.
1250
1250
  */
1251
- results: Array<MockResult_2<ReturnType<T>>>;
1251
+ results: MockResult_2<ReturnType<T>>[];
1252
1252
  /**
1253
1253
  * List of the results of all values that were `resolved` or `rejected` from the function.
1254
1254
  */
@@ -2270,8 +2270,8 @@ declare type TestContext = {
2270
2270
  };
2271
2271
 
2272
2272
  declare interface TestEachFn {
2273
- <T extends Record<string, unknown>>(cases: ReadonlyArray<T>): (description: string, fn?: (param: T) => MaybePromise<void>, timeout?: number) => void;
2274
- <T extends readonly [unknown, ...Array<unknown>]>(cases: ReadonlyArray<T>): (description: string, fn: (...args: [...T]) => MaybePromise<void>, timeout?: number) => void;
2273
+ <T extends Record<string, unknown>>(cases: readonly T[]): (description: string, fn?: (param: T) => MaybePromise<void>, timeout?: number) => void;
2274
+ <T extends readonly [unknown, ...unknown[]]>(cases: readonly T[]): (description: string, fn: (...args: [...T]) => MaybePromise<void>, timeout?: number) => void;
2275
2275
  }
2276
2276
 
2277
2277
  declare type Tester = (this: TesterContext, a: any, b: any, customTesters: Array<Tester>) => boolean | undefined;
@@ -2291,7 +2291,7 @@ declare type TestFileResult = TestResult & {
2291
2291
 
2292
2292
  declare type TestFn<ExtraContext = object> = (description: string, fn?: TestCallbackFn<ExtraContext>, timeout?: number) => void;
2293
2293
 
2294
- declare type TestForFn<ExtraContext = object> = <T>(cases: ReadonlyArray<T>) => (description: string, fn?: (param: T, context: TestContext & ExtraContext) => MaybePromise<void>, timeout?: number) => void;
2294
+ declare type TestForFn<ExtraContext = object> = <T>(cases: readonly T[]) => (description: string, fn?: (param: T, context: TestContext & ExtraContext) => MaybePromise<void>, timeout?: number) => void;
2295
2295
 
2296
2296
  /** The test file original path */
2297
2297
  declare type TestPath = string;
@@ -475,7 +475,7 @@ declare interface ExpectStatic extends ExpectStatic_2 {
475
475
  unreachable: (message?: string) => never;
476
476
  soft: <T>(actual: T, message?: string) => Assertion_2<T>;
477
477
  poll: <T>(actual: () => T, options?: ExpectPollOptions) => Omit<PromisifyAssertion_2<Awaited<T>>, 'rejects' | 'resolves' | 'toThrow' | 'toThrowError' | 'throw' | 'throws' | 'matchSnapshot' | 'toMatchSnapshot' | 'toMatchInlineSnapshot' | 'toThrowErrorMatchingSnapshot' | 'toThrowErrorMatchingInlineSnapshot'>;
478
- addEqualityTesters: (testers: Array<Tester>) => void;
478
+ addEqualityTesters: (testers: Tester[]) => void;
479
479
  assertions: (expected: number) => void;
480
480
  hasAssertions: () => void;
481
481
  addSnapshotSerializer: typeof addSerializer;
@@ -1962,7 +1962,7 @@ declare type TestSuite = {
1962
1962
  sequential?: boolean;
1963
1963
  testPath: TestPath;
1964
1964
  /** nested cases and suite could in a suite */
1965
- tests: Array<TestSuite | TestCase>;
1965
+ tests: (TestSuite | TestCase)[];
1966
1966
  type: 'suite';
1967
1967
  afterAllListeners?: AfterAllListener[];
1968
1968
  beforeAllListeners?: BeforeAllListener[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rstest/core",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "The Rsbuild-based test tool.",
5
5
  "bugs": {
6
6
  "url": "https://github.com/web-infra-dev/rstest/issues"
@@ -50,7 +50,7 @@
50
50
  "dependencies": {
51
51
  "chai": "^5.2.1",
52
52
  "@types/chai": "^5.2.2",
53
- "@rsbuild/core": "1.4.12",
53
+ "@rsbuild/core": "1.4.15",
54
54
  "birpc": "2.5.0",
55
55
  "pathe": "^2.0.3",
56
56
  "std-env": "^3.9.0",
@@ -62,7 +62,7 @@
62
62
  "@babel/code-frame": "^7.27.1",
63
63
  "@jridgewell/trace-mapping": "0.3.29",
64
64
  "@microsoft/api-extractor": "^7.52.10",
65
- "@rslib/core": "0.11.0",
65
+ "@rslib/core": "0.11.2",
66
66
  "@sinonjs/fake-timers": "^14.0.0",
67
67
  "@types/babel__code-frame": "^7.0.6",
68
68
  "@types/jsdom": "^21.1.7",
@@ -74,7 +74,7 @@
74
74
  "jsdom": "^26.1.0",
75
75
  "license-webpack-plugin": "^4.0.2",
76
76
  "picocolors": "^1.1.1",
77
- "rslog": "^1.2.9",
77
+ "rslog": "^1.2.11",
78
78
  "source-map-support": "^0.5.21",
79
79
  "stacktrace-parser": "0.1.11",
80
80
  "tinyglobby": "^0.2.14",
package/dist/629.js DELETED
@@ -1,84 +0,0 @@
1
- import 'module';
2
- /*#__PURE__*/ import.meta.url;
3
- export const __webpack_ids__ = [
4
- "629"
5
- ];
6
- export const __webpack_modules__ = {
7
- "./src/core/runTests.ts": function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
8
- __webpack_require__.d(__webpack_exports__, {
9
- runTests: ()=>runTests
10
- });
11
- var _pool__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/pool/index.ts");
12
- var _utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/utils/index.ts");
13
- var _rsbuild__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./src/core/rsbuild.ts");
14
- async function runTests(context, fileFilters) {
15
- const { normalizedConfig: { include, exclude, root, name, setupFiles: setups, includeSource }, rootPath, reporters, snapshotManager, command } = context;
16
- const globTestSourceEntries = async ()=>{
17
- const entries = await (0, _utils__WEBPACK_IMPORTED_MODULE_1__.GL)({
18
- include,
19
- exclude,
20
- includeSource,
21
- root,
22
- fileFilters
23
- });
24
- if (!Object.keys(entries).length) {
25
- _utils__WEBPACK_IMPORTED_MODULE_1__.kg.log(_utils__WEBPACK_IMPORTED_MODULE_1__.$_.red('No test files found.'));
26
- _utils__WEBPACK_IMPORTED_MODULE_1__.kg.log('');
27
- if (fileFilters.length) _utils__WEBPACK_IMPORTED_MODULE_1__.kg.log(_utils__WEBPACK_IMPORTED_MODULE_1__.$_.gray('filter: '), fileFilters.join(_utils__WEBPACK_IMPORTED_MODULE_1__.$_.gray(', ')));
28
- _utils__WEBPACK_IMPORTED_MODULE_1__.kg.log(_utils__WEBPACK_IMPORTED_MODULE_1__.$_.gray('include:'), include.join(_utils__WEBPACK_IMPORTED_MODULE_1__.$_.gray(', ')));
29
- _utils__WEBPACK_IMPORTED_MODULE_1__.kg.log(_utils__WEBPACK_IMPORTED_MODULE_1__.$_.gray('exclude:'), exclude.join(_utils__WEBPACK_IMPORTED_MODULE_1__.$_.gray(', ')));
30
- _utils__WEBPACK_IMPORTED_MODULE_1__.kg.log('');
31
- }
32
- return entries;
33
- };
34
- const setupFiles = (0, _utils__WEBPACK_IMPORTED_MODULE_1__.aA)(setups, rootPath);
35
- const rsbuildInstance = await (0, _rsbuild__WEBPACK_IMPORTED_MODULE_2__.z)(context, globTestSourceEntries, setupFiles);
36
- const getRsbuildStats = await (0, _rsbuild__WEBPACK_IMPORTED_MODULE_2__.r)({
37
- name,
38
- normalizedConfig: context.normalizedConfig,
39
- globTestSourceEntries,
40
- setupFiles,
41
- rsbuildInstance,
42
- rootPath
43
- });
44
- const run = async ()=>{
45
- const { entries, setupEntries, assetFiles, sourceMaps, getSourcemap, close, buildTime } = await getRsbuildStats();
46
- const testStart = Date.now();
47
- const pool = await (0, _pool__WEBPACK_IMPORTED_MODULE_0__.K)({
48
- entries,
49
- sourceMaps,
50
- setupEntries,
51
- assetFiles,
52
- context
53
- });
54
- const { results, testResults } = await pool.runTests();
55
- const testTime = Date.now() - testStart;
56
- const duration = {
57
- totalTime: testTime + buildTime,
58
- buildTime,
59
- testTime
60
- };
61
- if (results.some((r)=>'fail' === r.status)) process.exitCode = 1;
62
- for (const reporter of reporters)await reporter.onTestRunEnd?.({
63
- results,
64
- testResults,
65
- snapshotSummary: snapshotManager.summary,
66
- duration,
67
- getSourcemap
68
- });
69
- return async ()=>{
70
- await close();
71
- await pool.close();
72
- };
73
- };
74
- if ('watch' === command) rsbuildInstance.onDevCompileDone(async ()=>{
75
- await run();
76
- _utils__WEBPACK_IMPORTED_MODULE_1__.kg.log(_utils__WEBPACK_IMPORTED_MODULE_1__.$_.green(' Waiting for file changes...'));
77
- });
78
- else {
79
- const close = await run();
80
- await close();
81
- }
82
- }
83
- }
84
- };