@rspack/test-tools 1.5.7 → 1.5.8

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.
@@ -135,49 +135,51 @@ async function checkSnapshot(env, context, name, snapshot, filter) {
135
135
  if (path_1.default.extname(snapshot) === ".snap") {
136
136
  throw new Error("Snapshot with `.snap` will be managed by jest, please use `.snap.txt` instead");
137
137
  }
138
- const compiler = getCompiler(context, name);
139
- const stats = compiler.getStats();
140
- const c = compiler.getCompiler();
141
- if (!stats || !c)
138
+ const compilerManager = getCompiler(context, name);
139
+ const stats = compilerManager.getStats();
140
+ const compiler = compilerManager.getCompiler();
141
+ if (!stats || !compiler)
142
142
  return;
143
- if (stats.hasErrors()) {
144
- const errors = [];
145
- if (stats.stats) {
146
- for (const s of stats.stats) {
147
- if (s.hasErrors()) {
148
- errors.push(...s.compilation.errors);
149
- }
150
- }
143
+ const compilers = "compilers" in compiler
144
+ ? compiler.compilers
145
+ : [compiler];
146
+ const totalStats = "stats" in stats
147
+ ? stats.stats
148
+ : [stats];
149
+ const total = compilers.length;
150
+ for (let i = 0; i < compilers.length; i++) {
151
+ const c = compilers[i];
152
+ const stats = totalStats[i];
153
+ if (stats.hasErrors()) {
154
+ const errors = [];
155
+ errors.push(...stats.compilation.errors);
156
+ throw new Error(`Failed to compile in fixture ${name}, Errors: ${errors
157
+ ?.map(i => `${i.message}\n${i.stack}`)
158
+ .join("\n\n")}`);
151
159
  }
152
- else {
153
- const s = stats;
154
- errors.push(...s.compilation.errors);
155
- }
156
- throw new Error(`Failed to compile in fixture ${name}, Errors: ${errors
157
- ?.map(i => `${i.message}\n${i.stack}`)
158
- .join("\n\n")}`);
159
- }
160
- const compilation = c._lastCompilation ||
161
- c._lastCompilation;
162
- const snapshotFileFilter = filter ||
163
- ((file) => file.endsWith(".js") && !file.includes("runtime.js"));
164
- const fileContents = Object.entries(compilation.assets)
165
- .filter(([file]) => snapshotFileFilter(file))
166
- .map(([file, source]) => {
167
- const tag = path_1.default.extname(file).slice(1) || "txt";
168
- let content = (0, placeholder_1.normalizePlaceholder)(source.source().toString());
169
- const testConfig = context.getTestConfig();
170
- if (testConfig.snapshotContent) {
171
- content = testConfig.snapshotContent(content);
172
- }
173
- return `\`\`\`${tag} title=${file}\n${content}\n\`\`\``;
174
- });
175
- fileContents.sort();
176
- const content = fileContents.join("\n\n");
177
- const snapshotPath = path_1.default.isAbsolute(snapshot)
178
- ? snapshot
179
- : path_1.default.resolve(context.getSource(), `./__snapshots__/${snapshot}`);
180
- env.expect(content).toMatchFileSnapshot(snapshotPath);
160
+ const compilation = c._lastCompilation ||
161
+ c._lastCompilation;
162
+ const snapshotFileFilter = filter ||
163
+ ((file) => (file.endsWith(".js") || file.endsWith(".mjs")) &&
164
+ !file.includes("runtime.js"));
165
+ const fileContents = Object.entries(compilation.assets)
166
+ .filter(([file]) => snapshotFileFilter(file))
167
+ .map(([file, source]) => {
168
+ const tag = path_1.default.extname(file).slice(1) || "txt";
169
+ let content = (0, placeholder_1.normalizePlaceholder)(source.source().toString());
170
+ const testConfig = context.getTestConfig();
171
+ if (testConfig.snapshotContent) {
172
+ content = testConfig.snapshotContent(content);
173
+ }
174
+ return `\`\`\`${tag} title=${file}\n${content}\n\`\`\``;
175
+ });
176
+ fileContents.sort();
177
+ const content = fileContents.join("\n\n");
178
+ const snapshotPath = path_1.default.isAbsolute(snapshot)
179
+ ? snapshot
180
+ : path_1.default.resolve(context.getSource(), `./__snapshots__/${snapshot}${total > 1 ? `-${i}` : ""}`);
181
+ env.expect(content).toMatchFileSnapshot(snapshotPath);
182
+ }
181
183
  }
182
184
  function findMultiCompilerBundle(context, name, multiFindBundle) {
183
185
  if (typeof multiFindBundle !== "function") {
@@ -1,137 +1,155 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createCompilerCase = createCompilerCase;
4
- const simple_1 = require("../test/simple");
4
+ const creator_1 = require("../test/creator");
5
5
  const common_1 = require("./common");
6
- function createCompilerCase(name, src, dist, testConfig) {
7
- let caseConfigList = require(testConfig);
8
- if (!Array.isArray(caseConfigList)) {
9
- caseConfigList = [caseConfigList];
10
- }
11
- const runner = (0, simple_1.getSimpleProcessorRunner)(src, dist);
12
- for (const caseConfig of caseConfigList) {
13
- const testFn = caseConfig.skip ? it.skip : it;
14
- testFn(caseConfig.description, async () => {
15
- const logs = {
16
- mkdir: [],
17
- writeFile: []
18
- };
19
- const files = {};
20
- await runner(name, {
21
- config: async (context) => {
22
- const compiler = (0, common_1.getCompiler)(context, name);
23
- const options = caseConfig.options?.(context) || {};
24
- options.mode ??= "production";
25
- options.context ??= context.getSource();
26
- options.entry ??= "./a.js";
27
- options.output ??= {};
28
- options.output.path ??= "/";
29
- options.output.pathinfo ??= true;
30
- options.optimization ??= {};
31
- options.optimization.minimize ??= false;
32
- compiler.setOptions(options);
33
- },
34
- compiler: async (context) => {
35
- const compiler = (0, common_1.getCompiler)(context, name);
36
- if (caseConfig.compilerCallback) {
37
- compiler.createCompilerWithCallback(caseConfig.compilerCallback);
6
+ function createCompilerProcessor(name, caseConfig) {
7
+ const logs = {
8
+ mkdir: [],
9
+ writeFile: []
10
+ };
11
+ const files = {};
12
+ return {
13
+ config: async (context) => {
14
+ const compiler = (0, common_1.getCompiler)(context, name);
15
+ const options = caseConfig.options?.(context) || {};
16
+ options.mode ??= "production";
17
+ options.context ??= context.getSource();
18
+ options.entry ??= "./a.js";
19
+ options.output ??= {};
20
+ options.output.path ??= "/";
21
+ options.output.pathinfo ??= true;
22
+ options.optimization ??= {};
23
+ options.optimization.minimize ??= false;
24
+ compiler.setOptions(options);
25
+ },
26
+ compiler: async (context) => {
27
+ const compiler = (0, common_1.getCompiler)(context, name);
28
+ if (caseConfig.compilerCallback) {
29
+ compiler.createCompilerWithCallback(caseConfig.compilerCallback);
30
+ }
31
+ else {
32
+ compiler.createCompiler();
33
+ }
34
+ const c = compiler.getCompiler();
35
+ c.outputFileSystem = {
36
+ // CHANGE: Added support for the `options` parameter to enable recursive directory creation,
37
+ // accommodating Rspack's requirement that differs from webpack's usage
38
+ mkdir(path, callback) {
39
+ const recursive = false;
40
+ // if (typeof options === "function") {
41
+ // callback = options;
42
+ // } else if (options) {
43
+ // if (options.recursive !== undefined) recursive = options.recursive;
44
+ // }
45
+ logs.mkdir.push(path);
46
+ if (recursive) {
47
+ callback();
38
48
  }
39
49
  else {
40
- compiler.createCompiler();
50
+ const err = new Error();
51
+ err.code = "EEXIST";
52
+ callback(err);
41
53
  }
42
- const c = compiler.getCompiler();
43
- c.outputFileSystem = {
44
- // CHANGE: Added support for the `options` parameter to enable recursive directory creation,
45
- // accommodating Rspack's requirement that differs from webpack's usage
46
- mkdir(path, callback) {
47
- const recursive = false;
48
- // if (typeof options === "function") {
49
- // callback = options;
50
- // } else if (options) {
51
- // if (options.recursive !== undefined) recursive = options.recursive;
52
- // }
53
- logs.mkdir.push(path);
54
- if (recursive) {
55
- callback();
56
- }
57
- else {
58
- const err = new Error();
59
- err.code = "EEXIST";
60
- callback(err);
61
- }
62
- },
63
- writeFile(name, content, callback) {
64
- logs.writeFile.push(name, content);
65
- files[name] = content.toString("utf-8");
66
- callback();
67
- },
68
- stat(path, callback) {
69
- callback(new Error("ENOENT"));
70
- }
71
- };
72
- c.hooks.compilation.tap("CompilerTest", compilation => (compilation.bail = true));
73
- await caseConfig.compiler?.(context, c);
74
54
  },
75
- build: async (context) => {
76
- const compiler = (0, common_1.getCompiler)(context, name);
77
- if (typeof caseConfig.build === "function") {
78
- await caseConfig.build?.(context, compiler.getCompiler());
79
- }
80
- else {
81
- await compiler.build();
82
- }
55
+ writeFile(name, content, callback) {
56
+ logs.writeFile.push(name, content);
57
+ files[name] = content.toString("utf-8");
58
+ callback();
83
59
  },
84
- run: async (env, context) => { },
85
- check: async (env, context) => {
86
- const compiler = (0, common_1.getCompiler)(context, name);
87
- const c = compiler.getCompiler();
88
- const stats = compiler.getStats();
89
- if (caseConfig.error) {
90
- const statsJson = stats?.toJson({
91
- modules: true,
92
- reasons: true
93
- });
94
- const compilation = stats?.compilation;
95
- await caseConfig.check?.({
96
- context,
97
- compiler: c,
98
- stats: statsJson,
99
- compilation,
100
- files
101
- });
102
- }
103
- else if (stats) {
104
- expect(typeof stats).toBe("object");
105
- const compilation = stats.compilation;
106
- const statsJson = stats.toJson({
107
- modules: true,
108
- reasons: true
109
- });
110
- expect(typeof statsJson).toBe("object");
111
- expect(statsJson).toHaveProperty("errors");
112
- expect(Array.isArray(statsJson.errors)).toBe(true);
113
- if (statsJson.errors.length > 0) {
114
- expect(statsJson.errors[0]).toBeInstanceOf(Object);
115
- throw statsJson.errors[0];
116
- }
117
- statsJson.logs = logs;
118
- await caseConfig.check?.({
119
- context,
120
- stats: statsJson,
121
- files,
122
- compiler: c,
123
- compilation
124
- });
125
- }
126
- else {
127
- await caseConfig.check?.({
128
- context,
129
- files,
130
- compiler: c
131
- });
132
- }
60
+ stat(path, callback) {
61
+ callback(new Error("ENOENT"));
133
62
  }
134
- });
63
+ };
64
+ c.hooks.compilation.tap("CompilerTest", compilation => (compilation.bail = true));
65
+ await caseConfig.compiler?.(context, c);
66
+ },
67
+ build: async (context) => {
68
+ const compiler = (0, common_1.getCompiler)(context, name);
69
+ if (typeof caseConfig.build === "function") {
70
+ await caseConfig.build?.(context, compiler.getCompiler());
71
+ }
72
+ else {
73
+ await compiler.build();
74
+ }
75
+ },
76
+ run: async (env, context) => { },
77
+ check: async (env, context) => {
78
+ const compiler = (0, common_1.getCompiler)(context, name);
79
+ const c = compiler.getCompiler();
80
+ const stats = compiler.getStats();
81
+ if (caseConfig.error) {
82
+ const statsJson = stats?.toJson({
83
+ modules: true,
84
+ reasons: true
85
+ });
86
+ const compilation = stats?.compilation;
87
+ await caseConfig.check?.({
88
+ context,
89
+ compiler: c,
90
+ stats: statsJson,
91
+ compilation,
92
+ files
93
+ });
94
+ }
95
+ else if (stats) {
96
+ expect(typeof stats).toBe("object");
97
+ const compilation = stats.compilation;
98
+ const statsJson = stats.toJson({
99
+ modules: true,
100
+ reasons: true
101
+ });
102
+ expect(typeof statsJson).toBe("object");
103
+ expect(statsJson).toHaveProperty("errors");
104
+ expect(Array.isArray(statsJson.errors)).toBe(true);
105
+ if (statsJson.errors.length > 0) {
106
+ expect(statsJson.errors[0]).toBeInstanceOf(Object);
107
+ throw statsJson.errors[0];
108
+ }
109
+ statsJson.logs = logs;
110
+ await caseConfig.check?.({
111
+ context,
112
+ stats: statsJson,
113
+ files,
114
+ compiler: c,
115
+ compilation
116
+ });
117
+ }
118
+ else {
119
+ await caseConfig.check?.({
120
+ context,
121
+ files,
122
+ compiler: c
123
+ });
124
+ }
125
+ },
126
+ after: async (context) => {
127
+ await context.closeCompiler(name);
128
+ }
129
+ };
130
+ }
131
+ const creator = new creator_1.BasicCaseCreator({
132
+ clean: true,
133
+ describe: false,
134
+ steps: ({ name, caseConfig }) => {
135
+ return [createCompilerProcessor(name, caseConfig)];
136
+ },
137
+ concurrent: false
138
+ });
139
+ function createCompilerCase(name, src, dist, testConfig) {
140
+ let caseConfigList = require(testConfig);
141
+ if (!Array.isArray(caseConfigList)) {
142
+ caseConfigList = [caseConfigList];
143
+ }
144
+ for (let i = 0; i < caseConfigList.length; i++) {
145
+ const caseConfig = caseConfigList[i];
146
+ if (caseConfig.skip) {
147
+ it.skip(`${name}[${i}]`, () => { });
148
+ continue;
149
+ }
150
+ creator.create(`${name}[${i}]`, src, dist, undefined, {
151
+ caseConfig,
152
+ description: () => caseConfig.description
135
153
  });
136
154
  }
137
155
  }
@@ -6,42 +6,53 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.createErrorCase = createErrorCase;
7
7
  const node_path_1 = __importDefault(require("node:path"));
8
8
  const webpack_merge_1 = __importDefault(require("webpack-merge"));
9
- const simple_1 = require("../test/simple");
9
+ const creator_1 = require("../test/creator");
10
10
  const common_1 = require("./common");
11
11
  let addedSerializer = false;
12
+ const creator = new creator_1.BasicCaseCreator({
13
+ clean: true,
14
+ describe: true,
15
+ steps: ({ name, caseConfig }) => {
16
+ const config = caseConfig;
17
+ return [
18
+ {
19
+ config: async (context) => {
20
+ const compiler = (0, common_1.getCompiler)(context, name);
21
+ compiler.setOptions(options(context, config.options));
22
+ },
23
+ compiler: async (context) => {
24
+ const compilerManager = (0, common_1.getCompiler)(context, name);
25
+ compilerManager.createCompiler();
26
+ compiler(context, compilerManager.getCompiler(), config.compiler);
27
+ },
28
+ build: async (context) => {
29
+ const compiler = (0, common_1.getCompiler)(context, name);
30
+ if (typeof config.build === "function") {
31
+ await config.build(context, compiler.getCompiler());
32
+ }
33
+ else {
34
+ await compiler.build();
35
+ }
36
+ },
37
+ run: async (env, context) => {
38
+ // no need to run, just check the snapshot of diagnostics
39
+ },
40
+ check: async (env, context) => {
41
+ await check(env, context, name, config.check);
42
+ }
43
+ }
44
+ ];
45
+ },
46
+ concurrent: true
47
+ });
12
48
  function createErrorCase(name, src, dist, testConfig) {
13
49
  if (!addedSerializer) {
14
50
  addedSerializer = true;
15
51
  }
16
52
  const caseConfig = require(testConfig);
17
- const runner = (0, simple_1.getSimpleProcessorRunner)(src, dist);
18
- it(caseConfig.description, async () => {
19
- await runner(name, {
20
- config: async (context) => {
21
- const compiler = (0, common_1.getCompiler)(context, name);
22
- compiler.setOptions(options(context, caseConfig.options));
23
- },
24
- compiler: async (context) => {
25
- const compilerManager = (0, common_1.getCompiler)(context, name);
26
- compilerManager.createCompiler();
27
- compiler(context, compilerManager.getCompiler(), caseConfig.compiler);
28
- },
29
- build: async (context) => {
30
- const compiler = (0, common_1.getCompiler)(context, name);
31
- if (typeof caseConfig.build === "function") {
32
- await caseConfig.build(context, compiler.getCompiler());
33
- }
34
- else {
35
- await compiler.build();
36
- }
37
- },
38
- run: async (env, context) => {
39
- // no need to run, just check the snapshot of diagnostics
40
- },
41
- check: async (env, context) => {
42
- await check(env, context, name, caseConfig.check);
43
- }
44
- });
53
+ creator.create(name, src, dist, undefined, {
54
+ caseConfig,
55
+ description: () => caseConfig.description
45
56
  });
46
57
  }
47
58
  function options(context, custom) {
@@ -0,0 +1 @@
1
+ export declare function createEsmOutputCase(name: string, src: string, dist: string): void;
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createEsmOutputCase = createEsmOutputCase;
7
+ const core_1 = __importDefault(require("@rspack/core"));
8
+ const creator_1 = require("../test/creator");
9
+ const common_1 = require("./common");
10
+ const runner_1 = require("./runner");
11
+ const creator = new creator_1.BasicCaseCreator({
12
+ clean: true,
13
+ describe: false,
14
+ testConfig: testConfig => {
15
+ const oldModuleScope = testConfig.moduleScope;
16
+ testConfig.moduleScope = (ms, stats) => {
17
+ let res = ms;
18
+ // TODO: modify runner module scope based on stats here
19
+ if (typeof oldModuleScope === "function") {
20
+ res = oldModuleScope(ms, stats);
21
+ }
22
+ return res;
23
+ };
24
+ },
25
+ steps: ({ name }) => [
26
+ {
27
+ config: async (context) => {
28
+ (0, common_1.configMultiCompiler)(context, name, ["rspack.config.cjs", "rspack.config.js", "webpack.config.js"], defaultOptions, () => { });
29
+ },
30
+ compiler: async (context) => {
31
+ await (0, common_1.compiler)(context, name);
32
+ },
33
+ build: async (context) => {
34
+ await (0, common_1.build)(context, name);
35
+ },
36
+ run: async (env, context) => {
37
+ await (0, common_1.run)(env, context, name, (context) => (0, common_1.findMultiCompilerBundle)(context, name, (_index, _context, options) => {
38
+ if (options.output?.filename === "[name].mjs") {
39
+ return ["main.mjs"];
40
+ }
41
+ else {
42
+ return [options.output.filename];
43
+ }
44
+ }));
45
+ },
46
+ check: async (env, context) => {
47
+ await (0, common_1.check)(env, context, name);
48
+ await (0, common_1.checkSnapshot)(env, context, name, "esm.snap.txt");
49
+ }
50
+ }
51
+ ],
52
+ runner: {
53
+ key: runner_1.getMultiCompilerRunnerKey,
54
+ runner: runner_1.createMultiCompilerRunner
55
+ },
56
+ concurrent: false
57
+ });
58
+ const defaultOptions = (_index, context) => ({
59
+ context: context.getSource(),
60
+ mode: "production",
61
+ target: "async-node",
62
+ devtool: false,
63
+ entry: "./index.js",
64
+ cache: false,
65
+ output: {
66
+ path: context.getDist(),
67
+ filename: "[name].mjs",
68
+ chunkLoading: "import",
69
+ chunkFormat: false,
70
+ pathinfo: true,
71
+ module: true
72
+ },
73
+ bail: true,
74
+ optimization: {
75
+ minimize: false,
76
+ moduleIds: "named",
77
+ chunkIds: "named",
78
+ runtimeChunk: "single",
79
+ removeEmptyChunks: false,
80
+ concatenateModules: false,
81
+ splitChunks: false
82
+ },
83
+ plugins: [new core_1.default.experiments.EsmLibraryPlugin()],
84
+ experiments: {
85
+ css: true,
86
+ rspackFuture: {
87
+ bundlerInfo: {
88
+ force: false
89
+ }
90
+ },
91
+ outputModule: true
92
+ }
93
+ });
94
+ function createEsmOutputCase(name, src, dist) {
95
+ creator.create(name, src, dist);
96
+ }
package/dist/case/hash.js CHANGED
@@ -5,11 +5,11 @@ const creator_1 = require("../test/creator");
5
5
  const common_1 = require("./common");
6
6
  const REG_ERROR_CASE = /error$/;
7
7
  class HashCaseCreator extends creator_1.BasicCaseCreator {
8
- describe(name, tester, testConfig) {
8
+ describe(name, tester, testConfig, options) {
9
9
  it(`should print correct hash for ${name}`, async () => {
10
10
  await tester.prepare();
11
11
  await tester.compile();
12
- await tester.check(this.createEnv(testConfig));
12
+ await tester.check(this.createEnv(testConfig, options));
13
13
  await tester.resume();
14
14
  }, 30000);
15
15
  }
package/dist/case/hook.js CHANGED
@@ -11,52 +11,59 @@ const jest_snapshot_1 = require("jest-snapshot");
11
11
  const path_serializer_1 = require("path-serializer");
12
12
  const pretty_format_1 = require("pretty-format");
13
13
  const webpack_merge_1 = __importDefault(require("webpack-merge"));
14
- const createLazyTestEnv_1 = __importDefault(require("../helper/legacy/createLazyTestEnv"));
15
14
  const context_1 = require("../test/context");
16
- const simple_1 = require("../test/simple");
15
+ const creator_1 = require("../test/creator");
17
16
  const common_1 = require("./common");
18
17
  const srcDir = node_path_1.default.resolve(__dirname, "../../../../tests/rspack-test/fixtures");
19
18
  const distDir = node_path_1.default.resolve(__dirname, "../../../../tests/rspack-test/js/hook");
19
+ const creator = new creator_1.BasicCaseCreator({
20
+ clean: true,
21
+ describe: true,
22
+ createContext: (config) => new HookCasesContext(config.src, config.name, config),
23
+ steps: ({ name, caseConfig: _caseConfig, src }) => {
24
+ const caseConfig = _caseConfig;
25
+ return [
26
+ {
27
+ config: async (context) => {
28
+ const compiler = (0, common_1.getCompiler)(context, name);
29
+ const options = await (0, common_1.config)(context, name, ["rspack.config.js", "webpack.config.js"], defaultOptions(context, caseConfig.options));
30
+ if (!global.printLogger) {
31
+ options.infrastructureLogging = {
32
+ level: "error"
33
+ };
34
+ }
35
+ compiler.setOptions(options);
36
+ },
37
+ compiler: async (context) => {
38
+ const c = await (0, common_1.compiler)(context, name);
39
+ if (caseConfig.compiler) {
40
+ await caseConfig.compiler(context, c);
41
+ }
42
+ },
43
+ build: async (context) => {
44
+ await (0, common_1.build)(context, name);
45
+ },
46
+ run: async (env, context) => {
47
+ // no need to run, just check snapshot
48
+ },
49
+ check: async (env, context) => {
50
+ await (0, common_1.checkSnapshot)(env, context, name, node_path_1.default.join(src, "output.snap.txt"), caseConfig.snapshotFileFilter);
51
+ }
52
+ }
53
+ ];
54
+ }
55
+ });
20
56
  function createHookCase(name, src, dist, source) {
21
57
  const caseConfig = require(node_path_1.default.join(src, "test.js"));
22
58
  const testName = node_path_1.default.basename(name.slice(0, name.indexOf(node_path_1.default.extname(name))));
23
- const runner = (0, simple_1.getSimpleProcessorRunner)(source, dist, {
24
- env: () => env,
25
- context: () => new HookCasesContext(src, testName, {
59
+ creator.create(name, src, dist, undefined, {
60
+ caseConfig,
61
+ description: () => caseConfig.description,
62
+ createContext: (config) => new HookCasesContext(src, testName, {
26
63
  src: source,
27
64
  dist: dist
28
65
  })
29
66
  });
30
- it(caseConfig.description, async () => {
31
- await runner(name, {
32
- config: async (context) => {
33
- const compiler = (0, common_1.getCompiler)(context, name);
34
- const options = await (0, common_1.config)(context, name, ["rspack.config.js", "webpack.config.js"], defaultOptions(context, caseConfig.options));
35
- if (!global.printLogger) {
36
- options.infrastructureLogging = {
37
- level: "error"
38
- };
39
- }
40
- compiler.setOptions(options);
41
- },
42
- compiler: async (context) => {
43
- const c = await (0, common_1.compiler)(context, name);
44
- if (caseConfig.compiler) {
45
- await caseConfig.compiler(context, c);
46
- }
47
- },
48
- build: async (context) => {
49
- await (0, common_1.build)(context, name);
50
- },
51
- run: async (env, context) => {
52
- // no need to run, just check snapshot
53
- },
54
- check: async (env, context) => {
55
- await (0, common_1.checkSnapshot)(env, context, name, node_path_1.default.join(src, "output.snap.txt"), caseConfig.snapshotFileFilter);
56
- }
57
- });
58
- });
59
- const env = (0, createLazyTestEnv_1.default)(10000);
60
67
  }
61
68
  const sourceSerializer = {
62
69
  test(val) {
@@ -6,6 +6,7 @@ export { createDefaultsCase, getRspackDefaultConfig } from "./defaults";
6
6
  export { createDiagnosticCase } from "./diagnostic";
7
7
  export { createDiffCase } from "./diff";
8
8
  export { createErrorCase } from "./error";
9
+ export { createEsmOutputCase } from "./esm-output";
9
10
  export { createHashCase } from "./hash";
10
11
  export { createHookCase } from "./hook";
11
12
  export { createHotCase } from "./hot";
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createWatchCase = exports.createTreeShakingCase = exports.createStatsOutputCase = exports.createStatsAPICase = exports.createSerialCase = exports.createNormalCase = exports.createHotNormalCase = exports.createNativeWatcher = exports.createWatchIncrementalCase = exports.createHotIncrementalCase = exports.createHotStepCase = exports.createHotCase = exports.createHookCase = exports.createHashCase = exports.createErrorCase = exports.createDiffCase = exports.createDiagnosticCase = exports.getRspackDefaultConfig = exports.createDefaultsCase = exports.createConfigCase = exports.createCompilerCase = exports.createCacheCase = exports.createBuiltinCase = void 0;
3
+ exports.createWatchCase = exports.createTreeShakingCase = exports.createStatsOutputCase = exports.createStatsAPICase = exports.createSerialCase = exports.createNormalCase = exports.createHotNormalCase = exports.createNativeWatcher = exports.createWatchIncrementalCase = exports.createHotIncrementalCase = exports.createHotStepCase = exports.createHotCase = exports.createHookCase = exports.createHashCase = exports.createEsmOutputCase = exports.createErrorCase = exports.createDiffCase = exports.createDiagnosticCase = exports.getRspackDefaultConfig = exports.createDefaultsCase = exports.createConfigCase = exports.createCompilerCase = exports.createCacheCase = exports.createBuiltinCase = void 0;
4
4
  var builtin_1 = require("./builtin");
5
5
  Object.defineProperty(exports, "createBuiltinCase", { enumerable: true, get: function () { return builtin_1.createBuiltinCase; } });
6
6
  var cache_1 = require("./cache");
@@ -18,6 +18,8 @@ var diff_1 = require("./diff");
18
18
  Object.defineProperty(exports, "createDiffCase", { enumerable: true, get: function () { return diff_1.createDiffCase; } });
19
19
  var error_1 = require("./error");
20
20
  Object.defineProperty(exports, "createErrorCase", { enumerable: true, get: function () { return error_1.createErrorCase; } });
21
+ var esm_output_1 = require("./esm-output");
22
+ Object.defineProperty(exports, "createEsmOutputCase", { enumerable: true, get: function () { return esm_output_1.createEsmOutputCase; } });
21
23
  var hash_1 = require("./hash");
22
24
  Object.defineProperty(exports, "createHashCase", { enumerable: true, get: function () { return hash_1.createHashCase; } });
23
25
  var hook_1 = require("./hook");
@@ -2,42 +2,53 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createStatsAPICase = createStatsAPICase;
4
4
  const memfs_1 = require("memfs");
5
- const simple_1 = require("../test/simple");
5
+ const creator_1 = require("../test/creator");
6
6
  const common_1 = require("./common");
7
7
  let addedSerializer = false;
8
+ const creator = new creator_1.BasicCaseCreator({
9
+ clean: true,
10
+ describe: true,
11
+ steps: ({ name, caseConfig }) => {
12
+ const config = caseConfig;
13
+ return [
14
+ {
15
+ config: async (context) => {
16
+ const compiler = (0, common_1.getCompiler)(context, name);
17
+ compiler.setOptions(options(context, config.options));
18
+ },
19
+ compiler: async (context) => {
20
+ const compilerManager = (0, common_1.getCompiler)(context, name);
21
+ compilerManager.createCompiler();
22
+ compiler(context, compilerManager.getCompiler(), config.compiler);
23
+ },
24
+ build: async (context) => {
25
+ const compiler = (0, common_1.getCompiler)(context, name);
26
+ if (typeof config.build === "function") {
27
+ await config.build(context, compiler.getCompiler());
28
+ }
29
+ else {
30
+ await compiler.build();
31
+ }
32
+ },
33
+ run: async (env, context) => {
34
+ // no need to run, just check the snapshot of diagnostics
35
+ },
36
+ check: async (env, context) => {
37
+ await check(env, context, name, config.check);
38
+ }
39
+ }
40
+ ];
41
+ },
42
+ concurrent: true
43
+ });
8
44
  function createStatsAPICase(name, src, dist, testConfig) {
9
45
  if (!addedSerializer) {
10
46
  addedSerializer = true;
11
47
  }
12
48
  const caseConfig = require(testConfig);
13
- const runner = (0, simple_1.getSimpleProcessorRunner)(src, dist);
14
- it(caseConfig.description, async () => {
15
- await runner(name, {
16
- config: async (context) => {
17
- const compiler = (0, common_1.getCompiler)(context, name);
18
- compiler.setOptions(options(context, caseConfig.options));
19
- },
20
- compiler: async (context) => {
21
- const compilerManager = (0, common_1.getCompiler)(context, name);
22
- compilerManager.createCompiler();
23
- compiler(context, compilerManager.getCompiler(), caseConfig.compiler);
24
- },
25
- build: async (context) => {
26
- const compiler = (0, common_1.getCompiler)(context, name);
27
- if (typeof caseConfig.build === "function") {
28
- await caseConfig.build(context, compiler.getCompiler());
29
- }
30
- else {
31
- await compiler.build();
32
- }
33
- },
34
- run: async (env, context) => {
35
- // no need to run, just check the snapshot of diagnostics
36
- },
37
- check: async (env, context) => {
38
- await check(env, context, name, caseConfig.check);
39
- }
40
- });
49
+ creator.create(name, src, dist, undefined, {
50
+ caseConfig,
51
+ description: () => caseConfig.description
41
52
  });
42
53
  }
43
54
  function options(context, custom) {
@@ -1 +1,11 @@
1
+ import type { ECompilerType, ITestContext, ITestEnv, TCompilerOptions } from "../type";
2
+ export declare function createStatsProcessor(name: string, defaultOptions: (index: number, context: ITestContext) => TCompilerOptions<ECompilerType.Rspack>, overrideOptions: (index: number, context: ITestContext, options: TCompilerOptions<ECompilerType.Rspack>) => void): {
3
+ before: (context: ITestContext) => Promise<void>;
4
+ config: (context: ITestContext) => Promise<void>;
5
+ compiler: (context: ITestContext) => Promise<void>;
6
+ build: (context: ITestContext) => Promise<void>;
7
+ run: (env: ITestEnv, context: ITestContext) => Promise<void>;
8
+ check: (env: ITestEnv, context: ITestContext) => Promise<void>;
9
+ after: (context: ITestContext) => Promise<void>;
10
+ };
1
11
  export declare function createStatsOutputCase(name: string, src: string, dist: string): void;
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createStatsProcessor = createStatsProcessor;
6
7
  exports.createStatsOutputCase = createStatsOutputCase;
7
8
  const node_path_1 = __importDefault(require("node:path"));
8
9
  const fs_extra_1 = __importDefault(require("fs-extra"));
@@ -11,7 +12,7 @@ const captureStdio_1 = __importDefault(require("../helper/legacy/captureStdio"))
11
12
  const creator_1 = require("../test/creator");
12
13
  const common_1 = require("./common");
13
14
  const REG_ERROR_CASE = /error$/;
14
- function createStatsProcessor(name) {
15
+ function createStatsProcessor(name, defaultOptions, overrideOptions) {
15
16
  const writeStatsOuptut = false;
16
17
  const snapshotName = "stats.txt";
17
18
  let stderr = null;
@@ -43,7 +44,9 @@ function createStatsProcessor(name) {
43
44
  const creator = new creator_1.BasicCaseCreator({
44
45
  clean: true,
45
46
  describe: false,
46
- steps: ({ name }) => [createStatsProcessor(name)],
47
+ steps: ({ name }) => [
48
+ createStatsProcessor(name, defaultOptions, overrideOptions)
49
+ ],
47
50
  description: () => "should print correct stats for"
48
51
  });
49
52
  function createStatsOutputCase(name, src, dist) {
package/dist/index.d.ts CHANGED
@@ -6,6 +6,5 @@ export * from "./reporter";
6
6
  export * from "./runner";
7
7
  export * from "./test/context";
8
8
  export * from "./test/creator";
9
- export * from "./test/simple";
10
9
  export * from "./test/tester";
11
10
  export * from "./type";
package/dist/index.js CHANGED
@@ -22,6 +22,5 @@ __exportStar(require("./reporter"), exports);
22
22
  __exportStar(require("./runner"), exports);
23
23
  __exportStar(require("./test/context"), exports);
24
24
  __exportStar(require("./test/creator"), exports);
25
- __exportStar(require("./test/simple"), exports);
26
25
  __exportStar(require("./test/tester"), exports);
27
26
  __exportStar(require("./type"), exports);
@@ -361,6 +361,8 @@ class NodeRunner {
361
361
  context: esmContext,
362
362
  initializeImportMeta: (meta, _) => {
363
363
  meta.url = (0, node_url_1.pathToFileURL)(file.path).href;
364
+ meta.dirname = node_path_1.default.dirname(file.path);
365
+ meta.filename = file.path;
364
366
  },
365
367
  importModuleDynamically: async (specifier, module) => {
366
368
  const result = await _require(node_path_1.default.dirname(file.path), specifier, {
@@ -374,13 +376,15 @@ class NodeRunner {
374
376
  if (context.esmMode === type_1.EEsmMode.Unlinked)
375
377
  return esm;
376
378
  return (async () => {
377
- await esm.link(async (specifier, referencingModule) => {
378
- return await (0, asModule_1.default)(await _require(node_path_1.default.dirname(referencingModule.identifier
379
- ? referencingModule.identifier.slice(esmIdentifier.length + 1)
380
- : (0, node_url_1.fileURLToPath)(referencingModule.url)), specifier, {
381
- esmMode: type_1.EEsmMode.Unlinked
382
- }), referencingModule.context, true);
383
- });
379
+ if (esm.status === "unlinked") {
380
+ await esm.link(async (specifier, referencingModule) => {
381
+ return await (0, asModule_1.default)(await _require(node_path_1.default.dirname(referencingModule.identifier
382
+ ? referencingModule.identifier.slice(esmIdentifier.length + 1)
383
+ : (0, node_url_1.fileURLToPath)(referencingModule.url)), specifier, {
384
+ esmMode: type_1.EEsmMode.Unlinked
385
+ }), referencingModule.context, true);
386
+ });
387
+ }
384
388
  if (esm.instantiate)
385
389
  esm.instantiate();
386
390
  await esm.evaluate();
@@ -1,4 +1,4 @@
1
- import type { ECompilerType, ITestEnv, ITester, ITestProcessor, TTestConfig, TTestRunnerCreator } from "../type";
1
+ import type { ECompilerType, ITestContext, ITestEnv, ITester, ITesterConfig, ITestProcessor, TTestConfig, TTestRunnerCreator } from "../type";
2
2
  declare global {
3
3
  var testFilter: string | undefined;
4
4
  }
@@ -20,27 +20,28 @@ export interface IBasicCaseCreatorOptions<T extends ECompilerType> {
20
20
  testConfig?: (testConfig: TTestConfig<T>) => void;
21
21
  description?: (name: string, step: number) => string;
22
22
  runner?: TTestRunnerCreator;
23
- [key: string]: unknown;
23
+ createContext?: (config: ITesterConfig) => ITestContext;
24
24
  concurrent?: boolean | number;
25
+ [key: string]: unknown;
25
26
  }
26
27
  export declare class BasicCaseCreator<T extends ECompilerType> {
27
28
  protected _options: IBasicCaseCreatorOptions<T>;
28
29
  protected currentConcurrent: number;
29
30
  protected tasks: [string, () => void][];
30
31
  constructor(_options: IBasicCaseCreatorOptions<T>);
31
- create(name: string, src: string, dist: string, temp?: string): ITester | undefined;
32
+ create(name: string, src: string, dist: string, temp?: string, caseOptions?: Partial<IBasicCaseCreatorOptions<T>>): ITester | undefined;
32
33
  protected shouldRun(name: string): boolean;
33
- protected describeConcurrent(name: string, tester: ITester, testConfig: TTestConfig<T>): void;
34
- protected describe(name: string, tester: ITester, testConfig: TTestConfig<T>): void;
34
+ protected describeConcurrent(name: string, tester: ITester, testConfig: TTestConfig<T>, options: IBasicCaseCreatorOptions<T>): void;
35
+ protected describe(name: string, tester: ITester, testConfig: TTestConfig<T>, options: IBasicCaseCreatorOptions<T>): void;
35
36
  protected createConcurrentEnv(): ITestEnv & IConcurrentTestEnv;
36
- protected createEnv(testConfig: TTestConfig<T>): ITestEnv;
37
+ protected createEnv(testConfig: TTestConfig<T>, options: IBasicCaseCreatorOptions<T>): ITestEnv;
37
38
  protected clean(folders: string[]): void;
38
39
  protected skip(name: string, reason: string | boolean): void;
39
40
  protected readTestConfig(src: string): TTestConfig<T>;
40
- protected checkSkipped(src: string, testConfig: TTestConfig<T>): boolean | string;
41
- protected createTester(name: string, src: string, dist: string, temp: string | undefined, testConfig: TTestConfig<T>): ITester;
42
- protected tryRunTask(): void;
43
- protected getMaxConcurrent(): number;
44
- protected registerConcurrentTask(name: string, starter: () => void): () => void;
41
+ protected checkSkipped(src: string, testConfig: TTestConfig<T>, options: IBasicCaseCreatorOptions<T>): boolean | string;
42
+ protected createTester(name: string, src: string, dist: string, temp: string | undefined, testConfig: TTestConfig<T>, options: IBasicCaseCreatorOptions<T>): ITester;
43
+ protected tryRunTask(concurrent?: number): void;
44
+ protected getMaxConcurrent(concurrent?: number): number;
45
+ protected registerConcurrentTask(name: string, starter: () => void, concurrent?: number): () => void;
45
46
  }
46
47
  export {};
@@ -16,31 +16,35 @@ class BasicCaseCreator {
16
16
  this.currentConcurrent = 0;
17
17
  this.tasks = [];
18
18
  }
19
- create(name, src, dist, temp) {
19
+ create(name, src, dist, temp, caseOptions) {
20
+ const options = {
21
+ ...this._options,
22
+ ...caseOptions
23
+ };
20
24
  const testConfig = this.readTestConfig(src);
21
- if (typeof this._options.testConfig === "function") {
22
- this._options.testConfig(testConfig);
25
+ if (typeof options.testConfig === "function") {
26
+ options.testConfig(testConfig);
23
27
  }
24
- const skipped = this.checkSkipped(src, testConfig);
28
+ const skipped = this.checkSkipped(src, testConfig, options);
25
29
  if (skipped) {
26
30
  this.skip(name, skipped);
27
31
  return;
28
32
  }
29
- if (this._options.clean) {
33
+ if (options.clean) {
30
34
  this.clean([dist, temp || ""].filter(Boolean));
31
35
  }
32
36
  const run = this.shouldRun(name);
33
- const tester = this.createTester(name, src, dist, temp, testConfig);
37
+ const tester = this.createTester(name, src, dist, temp, testConfig, options);
34
38
  const concurrent = process.env.WASM
35
39
  ? false
36
- : testConfig.concurrent || this._options.concurrent;
37
- if (this._options.describe) {
40
+ : testConfig.concurrent || options.concurrent;
41
+ if (options.describe) {
38
42
  if (run) {
39
43
  if (concurrent) {
40
- describe(name, () => this.describeConcurrent(name, tester, testConfig));
44
+ describe(name, () => this.describeConcurrent(name, tester, testConfig, options));
41
45
  }
42
46
  else {
43
- describe(name, () => this.describe(name, tester, testConfig));
47
+ describe(name, () => this.describe(name, tester, testConfig, options));
44
48
  }
45
49
  }
46
50
  else {
@@ -52,10 +56,10 @@ class BasicCaseCreator {
52
56
  else {
53
57
  if (run) {
54
58
  if (concurrent) {
55
- this.describeConcurrent(name, tester, testConfig);
59
+ this.describeConcurrent(name, tester, testConfig, options);
56
60
  }
57
61
  else {
58
- this.describe(name, tester, testConfig);
62
+ this.describe(name, tester, testConfig, options);
59
63
  }
60
64
  }
61
65
  else {
@@ -71,7 +75,7 @@ class BasicCaseCreator {
71
75
  }
72
76
  return name.includes(global.testFilter);
73
77
  }
74
- describeConcurrent(name, tester, testConfig) {
78
+ describeConcurrent(name, tester, testConfig, options) {
75
79
  beforeAll(async () => {
76
80
  await tester.prepare();
77
81
  });
@@ -79,7 +83,7 @@ class BasicCaseCreator {
79
83
  let chain = new Promise((resolve, reject) => {
80
84
  starter = resolve;
81
85
  });
82
- const ender = this.registerConcurrentTask(name, starter);
86
+ const ender = this.registerConcurrentTask(name, starter, options.concurrent);
83
87
  const env = this.createConcurrentEnv();
84
88
  for (let index = 0; index < tester.total; index++) {
85
89
  let stepSignalResolve = null;
@@ -88,8 +92,8 @@ class BasicCaseCreator {
88
92
  }).catch(() => {
89
93
  // prevent unhandled rejection
90
94
  });
91
- const description = typeof this._options.description === "function"
92
- ? this._options.description(name, index)
95
+ const description = typeof options.description === "function"
96
+ ? options.description(name, index)
93
97
  : index
94
98
  ? `step [${index}] should pass`
95
99
  : "should pass";
@@ -97,7 +101,7 @@ class BasicCaseCreator {
97
101
  stepSignal.then((e) => {
98
102
  cb(e);
99
103
  });
100
- }, this._options.timeout || 180000);
104
+ }, options.timeout || 180000);
101
105
  chain = chain.then(async () => {
102
106
  try {
103
107
  env.clear();
@@ -136,22 +140,28 @@ class BasicCaseCreator {
136
140
  await tester.resume();
137
141
  });
138
142
  }
139
- describe(name, tester, testConfig) {
143
+ describe(name, tester, testConfig, options) {
140
144
  beforeAll(async () => {
141
145
  await tester.prepare();
142
146
  });
143
147
  let bailout = false;
144
148
  for (let index = 0; index < tester.total; index++) {
145
- const description = typeof this._options.description === "function"
146
- ? this._options.description(name, index)
147
- : `step ${index ? `[${index}]` : ""} should pass`;
149
+ const description = typeof options.description === "function"
150
+ ? options.description(name, index)
151
+ : `step [${index}] should pass`;
148
152
  it(description, async () => {
149
153
  if (bailout) {
150
154
  throw `Case "${name}" step ${index + 1} bailout because ${tester.step + 1} failed`;
151
155
  }
152
- await tester.compile();
153
- await tester.check(env);
154
156
  const context = tester.getContext();
157
+ try {
158
+ await tester.compile();
159
+ }
160
+ catch (e) {
161
+ bailout = true;
162
+ context.emitError(name, e);
163
+ }
164
+ await tester.check(env);
155
165
  if (!tester.next() && context.hasError()) {
156
166
  bailout = true;
157
167
  const errors = context
@@ -160,8 +170,8 @@ class BasicCaseCreator {
160
170
  .join("\n\n");
161
171
  throw new Error(`Case "${name}" failed at step ${tester.step + 1}:\n${errors}`);
162
172
  }
163
- }, this._options.timeout || 30000);
164
- const env = this.createEnv(testConfig);
173
+ }, options.timeout || 30000);
174
+ const env = this.createEnv(testConfig, options);
165
175
  }
166
176
  afterAll(async () => {
167
177
  await tester.resume();
@@ -230,8 +240,8 @@ class BasicCaseCreator {
230
240
  jest
231
241
  };
232
242
  }
233
- createEnv(testConfig) {
234
- if (this._options.runner && !testConfig.noTests) {
243
+ createEnv(testConfig, options) {
244
+ if (options.runner && !testConfig.noTests) {
235
245
  return (0, createLazyTestEnv_1.default)(10000);
236
246
  }
237
247
  return {
@@ -257,30 +267,31 @@ class BasicCaseCreator {
257
267
  const testConfigFile = node_path_1.default.join(src, "test.config.js");
258
268
  return node_fs_1.default.existsSync(testConfigFile) ? require(testConfigFile) : {};
259
269
  }
260
- checkSkipped(src, testConfig) {
270
+ checkSkipped(src, testConfig, options) {
261
271
  const filterPath = node_path_1.default.join(src, "test.filter.js");
262
272
  // no test.filter.js, should not skip
263
273
  if (!node_fs_1.default.existsSync(filterPath)) {
264
274
  return false;
265
275
  }
266
276
  // test.filter.js exists, skip if it returns false|string|array
267
- const filtered = require(filterPath)(this._options, testConfig);
277
+ const filtered = require(filterPath)(options, testConfig);
268
278
  if (typeof filtered === "string" || Array.isArray(filtered)) {
269
279
  return true;
270
280
  }
271
281
  return !filtered;
272
282
  }
273
- createTester(name, src, dist, temp, testConfig) {
283
+ createTester(name, src, dist, temp, testConfig, options) {
274
284
  return new tester_1.Tester({
275
285
  name,
276
286
  src,
277
287
  dist,
278
288
  temp,
279
289
  testConfig,
280
- contextValue: this._options.contextValue,
281
- runnerCreator: this._options.runner,
282
- steps: this._options.steps({
283
- ...this._options,
290
+ contextValue: options.contextValue,
291
+ runnerCreator: options.runner,
292
+ createContext: options.createContext,
293
+ steps: options.steps({
294
+ ...options,
284
295
  name,
285
296
  src,
286
297
  dist,
@@ -288,25 +299,23 @@ class BasicCaseCreator {
288
299
  })
289
300
  });
290
301
  }
291
- tryRunTask() {
302
+ tryRunTask(concurrent) {
292
303
  while (this.tasks.length !== 0 &&
293
- this.currentConcurrent < this.getMaxConcurrent()) {
304
+ this.currentConcurrent < this.getMaxConcurrent(concurrent)) {
294
305
  const [_name, starter] = this.tasks.shift();
295
306
  this.currentConcurrent++;
296
307
  starter();
297
308
  }
298
309
  }
299
- getMaxConcurrent() {
300
- return typeof this._options.concurrent === "number"
301
- ? this._options.concurrent
302
- : DEFAULT_MAX_CONCURRENT;
310
+ getMaxConcurrent(concurrent) {
311
+ return typeof concurrent === "number" ? concurrent : DEFAULT_MAX_CONCURRENT;
303
312
  }
304
- registerConcurrentTask(name, starter) {
313
+ registerConcurrentTask(name, starter, concurrent) {
305
314
  this.tasks.push([name, starter]);
306
- this.tryRunTask();
315
+ this.tryRunTask(concurrent);
307
316
  return () => {
308
317
  this.currentConcurrent--;
309
- this.tryRunTask();
318
+ this.tryRunTask(concurrent);
310
319
  };
311
320
  }
312
321
  }
@@ -12,7 +12,9 @@ class Tester {
12
12
  this.steps = [];
13
13
  this.step = 0;
14
14
  this.total = 0;
15
- this.context = new context_1.TestContext(config);
15
+ this.context = config.createContext
16
+ ? config.createContext(config)
17
+ : new context_1.TestContext(config);
16
18
  this.steps = config.steps || [];
17
19
  this.step = 0;
18
20
  this.total = config.steps?.length || 0;
@@ -69,9 +71,9 @@ class Tester {
69
71
  for (const i of this.steps) {
70
72
  if (typeof i.afterAll === "function") {
71
73
  await i.afterAll(this.context);
72
- await this.context.closeCompiler(this.config.name);
73
74
  }
74
75
  }
76
+ await this.context.closeCompiler(this.config.name);
75
77
  }
76
78
  async runStepMethods(step, methods, force = false) {
77
79
  for (const i of methods) {
package/dist/type.d.ts CHANGED
@@ -54,6 +54,7 @@ export interface ITesterConfig {
54
54
  compilerFactories?: TCompilerFactories<ECompilerType>;
55
55
  contextValue?: Record<string, unknown>;
56
56
  runnerCreator?: TTestRunnerCreator;
57
+ createContext?: (config: ITesterConfig) => ITestContext;
57
58
  }
58
59
  export interface ITester {
59
60
  step: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rspack/test-tools",
3
- "version": "1.5.7",
3
+ "version": "1.5.8",
4
4
  "license": "MIT",
5
5
  "description": "Test tools for rspack",
6
6
  "main": "dist/index.js",
@@ -40,7 +40,7 @@
40
40
  "@babel/traverse": "7.28.4",
41
41
  "@babel/types": "7.28.4",
42
42
  "cross-env": "^10.0.0",
43
- "csv-to-markdown-table": "^1.5.0",
43
+ "csv-to-markdown-table": "1.5.0",
44
44
  "deepmerge": "^4.3.1",
45
45
  "filenamify": "4.3.0",
46
46
  "fs-extra": "^11.3.2",
@@ -50,7 +50,7 @@
50
50
  "jest-diff": "^29.7.0",
51
51
  "jest-snapshot": "29.7.0",
52
52
  "jsdom": "^26.1.0",
53
- "memfs": "4.38.2",
53
+ "memfs": "4.46.0",
54
54
  "loader-utils": "^2.0.4",
55
55
  "path-serializer": "0.5.1",
56
56
  "pretty-format": "29.7.0",
@@ -100,10 +100,10 @@
100
100
  "wast-loader": "^1.14.1",
101
101
  "worker-rspack-loader": "^3.1.2",
102
102
  "exports-loader": "^5.0.0",
103
- "@rspack/cli": "1.5.7",
104
- "@rspack/test-tools": "1.5.7",
103
+ "@rspack/cli": "1.5.8",
104
+ "@rspack/core": "1.5.8",
105
105
  "@rspack/binding-testing": "1.4.1",
106
- "@rspack/core": "1.5.7"
106
+ "@rspack/test-tools": "1.5.8"
107
107
  },
108
108
  "peerDependencies": {
109
109
  "@rspack/core": ">=1.0.0"
@@ -1,5 +0,0 @@
1
- import type { ITestContext, ITestEnv, ITestProcessor } from "../type";
2
- export declare function getSimpleProcessorRunner(src: string, dist: string, options?: {
3
- env?: () => ITestEnv;
4
- context?: (src: string, dist: string) => ITestContext;
5
- }): (name: string, processor: ITestProcessor) => Promise<void>;
@@ -1,44 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getSimpleProcessorRunner = getSimpleProcessorRunner;
4
- const context_1 = require("./context");
5
- const CONTEXT_MAP = new Map();
6
- function getSimpleProcessorRunner(src, dist, options = {}) {
7
- const createEnv = options.env || (() => ({ expect, it, beforeEach, afterEach, jest }));
8
- const createContext = options.context ||
9
- ((src, dist) => new context_1.TestContext({ src, dist }));
10
- const key = `src: ${src}, dist: ${dist}`;
11
- if (!CONTEXT_MAP.has(key)) {
12
- const context = createContext(src, dist);
13
- const runner = async function run(name, processor) {
14
- try {
15
- await processor.beforeAll?.(context);
16
- await processor.before?.(context);
17
- await processor.config?.(context);
18
- await processor.compiler?.(context);
19
- await processor.build?.(context);
20
- }
21
- catch (e) {
22
- context.emitError(name, e);
23
- }
24
- finally {
25
- if (!context.hasError()) {
26
- await processor.run?.(createEnv(), context);
27
- }
28
- await processor.check?.(createEnv(), context);
29
- await processor.after?.(context);
30
- await context.closeCompiler(name);
31
- await processor.afterAll?.(context);
32
- }
33
- if (context.hasError()) {
34
- const errors = context
35
- .getError()
36
- .map(i => `${i.stack}`.split("\n").join("\t\n"))
37
- .join("\n\n");
38
- throw new Error(`Case "${name}" failed:\n${errors}`);
39
- }
40
- };
41
- CONTEXT_MAP.set(key, runner);
42
- }
43
- return CONTEXT_MAP.get(key);
44
- }