@rspack/test-tools 1.5.6 → 1.5.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/case/builtin.d.ts +2 -0
- package/dist/case/builtin.js +173 -13
- package/dist/case/cache.d.ts +1 -1
- package/dist/case/cache.js +210 -11
- package/dist/case/common.d.ts +10 -0
- package/dist/case/common.js +237 -0
- package/dist/case/compiler.d.ts +7 -4
- package/dist/case/compiler.js +35 -18
- package/dist/case/config.d.ts +5 -1
- package/dist/case/config.js +102 -16
- package/dist/case/defaults.d.ts +12 -4
- package/dist/case/defaults.js +67 -12
- package/dist/case/diagnostic.d.ts +6 -0
- package/dist/case/diagnostic.js +123 -14
- package/dist/case/diff.d.ts +17 -1
- package/dist/case/diff.js +170 -22
- package/dist/case/error.d.ts +14 -4
- package/dist/case/error.js +103 -7
- package/dist/case/hash.d.ts +1 -1
- package/dist/case/hash.js +68 -7
- package/dist/case/hook.d.ts +35 -4
- package/dist/case/hook.js +196 -14
- package/dist/case/hot-step.js +307 -9
- package/dist/case/hot.d.ts +8 -1
- package/dist/case/hot.js +235 -8
- package/dist/case/incremental.d.ts +1 -1
- package/dist/case/incremental.js +39 -41
- package/dist/case/index.d.ts +20 -20
- package/dist/case/index.js +44 -34
- package/dist/case/native-watcher.js +10 -23
- package/dist/case/normal.js +174 -12
- package/dist/case/runner.d.ts +18 -0
- package/dist/case/runner.js +108 -0
- package/dist/case/serial.d.ts +1 -1
- package/dist/case/serial.js +8 -12
- package/dist/case/stats-api.d.ts +0 -5
- package/dist/case/stats-api.js +57 -7
- package/dist/case/stats-output.js +197 -11
- package/dist/case/treeshaking.js +34 -7
- package/dist/case/watch.d.ts +27 -0
- package/dist/case/watch.js +321 -21
- package/dist/helper/plugins/hot-update.d.ts +2 -2
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/runner/index.d.ts +2 -7
- package/dist/runner/index.js +2 -7
- package/dist/runner/{runner/node → node}/index.d.ts +1 -2
- package/dist/runner/{runner/node → node}/index.js +2 -2
- package/dist/runner/{runner/web → web}/fake.d.ts +1 -2
- package/dist/runner/{runner/web → web}/fake.js +7 -7
- package/dist/runner/{runner/web → web}/index.d.ts +2 -2
- package/dist/runner/{runner/web → web}/index.js +1 -1
- package/dist/runner/{runner/web → web}/jsdom.d.ts +1 -2
- package/dist/runner/{runner/web → web}/jsdom.js +4 -4
- package/dist/test/context.d.ts +3 -5
- package/dist/test/context.js +22 -12
- package/dist/test/creator.d.ts +2 -2
- package/dist/test/creator.js +2 -2
- package/dist/test/simple.js +1 -0
- package/dist/test/tester.js +1 -0
- package/dist/type.d.ts +41 -11
- package/dist/type.js +7 -1
- package/package.json +4 -4
- package/dist/processor/basic.d.ts +0 -24
- package/dist/processor/basic.js +0 -147
- package/dist/processor/builtin.d.ts +0 -9
- package/dist/processor/builtin.js +0 -171
- package/dist/processor/cache.d.ts +0 -20
- package/dist/processor/cache.js +0 -131
- package/dist/processor/config.d.ts +0 -11
- package/dist/processor/config.js +0 -88
- package/dist/processor/defaults.d.ts +0 -30
- package/dist/processor/defaults.js +0 -72
- package/dist/processor/diagnostic.d.ts +0 -15
- package/dist/processor/diagnostic.js +0 -104
- package/dist/processor/diff.d.ts +0 -30
- package/dist/processor/diff.js +0 -140
- package/dist/processor/error.d.ts +0 -23
- package/dist/processor/error.js +0 -95
- package/dist/processor/hash.d.ts +0 -10
- package/dist/processor/hash.js +0 -65
- package/dist/processor/hook.d.ts +0 -44
- package/dist/processor/hook.js +0 -206
- package/dist/processor/hot-incremental.d.ts +0 -14
- package/dist/processor/hot-incremental.js +0 -43
- package/dist/processor/hot-step.d.ts +0 -18
- package/dist/processor/hot-step.js +0 -307
- package/dist/processor/hot.d.ts +0 -17
- package/dist/processor/hot.js +0 -147
- package/dist/processor/index.d.ts +0 -20
- package/dist/processor/index.js +0 -36
- package/dist/processor/multi.d.ts +0 -17
- package/dist/processor/multi.js +0 -73
- package/dist/processor/normal.d.ts +0 -12
- package/dist/processor/normal.js +0 -170
- package/dist/processor/simple.d.ts +0 -24
- package/dist/processor/simple.js +0 -51
- package/dist/processor/snapshot.d.ts +0 -12
- package/dist/processor/snapshot.js +0 -66
- package/dist/processor/stats-api.d.ts +0 -18
- package/dist/processor/stats-api.js +0 -48
- package/dist/processor/stats.d.ts +0 -18
- package/dist/processor/stats.js +0 -206
- package/dist/processor/treeshaking.d.ts +0 -10
- package/dist/processor/treeshaking.js +0 -33
- package/dist/processor/watch.d.ts +0 -30
- package/dist/processor/watch.js +0 -252
- package/dist/runner/basic.d.ts +0 -10
- package/dist/runner/basic.js +0 -64
- package/dist/runner/cache.d.ts +0 -5
- package/dist/runner/cache.js +0 -92
- package/dist/runner/hot.d.ts +0 -5
- package/dist/runner/hot.js +0 -91
- package/dist/runner/multiple.d.ts +0 -11
- package/dist/runner/multiple.js +0 -52
- package/dist/runner/runner/index.d.ts +0 -2
- package/dist/runner/runner/index.js +0 -18
- package/dist/runner/type.d.ts +0 -42
- package/dist/runner/type.js +0 -9
- package/dist/runner/watch.d.ts +0 -7
- package/dist/runner/watch.js +0 -71
package/dist/case/hook.js
CHANGED
|
@@ -3,33 +3,215 @@ 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
|
-
const
|
|
10
|
-
const runner_1 = require("../runner");
|
|
15
|
+
const context_1 = require("../test/context");
|
|
11
16
|
const simple_1 = require("../test/simple");
|
|
12
|
-
const
|
|
17
|
+
const common_1 = require("./common");
|
|
18
|
+
const srcDir = node_path_1.default.resolve(__dirname, "../../../../tests/rspack-test/fixtures");
|
|
19
|
+
const distDir = node_path_1.default.resolve(__dirname, "../../../../tests/rspack-test/js/hook");
|
|
13
20
|
function createHookCase(name, src, dist, source) {
|
|
14
21
|
const caseConfig = require(node_path_1.default.join(src, "test.js"));
|
|
15
22
|
const testName = node_path_1.default.basename(name.slice(0, name.indexOf(node_path_1.default.extname(name))));
|
|
16
23
|
const runner = (0, simple_1.getSimpleProcessorRunner)(source, dist, {
|
|
17
24
|
env: () => env,
|
|
18
|
-
context: () => new
|
|
25
|
+
context: () => new HookCasesContext(src, testName, {
|
|
19
26
|
src: source,
|
|
20
|
-
dist: dist
|
|
21
|
-
runnerFactory: runner_1.BasicRunnerFactory
|
|
27
|
+
dist: dist
|
|
22
28
|
})
|
|
23
29
|
});
|
|
24
30
|
it(caseConfig.description, async () => {
|
|
25
|
-
await runner(name,
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
+
});
|
|
33
58
|
});
|
|
34
59
|
const env = (0, createLazyTestEnv_1.default)(10000);
|
|
35
60
|
}
|
|
61
|
+
const sourceSerializer = {
|
|
62
|
+
test(val) {
|
|
63
|
+
return val instanceof core_1.sources.Source;
|
|
64
|
+
},
|
|
65
|
+
print(val) {
|
|
66
|
+
return val.source();
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
const internalSerializer = {
|
|
70
|
+
test(val) {
|
|
71
|
+
return val instanceof core_1.Compiler || val instanceof core_1.Compilation;
|
|
72
|
+
},
|
|
73
|
+
print(val) {
|
|
74
|
+
return JSON.stringify(`${val.constructor.name}(internal ignored)`);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
const testPathSerializer = (0, path_serializer_1.createSnapshotSerializer)({
|
|
78
|
+
replace: [
|
|
79
|
+
{
|
|
80
|
+
match: srcDir,
|
|
81
|
+
mark: "<HOOK_SRC_DIR>"
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
match: distDir,
|
|
85
|
+
mark: "<HOOK_DIST_DIR>"
|
|
86
|
+
}
|
|
87
|
+
]
|
|
88
|
+
});
|
|
89
|
+
const escapeRegex = true;
|
|
90
|
+
const printFunctionName = false;
|
|
91
|
+
const normalizeNewlines = (str) => str.replace(/\r\n|\r/g, "\n");
|
|
92
|
+
const serialize = (val, indent = 2, formatOverrides = {}) => normalizeNewlines((0, pretty_format_1.format)(val, {
|
|
93
|
+
escapeRegex,
|
|
94
|
+
indent,
|
|
95
|
+
plugins: [
|
|
96
|
+
...(0, jest_snapshot_1.getSerializers)(),
|
|
97
|
+
sourceSerializer,
|
|
98
|
+
internalSerializer,
|
|
99
|
+
testPathSerializer
|
|
100
|
+
],
|
|
101
|
+
printFunctionName,
|
|
102
|
+
...formatOverrides
|
|
103
|
+
}));
|
|
104
|
+
class HookCasesContext extends context_1.TestContext {
|
|
105
|
+
constructor(src, testName, options) {
|
|
106
|
+
super(options);
|
|
107
|
+
this.src = src;
|
|
108
|
+
this.testName = testName;
|
|
109
|
+
this.options = options;
|
|
110
|
+
this.promises = [];
|
|
111
|
+
this.count = 0;
|
|
112
|
+
this.snapshots = {};
|
|
113
|
+
this.snapshotsList = [];
|
|
114
|
+
this.snapped = this.snapped.bind(this);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Snapshot function arguments and return value.
|
|
118
|
+
* Generated snapshot is located in the same directory with the test source.
|
|
119
|
+
* @example
|
|
120
|
+
* compiler.hooks.compilation("name", context.snapped((...args) => { ... }))
|
|
121
|
+
*/
|
|
122
|
+
snapped(cb, prefix = "") {
|
|
123
|
+
// eslint-disable-next-line
|
|
124
|
+
const context = this;
|
|
125
|
+
return function SNAPPED_HOOK(...args) {
|
|
126
|
+
const group = prefix ? prefix : context.count++;
|
|
127
|
+
context._addSnapshot(args, "input", group);
|
|
128
|
+
const output = cb.apply(this, args);
|
|
129
|
+
if (output && typeof output.then === "function") {
|
|
130
|
+
let resolve;
|
|
131
|
+
context.promises.push(new Promise(r => (resolve = r)));
|
|
132
|
+
return output
|
|
133
|
+
.then((o) => {
|
|
134
|
+
context._addSnapshot(o, "output (Promise resolved)", group);
|
|
135
|
+
return o;
|
|
136
|
+
})
|
|
137
|
+
.catch((o) => {
|
|
138
|
+
context._addSnapshot(o, "output (Promise rejected)", group);
|
|
139
|
+
return o;
|
|
140
|
+
})
|
|
141
|
+
.finally(resolve);
|
|
142
|
+
}
|
|
143
|
+
context._addSnapshot(output, "output", group);
|
|
144
|
+
return output;
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* @internal
|
|
149
|
+
*/
|
|
150
|
+
_addSnapshot(content, name, group) {
|
|
151
|
+
const normalizedContent = Buffer.isBuffer(content)
|
|
152
|
+
? content
|
|
153
|
+
: serialize(content, undefined, {
|
|
154
|
+
escapeString: true,
|
|
155
|
+
printBasicPrototype: true
|
|
156
|
+
}).replace(/\r\n/g, "\n");
|
|
157
|
+
(this.snapshots[group] = this.snapshots[group] || []).push([
|
|
158
|
+
normalizedContent,
|
|
159
|
+
name
|
|
160
|
+
]);
|
|
161
|
+
if (!this.snapshotsList.includes(group)) {
|
|
162
|
+
this.snapshotsList.push(group);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* @internal
|
|
167
|
+
*/
|
|
168
|
+
async collectSnapshots(env, options = {
|
|
169
|
+
diff: {}
|
|
170
|
+
}) {
|
|
171
|
+
await Promise.allSettled(this.promises);
|
|
172
|
+
if (!this.snapshotsList.length)
|
|
173
|
+
return;
|
|
174
|
+
const snapshots = this.snapshotsList.reduce((acc, group, index) => {
|
|
175
|
+
const block = this.snapshots[group || index].reduce((acc, [content, name]) => {
|
|
176
|
+
name = `## ${name || `test: ${index}`}\n\n`;
|
|
177
|
+
const block = `\`\`\`javascript\n${content}\n\`\`\`\n`;
|
|
178
|
+
return `${acc}${name + block}\n`;
|
|
179
|
+
}, "");
|
|
180
|
+
return `${acc}# ${Number.isInteger(group) ? `Group: ${index}` : group}\n\n${block}`;
|
|
181
|
+
}, "");
|
|
182
|
+
env
|
|
183
|
+
.expect(snapshots)
|
|
184
|
+
.toMatchFileSnapshot(node_path_1.default.join(this.src, "hooks.snap.txt"), options);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
exports.HookCasesContext = HookCasesContext;
|
|
188
|
+
function defaultOptions(context, custom) {
|
|
189
|
+
let defaultOptions = {
|
|
190
|
+
context: context.getSource(),
|
|
191
|
+
mode: "production",
|
|
192
|
+
target: "async-node",
|
|
193
|
+
devtool: false,
|
|
194
|
+
cache: false,
|
|
195
|
+
entry: "./hook",
|
|
196
|
+
output: {
|
|
197
|
+
path: context.getDist()
|
|
198
|
+
},
|
|
199
|
+
optimization: {
|
|
200
|
+
minimize: false
|
|
201
|
+
},
|
|
202
|
+
experiments: {
|
|
203
|
+
css: true,
|
|
204
|
+
rspackFuture: {
|
|
205
|
+
bundlerInfo: {
|
|
206
|
+
force: false
|
|
207
|
+
}
|
|
208
|
+
},
|
|
209
|
+
inlineConst: true,
|
|
210
|
+
lazyBarrel: true
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
if (custom) {
|
|
214
|
+
defaultOptions = (0, webpack_merge_1.default)(defaultOptions, custom(context));
|
|
215
|
+
}
|
|
216
|
+
return defaultOptions;
|
|
217
|
+
}
|
package/dist/case/hot-step.js
CHANGED
|
@@ -1,11 +1,311 @@
|
|
|
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.createHotStepCase = createHotStepCase;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
7
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
8
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
9
|
+
const helper_1 = require("../helper");
|
|
10
|
+
const placeholder_1 = require("../helper/expect/placeholder");
|
|
6
11
|
const creator_1 = require("../test/creator");
|
|
7
12
|
const type_1 = require("../type");
|
|
13
|
+
const common_1 = require("./common");
|
|
14
|
+
const hot_1 = require("./hot");
|
|
15
|
+
const NOOP_SET = new Set();
|
|
16
|
+
const escapeLocalName = (str) => str.split(/[-<>:"/|?*.]/).join("_");
|
|
17
|
+
const SELF_HANDLER = (file, options) => {
|
|
18
|
+
let res = [];
|
|
19
|
+
const hotUpdateGlobal = (_, modules) => {
|
|
20
|
+
res = Object.keys(modules);
|
|
21
|
+
};
|
|
22
|
+
const hotUpdateGlobalKey = escapeLocalName(`${options.output?.hotUpdateGlobal || "webpackHotUpdate"}${options.output?.uniqueName || ""}`);
|
|
23
|
+
global.self ??= {};
|
|
24
|
+
global.self[hotUpdateGlobalKey] = hotUpdateGlobal;
|
|
25
|
+
require(file);
|
|
26
|
+
delete global.self[hotUpdateGlobalKey];
|
|
27
|
+
if (!Object.keys(global.self).length) {
|
|
28
|
+
delete global.self;
|
|
29
|
+
}
|
|
30
|
+
return res;
|
|
31
|
+
};
|
|
32
|
+
const NODE_HANDLER = (file) => {
|
|
33
|
+
return Object.keys(require(file).modules) || [];
|
|
34
|
+
};
|
|
35
|
+
const GET_MODULE_HANDLER = {
|
|
36
|
+
web: SELF_HANDLER,
|
|
37
|
+
webworker: SELF_HANDLER,
|
|
38
|
+
"async-node": NODE_HANDLER,
|
|
39
|
+
node: NODE_HANDLER
|
|
40
|
+
};
|
|
8
41
|
const creators = new Map();
|
|
42
|
+
function createHotStepProcessor(name, target) {
|
|
43
|
+
const processor = (0, hot_1.createHotProcessor)(name, target);
|
|
44
|
+
const entries = {};
|
|
45
|
+
const hashes = [];
|
|
46
|
+
function matchStepSnapshot(env, context, step, options, stats, runtime) {
|
|
47
|
+
const getModuleHandler = GET_MODULE_HANDLER[options.target];
|
|
48
|
+
env.expect(typeof getModuleHandler).toBe("function");
|
|
49
|
+
const lastHash = hashes[hashes.length - 1];
|
|
50
|
+
const snapshotPath = context.getSource(`__snapshots__/${options.target}/${step}.snap.txt`);
|
|
51
|
+
const title = `Case ${node_path_1.default.basename(name)}: Step ${step}`;
|
|
52
|
+
const hotUpdateFile = [];
|
|
53
|
+
const hotUpdateManifest = [];
|
|
54
|
+
const changedFiles = step === 0
|
|
55
|
+
? []
|
|
56
|
+
: processor.hotUpdateContext.changedFiles.map((i) => (0, helper_1.escapeSep)(node_path_1.default.relative(context.getSource(), i)));
|
|
57
|
+
changedFiles.sort();
|
|
58
|
+
const resultHashes = {
|
|
59
|
+
[lastHash || "LAST_HASH"]: "LAST_HASH",
|
|
60
|
+
[stats.hash]: "CURRENT_HASH"
|
|
61
|
+
};
|
|
62
|
+
// TODO: find a better way
|
|
63
|
+
// replace [runtime] to [runtime of id] to prevent worker hash
|
|
64
|
+
const runtimes = {};
|
|
65
|
+
for (const [id, runtime] of Object.entries(entries)) {
|
|
66
|
+
if (typeof runtime === "string") {
|
|
67
|
+
if (runtime !== id) {
|
|
68
|
+
runtimes[runtime] = `[runtime of ${id}]`;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
else if (Array.isArray(runtime)) {
|
|
72
|
+
for (const r of runtime) {
|
|
73
|
+
if (r !== id) {
|
|
74
|
+
runtimes[r] = `[runtime of ${id}]`;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
const replaceContent = (rawStr) => {
|
|
80
|
+
let str = rawStr;
|
|
81
|
+
const replaceContentConfig = context.getTestConfig().snapshotContent;
|
|
82
|
+
if (replaceContentConfig) {
|
|
83
|
+
str = replaceContentConfig(str);
|
|
84
|
+
}
|
|
85
|
+
return (0, placeholder_1.normalizePlaceholder)(Object.entries(resultHashes)
|
|
86
|
+
.reduce((str, [raw, replacement]) => {
|
|
87
|
+
return str.split(raw).join(replacement);
|
|
88
|
+
}, str)
|
|
89
|
+
.replace(/\/\/ (\d+)\s+(?=var cssReload)/, "")
|
|
90
|
+
.replaceAll(/var data = "(?:.*)"/g, match => {
|
|
91
|
+
return decodeURIComponent(match).replaceAll(/\\/g, "/");
|
|
92
|
+
}));
|
|
93
|
+
};
|
|
94
|
+
const replaceFileName = (str) => {
|
|
95
|
+
return Object.entries({
|
|
96
|
+
...resultHashes,
|
|
97
|
+
...runtimes
|
|
98
|
+
}).reduce((str, [raw, replacement]) => {
|
|
99
|
+
return str.split(raw).join(replacement);
|
|
100
|
+
}, str);
|
|
101
|
+
};
|
|
102
|
+
const fileList = stats
|
|
103
|
+
.assets.map(i => {
|
|
104
|
+
const fileName = i.name;
|
|
105
|
+
const renderName = replaceFileName(fileName);
|
|
106
|
+
const content = replaceContent(fs_extra_1.default.readFileSync(context.getDist(fileName), "utf-8"));
|
|
107
|
+
if (fileName.endsWith("hot-update.js")) {
|
|
108
|
+
const modules = getModuleHandler(context.getDist(fileName), options);
|
|
109
|
+
const runtime = [];
|
|
110
|
+
for (const i of content.matchAll(/\/\/ (webpack\/runtime\/[\w_-]+)\s*\n/g)) {
|
|
111
|
+
runtime.push(i[1]);
|
|
112
|
+
}
|
|
113
|
+
modules.sort();
|
|
114
|
+
runtime.sort();
|
|
115
|
+
hotUpdateFile.push({
|
|
116
|
+
name: renderName,
|
|
117
|
+
content,
|
|
118
|
+
modules,
|
|
119
|
+
runtime
|
|
120
|
+
});
|
|
121
|
+
return `- Update: ${renderName}, size: ${content.length}`;
|
|
122
|
+
}
|
|
123
|
+
if (fileName.endsWith("hot-update.json")) {
|
|
124
|
+
const manifest = JSON.parse(content);
|
|
125
|
+
manifest.c?.sort();
|
|
126
|
+
manifest.r?.sort();
|
|
127
|
+
manifest.m?.sort();
|
|
128
|
+
hotUpdateManifest.push({
|
|
129
|
+
name: renderName,
|
|
130
|
+
content: JSON.stringify(manifest)
|
|
131
|
+
});
|
|
132
|
+
return `- Manifest: ${renderName}, size: ${i.size}`;
|
|
133
|
+
}
|
|
134
|
+
if (fileName.endsWith(".js")) {
|
|
135
|
+
return `- Bundle: ${renderName}`;
|
|
136
|
+
}
|
|
137
|
+
})
|
|
138
|
+
.filter(Boolean);
|
|
139
|
+
fileList.sort();
|
|
140
|
+
hotUpdateManifest.sort((a, b) => (a.name > b.name ? 1 : -1));
|
|
141
|
+
hotUpdateFile.sort((a, b) => (a.name > b.name ? 1 : -1));
|
|
142
|
+
if (runtime?.javascript) {
|
|
143
|
+
runtime.javascript.outdatedModules.sort();
|
|
144
|
+
runtime.javascript.updatedModules.sort();
|
|
145
|
+
runtime.javascript.updatedRuntime.sort();
|
|
146
|
+
runtime.javascript.acceptedModules.sort();
|
|
147
|
+
runtime.javascript.disposedModules.sort();
|
|
148
|
+
for (const value of Object.values(runtime.javascript.outdatedDependencies)) {
|
|
149
|
+
value.sort();
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
const content = `
|
|
153
|
+
# ${title}
|
|
154
|
+
|
|
155
|
+
## Changed Files
|
|
156
|
+
${changedFiles.map(i => `- ${i}`).join("\n")}
|
|
157
|
+
|
|
158
|
+
## Asset Files
|
|
159
|
+
${fileList.join("\n")}
|
|
160
|
+
|
|
161
|
+
## Manifest
|
|
162
|
+
${hotUpdateManifest
|
|
163
|
+
.map(i => `
|
|
164
|
+
### ${i.name}
|
|
165
|
+
|
|
166
|
+
\`\`\`json
|
|
167
|
+
${i.content}
|
|
168
|
+
\`\`\`
|
|
169
|
+
`)
|
|
170
|
+
.join("\n\n")}
|
|
171
|
+
|
|
172
|
+
## Update
|
|
173
|
+
|
|
174
|
+
${hotUpdateFile
|
|
175
|
+
.map(i => `
|
|
176
|
+
### ${i.name}
|
|
177
|
+
|
|
178
|
+
#### Changed Modules
|
|
179
|
+
${i.modules.map(i => `- ${i}`).join("\n")}
|
|
180
|
+
|
|
181
|
+
#### Changed Runtime Modules
|
|
182
|
+
${i.runtime.map(i => `- ${i}`).join("\n")}
|
|
183
|
+
|
|
184
|
+
#### Changed Content
|
|
185
|
+
\`\`\`js
|
|
186
|
+
${i.content}
|
|
187
|
+
\`\`\`
|
|
188
|
+
`)
|
|
189
|
+
.join("\n\n")}
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
${runtime
|
|
193
|
+
? `
|
|
194
|
+
## Runtime
|
|
195
|
+
### Status
|
|
196
|
+
|
|
197
|
+
\`\`\`txt
|
|
198
|
+
${runtime.statusPath.join(" => ")}
|
|
199
|
+
\`\`\`
|
|
200
|
+
|
|
201
|
+
${runtime.javascript
|
|
202
|
+
? `
|
|
203
|
+
|
|
204
|
+
### JavaScript
|
|
205
|
+
|
|
206
|
+
#### Outdated
|
|
207
|
+
|
|
208
|
+
Outdated Modules:
|
|
209
|
+
${runtime.javascript.outdatedModules.map(i => `- ${i}`).join("\n")}
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
Outdated Dependencies:
|
|
213
|
+
\`\`\`json
|
|
214
|
+
${JSON.stringify(runtime.javascript.outdatedDependencies || {}, null, 2)}
|
|
215
|
+
\`\`\`
|
|
216
|
+
|
|
217
|
+
#### Updated
|
|
218
|
+
|
|
219
|
+
Updated Modules:
|
|
220
|
+
${runtime.javascript.updatedModules.map(i => `- ${i}`).join("\n")}
|
|
221
|
+
|
|
222
|
+
Updated Runtime:
|
|
223
|
+
${runtime.javascript.updatedRuntime.map(i => `- \`${i}\``).join("\n")}
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
#### Callback
|
|
227
|
+
|
|
228
|
+
Accepted Callback:
|
|
229
|
+
${runtime.javascript.acceptedModules.map(i => `- ${i}`).join("\n")}
|
|
230
|
+
|
|
231
|
+
Disposed Callback:
|
|
232
|
+
${runtime.javascript.disposedModules.map(i => `- ${i}`).join("\n")}
|
|
233
|
+
`
|
|
234
|
+
: ""}
|
|
235
|
+
|
|
236
|
+
`
|
|
237
|
+
: ""}
|
|
238
|
+
|
|
239
|
+
`
|
|
240
|
+
.replaceAll(/%3A(\d+)%2F/g, (match, capture) => {
|
|
241
|
+
return match.replace(capture, "PORT");
|
|
242
|
+
})
|
|
243
|
+
.trim();
|
|
244
|
+
env.expect(content).toMatchFileSnapshot(snapshotPath);
|
|
245
|
+
}
|
|
246
|
+
const originRun = processor.run;
|
|
247
|
+
processor.run = async function (env, context) {
|
|
248
|
+
context.setValue(name, "hotUpdateStepChecker", (hotUpdateContext, stats, runtime) => {
|
|
249
|
+
const statsJson = stats.toJson({
|
|
250
|
+
assets: true,
|
|
251
|
+
chunks: true
|
|
252
|
+
});
|
|
253
|
+
const chunks = Array.from(
|
|
254
|
+
// Some chunk fields are missing from rspack
|
|
255
|
+
stats?.compilation.chunks || NOOP_SET);
|
|
256
|
+
for (const entry of chunks.filter(i => i.hasRuntime())) {
|
|
257
|
+
if (!entries[entry.id] && entry.runtime) {
|
|
258
|
+
entries[entry.id] =
|
|
259
|
+
// Webpack uses `string | SortableSet<string>` for `entry.runtime`
|
|
260
|
+
typeof entry.runtime === "string"
|
|
261
|
+
? [entry.runtime]
|
|
262
|
+
: Array.from(entry.runtime);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
const compiler = context.getCompiler(name, type_1.ECompilerType.Rspack);
|
|
266
|
+
const compilerOptions = compiler.getOptions();
|
|
267
|
+
matchStepSnapshot(env, context, hotUpdateContext.updateIndex, compilerOptions, statsJson, runtime);
|
|
268
|
+
hashes.push(stats.hash);
|
|
269
|
+
});
|
|
270
|
+
context.setValue(name, "hotUpdateStepErrorChecker", (_, stats, runtime) => {
|
|
271
|
+
hashes.push(stats.hash);
|
|
272
|
+
});
|
|
273
|
+
await originRun(env, context);
|
|
274
|
+
};
|
|
275
|
+
processor.check = async function (env, context) {
|
|
276
|
+
const compiler = (0, common_1.getCompiler)(context, name);
|
|
277
|
+
const stats = compiler.getStats();
|
|
278
|
+
if (!stats || !stats.hash) {
|
|
279
|
+
env.expect(false);
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
const statsJson = stats.toJson({ assets: true, chunks: true });
|
|
283
|
+
const chunks = Array.from(
|
|
284
|
+
// Some chunk fields are missing from rspack
|
|
285
|
+
stats?.compilation.chunks || NOOP_SET);
|
|
286
|
+
for (const entry of chunks.filter(i => i.hasRuntime())) {
|
|
287
|
+
if (entry.runtime) {
|
|
288
|
+
entries[entry.id] =
|
|
289
|
+
// Webpack uses `string | SortableSet<string>` for `entry.runtime`
|
|
290
|
+
typeof entry.runtime === "string"
|
|
291
|
+
? [entry.runtime]
|
|
292
|
+
: Array.from(entry.runtime);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
let matchFailed = null;
|
|
296
|
+
try {
|
|
297
|
+
matchStepSnapshot(env, context, 0, compiler.getOptions(), statsJson);
|
|
298
|
+
}
|
|
299
|
+
catch (e) {
|
|
300
|
+
matchFailed = e;
|
|
301
|
+
}
|
|
302
|
+
hashes.push(stats.hash);
|
|
303
|
+
if (matchFailed) {
|
|
304
|
+
throw matchFailed;
|
|
305
|
+
}
|
|
306
|
+
};
|
|
307
|
+
return processor;
|
|
308
|
+
}
|
|
9
309
|
function getCreator(target) {
|
|
10
310
|
if (!creators.has(target)) {
|
|
11
311
|
creators.set(target, new creator_1.BasicCaseCreator({
|
|
@@ -13,14 +313,12 @@ function getCreator(target) {
|
|
|
13
313
|
describe: false,
|
|
14
314
|
target,
|
|
15
315
|
steps: ({ name, target }) => [
|
|
16
|
-
|
|
17
|
-
name,
|
|
18
|
-
target: target,
|
|
19
|
-
compilerType: type_1.ECompilerType.Rspack,
|
|
20
|
-
configFiles: ["rspack.config.js", "webpack.config.js"]
|
|
21
|
-
})
|
|
316
|
+
createHotStepProcessor(name, target)
|
|
22
317
|
],
|
|
23
|
-
runner:
|
|
318
|
+
runner: {
|
|
319
|
+
key: (context, name, file) => name,
|
|
320
|
+
runner: hot_1.createHotRunner
|
|
321
|
+
},
|
|
24
322
|
concurrent: true
|
|
25
323
|
}));
|
|
26
324
|
}
|
package/dist/case/hot.d.ts
CHANGED
|
@@ -1,2 +1,9 @@
|
|
|
1
|
-
import { ECompilerType, type TCompilerOptions } from "../type";
|
|
1
|
+
import { type ECompilerType, type ITestContext, type ITestEnv, type ITestProcessor, type ITestRunner, type TCompilerOptions, type THotUpdateContext } from "../type";
|
|
2
|
+
type TTarget = TCompilerOptions<ECompilerType.Rspack>["target"];
|
|
3
|
+
export declare function createHotProcessor(name: string, target: TTarget, incremental?: boolean): THotProcessor;
|
|
2
4
|
export declare function createHotCase(name: string, src: string, dist: string, target: TCompilerOptions<ECompilerType.Rspack>["target"]): void;
|
|
5
|
+
type THotProcessor = ITestProcessor & {
|
|
6
|
+
hotUpdateContext: THotUpdateContext;
|
|
7
|
+
};
|
|
8
|
+
export declare function createHotRunner<T extends ECompilerType = ECompilerType.Rspack>(context: ITestContext, name: string, file: string, env: ITestEnv): ITestRunner;
|
|
9
|
+
export {};
|