@rspack-canary/test-tools 1.5.6-canary-e598f284-20250921173624 → 1.5.7-canary-a3406c0a-20250922173625

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.
Files changed (70) hide show
  1. package/dist/case/builtin.d.ts +2 -0
  2. package/dist/case/builtin.js +153 -2
  3. package/dist/case/cache.js +115 -9
  4. package/dist/case/compiler.js +1 -1
  5. package/dist/case/config.d.ts +4 -1
  6. package/dist/case/config.js +80 -2
  7. package/dist/case/defaults.d.ts +11 -3
  8. package/dist/case/defaults.js +47 -2
  9. package/dist/case/diagnostic.d.ts +6 -0
  10. package/dist/case/diagnostic.js +109 -9
  11. package/dist/case/error.d.ts +2 -2
  12. package/dist/case/error.js +79 -2
  13. package/dist/case/hash.js +61 -7
  14. package/dist/case/hook.d.ts +35 -3
  15. package/dist/case/hook.js +185 -4
  16. package/dist/case/hot-step.d.ts +1 -1
  17. package/dist/case/hot-step.js +302 -8
  18. package/dist/case/hot.d.ts +8 -1
  19. package/dist/case/hot.js +147 -7
  20. package/dist/case/incremental.js +21 -8
  21. package/dist/case/index.d.ts +20 -20
  22. package/dist/case/index.js +44 -34
  23. package/dist/case/normal.js +152 -5
  24. package/dist/case/serial.js +7 -3
  25. package/dist/case/stats-api.d.ts +0 -5
  26. package/dist/case/stats-api.js +33 -2
  27. package/dist/case/stats-output.js +200 -10
  28. package/dist/case/treeshaking.js +19 -3
  29. package/dist/helper/plugins/hot-update.d.ts +2 -2
  30. package/dist/processor/basic.d.ts +4 -1
  31. package/dist/processor/basic.js +20 -10
  32. package/dist/processor/index.d.ts +0 -14
  33. package/dist/processor/index.js +0 -14
  34. package/dist/processor/multi.d.ts +3 -1
  35. package/dist/processor/multi.js +2 -0
  36. package/dist/processor/simple.d.ts +1 -1
  37. package/dist/processor/simple.js +4 -4
  38. package/dist/processor/snapshot.js +4 -3
  39. package/dist/type.d.ts +1 -1
  40. package/package.json +4 -4
  41. package/dist/processor/builtin.d.ts +0 -9
  42. package/dist/processor/builtin.js +0 -171
  43. package/dist/processor/cache.d.ts +0 -20
  44. package/dist/processor/cache.js +0 -131
  45. package/dist/processor/config.d.ts +0 -11
  46. package/dist/processor/config.js +0 -88
  47. package/dist/processor/defaults.d.ts +0 -30
  48. package/dist/processor/defaults.js +0 -72
  49. package/dist/processor/diagnostic.d.ts +0 -15
  50. package/dist/processor/diagnostic.js +0 -104
  51. package/dist/processor/error.d.ts +0 -23
  52. package/dist/processor/error.js +0 -95
  53. package/dist/processor/hash.d.ts +0 -10
  54. package/dist/processor/hash.js +0 -65
  55. package/dist/processor/hook.d.ts +0 -44
  56. package/dist/processor/hook.js +0 -206
  57. package/dist/processor/hot-incremental.d.ts +0 -14
  58. package/dist/processor/hot-incremental.js +0 -43
  59. package/dist/processor/hot-step.d.ts +0 -18
  60. package/dist/processor/hot-step.js +0 -307
  61. package/dist/processor/hot.d.ts +0 -17
  62. package/dist/processor/hot.js +0 -147
  63. package/dist/processor/normal.d.ts +0 -12
  64. package/dist/processor/normal.js +0 -170
  65. package/dist/processor/stats-api.d.ts +0 -18
  66. package/dist/processor/stats-api.js +0 -48
  67. package/dist/processor/stats.d.ts +0 -18
  68. package/dist/processor/stats.js +0 -206
  69. package/dist/processor/treeshaking.d.ts +0 -10
  70. package/dist/processor/treeshaking.js +0 -33
@@ -1,6 +1,6 @@
1
- import { type IErrorProcessorOptions } from "../processor";
1
+ import { type ISimpleProcessorOptions } from "../processor";
2
2
  import { ECompilerType } from "../type";
3
- export type TErrorCaseConfig = Omit<IErrorProcessorOptions<ECompilerType.Rspack>, "name" | "compilerType"> & {
3
+ export type TErrorCaseConfig = Omit<ISimpleProcessorOptions<ECompilerType.Rspack>, "name" | "compilerType"> & {
4
4
  description: string;
5
5
  };
6
6
  export declare function createErrorCase(name: string, src: string, dist: string, testConfig: string): void;
@@ -1,10 +1,84 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.createErrorCase = createErrorCase;
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const webpack_merge_1 = __importDefault(require("webpack-merge"));
4
9
  const processor_1 = require("../processor");
5
10
  const simple_1 = require("../test/simple");
6
11
  const type_1 = require("../type");
7
12
  let addedSerializer = false;
13
+ function options(context, custom) {
14
+ let options = {
15
+ context: node_path_1.default.resolve(__dirname, "../../../../tests/rspack-test/fixtures/errors"),
16
+ mode: "none",
17
+ devtool: false,
18
+ optimization: {
19
+ minimize: false,
20
+ moduleIds: "named",
21
+ chunkIds: "named"
22
+ },
23
+ experiments: {
24
+ css: true,
25
+ rspackFuture: {
26
+ bundlerInfo: {
27
+ force: false
28
+ }
29
+ }
30
+ }
31
+ };
32
+ if (typeof custom === "function") {
33
+ options = (0, webpack_merge_1.default)(options, custom(context, options));
34
+ }
35
+ if (options.mode === "production") {
36
+ if (options.optimization)
37
+ options.optimization.minimize = true;
38
+ else
39
+ options.optimization = { minimize: true };
40
+ }
41
+ return options;
42
+ }
43
+ async function compiler(context, compiler, custom) {
44
+ if (compiler) {
45
+ compiler.outputFileSystem = {
46
+ // CHANGE: rspack outputFileSystem `mkdirp` uses option `{ recursive: true }`, webpack's second parameter is alway a callback
47
+ mkdir(dir, maybeOptionOrCallback, maybeCallback) {
48
+ if (typeof maybeOptionOrCallback === "function") {
49
+ maybeOptionOrCallback();
50
+ }
51
+ else if (typeof maybeCallback === "function") {
52
+ maybeCallback();
53
+ }
54
+ },
55
+ writeFile(file, content, callback) {
56
+ callback();
57
+ },
58
+ stat(file, callback) {
59
+ callback(new Error("ENOENT"));
60
+ },
61
+ mkdirSync() { },
62
+ writeFileSync() { }
63
+ };
64
+ }
65
+ await custom?.(context, compiler);
66
+ }
67
+ class RspackStatsDiagnostics {
68
+ constructor(errors, warnings) {
69
+ this.errors = errors;
70
+ this.warnings = warnings;
71
+ }
72
+ }
73
+ async function check(env, context, _, stats, check) {
74
+ env.expect(typeof stats).toBe("object");
75
+ const statsResult = stats.toJson({ errorDetails: false });
76
+ env.expect(typeof statsResult).toBe("object");
77
+ const { errors, warnings } = statsResult;
78
+ env.expect(Array.isArray(errors)).toBe(true);
79
+ env.expect(Array.isArray(warnings)).toBe(true);
80
+ await check?.(new RspackStatsDiagnostics(errors, warnings));
81
+ }
8
82
  function createErrorCase(name, src, dist, testConfig) {
9
83
  if (!addedSerializer) {
10
84
  addedSerializer = true;
@@ -12,10 +86,13 @@ function createErrorCase(name, src, dist, testConfig) {
12
86
  const caseConfig = require(testConfig);
13
87
  const runner = (0, simple_1.getSimpleProcessorRunner)(src, dist);
14
88
  it(caseConfig.description, async () => {
15
- await runner(name, new processor_1.ErrorProcessor({
89
+ await runner(name, new processor_1.SimpleTaskProcessor({
16
90
  name: name,
17
91
  compilerType: type_1.ECompilerType.Rspack,
18
- ...caseConfig
92
+ options: context => options(context, caseConfig.options),
93
+ compiler: (context, c) => compiler(context, c, caseConfig.compiler),
94
+ build: caseConfig.build,
95
+ check: (env, context, compiler, stats) => check(env, context, compiler, stats, caseConfig.check)
19
96
  }));
20
97
  });
21
98
  }
package/dist/case/hash.js CHANGED
@@ -4,6 +4,35 @@ exports.createHashCase = createHashCase;
4
4
  const processor_1 = require("../processor");
5
5
  const creator_1 = require("../test/creator");
6
6
  const type_1 = require("../type");
7
+ const REG_ERROR_CASE = /error$/;
8
+ function defaultOptions(index, context) {
9
+ return {
10
+ context: context.getSource(),
11
+ output: {
12
+ path: context.getDist()
13
+ },
14
+ experiments: {
15
+ css: true,
16
+ rspackFuture: {
17
+ bundlerInfo: {
18
+ force: false
19
+ }
20
+ },
21
+ inlineConst: true,
22
+ lazyBarrel: true
23
+ }
24
+ };
25
+ }
26
+ function overrideOptions(index, context, options) {
27
+ if (!options.entry) {
28
+ options.entry = "./index.js";
29
+ }
30
+ if (!global.printLogger) {
31
+ options.infrastructureLogging = {
32
+ level: "error"
33
+ };
34
+ }
35
+ }
7
36
  class HashCaseCreator extends creator_1.BasicCaseCreator {
8
37
  describe(name, tester, testConfig) {
9
38
  it(`should print correct hash for ${name}`, async () => {
@@ -14,16 +43,41 @@ class HashCaseCreator extends creator_1.BasicCaseCreator {
14
43
  }, 30000);
15
44
  }
16
45
  }
46
+ async function check(env, context, compiler, stats) {
47
+ const testConfig = context.getTestConfig();
48
+ if (!stats) {
49
+ env.expect(false);
50
+ return;
51
+ }
52
+ if (REG_ERROR_CASE.test(this._options.name)) {
53
+ env.expect(stats.hasErrors());
54
+ }
55
+ else {
56
+ env.expect(!stats.hasErrors());
57
+ }
58
+ if (typeof testConfig.validate === "function") {
59
+ testConfig.validate(stats);
60
+ }
61
+ else {
62
+ throw new Error("HashTestCases should have test.config.js and a validate method");
63
+ }
64
+ }
65
+ function createHashProcessor(name) {
66
+ const processor = new processor_1.MultiTaskProcessor({
67
+ name,
68
+ compilerType: type_1.ECompilerType.Rspack,
69
+ configFiles: ["rspack.config.js", "webpack.config.js"],
70
+ runable: false,
71
+ defaultOptions,
72
+ overrideOptions,
73
+ check
74
+ });
75
+ return processor;
76
+ }
17
77
  const creator = new HashCaseCreator({
18
78
  clean: true,
19
79
  describe: false,
20
- steps: ({ name }) => [
21
- new processor_1.HashProcessor({
22
- name,
23
- compilerType: type_1.ECompilerType.Rspack,
24
- configFiles: ["rspack.config.js", "webpack.config.js"]
25
- })
26
- ]
80
+ steps: ({ name }) => [createHashProcessor(name)]
27
81
  });
28
82
  function createHashCase(name, src, dist) {
29
83
  creator.create(name, src, dist);
@@ -1,6 +1,38 @@
1
- import { type IHookProcessorOptions } from "../processor";
2
- import { ECompilerType } from "../type";
3
- export type THookCaseConfig = Omit<IHookProcessorOptions<ECompilerType.Rspack>, "name" | "compilerType" | "runable"> & {
1
+ import { type ISnapshotProcessorOptions } from "../processor";
2
+ import { TestContext, type TTestContextOptions } from "../test/context";
3
+ import type { ITestEnv } from "../type";
4
+ import { ECompilerType, type ITestContext, type TCompiler, type TCompilerOptions } from "../type";
5
+ export declare class HookCasesContext extends TestContext {
6
+ protected src: string;
7
+ protected testName: string;
8
+ protected options: TTestContextOptions;
9
+ protected promises: Promise<void>[];
10
+ protected count: number;
11
+ protected snapshots: Record<string | number, Array<[string | Buffer, string]>>;
12
+ protected snapshotsList: Array<string | number>;
13
+ constructor(src: string, testName: string, options: TTestContextOptions);
14
+ /**
15
+ * Snapshot function arguments and return value.
16
+ * Generated snapshot is located in the same directory with the test source.
17
+ * @example
18
+ * compiler.hooks.compilation("name", context.snapped((...args) => { ... }))
19
+ */
20
+ snapped(cb: (...args: unknown[]) => Promise<unknown>, prefix?: string): (this: any, ...args: unknown[]) => Promise<unknown>;
21
+ /**
22
+ * @internal
23
+ */
24
+ _addSnapshot(content: unknown, name: string, group: string | number): void;
25
+ /**
26
+ * @internal
27
+ */
28
+ collectSnapshots(env: ITestEnv, options?: {
29
+ diff: {};
30
+ }): Promise<void>;
31
+ }
32
+ export type THookCaseConfig = Omit<ISnapshotProcessorOptions<ECompilerType.Rspack>, "name" | "compilerType" | "runable"> & {
33
+ options?: (context: ITestContext) => TCompilerOptions<ECompilerType.Rspack>;
34
+ compiler?: (context: ITestContext, compiler: TCompiler<ECompilerType.Rspack>) => Promise<void>;
35
+ check?: (context: ITestContext) => Promise<void>;
4
36
  description: string;
5
37
  };
6
38
  export declare function createHookCase(name: string, src: string, dist: string, source: string): void;
package/dist/case/hook.js CHANGED
@@ -3,32 +3,213 @@ 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.HookCasesContext = void 0;
6
7
  exports.createHookCase = createHookCase;
7
8
  const node_path_1 = __importDefault(require("node:path"));
9
+ const core_1 = require("@rspack/core");
10
+ const jest_snapshot_1 = require("jest-snapshot");
11
+ const path_serializer_1 = require("path-serializer");
12
+ const pretty_format_1 = require("pretty-format");
13
+ const webpack_merge_1 = __importDefault(require("webpack-merge"));
8
14
  const createLazyTestEnv_1 = __importDefault(require("../helper/legacy/createLazyTestEnv"));
9
15
  const processor_1 = require("../processor");
10
16
  const runner_1 = require("../runner");
17
+ const context_1 = require("../test/context");
11
18
  const simple_1 = require("../test/simple");
12
19
  const type_1 = require("../type");
20
+ const srcDir = node_path_1.default.resolve(__dirname, "../../../../tests/rspack-test/fixtures");
21
+ const distDir = node_path_1.default.resolve(__dirname, "../../../../tests/rspack-test/js/hook");
22
+ const sourceSerializer = {
23
+ test(val) {
24
+ return val instanceof core_1.sources.Source;
25
+ },
26
+ print(val) {
27
+ return val.source();
28
+ }
29
+ };
30
+ const internalSerializer = {
31
+ test(val) {
32
+ return val instanceof core_1.Compiler || val instanceof core_1.Compilation;
33
+ },
34
+ print(val) {
35
+ return JSON.stringify(`${val.constructor.name}(internal ignored)`);
36
+ }
37
+ };
38
+ const testPathSerializer = (0, path_serializer_1.createSnapshotSerializer)({
39
+ replace: [
40
+ {
41
+ match: srcDir,
42
+ mark: "<HOOK_SRC_DIR>"
43
+ },
44
+ {
45
+ match: distDir,
46
+ mark: "<HOOK_DIST_DIR>"
47
+ }
48
+ ]
49
+ });
50
+ const escapeRegex = true;
51
+ const printFunctionName = false;
52
+ const normalizeNewlines = (str) => str.replace(/\r\n|\r/g, "\n");
53
+ const serialize = (val, indent = 2, formatOverrides = {}) => normalizeNewlines((0, pretty_format_1.format)(val, {
54
+ escapeRegex,
55
+ indent,
56
+ plugins: [
57
+ ...(0, jest_snapshot_1.getSerializers)(),
58
+ sourceSerializer,
59
+ internalSerializer,
60
+ testPathSerializer
61
+ ],
62
+ printFunctionName,
63
+ ...formatOverrides
64
+ }));
65
+ class HookCasesContext extends context_1.TestContext {
66
+ constructor(src, testName, options) {
67
+ super(options);
68
+ this.src = src;
69
+ this.testName = testName;
70
+ this.options = options;
71
+ this.promises = [];
72
+ this.count = 0;
73
+ this.snapshots = {};
74
+ this.snapshotsList = [];
75
+ this.snapped = this.snapped.bind(this);
76
+ }
77
+ /**
78
+ * Snapshot function arguments and return value.
79
+ * Generated snapshot is located in the same directory with the test source.
80
+ * @example
81
+ * compiler.hooks.compilation("name", context.snapped((...args) => { ... }))
82
+ */
83
+ snapped(cb, prefix = "") {
84
+ // eslint-disable-next-line
85
+ const context = this;
86
+ return function SNAPPED_HOOK(...args) {
87
+ const group = prefix ? prefix : context.count++;
88
+ context._addSnapshot(args, "input", group);
89
+ const output = cb.apply(this, args);
90
+ if (output && typeof output.then === "function") {
91
+ let resolve;
92
+ context.promises.push(new Promise(r => (resolve = r)));
93
+ return output
94
+ .then((o) => {
95
+ context._addSnapshot(o, "output (Promise resolved)", group);
96
+ return o;
97
+ })
98
+ .catch((o) => {
99
+ context._addSnapshot(o, "output (Promise rejected)", group);
100
+ return o;
101
+ })
102
+ .finally(resolve);
103
+ }
104
+ context._addSnapshot(output, "output", group);
105
+ return output;
106
+ };
107
+ }
108
+ /**
109
+ * @internal
110
+ */
111
+ _addSnapshot(content, name, group) {
112
+ const normalizedContent = Buffer.isBuffer(content)
113
+ ? content
114
+ : serialize(content, undefined, {
115
+ escapeString: true,
116
+ printBasicPrototype: true
117
+ }).replace(/\r\n/g, "\n");
118
+ (this.snapshots[group] = this.snapshots[group] || []).push([
119
+ normalizedContent,
120
+ name
121
+ ]);
122
+ if (!this.snapshotsList.includes(group)) {
123
+ this.snapshotsList.push(group);
124
+ }
125
+ }
126
+ /**
127
+ * @internal
128
+ */
129
+ async collectSnapshots(env, options = {
130
+ diff: {}
131
+ }) {
132
+ await Promise.allSettled(this.promises);
133
+ if (!this.snapshotsList.length)
134
+ return;
135
+ const snapshots = this.snapshotsList.reduce((acc, group, index) => {
136
+ const block = this.snapshots[group || index].reduce((acc, [content, name]) => {
137
+ name = `## ${name || `test: ${index}`}\n\n`;
138
+ const block = `\`\`\`javascript\n${content}\n\`\`\`\n`;
139
+ return `${acc}${name + block}\n`;
140
+ }, "");
141
+ return `${acc}# ${Number.isInteger(group) ? `Group: ${index}` : group}\n\n${block}`;
142
+ }, "");
143
+ env
144
+ .expect(snapshots)
145
+ .toMatchFileSnapshot(node_path_1.default.join(this.src, "hooks.snap.txt"), options);
146
+ }
147
+ }
148
+ exports.HookCasesContext = HookCasesContext;
13
149
  function createHookCase(name, src, dist, source) {
14
150
  const caseConfig = require(node_path_1.default.join(src, "test.js"));
15
151
  const testName = node_path_1.default.basename(name.slice(0, name.indexOf(node_path_1.default.extname(name))));
16
152
  const runner = (0, simple_1.getSimpleProcessorRunner)(source, dist, {
17
153
  env: () => env,
18
- context: () => new processor_1.HookCasesContext(src, testName, {
154
+ context: () => new HookCasesContext(src, testName, {
19
155
  src: source,
20
156
  dist: dist,
21
157
  runnerFactory: runner_1.BasicRunnerFactory
22
158
  })
23
159
  });
24
160
  it(caseConfig.description, async () => {
25
- await runner(name, new processor_1.HookTaskProcessor({
161
+ await runner(name, new processor_1.SnapshotProcessor({
26
162
  name,
27
163
  compilerType: type_1.ECompilerType.Rspack,
28
164
  findBundle: () => ["main.js"],
29
165
  snapshot: node_path_1.default.join(src, "output.snap.txt"),
30
- runable: true,
31
- ...caseConfig
166
+ runable: false,
167
+ defaultOptions: context => {
168
+ let defaultOptions = {
169
+ context: context.getSource(),
170
+ mode: "production",
171
+ target: "async-node",
172
+ devtool: false,
173
+ cache: false,
174
+ entry: "./hook",
175
+ output: {
176
+ path: context.getDist()
177
+ },
178
+ optimization: {
179
+ minimize: false
180
+ },
181
+ experiments: {
182
+ css: true,
183
+ rspackFuture: {
184
+ bundlerInfo: {
185
+ force: false
186
+ }
187
+ },
188
+ inlineConst: true,
189
+ lazyBarrel: true
190
+ }
191
+ };
192
+ if (caseConfig.options) {
193
+ defaultOptions = (0, webpack_merge_1.default)(defaultOptions, caseConfig.options(context));
194
+ }
195
+ return defaultOptions;
196
+ },
197
+ overrideOptions: (context, options) => {
198
+ if (!global.printLogger) {
199
+ options.infrastructureLogging = {
200
+ level: "error"
201
+ };
202
+ }
203
+ },
204
+ compiler: caseConfig.compiler,
205
+ check: async function (env, context, compiler, stats) {
206
+ await context.collectSnapshots(env);
207
+ await processor_1.SnapshotProcessor.prototype.check.call(this, env, context);
208
+ if (typeof caseConfig.check === "function") {
209
+ await caseConfig.check(context);
210
+ }
211
+ },
212
+ snapshotFileFilter: caseConfig.snapshotFileFilter
32
213
  }));
33
214
  });
34
215
  const env = (0, createLazyTestEnv_1.default)(10000);
@@ -1,2 +1,2 @@
1
- import { ECompilerType, type TCompilerOptions } from "../type";
1
+ import type { ECompilerType, TCompilerOptions } from "../type";
2
2
  export declare function createHotStepCase(name: string, src: string, dist: string, target: TCompilerOptions<ECompilerType.Rspack>["target"]): void;