@rspack-debug/test-tools 2.0.0-canary.20260120 → 2.0.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  Test tools for rspack.
10
10
 
11
- ## Wasm Tests
11
+ ## Wasm tests
12
12
 
13
13
  We expect to reuse the tests for Rspack wasm target as many as possible and we have managed to do it partially. Currently wasm tests should be run with an environment variable `WASM=1` under the following limitations:
14
14
 
@@ -120,7 +120,6 @@ function defaultOptions(context) {
120
120
  name: 'runtime',
121
121
  },
122
122
  minimize: false,
123
- removeAvailableModules: true,
124
123
  removeEmptyChunks: true,
125
124
  moduleIds: 'named',
126
125
  chunkIds: 'named',
@@ -75,7 +75,6 @@ const creators = new Map();
75
75
  async function generateOptions(context, temp, target, updatePlugin) {
76
76
  let options = {
77
77
  context: temp,
78
- mode: 'production',
79
78
  cache: true,
80
79
  devtool: false,
81
80
  output: {
@@ -12,8 +12,8 @@ exports.checkSnapshot = checkSnapshot;
12
12
  exports.afterExecute = afterExecute;
13
13
  exports.findMultiCompilerBundle = findMultiCompilerBundle;
14
14
  exports.configMultiCompiler = configMultiCompiler;
15
+ const node_path_1 = __importDefault(require("node:path"));
15
16
  const fs_extra_1 = __importDefault(require("fs-extra"));
16
- const path_1 = __importDefault(require("path"));
17
17
  const webpack_merge_1 = __importDefault(require("webpack-merge"));
18
18
  const helper_1 = require("../helper");
19
19
  const placeholder_1 = require("../helper/expect/placeholder");
@@ -97,7 +97,7 @@ async function check(env, context, name) {
97
97
  const options = compiler.getOptions();
98
98
  if (stats) {
99
99
  if (testConfig.writeStatsOuptut) {
100
- fs_extra_1.default.writeFileSync(path_1.default.join(context.getDist(), 'stats.txt'), stats.toString({
100
+ fs_extra_1.default.writeFileSync(node_path_1.default.join(context.getDist(), 'stats.txt'), stats.toString({
101
101
  preset: 'verbose',
102
102
  colors: false,
103
103
  }), 'utf-8');
@@ -110,7 +110,7 @@ async function check(env, context, name) {
110
110
  chunkGroups: true,
111
111
  errorDetails: true,
112
112
  });
113
- fs_extra_1.default.writeFileSync(path_1.default.join(context.getDist(), 'stats.json'), JSON.stringify(jsonStats, null, 2), 'utf-8');
113
+ fs_extra_1.default.writeFileSync(node_path_1.default.join(context.getDist(), 'stats.json'), JSON.stringify(jsonStats, null, 2), 'utf-8');
114
114
  }
115
115
  if (fs_extra_1.default.existsSync(context.getSource('errors.js')) ||
116
116
  fs_extra_1.default.existsSync(context.getSource('warnings.js')) ||
@@ -141,7 +141,7 @@ async function check(env, context, name) {
141
141
  }
142
142
  }
143
143
  async function checkSnapshot(env, context, name, snapshot, filter) {
144
- if (path_1.default.extname(snapshot) === '.snap') {
144
+ if (node_path_1.default.extname(snapshot) === '.snap') {
145
145
  throw new Error('Snapshot with `.snap` will be managed by rstest, please use `.snap.txt` instead');
146
146
  }
147
147
  const compilerManager = context.getCompiler();
@@ -172,20 +172,20 @@ async function checkSnapshot(env, context, name, snapshot, filter) {
172
172
  const fileContents = Object.entries(compilation.assets)
173
173
  .filter(([file]) => snapshotFileFilter(file))
174
174
  .map(([file, source]) => {
175
- const tag = path_1.default.extname(file).slice(1) || 'txt';
175
+ const tag = node_path_1.default.extname(file).slice(1) || 'txt';
176
176
  let content = (0, placeholder_1.normalizePlaceholder)(source.source().toString());
177
177
  const testConfig = context.getTestConfig();
178
178
  if (testConfig.snapshotContent) {
179
179
  content = testConfig.snapshotContent(content);
180
180
  }
181
- const filePath = file.replaceAll(path_1.default.sep, '/');
181
+ const filePath = file.replaceAll(node_path_1.default.sep, '/');
182
182
  return `\`\`\`${tag} title=${filePath}\n${content}\n\`\`\``;
183
183
  });
184
184
  fileContents.sort();
185
185
  const content = fileContents.join('\n\n');
186
- const snapshotPath = path_1.default.isAbsolute(snapshot)
186
+ const snapshotPath = node_path_1.default.isAbsolute(snapshot)
187
187
  ? snapshot
188
- : path_1.default.resolve(context.getSource(), path_1.default.join('__snapshots__', `${snapshot}${total > 1 ? `-${i}` : ''}`));
188
+ : node_path_1.default.resolve(context.getSource(), node_path_1.default.join('__snapshots__', `${snapshot}${total > 1 ? `-${i}` : ''}`));
189
189
  env.expect(content).toMatchFileSnapshotSync(snapshotPath);
190
190
  }
191
191
  }
@@ -9,8 +9,8 @@ exports.defaultOptions = defaultOptions;
9
9
  exports.enableEsmLibraryPlugin = enableEsmLibraryPlugin;
10
10
  exports.overrideOptions = overrideOptions;
11
11
  exports.findBundle = findBundle;
12
+ const node_path_1 = __importDefault(require("node:path"));
12
13
  const fs_extra_1 = __importDefault(require("fs-extra"));
13
- const path_1 = __importDefault(require("path"));
14
14
  const parseResource_1 = require("../helper/legacy/parseResource");
15
15
  const creator_1 = require("../test/creator");
16
16
  const common_1 = require("./common");
@@ -94,7 +94,7 @@ function overrideOptions(index, context, options) {
94
94
  if (!options.output?.filename) {
95
95
  const runtimeChunkForModernModule = options.optimization?.runtimeChunk === undefined &&
96
96
  enableEsmLibraryPlugin(options);
97
- const outputModule = options.experiments?.outputModule || enableEsmLibraryPlugin(options);
97
+ const outputModule = options.output?.module || enableEsmLibraryPlugin(options);
98
98
  options.output ??= {};
99
99
  options.output.filename = `${runtimeChunkForModernModule ? `[name]${outputModule ? '.mjs' : '.js'}` : `bundle${index}${outputModule ? '.mjs' : '.js'}`}`;
100
100
  }
@@ -115,15 +115,15 @@ function findBundle(index, context, options) {
115
115
  if (typeof testConfig.findBundle === 'function') {
116
116
  return testConfig.findBundle(index, options);
117
117
  }
118
- const ext = path_1.default.extname((0, parseResource_1.parseResource)(options.output?.filename).path);
118
+ const ext = node_path_1.default.extname((0, parseResource_1.parseResource)(options.output?.filename).path);
119
119
  const bundlePath = [];
120
120
  if (options.output?.path &&
121
- fs_extra_1.default.existsSync(path_1.default.join(options.output.path, `bundle${index}${ext}`))) {
122
- const cssOutputPath = path_1.default.join(options.output.path, (typeof options.output?.cssFilename === 'string' &&
121
+ fs_extra_1.default.existsSync(node_path_1.default.join(options.output.path, `bundle${index}${ext}`))) {
122
+ const cssOutputPath = node_path_1.default.join(options.output.path, (typeof options.output?.cssFilename === 'string' &&
123
123
  options.output?.cssFilename) ||
124
124
  `bundle${index}.css`);
125
125
  if (fs_extra_1.default.existsSync(cssOutputPath)) {
126
- bundlePath.push(path_1.default.relative(options.output.path, cssOutputPath));
126
+ bundlePath.push(node_path_1.default.relative(options.output.path, cssOutputPath));
127
127
  }
128
128
  bundlePath.push(`./bundle${index}${ext}`);
129
129
  }
@@ -1,10 +1,6 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.createEsmOutputCase = createEsmOutputCase;
7
- const core_1 = __importDefault(require("@rspack/core"));
8
4
  const creator_1 = require("../test/creator");
9
5
  const common_1 = require("./common");
10
6
  const runner_1 = require("./runner");
@@ -25,26 +21,7 @@ const creator = new creator_1.BasicCaseCreator({
25
21
  steps: ({ name }) => [
26
22
  {
27
23
  config: async (context) => {
28
- (0, common_1.configMultiCompiler)(context, name, ['rspack.config.cjs', 'rspack.config.js', 'webpack.config.js'], defaultOptions, (_index, context, options) => {
29
- const testConfig = context.getTestConfig();
30
- if (testConfig.esmLibPluginOptions) {
31
- let target;
32
- const otherPlugins = options.plugins?.filter((plugin) => {
33
- const isTarget = plugin instanceof core_1.default.experiments.EsmLibraryPlugin;
34
- if (isTarget) {
35
- target = plugin;
36
- }
37
- return !isTarget;
38
- }) ?? [];
39
- options.plugins = [
40
- ...otherPlugins,
41
- new core_1.default.experiments.EsmLibraryPlugin({
42
- ...target.options,
43
- ...testConfig.esmLibPluginOptions,
44
- }),
45
- ];
46
- }
47
- });
24
+ (0, common_1.configMultiCompiler)(context, name, ['rspack.config.cjs', 'rspack.config.js', 'webpack.config.js'], defaultOptions, () => { });
48
25
  },
49
26
  compiler: async (context) => {
50
27
  await (0, common_1.compiler)(context, name);
@@ -93,6 +70,9 @@ const defaultOptions = (_index, context) => ({
93
70
  filename: '[name].mjs',
94
71
  pathinfo: true,
95
72
  module: true,
73
+ library: {
74
+ type: 'modern-module',
75
+ },
96
76
  bundlerInfo: {
97
77
  force: false,
98
78
  },
@@ -117,10 +97,6 @@ const defaultOptions = (_index, context) => ({
117
97
  fs: 'module-import fs',
118
98
  path: 'module-import path',
119
99
  },
120
- plugins: [new core_1.default.experiments.EsmLibraryPlugin()],
121
- experiments: {
122
- outputModule: true,
123
- },
124
100
  });
125
101
  function createEsmOutputCase(name, src, dist) {
126
102
  creator.create(name, src, dist);
package/dist/case/hot.js CHANGED
@@ -30,8 +30,7 @@ function createHotProcessor(name, src, temp, target, incremental = false) {
30
30
  options = await (0, common_1.config)(context, name, ['rspack.config.js', 'webpack.config.js'], options);
31
31
  overrideOptions(context, options, target, updatePlugin);
32
32
  if (incremental) {
33
- options.experiments ??= {};
34
- options.experiments.incremental ??= 'advance-silent';
33
+ options.incremental ??= 'advance-silent';
35
34
  }
36
35
  compiler.setOptions(options);
37
36
  },
@@ -114,10 +113,8 @@ function defaultOptions(context, target) {
114
113
  moduleIds: 'named',
115
114
  },
116
115
  target,
117
- experiments: {
118
- // test incremental: "safe" here, we test default incremental in Incremental-*.test.js
119
- incremental: 'safe',
120
- },
116
+ // test incremental: "safe" here, we test default incremental in Incremental-*.test.js
117
+ incremental: 'safe',
121
118
  };
122
119
  options.plugins ??= [];
123
120
  options.plugins.push(new core_1.default.HotModuleReplacementPlugin());
@@ -102,7 +102,6 @@ function defaultOptions(context, compilerOptions, mode) {
102
102
  ...testConfig.optimization,
103
103
  }
104
104
  : {
105
- removeAvailableModules: true,
106
105
  removeEmptyChunks: true,
107
106
  mergeDuplicateChunks: true,
108
107
  // CHANGE: rspack does not support `flagIncludedChunks` yet.
@@ -144,6 +143,7 @@ function defaultOptions(context, compilerOptions, mode) {
144
143
  bundlerInfo: {
145
144
  force: false,
146
145
  },
146
+ ...(compilerOptions?.module ? { module: true } : {}),
147
147
  },
148
148
  resolve: {
149
149
  modules: ['web_modules', 'node_modules'],
@@ -196,13 +196,11 @@ function defaultOptions(context, compilerOptions, mode) {
196
196
  });
197
197
  }),
198
198
  experiments: {
199
- css: false,
200
199
  asyncWebAssembly: true,
201
200
  // CHANGE: rspack does not support `backCompat` yet.
202
201
  // backCompat: false,
203
202
  // CHANGE: Rspack enables `css` by default.
204
203
  // Turning off here to fallback to webpack's default css processing logic.
205
- ...(compilerOptions?.module ? { outputModule: true } : {}),
206
204
  },
207
205
  };
208
206
  }
@@ -272,7 +272,7 @@ function overrideOptions(index, context, options, tempDir, nativeWatcher) {
272
272
  options.output.bundlerInfo ??= {};
273
273
  options.output.bundlerInfo.force ??= false;
274
274
  // test incremental: "safe" here, we test default incremental in Incremental-*.test.js
275
- options.experiments.incremental ??= 'safe';
275
+ options.incremental ??= 'safe';
276
276
  if (!global.printLogger) {
277
277
  options.infrastructureLogging = {
278
278
  level: 'error',
@@ -289,9 +289,7 @@ function findBundle(index, context, options, stepName) {
289
289
  function defaultOptions({ incremental = false, ignoreNotFriendlyForIncrementalWarnings = false, } = {}) {
290
290
  if (incremental) {
291
291
  return {
292
- experiments: {
293
- incremental: 'advance',
294
- },
292
+ incremental: 'advance',
295
293
  ignoreWarnings: ignoreNotFriendlyForIncrementalWarnings
296
294
  ? [/is not friendly for incremental/]
297
295
  : undefined,
@@ -1,4 +1,5 @@
1
1
  export * from './directory';
2
+ export { normalizePlaceholder } from './expect/placeholder';
2
3
  export * from './is';
3
4
  export * from './parse-modules';
4
5
  export * from './read-config-file';
@@ -14,7 +14,10 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.normalizePlaceholder = void 0;
17
18
  __exportStar(require("./directory"), exports);
19
+ var placeholder_1 = require("./expect/placeholder");
20
+ Object.defineProperty(exports, "normalizePlaceholder", { enumerable: true, get: function () { return placeholder_1.normalizePlaceholder; } });
18
21
  __exportStar(require("./is"), exports);
19
22
  __exportStar(require("./parse-modules"), exports);
20
23
  __exportStar(require("./read-config-file"), exports);
@@ -9,8 +9,24 @@ module.exports = function copyDiff(src, dest, initial) {
9
9
  for (const filename of files) {
10
10
  const srcFile = path.join(src, filename);
11
11
  const destFile = path.join(dest, filename);
12
- const directory = fs.statSync(srcFile).isDirectory();
13
- if (directory) {
12
+ const stats = fs.lstatSync(srcFile);
13
+ if (stats.isSymbolicLink()) {
14
+ const linkTarget = fs.readlinkSync(srcFile);
15
+ if (fs.existsSync(destFile)) {
16
+ const destStats = fs.lstatSync(destFile);
17
+ if (destStats.isSymbolicLink()) {
18
+ fs.unlinkSync(destFile);
19
+ }
20
+ else if (destStats.isDirectory()) {
21
+ rimrafSync(destFile);
22
+ }
23
+ else {
24
+ fs.unlinkSync(destFile);
25
+ }
26
+ }
27
+ fs.symlinkSync(linkTarget, destFile);
28
+ }
29
+ else if (stats.isDirectory()) {
14
30
  copyDiff(srcFile, destFile, initial);
15
31
  }
16
32
  else {
@@ -1,7 +1,7 @@
1
1
  // @ts-nocheck
2
2
  'use strict';
3
- const fs = require('fs');
4
- const path = require('path');
3
+ const fs = require('node:fs');
4
+ const path = require('node:path');
5
5
  /**
6
6
  * @param {{output: {path: string}}} options options
7
7
  * @param {RegExp} regexp regexp
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from './case';
2
2
  export * from './helper';
3
3
  export * from './plugin';
4
+ export * from './reporter';
4
5
  export * from './runner';
5
6
  export * from './test/context';
6
7
  export * from './test/creator';
package/dist/index.js CHANGED
@@ -17,6 +17,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./case"), exports);
18
18
  __exportStar(require("./helper"), exports);
19
19
  __exportStar(require("./plugin"), exports);
20
+ __exportStar(require("./reporter"), exports);
20
21
  __exportStar(require("./runner"), exports);
21
22
  __exportStar(require("./test/context"), exports);
22
23
  __exportStar(require("./test/creator"), exports);
@@ -0,0 +1 @@
1
+ export * from './streamed-events-reporter';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./streamed-events-reporter"), exports);
@@ -0,0 +1,34 @@
1
+ import type { Reporter, TestCaseInfo, TestFileInfo, TestResult, TestSuiteInfo } from '@rstest/core';
2
+ /**
3
+ * Stream Rstest events to a file in real-time for inspecting how tests are executed.
4
+ *
5
+ * Event format: `<context> | <event_type> | <timestamp> [| <additional_fields>]`
6
+ *
7
+ * @example
8
+ * __GLOBAL__ | TEST_RUN_START | 2025-01-15T10:30:00.123Z
9
+ * tests/unit/example.test.ts | FILE_START | 2025-01-15T10:30:00.456Z
10
+ * tests/unit/example.test.ts | FILE_READY | 2025-01-15T10:30:00.789Z
11
+ * tests/unit/example.test.ts > Suite Name | SUITE_START | 2025-01-15T10:30:01.000Z
12
+ * tests/unit/example.test.ts > Suite Name > nested describe | SUITE_START | 2025-01-15T10:30:01.100Z
13
+ * tests/unit/example.test.ts > Suite Name > nested describe > should work | TEST_START | 2025-01-15T10:30:01.200Z
14
+ * tests/unit/example.test.ts > Suite Name > nested describe > should work | TEST_END | 2025-01-15T10:30:01.350Z | passed | 150ms
15
+ * tests/unit/example.test.ts > Suite Name > nested describe | SUITE_END | 2025-01-15T10:30:01.400Z | passed | 300ms
16
+ * tests/unit/example.test.ts > Suite Name | SUITE_END | 2025-01-15T10:30:01.500Z | passed | 500ms
17
+ * __GLOBAL__ | TEST_RUN_END | 2025-01-15T10:30:02.000Z
18
+ * */
19
+ export declare class StreamedEventReporter implements Reporter {
20
+ private stream;
21
+ private outputPath;
22
+ constructor(outputPath?: string);
23
+ private write;
24
+ private formatTimestamp;
25
+ onTestRunStart(): void;
26
+ onTestFileStart(file: TestFileInfo): void;
27
+ onTestFileReady(file: TestFileInfo): void;
28
+ onTestSuiteStart(suite: TestSuiteInfo): void;
29
+ onTestSuiteResult(result: TestResult): void;
30
+ onTestCaseStart(test: TestCaseInfo): void;
31
+ onTestCaseResult(result: TestResult): void;
32
+ onTestRunEnd(): Promise<void>;
33
+ onExit(): void;
34
+ }
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.StreamedEventReporter = void 0;
37
+ const fs = __importStar(require("node:fs"));
38
+ const path = __importStar(require("node:path"));
39
+ /**
40
+ * Stream Rstest events to a file in real-time for inspecting how tests are executed.
41
+ *
42
+ * Event format: `<context> | <event_type> | <timestamp> [| <additional_fields>]`
43
+ *
44
+ * @example
45
+ * __GLOBAL__ | TEST_RUN_START | 2025-01-15T10:30:00.123Z
46
+ * tests/unit/example.test.ts | FILE_START | 2025-01-15T10:30:00.456Z
47
+ * tests/unit/example.test.ts | FILE_READY | 2025-01-15T10:30:00.789Z
48
+ * tests/unit/example.test.ts > Suite Name | SUITE_START | 2025-01-15T10:30:01.000Z
49
+ * tests/unit/example.test.ts > Suite Name > nested describe | SUITE_START | 2025-01-15T10:30:01.100Z
50
+ * tests/unit/example.test.ts > Suite Name > nested describe > should work | TEST_START | 2025-01-15T10:30:01.200Z
51
+ * tests/unit/example.test.ts > Suite Name > nested describe > should work | TEST_END | 2025-01-15T10:30:01.350Z | passed | 150ms
52
+ * tests/unit/example.test.ts > Suite Name > nested describe | SUITE_END | 2025-01-15T10:30:01.400Z | passed | 300ms
53
+ * tests/unit/example.test.ts > Suite Name | SUITE_END | 2025-01-15T10:30:01.500Z | passed | 500ms
54
+ * __GLOBAL__ | TEST_RUN_END | 2025-01-15T10:30:02.000Z
55
+ * */
56
+ class StreamedEventReporter {
57
+ constructor(outputPath) {
58
+ this.outputPath =
59
+ outputPath || path.join(process.cwd(), 'rstest-streamed-report.txt');
60
+ const dir = path.dirname(this.outputPath);
61
+ if (!fs.existsSync(dir)) {
62
+ fs.mkdirSync(dir, { recursive: true });
63
+ }
64
+ this.stream = fs.createWriteStream(this.outputPath, { flags: 'w' });
65
+ }
66
+ write(message) {
67
+ this.stream.write(`${message}\n`);
68
+ }
69
+ formatTimestamp() {
70
+ return new Date().toISOString();
71
+ }
72
+ onTestRunStart() {
73
+ this.write(`__GLOBAL__ | TEST_RUN_START | ${this.formatTimestamp()}`);
74
+ }
75
+ onTestFileStart(file) {
76
+ this.write(`${file.testPath} | FILE_START | ${this.formatTimestamp()}`);
77
+ }
78
+ onTestFileReady(file) {
79
+ this.write(`${file.testPath} | FILE_READY | ${this.formatTimestamp()}`);
80
+ }
81
+ onTestSuiteStart(suite) {
82
+ const suitePath = suite.parentNames
83
+ ? `${suite.parentNames.join(' > ')} > ${suite.name}`
84
+ : suite.name;
85
+ this.write(`${suite.testPath} > ${suitePath} | SUITE_START | ${this.formatTimestamp()}`);
86
+ }
87
+ onTestSuiteResult(result) {
88
+ const suitePath = result.parentNames
89
+ ? `${result.parentNames.join(' > ')} > ${result.name}`
90
+ : result.name;
91
+ this.write(`${result.testPath} > ${suitePath} | SUITE_END | ${this.formatTimestamp()} | ${result.status} | ${result.duration}ms`);
92
+ }
93
+ onTestCaseStart(test) {
94
+ const testPath = test.parentNames
95
+ ? `${test.parentNames.join(' > ')} > ${test.name}`
96
+ : test.name;
97
+ this.write(`${test.testPath} > ${testPath} | TEST_START | ${this.formatTimestamp()}`);
98
+ }
99
+ onTestCaseResult(result) {
100
+ const testPath = result.parentNames
101
+ ? `${result.parentNames.join(' > ')} > ${result.name}`
102
+ : result.name;
103
+ this.write(`${result.testPath} > ${testPath} | TEST_END | ${this.formatTimestamp()} | ${result.status} | ${result.duration}ms`);
104
+ if (result.errors && result.errors.length > 0) {
105
+ this.write(`${result.testPath} > ${testPath} | TEST_ERROR | ${this.formatTimestamp()} | ${result.errors[0].message}`);
106
+ }
107
+ }
108
+ async onTestRunEnd() {
109
+ this.write(`__GLOBAL__ | TEST_RUN_END | ${this.formatTimestamp()}`);
110
+ return new Promise((resolve) => {
111
+ this.stream.end(() => {
112
+ resolve();
113
+ });
114
+ });
115
+ }
116
+ onExit() {
117
+ this.stream.end();
118
+ }
119
+ }
120
+ exports.StreamedEventReporter = StreamedEventReporter;
@@ -118,8 +118,8 @@ class WebRunner extends node_1.NodeRunner {
118
118
  finalCode = node_fs_1.default.readFileSync(filePath);
119
119
  }
120
120
  try {
121
- that.dom.window['__LINK_SHEET__'] ??= {};
122
- that.dom.window['__LINK_SHEET__'][url] = finalCode.toString();
121
+ that.dom.window.__LINK_SHEET__ ??= {};
122
+ that.dom.window.__LINK_SHEET__[url] = finalCode.toString();
123
123
  return Promise.resolve(finalCode);
124
124
  }
125
125
  catch (err) {
@@ -196,7 +196,7 @@ class WebRunner extends node_1.NodeRunner {
196
196
  moduleScope.window = this.dom.window;
197
197
  moduleScope.document = this.dom.window.document;
198
198
  moduleScope.getLinkSheet = (link) => {
199
- return this.dom.window['__LINK_SHEET__'][link.href];
199
+ return this.dom.window.__LINK_SHEET__[link.href];
200
200
  };
201
201
  return moduleScope;
202
202
  }
@@ -268,9 +268,9 @@ class WebRunner extends node_1.NodeRunner {
268
268
  .map((arg) => `window["${scopeKey}"]["${arg}"]`)
269
269
  .join(', ');
270
270
  this.dom.window[scopeKey] = currentModuleScope;
271
- this.dom.window['__GLOBAL_SHARED__'] = this.globalContext;
272
- this.dom.window['__LOCATED_ERROR__'] = locatedError;
273
- this.dom.window['__FILE__'] = file;
271
+ this.dom.window.__GLOBAL_SHARED__ = this.globalContext;
272
+ this.dom.window.__LOCATED_ERROR__ = locatedError;
273
+ this.dom.window.__FILE__ = file;
274
274
  return [
275
275
  m,
276
276
  `${proxyCode}
package/dist/type.d.ts CHANGED
@@ -136,9 +136,6 @@ export type TTestConfig = {
136
136
  snapshotContent?(content: string): string;
137
137
  checkSteps?: boolean;
138
138
  ignoreNotFriendlyForIncrementalWarnings?: boolean;
139
- esmLibPluginOptions?: {
140
- preserveModules?: string;
141
- };
142
139
  resourceLoader?: (url: string, element: HTMLScriptElement) => Buffer | null;
143
140
  };
144
141
  export type TTestFilter = (creatorConfig: Record<string, unknown>, testConfig: TTestConfig) => boolean | string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rspack-debug/test-tools",
3
- "version": "2.0.0-canary.20260120",
3
+ "version": "2.0.0-rc.0",
4
4
  "license": "MIT",
5
5
  "description": "Test tools for rspack",
6
6
  "main": "dist/index.js",
@@ -15,7 +15,9 @@
15
15
  "./package.json": "./package.json",
16
16
  "./helper/*": "./dist/helper/*.js",
17
17
  "./helper/legacy/*": "./dist/helper/legacy/*.js",
18
- "./helper/util/*": "./dist/helper/util/*.js"
18
+ "./helper/util/*": "./dist/helper/util/*.js",
19
+ "./reporter": "./dist/reporter/index.js",
20
+ "./reporter/*": "./dist/reporter/*.js"
19
21
  },
20
22
  "files": [
21
23
  "client",
@@ -35,27 +37,27 @@
35
37
  "directory": "packages/rspack-test-tools"
36
38
  },
37
39
  "dependencies": {
38
- "@babel/generator": "7.28.6",
39
- "@babel/parser": "7.28.6",
40
- "@babel/traverse": "7.28.6",
41
- "@babel/types": "7.28.6",
40
+ "@babel/generator": "7.29.1",
41
+ "@babel/parser": "7.29.2",
42
+ "@babel/traverse": "7.29.0",
43
+ "@babel/types": "7.29.0",
42
44
  "cross-env": "^10.1.0",
43
45
  "filenamify": "4.3.0",
44
- "fs-extra": "^11.3.3",
46
+ "fs-extra": "^11.3.4",
45
47
  "iconv-lite": "^0.7.2",
46
48
  "javascript-stringify": "^2.1.0",
47
49
  "jest-diff": "^30.2.0",
48
50
  "jest-snapshot": "29.7.0",
49
51
  "jsdom": "^26.1.0",
50
52
  "memfs": "4.53.0",
51
- "path-serializer": "0.5.1",
52
- "pretty-format": "30.2.0",
53
+ "path-serializer": "0.6.0",
54
+ "pretty-format": "30.3.0",
53
55
  "rimraf": "^5.0.10",
54
56
  "source-map": "^0.7.6",
55
- "terser-webpack-plugin": "^5.3.16",
56
- "webpack": "5.102.1",
57
+ "terser-webpack-plugin": "^5.4.0",
58
+ "webpack": "5.104.1",
57
59
  "webpack-merge": "6.0.1",
58
- "webpack-sources": "3.3.3",
60
+ "webpack-sources": "3.3.4",
59
61
  "chalk": "^4.1.2"
60
62
  },
61
63
  "devDependencies": {
@@ -63,17 +65,15 @@
63
65
  "@types/babel__traverse": "7.28.0",
64
66
  "@types/fs-extra": "11.0.4",
65
67
  "@types/jsdom": "^21.1.7",
66
- "typescript": "^5.9.3",
68
+ "typescript": "^6.0.2",
67
69
  "wast-loader": "^1.14.1",
68
- "@rspack/core": "npm:@rspack-debug/core@2.0.0-canary.20260120"
70
+ "@rspack/core": "npm:@rspack-debug/core@2.0.0-rc.0"
69
71
  },
70
72
  "peerDependencies": {
71
73
  "@rspack/core": ">=1.0.0"
72
74
  },
73
75
  "scripts": {
74
76
  "build": "tsc -b ./tsconfig.build.json",
75
- "dev": "tsc -b -w",
76
- "api-extractor": "api-extractor run --verbose",
77
- "api-extractor:ci": "api-extractor run --verbose || diff temp/test-tools.api.md etc/test-tools.api.md"
77
+ "dev": "tsc -b -w"
78
78
  }
79
79
  }