Skip to content

Commit e2f02f1

Browse files
authored
test: custom resource loader of test cases (#12091)
1 parent 9491c3a commit e2f02f1

File tree

13 files changed

+101
-25
lines changed

13 files changed

+101
-25
lines changed

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ export function createHotNormalCase(name: string, src: string, dist: string): vo
104104
// @public (undocumented)
105105
export function createHotStepCase(name: string, src: string, dist: string, temp: string, target: RspackOptions["target"]): void;
106106

107+
// @public (undocumented)
108+
export const createLocatedError: (collectedErrors: Error[], offset: number) => (e: Error, file: TRunnerFile) => Error;
109+
107110
// @public (undocumented)
108111
export function createMultiCompilerCase(name: string, src: string, dist: string, testConfig: string): void;
109112

@@ -779,6 +782,7 @@ export type TTestConfig = {
779782
esmLibPluginOptions?: {
780783
preserveModules?: string;
781784
};
785+
resourceLoader?: (url: string, element: HTMLScriptElement) => Buffer | null;
782786
};
783787

784788
// @public (undocumented)
@@ -810,7 +814,7 @@ export class WebRunner extends NodeRunner {
810814
protected createJSDOMRequirer(): TRunnerRequirer;
811815
// (undocumented)
812816
protected createResourceLoader(): {
813-
fetch(url: string, _: {
817+
fetch(url: string, options: {
814818
element: HTMLScriptElement;
815819
}): any;
816820
};

packages/rspack-test-tools/src/runner/web/index.ts

Lines changed: 73 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,25 @@ export class WebRunner extends NodeRunner {
103103
protected createResourceLoader() {
104104
const that = this;
105105
class CustomResourceLoader extends ResourceLoader {
106-
fetch(url: string, _: { element: HTMLScriptElement }) {
106+
fetch(url: string, options: { element: HTMLScriptElement }) {
107+
if (that._options.testConfig.resourceLoader) {
108+
that.log(`resource custom loader: start ${url}`);
109+
const content = that._options.testConfig.resourceLoader(
110+
url,
111+
options.element
112+
);
113+
if (content !== undefined) {
114+
that.log(`resource custom loader: accepted`);
115+
return Promise.resolve(content) as any;
116+
} else {
117+
that.log(`resource custom loader: not found`);
118+
}
119+
}
120+
107121
const filePath = that.urlToPath(url);
108122
that.log(`resource loader: ${url} -> ${filePath}`);
109123
let finalCode: string | Buffer | void;
124+
110125
if (path.extname(filePath) === ".js") {
111126
const currentDirectory = path.dirname(filePath);
112127
const file = that.getFile(filePath, currentDirectory);
@@ -274,6 +289,26 @@ export class WebRunner extends NodeRunner {
274289
}
275290
});`;
276291

292+
const proxyLines = proxyCode.split("\n");
293+
294+
const locatedError = createLocatedError(
295+
this._options.errors || [],
296+
proxyLines.length + 1
297+
);
298+
const originIt = currentModuleScope.it;
299+
currentModuleScope.it = (
300+
description: string,
301+
fn: (...args: any[]) => Promise<void>
302+
) => {
303+
return originIt(description, async (...args: any[]) => {
304+
try {
305+
return await fn(...args);
306+
} catch (e) {
307+
throw locatedError(e as Error, file);
308+
}
309+
});
310+
};
311+
277312
const scopeKey = escapeSep(file!.path);
278313
const args = Object.keys(currentModuleScope).filter(
279314
arg => !["window", "self", "globalThis", "console"].includes(arg)
@@ -283,14 +318,18 @@ export class WebRunner extends NodeRunner {
283318
.join(", ");
284319
this.dom.window[scopeKey] = currentModuleScope;
285320
this.dom.window["__GLOBAL_SHARED__"] = this.globalContext;
321+
this.dom.window["__LOCATED_ERROR__"] = locatedError;
322+
this.dom.window["__FILE__"] = file;
286323

287324
return [
288325
m,
289326
`${proxyCode}
290-
(function(window, self, globalThis, console, ${args.join(", ")}) {
327+
(function(window, self, globalThis, console, ${args.join(", ")}) { try {
291328
${file.content}
292-
})($$g$$, $$self$$, $$g$$, window["console"], ${argValues});`,
293-
proxyCode.split("\n").length + 1
329+
} catch (e) {
330+
throw __LOCATED_ERROR__(e, window["__FILE__"]);
331+
}})($$g$$, $$self$$, $$g$$, window["console"], ${argValues});`,
332+
proxyLines.length + 1
294333
];
295334
}
296335

@@ -319,8 +358,9 @@ export class WebRunner extends NodeRunner {
319358
});
320359
} catch (e) {
321360
const error = new Error(
322-
`Parse script '${file.path}' failed: ${(e as Error).message}`
361+
`Parse script '${file.path}' failed:\n${(e as Error).message}`
323362
);
363+
error.stack = `${error.message}\n${(e as Error).stack}`;
324364
this._options.errors?.push(error);
325365
throw error;
326366
}
@@ -337,3 +377,31 @@ export class WebRunner extends NodeRunner {
337377
this.requirers.set("cjs", this.createJSDOMRequirer());
338378
}
339379
}
380+
381+
export const createLocatedError = (
382+
collectedErrors: Error[],
383+
offset: number
384+
) => {
385+
return (e: Error, file: TRunnerFile) => {
386+
const match = (e.stack || e.message).match(/<anonymous>:(\d+)/);
387+
if (match) {
388+
const [, line] = match;
389+
const realLine = Number(line) - offset;
390+
const codeLines = file.content.split("\n");
391+
const lineContents = [
392+
...codeLines
393+
.slice(Math.max(0, realLine - 3), Math.max(0, realLine - 1))
394+
.map(line => `│ ${line}`),
395+
`│> ${codeLines[realLine - 1]}`,
396+
...codeLines.slice(realLine, realLine + 2).map(line => `│ ${line}`)
397+
];
398+
const message = `Error in JSDOM when running file '${file.path}' at line ${realLine}: ${e.message}\n${lineContents.join("\n")}`;
399+
const finalError = new Error(message);
400+
finalError.stack = `${message}\n${e.stack}`;
401+
collectedErrors.push(finalError);
402+
return finalError;
403+
} else {
404+
return e;
405+
}
406+
};
407+
};

packages/rspack-test-tools/src/type.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ export type TTestConfig = {
186186
esmLibPluginOptions?: {
187187
preserveModules?: string;
188188
};
189+
resourceLoader?: (url: string, element: HTMLScriptElement) => Buffer | null;
189190
};
190191

191192
export type TTestFilter = (

tests/rspack-test/configCases/split-chunks/issue-9491/test.filter.js

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
module.exports = () => "FIXME: should be string";
1+
module.exports = () => "TODO: support context module of new URL";
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
module.exports = [[/BREAKING CHANGE/, /experiments\.asyncWebAssembly/]];
1+
module.exports = [[/You may need an appropriate loader to handle this file type/]];

tests/rspack-test/configCases/wasm/missing-wasm-experiment/test.filter.js

Lines changed: 0 additions & 2 deletions
This file was deleted.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module.exports = {
2+
resourceLoader: function (url) {
3+
// ignore /somewhere/else.js
4+
if (/\/somewhere\/else\.js$/.test(url)) {
5+
return null;
6+
}
7+
}
8+
};

tests/rspack-test/configCases/web/attach-existing/test.filter.js

Lines changed: 0 additions & 1 deletion
This file was deleted.

tests/rspack-test/configCases/web/node-source-future-defaults/test.filter.js

Lines changed: 0 additions & 2 deletions
This file was deleted.

0 commit comments

Comments
 (0)