Skip to content

Commit 0221567

Browse files
authored
test: refactor processor (#11732)
* test: refactor processor * test: refactor processor
1 parent 59a0c65 commit 0221567

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+2435
-3074
lines changed

packages/rspack-test-tools/etc/test-tools.api.md

Lines changed: 22 additions & 462 deletions
Large diffs are not rendered by default.

packages/rspack-test-tools/src/case/builtin.ts

Lines changed: 171 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,176 @@
11
import path from "node:path";
2+
import { rspack } from "@rspack/core";
3+
import fs from "fs-extra";
4+
import { merge } from "webpack-merge";
25
import { isJavaScript } from "../helper";
3-
import { BuiltinProcessor, type IBuiltinProcessorOptions } from "../processor";
6+
import {
7+
type ISnapshotProcessorOptions,
8+
SnapshotProcessor
9+
} from "../processor";
410
import { BasicCaseCreator } from "../test/creator";
5-
import { ECompilerType } from "../type";
11+
import {
12+
ECompilerType,
13+
type ITestContext,
14+
type TCompilerOptions
15+
} from "../type";
16+
17+
export function defaultOptions<T extends ECompilerType.Rspack>(
18+
context: ITestContext
19+
): TCompilerOptions<T> {
20+
let defaultOptions = {
21+
entry: {
22+
main: {
23+
import: "./index"
24+
}
25+
},
26+
output: {
27+
publicPath: "/",
28+
path: context.getDist(),
29+
filename: "[name].js",
30+
chunkFilename: "[name].js",
31+
chunkFormat: "array-push",
32+
cssFilename: "[name].css",
33+
cssChunkFilename: "[name].css",
34+
assetModuleFilename: "[hash][ext][query]",
35+
sourceMapFilename: "[file].map",
36+
chunkLoadingGlobal: "webpackChunkwebpack",
37+
chunkLoading: "jsonp",
38+
uniqueName: "__rspack_test__",
39+
enabledLibraryTypes: ["system"],
40+
strictModuleErrorHandling: false,
41+
iife: true,
42+
module: false,
43+
asyncChunks: true,
44+
scriptType: false,
45+
globalObject: "self",
46+
importFunctionName: "import",
47+
wasmLoading: "fetch",
48+
webassemblyModuleFilename: "[hash].module.wasm",
49+
workerChunkLoading: "import-scripts",
50+
workerWasmLoading: "fetch"
51+
},
52+
module: {
53+
rules: [
54+
{
55+
test: /\.json$/,
56+
type: "json"
57+
},
58+
{
59+
test: /\.mjs$/,
60+
type: "javascript/esm"
61+
},
62+
{
63+
test: /\.cjs$/,
64+
type: "javascript/dynamic"
65+
},
66+
{
67+
test: /\.js$/,
68+
type: "javascript/auto"
69+
},
70+
{
71+
test: /\.css$/,
72+
type: "css"
73+
},
74+
{
75+
test: /\.wasm$/,
76+
type: "webassembly/async"
77+
}
78+
]
79+
},
80+
node: {
81+
__dirname: "mock",
82+
__filename: "mock",
83+
global: "warn"
84+
},
85+
optimization: {
86+
runtimeChunk: {
87+
name: "runtime"
88+
},
89+
minimize: false,
90+
removeAvailableModules: true,
91+
removeEmptyChunks: true,
92+
moduleIds: "named",
93+
chunkIds: "named",
94+
sideEffects: false,
95+
mangleExports: false,
96+
usedExports: false,
97+
concatenateModules: false,
98+
nodeEnv: false
99+
},
100+
resolve: {
101+
extensions: [
102+
".js",
103+
".jsx",
104+
".ts",
105+
".tsx",
106+
".json",
107+
".d.ts",
108+
".css",
109+
".wasm"
110+
]
111+
},
112+
resolveLoader: {
113+
extensions: [".js"]
114+
},
115+
experiments: {
116+
css: true,
117+
futureDefaults: true,
118+
rspackFuture: {
119+
bundlerInfo: {
120+
force: false
121+
}
122+
}
123+
},
124+
devtool: false,
125+
context: context.getSource(),
126+
plugins: []
127+
} as TCompilerOptions<T>;
128+
129+
const testConfigFile = context.getSource("rspack.config.js");
130+
if (fs.existsSync(testConfigFile)) {
131+
const caseOptions = require(testConfigFile);
132+
if (caseOptions.entry) {
133+
delete defaultOptions.entry;
134+
}
135+
defaultOptions = merge(defaultOptions, caseOptions);
136+
}
137+
138+
// TODO: remove builtin compatible code
139+
const defineOptions = (defaultOptions as any).builtins?.define;
140+
if (defineOptions) {
141+
defaultOptions.plugins!.push(new rspack.DefinePlugin(defineOptions));
142+
}
143+
144+
const provideOptions = (defaultOptions as any).builtins?.provide;
145+
if (provideOptions) {
146+
defaultOptions.plugins!.push(new rspack.ProvidePlugin(provideOptions));
147+
}
148+
149+
const htmlOptions = (defaultOptions as any).builtins?.html;
150+
if (htmlOptions) {
151+
if (Array.isArray(htmlOptions)) {
152+
for (const item of htmlOptions) {
153+
defaultOptions.plugins!.push(new rspack.HtmlRspackPlugin(item));
154+
}
155+
} else {
156+
defaultOptions.plugins!.push(new rspack.HtmlRspackPlugin(htmlOptions));
157+
}
158+
}
159+
160+
delete (defaultOptions as any).builtins;
161+
162+
if (!global.printLogger) {
163+
defaultOptions.infrastructureLogging = {
164+
level: "error"
165+
};
166+
}
167+
168+
return defaultOptions;
169+
}
6170

7171
const FILTERS: Record<
8172
string,
9-
IBuiltinProcessorOptions<ECompilerType>["snapshotFileFilter"]
173+
ISnapshotProcessorOptions<ECompilerType>["snapshotFileFilter"]
10174
> = {
11175
"plugin-css": (file: string) => file.endsWith(".css"),
12176
"plugin-css-modules": (file: string) =>
@@ -24,11 +188,13 @@ const creator = new BasicCaseCreator({
24188
const cat = path.basename(path.dirname(src));
25189
const filter = FILTERS[cat];
26190
return [
27-
new BuiltinProcessor({
191+
new SnapshotProcessor({
28192
name,
29193
snapshot: "output.snap.txt",
30194
snapshotFileFilter: filter,
31-
compilerType: ECompilerType.Rspack
195+
compilerType: ECompilerType.Rspack,
196+
defaultOptions,
197+
runable: false
32198
})
33199
];
34200
},

packages/rspack-test-tools/src/case/cache.ts

Lines changed: 153 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
1-
import { CacheProcessor } from "../processor/cache";
1+
import path from "node:path";
2+
import rspack from "@rspack/core";
3+
import { isJavaScript } from "../helper";
4+
import { HotUpdatePlugin } from "../helper/hot-update";
5+
import { BasicProcessor } from "../processor";
26
import { CacheRunnerFactory } from "../runner";
37
import { BasicCaseCreator } from "../test/creator";
4-
import { ECompilerType, type TCompilerOptions } from "../type";
8+
import {
9+
ECompilerType,
10+
type ITestContext,
11+
type TCompilerOptions
12+
} from "../type";
513

614
type TTarget = TCompilerOptions<ECompilerType.Rspack>["target"];
715

@@ -10,6 +18,148 @@ const creators: Map<
1018
BasicCaseCreator<ECompilerType.Rspack>
1119
> = new Map();
1220

21+
function defaultOptions(
22+
context: ITestContext,
23+
temp: string,
24+
target: TTarget
25+
): TCompilerOptions<ECompilerType.Rspack> {
26+
const options = {
27+
context: temp,
28+
mode: "production",
29+
cache: true,
30+
devtool: false,
31+
output: {
32+
path: context.getDist(),
33+
filename: "bundle.js",
34+
chunkFilename: "[name].chunk.[fullhash].js",
35+
publicPath: "https://test.cases/path/",
36+
library: { type: "commonjs2" }
37+
},
38+
optimization: {
39+
moduleIds: "named",
40+
emitOnErrors: true
41+
},
42+
target,
43+
experiments: {
44+
css: true,
45+
rspackFuture: {
46+
bundlerInfo: {
47+
force: false
48+
}
49+
},
50+
inlineConst: true,
51+
lazyBarrel: true
52+
}
53+
} as TCompilerOptions<ECompilerType.Rspack>;
54+
55+
options.plugins ??= [];
56+
(options as TCompilerOptions<ECompilerType.Rspack>).plugins!.push(
57+
new rspack.HotModuleReplacementPlugin()
58+
);
59+
60+
return options;
61+
}
62+
63+
function overrideOptions<T extends ECompilerType>(
64+
options: TCompilerOptions<T>,
65+
temp: string,
66+
target: TTarget,
67+
updatePlugin: HotUpdatePlugin
68+
): void {
69+
if (!options.entry) {
70+
options.entry = "./index.js";
71+
}
72+
73+
// rewrite context to temp dir
74+
options.context = temp;
75+
options.module ??= {};
76+
for (const cssModuleType of ["css/auto", "css/module", "css"] as const) {
77+
options.module!.generator ??= {};
78+
options.module!.generator[cssModuleType] ??= {};
79+
options.module!.generator[cssModuleType]!.exportsOnly ??=
80+
target === "async-node";
81+
}
82+
options.plugins ??= [];
83+
(options as TCompilerOptions<ECompilerType.Rspack>).plugins!.push(
84+
updatePlugin
85+
);
86+
if (!global.printLogger) {
87+
options.infrastructureLogging = {
88+
level: "error"
89+
};
90+
}
91+
}
92+
93+
function findBundle(
94+
name: string,
95+
target: TTarget,
96+
context: ITestContext
97+
): string[] {
98+
const files: string[] = [];
99+
const prefiles: string[] = [];
100+
const compiler = context.getCompiler(name);
101+
if (!compiler) throw new Error("Compiler should exists when find bundle");
102+
const stats = compiler.getStats();
103+
if (!stats) throw new Error("Stats should exists when find bundle");
104+
const info = stats.toJson({ all: false, entrypoints: true });
105+
if (target === "web" || target === "webworker") {
106+
for (const file of info.entrypoints!.main.assets!) {
107+
if (isJavaScript(file.name)) {
108+
files.push(file.name);
109+
} else {
110+
prefiles.push(file.name);
111+
}
112+
}
113+
} else {
114+
const assets = info.entrypoints!.main.assets!.filter(s =>
115+
isJavaScript(s.name)
116+
);
117+
files.push(assets[assets.length - 1].name);
118+
}
119+
return [...prefiles, ...files];
120+
}
121+
122+
function createCacheProcessor(
123+
name: string,
124+
src: string,
125+
temp: string,
126+
target: TTarget
127+
) {
128+
const updatePlugin = new HotUpdatePlugin(src, temp);
129+
130+
const processor = new BasicProcessor<ECompilerType.Rspack>({
131+
name,
132+
runable: true,
133+
compilerType: ECompilerType.Rspack,
134+
configFiles: ["rspack.config.js", "webpack.config.js"].map(i =>
135+
path.resolve(temp, i)
136+
),
137+
defaultOptions: context => defaultOptions(context, temp, target),
138+
overrideOptions: (context, options) =>
139+
overrideOptions(options, temp, target, updatePlugin),
140+
findBundle: context => findBundle(name, target, context)
141+
});
142+
143+
processor.before = async (context: ITestContext) => {
144+
await updatePlugin.initialize();
145+
context.setValue(name, "hotUpdateContext", updatePlugin);
146+
};
147+
148+
const originalAfterAll = processor.afterAll;
149+
processor.afterAll = async function (context) {
150+
await originalAfterAll.call(this, context);
151+
const updateIndex = updatePlugin.getUpdateIndex();
152+
const totalUpdates = updatePlugin.getTotalUpdates();
153+
if (updateIndex + 1 !== totalUpdates) {
154+
throw new Error(
155+
`Should run all hot steps (${updateIndex + 1} / ${totalUpdates}): ${this._options.name}`
156+
);
157+
}
158+
};
159+
160+
return processor;
161+
}
162+
13163
function getCreator(target: TTarget) {
14164
if (!creators.has(target)) {
15165
creators.set(
@@ -19,14 +169,7 @@ function getCreator(target: TTarget) {
19169
describe: true,
20170
target,
21171
steps: ({ name, src, target, temp }) => [
22-
new CacheProcessor({
23-
name,
24-
sourceDir: src,
25-
tempDir: temp!,
26-
target: target as TTarget,
27-
compilerType: ECompilerType.Rspack,
28-
configFiles: ["rspack.config.js", "webpack.config.js"]
29-
})
172+
createCacheProcessor(name, src, temp!, target as TTarget)
30173
],
31174
runner: CacheRunnerFactory,
32175
concurrent: true

packages/rspack-test-tools/src/case/compiler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ export function createCompilerCase(
120120
);
121121
await caseConfig.compiler?.(context, compiler);
122122
},
123-
async check(context, compiler, stats) {
123+
async check(env, context, compiler, stats) {
124124
if (caseConfig.error) {
125125
const statsJson = stats?.toJson({
126126
modules: true,

0 commit comments

Comments
 (0)