@rspack-canary/test-tools 1.6.0-canary-e28e40e9-20251022173516 → 1.6.0-canary-941e2203-20251024173714
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.js +1 -1
- package/dist/case/cache.js +5 -5
- package/dist/case/common.d.ts +1 -2
- package/dist/case/common.js +32 -26
- package/dist/case/compiler.js +5 -6
- package/dist/case/defaults.js +9 -9
- package/dist/case/diagnostic.js +4 -5
- package/dist/case/error.js +7 -8
- package/dist/case/example.js +2 -2
- package/dist/case/hash.js +1 -1
- package/dist/case/hook.js +3 -2
- package/dist/case/hot-step.js +4 -5
- package/dist/case/hot.js +6 -6
- package/dist/case/multi-compiler.js +3 -4
- package/dist/case/normal.js +1 -1
- package/dist/case/runner.js +12 -8
- package/dist/case/stats-api.js +4 -5
- package/dist/case/stats-output.js +1 -1
- package/dist/case/treeshaking.js +1 -1
- package/dist/case/watch.js +13 -13
- package/dist/compiler.d.ts +4 -3
- package/dist/compiler.js +113 -6
- package/dist/helper/index.d.ts +1 -0
- package/dist/helper/index.js +1 -0
- package/dist/helper/read-config-file.js +7 -0
- package/dist/helper/setup-env.js +1 -0
- package/dist/helper/stringify-config.d.ts +2 -0
- package/dist/helper/stringify-config.js +43 -0
- package/dist/runner/node/index.d.ts +4 -0
- package/dist/runner/node/index.js +83 -6
- package/dist/runner/web/index.d.ts +1 -0
- package/dist/runner/web/index.js +38 -50
- package/dist/test/context.d.ts +13 -14
- package/dist/test/context.js +44 -51
- package/dist/test/creator.js +1 -1
- package/dist/test/debug.d.ts +15 -0
- package/dist/test/debug.js +205 -0
- package/dist/test/tester.js +13 -4
- package/dist/type.d.ts +10 -10
- package/package.json +3 -2
package/dist/case/stats-api.js
CHANGED
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.createStatsAPICase = createStatsAPICase;
|
|
4
4
|
const memfs_1 = require("memfs");
|
|
5
5
|
const creator_1 = require("../test/creator");
|
|
6
|
-
const common_1 = require("./common");
|
|
7
6
|
let addedSerializer = false;
|
|
8
7
|
const creator = new creator_1.BasicCaseCreator({
|
|
9
8
|
clean: true,
|
|
@@ -13,16 +12,16 @@ const creator = new creator_1.BasicCaseCreator({
|
|
|
13
12
|
return [
|
|
14
13
|
{
|
|
15
14
|
config: async (context) => {
|
|
16
|
-
const compiler =
|
|
15
|
+
const compiler = context.getCompiler();
|
|
17
16
|
compiler.setOptions(options(context, config.options));
|
|
18
17
|
},
|
|
19
18
|
compiler: async (context) => {
|
|
20
|
-
const compilerManager =
|
|
19
|
+
const compilerManager = context.getCompiler();
|
|
21
20
|
compilerManager.createCompiler();
|
|
22
21
|
compiler(context, compilerManager.getCompiler(), config.compiler);
|
|
23
22
|
},
|
|
24
23
|
build: async (context) => {
|
|
25
|
-
const compiler =
|
|
24
|
+
const compiler = context.getCompiler();
|
|
26
25
|
if (typeof config.build === "function") {
|
|
27
26
|
await config.build(context, compiler.getCompiler());
|
|
28
27
|
}
|
|
@@ -74,7 +73,7 @@ async function compiler(context, compiler, custom) {
|
|
|
74
73
|
}
|
|
75
74
|
}
|
|
76
75
|
async function check(env, context, name, custom) {
|
|
77
|
-
const manager =
|
|
76
|
+
const manager = context.getCompiler();
|
|
78
77
|
const stats = manager.getStats();
|
|
79
78
|
env.expect(typeof stats).toBe("object");
|
|
80
79
|
await custom?.(stats, manager.getCompiler());
|
|
@@ -114,7 +114,7 @@ class RspackStats {
|
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
116
|
async function check(env, context, name, writeStatsOuptut, snapshot, stderr) {
|
|
117
|
-
const compiler =
|
|
117
|
+
const compiler = context.getCompiler();
|
|
118
118
|
const options = compiler.getOptions();
|
|
119
119
|
const stats = compiler.getStats();
|
|
120
120
|
if (!stats || !compiler)
|
package/dist/case/treeshaking.js
CHANGED
|
@@ -13,7 +13,7 @@ const creator = new creator_1.BasicCaseCreator({
|
|
|
13
13
|
steps: ({ name }) => [
|
|
14
14
|
{
|
|
15
15
|
config: async (context) => {
|
|
16
|
-
const compiler =
|
|
16
|
+
const compiler = context.getCompiler();
|
|
17
17
|
const options = (0, builtin_1.defaultOptions)(context);
|
|
18
18
|
overrideOptions(context, options);
|
|
19
19
|
compiler.setOptions(options);
|
package/dist/case/watch.js
CHANGED
|
@@ -29,7 +29,7 @@ function createWatchInitialProcessor(name, tempDir, step, watchState, { incremen
|
|
|
29
29
|
};
|
|
30
30
|
return {
|
|
31
31
|
before: async (context) => {
|
|
32
|
-
context.setValue(
|
|
32
|
+
context.setValue("watchContext", watchContext);
|
|
33
33
|
},
|
|
34
34
|
config: async (context) => {
|
|
35
35
|
const testConfig = context.getTestConfig();
|
|
@@ -46,9 +46,9 @@ function createWatchInitialProcessor(name, tempDir, step, watchState, { incremen
|
|
|
46
46
|
const compilerOptions = multiCompilerOptions.length === 1
|
|
47
47
|
? multiCompilerOptions[0]
|
|
48
48
|
: multiCompilerOptions;
|
|
49
|
-
const compiler =
|
|
49
|
+
const compiler = context.getCompiler();
|
|
50
50
|
compiler.setOptions(compilerOptions);
|
|
51
|
-
context.setValue(
|
|
51
|
+
context.setValue("multiCompilerOptions", multiCompilerOptions);
|
|
52
52
|
},
|
|
53
53
|
compiler: async (context) => {
|
|
54
54
|
const c = await (0, common_1.compiler)(context, name);
|
|
@@ -57,7 +57,7 @@ function createWatchInitialProcessor(name, tempDir, step, watchState, { incremen
|
|
|
57
57
|
});
|
|
58
58
|
},
|
|
59
59
|
build: async (context) => {
|
|
60
|
-
const compiler =
|
|
60
|
+
const compiler = context.getCompiler();
|
|
61
61
|
node_fs_1.default.mkdirSync(watchContext.tempDir, { recursive: true });
|
|
62
62
|
(0, copyDiff_1.default)(node_path_1.default.join(context.getSource(), watchContext.step), watchContext.tempDir, true);
|
|
63
63
|
const task = new Promise((resolve, reject) => {
|
|
@@ -77,12 +77,12 @@ function createWatchInitialProcessor(name, tempDir, step, watchState, { incremen
|
|
|
77
77
|
const testConfig = context.getTestConfig();
|
|
78
78
|
if (testConfig.noTests)
|
|
79
79
|
return;
|
|
80
|
-
const errors = (context.getError(
|
|
80
|
+
const errors = (context.getError() || []).map(e => ({
|
|
81
81
|
message: e.message,
|
|
82
82
|
stack: e.stack
|
|
83
83
|
}));
|
|
84
84
|
const warnings = [];
|
|
85
|
-
const compiler =
|
|
85
|
+
const compiler = context.getCompiler();
|
|
86
86
|
const stats = compiler.getStats();
|
|
87
87
|
const options = compiler.getOptions();
|
|
88
88
|
const checkStats = testConfig.checkStats || (() => true);
|
|
@@ -148,7 +148,7 @@ function createWatchInitialProcessor(name, tempDir, step, watchState, { incremen
|
|
|
148
148
|
await (0, checkArrayExpectation_1.default)(node_path_1.default.join(context.getSource(), watchContext.step), { warnings }, "warning", "warnings", "Warning", options);
|
|
149
149
|
// clear error if checked
|
|
150
150
|
if (node_fs_1.default.existsSync(context.getSource("errors.js"))) {
|
|
151
|
-
context.clearError(
|
|
151
|
+
context.clearError();
|
|
152
152
|
}
|
|
153
153
|
// check hash
|
|
154
154
|
if (testConfig.writeStatsOuptut) {
|
|
@@ -169,7 +169,7 @@ function createWatchStepProcessor(name, tempDir, step, watchState, { incremental
|
|
|
169
169
|
// do nothing
|
|
170
170
|
};
|
|
171
171
|
processor.build = async (context) => {
|
|
172
|
-
const compiler =
|
|
172
|
+
const compiler = context.getCompiler();
|
|
173
173
|
const task = new Promise((resolve, reject) => {
|
|
174
174
|
compiler.getEmitter().once(compiler_1.ECompilerEvent.Build, (e, stats) => {
|
|
175
175
|
if (e)
|
|
@@ -283,13 +283,13 @@ function defaultOptions({ incremental = false, ignoreNotFriendlyForIncrementalWa
|
|
|
283
283
|
return {};
|
|
284
284
|
}
|
|
285
285
|
function getWatchRunnerKey(context, name, file) {
|
|
286
|
-
const watchContext = context.getValue(
|
|
286
|
+
const watchContext = context.getValue("watchContext");
|
|
287
287
|
const stepName = watchContext?.step;
|
|
288
288
|
return `${name}-${stepName}`;
|
|
289
289
|
}
|
|
290
290
|
function cachedWatchStats(context, name) {
|
|
291
|
-
const compiler = context.getCompiler(
|
|
292
|
-
const watchContext = context.getValue(
|
|
291
|
+
const compiler = context.getCompiler();
|
|
292
|
+
const watchContext = context.getValue("watchContext");
|
|
293
293
|
const stepName = watchContext?.step;
|
|
294
294
|
const statsGetter = (() => {
|
|
295
295
|
const cached = {};
|
|
@@ -306,9 +306,9 @@ function cachedWatchStats(context, name) {
|
|
|
306
306
|
return statsGetter;
|
|
307
307
|
}
|
|
308
308
|
function createWatchRunner(context, name, file, env) {
|
|
309
|
-
const compiler = context.getCompiler(
|
|
309
|
+
const compiler = context.getCompiler();
|
|
310
310
|
const compilerOptions = compiler.getOptions();
|
|
311
|
-
const watchContext = context.getValue(
|
|
311
|
+
const watchContext = context.getValue("watchContext");
|
|
312
312
|
const stepName = watchContext?.step;
|
|
313
313
|
if (!stepName) {
|
|
314
314
|
throw new Error("Can not get watch step name from context");
|
package/dist/compiler.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import EventEmitter from "node:events";
|
|
2
|
-
import
|
|
3
|
-
import type { ITestCompilerManager } from "./type";
|
|
2
|
+
import { Compiler, type RspackOptions, type Stats } from "@rspack/core";
|
|
3
|
+
import type { ITestCompilerManager, ITestContext } from "./type";
|
|
4
4
|
export declare enum ECompilerEvent {
|
|
5
5
|
Build = "build",
|
|
6
6
|
Option = "option",
|
|
@@ -8,11 +8,12 @@ export declare enum ECompilerEvent {
|
|
|
8
8
|
Close = "close"
|
|
9
9
|
}
|
|
10
10
|
export declare class TestCompilerManager implements ITestCompilerManager {
|
|
11
|
+
protected context: ITestContext;
|
|
11
12
|
protected compilerOptions: RspackOptions;
|
|
12
13
|
protected compilerInstance: Compiler | null;
|
|
13
14
|
protected compilerStats: Stats | null;
|
|
14
15
|
protected emitter: EventEmitter;
|
|
15
|
-
constructor();
|
|
16
|
+
constructor(context: ITestContext);
|
|
16
17
|
getOptions(): RspackOptions;
|
|
17
18
|
setOptions(newOptions: RspackOptions): RspackOptions;
|
|
18
19
|
mergeOptions(newOptions: RspackOptions): RspackOptions;
|
package/dist/compiler.js
CHANGED
|
@@ -5,7 +5,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.TestCompilerManager = exports.ECompilerEvent = void 0;
|
|
7
7
|
const node_events_1 = __importDefault(require("node:events"));
|
|
8
|
+
const core_1 = require("@rspack/core");
|
|
8
9
|
const webpack_merge_1 = __importDefault(require("webpack-merge"));
|
|
10
|
+
const debug_1 = require("./test/debug");
|
|
9
11
|
var ECompilerEvent;
|
|
10
12
|
(function (ECompilerEvent) {
|
|
11
13
|
ECompilerEvent["Build"] = "build";
|
|
@@ -14,7 +16,8 @@ var ECompilerEvent;
|
|
|
14
16
|
ECompilerEvent["Close"] = "close";
|
|
15
17
|
})(ECompilerEvent || (exports.ECompilerEvent = ECompilerEvent = {}));
|
|
16
18
|
class TestCompilerManager {
|
|
17
|
-
constructor() {
|
|
19
|
+
constructor(context) {
|
|
20
|
+
this.context = context;
|
|
18
21
|
this.compilerOptions = {};
|
|
19
22
|
this.compilerInstance = null;
|
|
20
23
|
this.compilerStats = null;
|
|
@@ -38,11 +41,57 @@ class TestCompilerManager {
|
|
|
38
41
|
}
|
|
39
42
|
createCompiler() {
|
|
40
43
|
this.compilerInstance = require("@rspack/core")(this.compilerOptions);
|
|
44
|
+
if (__DEBUG__) {
|
|
45
|
+
const context = this.context;
|
|
46
|
+
this.compilerInstance = new Proxy(this.compilerInstance, {
|
|
47
|
+
get(target, p, receiver) {
|
|
48
|
+
const value = Reflect.get(target, p, receiver);
|
|
49
|
+
if (typeof value === "function" &&
|
|
50
|
+
core_1.Compiler.prototype.hasOwnProperty(p)) {
|
|
51
|
+
return value.bind(target);
|
|
52
|
+
}
|
|
53
|
+
return value;
|
|
54
|
+
},
|
|
55
|
+
set(target, p, value, receiver) {
|
|
56
|
+
const debugSetProperties = context.getValue(debug_1.DEBUG_SCOPES.CreateCompilerSetProperties) || [];
|
|
57
|
+
debugSetProperties.push(`${p} ${new Error().stack?.split("\n")[2]?.trim()}`);
|
|
58
|
+
context.setValue(debug_1.DEBUG_SCOPES.CreateCompilerSetProperties, debugSetProperties);
|
|
59
|
+
return Reflect.set(target, p, value, receiver);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
this.context.setValue(debug_1.DEBUG_SCOPES.CreateCompilerInstance, {
|
|
63
|
+
path: require.resolve("@rspack/core"),
|
|
64
|
+
mode: "no-callback"
|
|
65
|
+
});
|
|
66
|
+
}
|
|
41
67
|
this.emitter.emit(ECompilerEvent.Create, this.compilerInstance);
|
|
42
68
|
return this.compilerInstance;
|
|
43
69
|
}
|
|
44
70
|
createCompilerWithCallback(callback) {
|
|
45
71
|
this.compilerInstance = require("@rspack/core")(this.compilerOptions, callback);
|
|
72
|
+
if (__DEBUG__) {
|
|
73
|
+
const context = this.context;
|
|
74
|
+
this.compilerInstance = new Proxy(this.compilerInstance, {
|
|
75
|
+
get(target, p, receiver) {
|
|
76
|
+
const value = Reflect.get(target, p, receiver);
|
|
77
|
+
if (typeof value === "function" &&
|
|
78
|
+
core_1.Compiler.prototype.hasOwnProperty(p)) {
|
|
79
|
+
return value.bind(target);
|
|
80
|
+
}
|
|
81
|
+
return value;
|
|
82
|
+
},
|
|
83
|
+
set(target, p, value, receiver) {
|
|
84
|
+
const debugSetProperties = context.getValue(debug_1.DEBUG_SCOPES.CreateCompilerSetProperties) || [];
|
|
85
|
+
debugSetProperties.push(`${p} ${new Error().stack?.split("\n")[2]?.trim()}`);
|
|
86
|
+
context.setValue(debug_1.DEBUG_SCOPES.CreateCompilerSetProperties, debugSetProperties);
|
|
87
|
+
return Reflect.set(target, p, value, receiver);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
this.context.setValue(debug_1.DEBUG_SCOPES.CreateCompilerInstance, {
|
|
91
|
+
path: require.resolve("@rspack/core"),
|
|
92
|
+
mode: "callback"
|
|
93
|
+
});
|
|
94
|
+
}
|
|
46
95
|
this.emitter.emit(ECompilerEvent.Create, this.compilerInstance);
|
|
47
96
|
return this.compilerInstance;
|
|
48
97
|
}
|
|
@@ -51,11 +100,39 @@ class TestCompilerManager {
|
|
|
51
100
|
throw new Error("Compiler should be created before build");
|
|
52
101
|
return new Promise((resolve, reject) => {
|
|
53
102
|
try {
|
|
103
|
+
const context = this.context;
|
|
104
|
+
if (__DEBUG__) {
|
|
105
|
+
context.setValue(debug_1.DEBUG_SCOPES.BuildMethod, {
|
|
106
|
+
method: "run"
|
|
107
|
+
});
|
|
108
|
+
}
|
|
54
109
|
this.compilerInstance.run((error, newStats) => {
|
|
55
110
|
this.emitter.emit(ECompilerEvent.Build, error, newStats);
|
|
56
|
-
if (error)
|
|
111
|
+
if (error) {
|
|
112
|
+
if (__DEBUG__) {
|
|
113
|
+
context.setValue(debug_1.DEBUG_SCOPES.BuildError, {
|
|
114
|
+
type: "fatal",
|
|
115
|
+
errors: [error]
|
|
116
|
+
});
|
|
117
|
+
}
|
|
57
118
|
return reject(error);
|
|
119
|
+
}
|
|
58
120
|
this.compilerStats = newStats;
|
|
121
|
+
if (__DEBUG__) {
|
|
122
|
+
if (newStats?.hasErrors()) {
|
|
123
|
+
context.setValue(debug_1.DEBUG_SCOPES.BuildError, {
|
|
124
|
+
type: "stats",
|
|
125
|
+
errors: newStats.toJson({
|
|
126
|
+
errors: true
|
|
127
|
+
}).errors || []
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
if (newStats?.hasWarnings()) {
|
|
131
|
+
context.setValue(debug_1.DEBUG_SCOPES.BuildWarning, newStats.toJson({
|
|
132
|
+
warnings: true
|
|
133
|
+
}).warnings || []);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
59
136
|
resolve(newStats);
|
|
60
137
|
});
|
|
61
138
|
}
|
|
@@ -67,7 +144,8 @@ class TestCompilerManager {
|
|
|
67
144
|
watch(timeout = 1000) {
|
|
68
145
|
if (!this.compilerInstance)
|
|
69
146
|
throw new Error("Compiler should be created before watch");
|
|
70
|
-
this.
|
|
147
|
+
const context = this.context;
|
|
148
|
+
const watchOptions = {
|
|
71
149
|
// IMPORTANT:
|
|
72
150
|
// This is a workaround for the issue that watchpack cannot detect the file change in time
|
|
73
151
|
// so we set the poll to 300ms to make it more sensitive to the file change
|
|
@@ -76,11 +154,40 @@ class TestCompilerManager {
|
|
|
76
154
|
// want to watch all files, which aligns with webpack's default behavior
|
|
77
155
|
ignored: [],
|
|
78
156
|
aggregateTimeout: timeout
|
|
79
|
-
}
|
|
157
|
+
};
|
|
158
|
+
if (__DEBUG__) {
|
|
159
|
+
context.setValue(debug_1.DEBUG_SCOPES.BuildMethod, {
|
|
160
|
+
method: "watch",
|
|
161
|
+
options: watchOptions
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
this.compilerInstance.watch(watchOptions, (error, newStats) => {
|
|
80
165
|
this.emitter.emit(ECompilerEvent.Build, error, newStats);
|
|
81
|
-
if (
|
|
82
|
-
|
|
166
|
+
if (__DEBUG__) {
|
|
167
|
+
if (error) {
|
|
168
|
+
context.setValue(debug_1.DEBUG_SCOPES.BuildError, {
|
|
169
|
+
type: "fatal",
|
|
170
|
+
errors: [error]
|
|
171
|
+
});
|
|
172
|
+
return error;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
83
175
|
if (newStats) {
|
|
176
|
+
if (__DEBUG__) {
|
|
177
|
+
if (newStats.hasErrors()) {
|
|
178
|
+
context.setValue(debug_1.DEBUG_SCOPES.BuildError, {
|
|
179
|
+
type: "stats",
|
|
180
|
+
errors: newStats.toJson({
|
|
181
|
+
errors: true
|
|
182
|
+
}).errors || []
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
if (newStats.hasWarnings()) {
|
|
186
|
+
context.setValue(debug_1.DEBUG_SCOPES.BuildWarning, newStats.toJson({
|
|
187
|
+
warnings: true
|
|
188
|
+
}).warnings || []);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
84
191
|
this.compilerStats = newStats;
|
|
85
192
|
}
|
|
86
193
|
return newStats;
|
package/dist/helper/index.d.ts
CHANGED
package/dist/helper/index.js
CHANGED
|
@@ -18,6 +18,7 @@ __exportStar(require("./directory"), exports);
|
|
|
18
18
|
__exportStar(require("./is"), exports);
|
|
19
19
|
__exportStar(require("./parse-modules"), exports);
|
|
20
20
|
__exportStar(require("./read-config-file"), exports);
|
|
21
|
+
__exportStar(require("./stringify-config"), exports);
|
|
21
22
|
__exportStar(require("./update-snapshot"), exports);
|
|
22
23
|
__exportStar(require("./util/checkStats"), exports);
|
|
23
24
|
__exportStar(require("./win"), exports);
|
|
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.readConfigFile = readConfigFile;
|
|
7
7
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
8
|
+
const debug_1 = require("../test/debug");
|
|
8
9
|
function readConfigFile(files, context, prevOption, functionApply) {
|
|
9
10
|
const existsFile = files.find(i => fs_extra_1.default.existsSync(i));
|
|
10
11
|
let fileConfig = existsFile ? require(existsFile) : {};
|
|
@@ -12,5 +13,11 @@ function readConfigFile(files, context, prevOption, functionApply) {
|
|
|
12
13
|
fileConfig = fileConfig({ config: prevOption }, { testPath: context.getDist(), tempPath: context.getTemp() });
|
|
13
14
|
}
|
|
14
15
|
const configArr = Array.isArray(fileConfig) ? fileConfig : [fileConfig];
|
|
16
|
+
if (existsFile) {
|
|
17
|
+
context.setValue(debug_1.DEBUG_SCOPES.CompilerOptionsReadConfigFile, {
|
|
18
|
+
file: existsFile,
|
|
19
|
+
config: fileConfig
|
|
20
|
+
});
|
|
21
|
+
}
|
|
15
22
|
return functionApply ? functionApply(configArr) : configArr;
|
|
16
23
|
}
|
package/dist/helper/setup-env.js
CHANGED
|
@@ -16,6 +16,7 @@ if (process.env.RSTEST) {
|
|
|
16
16
|
global.__ROOT_PATH__ ??= process.env.__ROOT_PATH__;
|
|
17
17
|
global.__RSPACK_PATH__ ??= process.env.__RSPACK_PATH__;
|
|
18
18
|
global.__RSPACK_TEST_TOOLS_PATH__ ??= process.env.__RSPACK_TEST_TOOLS_PATH__;
|
|
19
|
+
global.__DEBUG__ ??= process.env.DEBUG === "test";
|
|
19
20
|
}
|
|
20
21
|
else {
|
|
21
22
|
// Compatible with wasm tests (lazyTestEnv)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = stringifyConfig;
|
|
4
|
+
const javascript_stringify_1 = require("javascript-stringify");
|
|
5
|
+
function stringifyConfig(config, verbose = false) {
|
|
6
|
+
return (0, javascript_stringify_1.stringify)(config, (value, indent, stringify) => {
|
|
7
|
+
// improve plugin output
|
|
8
|
+
if (value?.__pluginName) {
|
|
9
|
+
const prefix = `/* config.${value.__pluginType}('${value.__pluginName}') */\n`;
|
|
10
|
+
const constructorExpression = value.__pluginPath
|
|
11
|
+
? // The path is stringified to ensure special characters are escaped
|
|
12
|
+
// (such as the backslashes in Windows-style paths).
|
|
13
|
+
`(require(${stringify(value.__pluginPath)}))`
|
|
14
|
+
: value.__pluginConstructorName;
|
|
15
|
+
if (constructorExpression) {
|
|
16
|
+
// get correct indentation for args by stringifying the args array and
|
|
17
|
+
// discarding the square brackets.
|
|
18
|
+
const args = stringify(value.__pluginArgs)?.slice(1, -1);
|
|
19
|
+
return `${prefix}new ${constructorExpression}(${args})`;
|
|
20
|
+
}
|
|
21
|
+
return (prefix +
|
|
22
|
+
stringify(value.__pluginArgs?.length ? { args: value.__pluginArgs } : {}));
|
|
23
|
+
}
|
|
24
|
+
// improve rule/use output
|
|
25
|
+
if (value?.__ruleNames) {
|
|
26
|
+
const ruleTypes = value.__ruleTypes;
|
|
27
|
+
const prefix = `/* config.module${value.__ruleNames
|
|
28
|
+
.map((r, index) => `.${ruleTypes ? ruleTypes[index] : "rule"}('${r}')`)
|
|
29
|
+
.join("")}${value.__useName ? `.use('${value.__useName}')` : ``} */\n`;
|
|
30
|
+
return prefix + stringify(value);
|
|
31
|
+
}
|
|
32
|
+
if (value?.__expression) {
|
|
33
|
+
return value.__expression;
|
|
34
|
+
}
|
|
35
|
+
// shorten long functions
|
|
36
|
+
if (typeof value === "function") {
|
|
37
|
+
if (!verbose && value.toString().length > 100) {
|
|
38
|
+
return `function () { /* omitted long function */ }`;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return stringify(value);
|
|
42
|
+
}, 2);
|
|
43
|
+
}
|
|
@@ -13,6 +13,8 @@ export interface INodeRunnerOptions {
|
|
|
13
13
|
dist: string;
|
|
14
14
|
compilerOptions: RspackOptions;
|
|
15
15
|
cachable?: boolean;
|
|
16
|
+
logs?: string[];
|
|
17
|
+
errors?: Error[];
|
|
16
18
|
}
|
|
17
19
|
export declare class NodeRunner implements ITestRunner {
|
|
18
20
|
protected _options: INodeRunnerOptions;
|
|
@@ -21,6 +23,7 @@ export declare class NodeRunner implements ITestRunner {
|
|
|
21
23
|
protected baseModuleScope: IModuleScope | null;
|
|
22
24
|
protected requirers: Map<string, TRunnerRequirer>;
|
|
23
25
|
constructor(_options: INodeRunnerOptions);
|
|
26
|
+
protected log(message: string): void;
|
|
24
27
|
run(file: string): Promise<unknown>;
|
|
25
28
|
getRequire(): TRunnerRequirer;
|
|
26
29
|
getGlobal(name: string): unknown;
|
|
@@ -36,3 +39,4 @@ export declare class NodeRunner implements ITestRunner {
|
|
|
36
39
|
protected createCjsRequirer(): TRunnerRequirer;
|
|
37
40
|
protected createEsmRequirer(): TRunnerRequirer;
|
|
38
41
|
}
|
|
42
|
+
export declare const createLocatedError: (collectedErrors: Error[], offset: number) => (e: Error, file: TRunnerFile) => Error;
|
|
@@ -36,7 +36,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
36
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.NodeRunner = void 0;
|
|
39
|
+
exports.createLocatedError = exports.NodeRunner = void 0;
|
|
40
40
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
41
41
|
const node_path_1 = __importDefault(require("node:path"));
|
|
42
42
|
const node_url_1 = require("node:url");
|
|
@@ -45,6 +45,7 @@ const asModule_1 = __importDefault(require("../../helper/legacy/asModule"));
|
|
|
45
45
|
const createFakeWorker_1 = __importDefault(require("../../helper/legacy/createFakeWorker"));
|
|
46
46
|
const urlToRelativePath_1 = __importDefault(require("../../helper/legacy/urlToRelativePath"));
|
|
47
47
|
const type_1 = require("../../type");
|
|
48
|
+
const EVAL_LOCATION_REGEX = /<anonymous>:(\d+)/;
|
|
48
49
|
const isRelativePath = (p) => /^\.\.?\//.test(p);
|
|
49
50
|
const getSubPath = (p) => {
|
|
50
51
|
const lastSlash = p.lastIndexOf("/");
|
|
@@ -72,6 +73,9 @@ class NodeRunner {
|
|
|
72
73
|
this.baseModuleScope = null;
|
|
73
74
|
this.requirers = new Map();
|
|
74
75
|
}
|
|
76
|
+
log(message) {
|
|
77
|
+
this._options.logs?.push(`[NodeRunner] ${message}`);
|
|
78
|
+
}
|
|
75
79
|
run(file) {
|
|
76
80
|
if (!this.globalContext) {
|
|
77
81
|
this.globalContext = this.createGlobalContext();
|
|
@@ -93,7 +97,15 @@ class NodeRunner {
|
|
|
93
97
|
}
|
|
94
98
|
getRequire() {
|
|
95
99
|
const entryRequire = this.requirers.get("entry");
|
|
96
|
-
|
|
100
|
+
const runner = this;
|
|
101
|
+
return function (currentDirectory, modulePath, context = {}) {
|
|
102
|
+
const from = this?.from;
|
|
103
|
+
if (from) {
|
|
104
|
+
runner.log(`require: ${modulePath} from ${from}`);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
runner.log(`require: ${modulePath}`);
|
|
108
|
+
}
|
|
97
109
|
const p = Array.isArray(modulePath)
|
|
98
110
|
? modulePath
|
|
99
111
|
: modulePath.split("?")[0];
|
|
@@ -177,7 +189,10 @@ class NodeRunner {
|
|
|
177
189
|
return baseModuleScope;
|
|
178
190
|
}
|
|
179
191
|
createModuleScope(requireFn, m, file) {
|
|
180
|
-
const requirer = requireFn.bind(
|
|
192
|
+
const requirer = requireFn.bind({
|
|
193
|
+
from: file.path,
|
|
194
|
+
module: m
|
|
195
|
+
}, node_path_1.default.dirname(file.path));
|
|
181
196
|
requirer.webpackTestSuiteRequire = true;
|
|
182
197
|
return {
|
|
183
198
|
...this.baseModuleScope,
|
|
@@ -246,6 +261,7 @@ class NodeRunner {
|
|
|
246
261
|
this.requirers.set("json", this.createJsonRequirer());
|
|
247
262
|
this.requirers.set("entry", (currentDirectory, modulePath, context) => {
|
|
248
263
|
const file = this.getFile(modulePath, currentDirectory);
|
|
264
|
+
this.log(`entry: ${modulePath} -> ${file?.path}`);
|
|
249
265
|
if (!file) {
|
|
250
266
|
return this.requirers.get("miss")(currentDirectory, modulePath);
|
|
251
267
|
}
|
|
@@ -270,11 +286,14 @@ class NodeRunner {
|
|
|
270
286
|
}
|
|
271
287
|
createMissRequirer() {
|
|
272
288
|
return (currentDirectory, modulePath, context = {}) => {
|
|
289
|
+
this.log(`missing: ${modulePath}`);
|
|
273
290
|
const modulePathStr = modulePath;
|
|
274
291
|
const modules = this._options.testConfig.modules;
|
|
275
292
|
if (modules && modulePathStr in modules) {
|
|
293
|
+
this.log(`mock module: ${modulePathStr}`);
|
|
276
294
|
return modules[modulePathStr];
|
|
277
295
|
}
|
|
296
|
+
this.log(`native require: ${modulePathStr}`);
|
|
278
297
|
return require(modulePathStr.startsWith("node:")
|
|
279
298
|
? modulePathStr.slice(5)
|
|
280
299
|
: modulePathStr);
|
|
@@ -286,6 +305,7 @@ class NodeRunner {
|
|
|
286
305
|
throw new Error("Array module path is not supported in hot cases");
|
|
287
306
|
}
|
|
288
307
|
const file = context.file || this.getFile(modulePath, currentDirectory);
|
|
308
|
+
this.log(`json: ${modulePath} -> ${file?.path}`);
|
|
289
309
|
if (!file) {
|
|
290
310
|
return this.requirers.get("miss")(currentDirectory, modulePath);
|
|
291
311
|
}
|
|
@@ -298,10 +318,12 @@ class NodeRunner {
|
|
|
298
318
|
return require("@rspack/test-tools");
|
|
299
319
|
}
|
|
300
320
|
const file = context.file || this.getFile(modulePath, currentDirectory);
|
|
321
|
+
this.log(`cjs: ${modulePath} -> ${file?.path}`);
|
|
301
322
|
if (!file) {
|
|
302
323
|
return this.requirers.get("miss")(currentDirectory, modulePath);
|
|
303
324
|
}
|
|
304
325
|
if (file.path in this.requireCache) {
|
|
326
|
+
this.log(`cjs cache hit: ${file.path}`);
|
|
305
327
|
return this.requireCache[file.path].exports;
|
|
306
328
|
}
|
|
307
329
|
const m = {
|
|
@@ -325,19 +347,45 @@ class NodeRunner {
|
|
|
325
347
|
currentModuleScope.__STATS_I__ = statsIndex;
|
|
326
348
|
}
|
|
327
349
|
}
|
|
350
|
+
const createNodeLocatedError = (0, exports.createLocatedError)(this._options.errors || [], 2);
|
|
351
|
+
const originIt = currentModuleScope.it;
|
|
352
|
+
currentModuleScope.it = (description, fn) => {
|
|
353
|
+
originIt(description, async () => {
|
|
354
|
+
try {
|
|
355
|
+
await fn();
|
|
356
|
+
}
|
|
357
|
+
catch (err) {
|
|
358
|
+
throw createNodeLocatedError(err, file);
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
};
|
|
362
|
+
currentModuleScope.__CREATE_LOCATED_ERROR__ = createNodeLocatedError;
|
|
363
|
+
currentModuleScope.__FILE__ = file;
|
|
328
364
|
const args = Object.keys(currentModuleScope);
|
|
329
365
|
const argValues = args.map(arg => currentModuleScope[arg]);
|
|
330
366
|
const code = `(function(${args.join(", ")}) {
|
|
331
|
-
|
|
367
|
+
try {
|
|
368
|
+
${file.content}
|
|
369
|
+
} catch(err) {
|
|
370
|
+
throw __CREATE_LOCATED_ERROR__(err, __FILE__);
|
|
371
|
+
}
|
|
332
372
|
})`;
|
|
333
373
|
this.preExecute(code, file);
|
|
374
|
+
this.log(`run mode: ${this._options.runInNewContext ? "new context" : "this context"}`);
|
|
334
375
|
const fn = this._options.runInNewContext
|
|
335
|
-
? node_vm_1.default.runInNewContext(code, this.globalContext,
|
|
336
|
-
|
|
376
|
+
? node_vm_1.default.runInNewContext(code, this.globalContext, {
|
|
377
|
+
filename: file.path,
|
|
378
|
+
lineOffset: 1
|
|
379
|
+
})
|
|
380
|
+
: node_vm_1.default.runInThisContext(code, {
|
|
381
|
+
filename: file.path,
|
|
382
|
+
lineOffset: 1
|
|
383
|
+
});
|
|
337
384
|
fn.call(this._options.testConfig.nonEsmThis
|
|
338
385
|
? this._options.testConfig.nonEsmThis(modulePath)
|
|
339
386
|
: m.exports, ...argValues);
|
|
340
387
|
this.postExecute(m, file);
|
|
388
|
+
this.log(`end cjs: ${modulePath}`);
|
|
341
389
|
return m.exports;
|
|
342
390
|
};
|
|
343
391
|
}
|
|
@@ -353,6 +401,7 @@ class NodeRunner {
|
|
|
353
401
|
}
|
|
354
402
|
const _require = this.getRequire();
|
|
355
403
|
const file = context.file || this.getFile(modulePath, currentDirectory);
|
|
404
|
+
this.log(`esm: ${modulePath} -> ${file?.path}`);
|
|
356
405
|
if (!file) {
|
|
357
406
|
return this.requirers.get("miss")(currentDirectory, modulePath);
|
|
358
407
|
}
|
|
@@ -378,6 +427,7 @@ class NodeRunner {
|
|
|
378
427
|
meta.filename = file.path;
|
|
379
428
|
},
|
|
380
429
|
importModuleDynamically: async (specifier, module) => {
|
|
430
|
+
this.log(`import: ${specifier} from ${file?.path}`);
|
|
381
431
|
const result = await _require(node_path_1.default.dirname(file.path), specifier, {
|
|
382
432
|
esmMode: type_1.EEsmMode.Evaluated
|
|
383
433
|
});
|
|
@@ -403,9 +453,36 @@ class NodeRunner {
|
|
|
403
453
|
return esm;
|
|
404
454
|
}
|
|
405
455
|
const ns = esm.namespace;
|
|
456
|
+
this.log(`end esm: ${modulePath}`);
|
|
406
457
|
return ns.default && ns.default instanceof Promise ? ns.default : ns;
|
|
407
458
|
})();
|
|
408
459
|
};
|
|
409
460
|
}
|
|
410
461
|
}
|
|
411
462
|
exports.NodeRunner = NodeRunner;
|
|
463
|
+
const createLocatedError = (collectedErrors, offset) => {
|
|
464
|
+
return (e, file) => {
|
|
465
|
+
const match = (e.stack || e.message).match(EVAL_LOCATION_REGEX);
|
|
466
|
+
if (match) {
|
|
467
|
+
const [, line] = match;
|
|
468
|
+
const realLine = Number(line) - offset;
|
|
469
|
+
const codeLines = file.content.split("\n");
|
|
470
|
+
const lineContents = [
|
|
471
|
+
...codeLines
|
|
472
|
+
.slice(Math.max(0, realLine - 3), Math.max(0, realLine - 1))
|
|
473
|
+
.map(line => `│ ${line}`),
|
|
474
|
+
`│> ${codeLines[realLine - 1]}`,
|
|
475
|
+
...codeLines.slice(realLine, realLine + 2).map(line => `│ ${line}`)
|
|
476
|
+
];
|
|
477
|
+
const message = `Error in JSDOM when running file '${file.path}' at line ${realLine}: ${e.message}\n${lineContents.join("\n")}`;
|
|
478
|
+
const finalError = new Error(message);
|
|
479
|
+
finalError.stack = undefined;
|
|
480
|
+
collectedErrors.push(finalError);
|
|
481
|
+
return finalError;
|
|
482
|
+
}
|
|
483
|
+
else {
|
|
484
|
+
return e;
|
|
485
|
+
}
|
|
486
|
+
};
|
|
487
|
+
};
|
|
488
|
+
exports.createLocatedError = createLocatedError;
|
|
@@ -9,6 +9,7 @@ export declare class WebRunner extends NodeRunner {
|
|
|
9
9
|
constructor(_webOptions: IWebRunnerOptions);
|
|
10
10
|
run(file: string): Promise<unknown>;
|
|
11
11
|
getGlobal(name: string): unknown;
|
|
12
|
+
protected log(message: string): void;
|
|
12
13
|
protected createResourceLoader(): {
|
|
13
14
|
fetch(url: string, _: {
|
|
14
15
|
element: HTMLScriptElement;
|