@rspack-canary/test-tools 1.6.1-canary-a0be7ea2-20251104174026 → 1.6.1-canary-61cb132a-20251105091940

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.
@@ -178,6 +178,7 @@ class NodeRunner {
178
178
  Buffer,
179
179
  setImmediate,
180
180
  self: this.globalContext,
181
+ __TEST_PATH__: __TEST_PATH__,
181
182
  __MODE__: this._options.compilerOptions.mode,
182
183
  __SNAPSHOT__: node_path_1.default.join(this._options.source, "__snapshot__"),
183
184
  Worker: (0, createFakeWorker_1.default)(this._options.env, {
@@ -11,7 +11,7 @@ export declare class WebRunner extends NodeRunner {
11
11
  getGlobal(name: string): unknown;
12
12
  protected log(message: string): void;
13
13
  protected createResourceLoader(): {
14
- fetch(url: string, _: {
14
+ fetch(url: string, options: {
15
15
  element: HTMLScriptElement;
16
16
  }): any;
17
17
  };
@@ -27,3 +27,4 @@ export declare class WebRunner extends NodeRunner {
27
27
  protected createJSDOMRequirer(): TRunnerRequirer;
28
28
  protected createRunner(): void;
29
29
  }
30
+ export declare const createLocatedError: (collectedErrors: Error[], offset: number) => (e: Error, file: TRunnerFile) => Error;
@@ -3,7 +3,7 @@ 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.WebRunner = void 0;
6
+ exports.createLocatedError = exports.WebRunner = void 0;
7
7
  const node_fs_1 = __importDefault(require("node:fs"));
8
8
  const node_path_1 = __importDefault(require("node:path"));
9
9
  const node_url_1 = require("node:url");
@@ -90,7 +90,18 @@ class WebRunner extends node_1.NodeRunner {
90
90
  createResourceLoader() {
91
91
  const that = this;
92
92
  class CustomResourceLoader extends jsdom_1.ResourceLoader {
93
- fetch(url, _) {
93
+ fetch(url, options) {
94
+ if (that._options.testConfig.resourceLoader) {
95
+ that.log(`resource custom loader: start ${url}`);
96
+ const content = that._options.testConfig.resourceLoader(url, options.element);
97
+ if (content !== undefined) {
98
+ that.log(`resource custom loader: accepted`);
99
+ return Promise.resolve(content);
100
+ }
101
+ else {
102
+ that.log(`resource custom loader: not found`);
103
+ }
104
+ }
94
105
  const filePath = that.urlToPath(url);
95
106
  that.log(`resource loader: ${url} -> ${filePath}`);
96
107
  let finalCode;
@@ -234,6 +245,19 @@ class WebRunner extends node_1.NodeRunner {
234
245
  return Reflect.set(target, prop, value, receiver);
235
246
  }
236
247
  });`;
248
+ const proxyLines = proxyCode.split("\n");
249
+ const locatedError = (0, exports.createLocatedError)(this._options.errors || [], proxyLines.length + 1);
250
+ const originIt = currentModuleScope.it;
251
+ currentModuleScope.it = (description, fn) => {
252
+ return originIt(description, async (...args) => {
253
+ try {
254
+ return await fn(...args);
255
+ }
256
+ catch (e) {
257
+ throw locatedError(e, file);
258
+ }
259
+ });
260
+ };
237
261
  const scopeKey = (0, helper_1.escapeSep)(file.path);
238
262
  const args = Object.keys(currentModuleScope).filter(arg => !["window", "self", "globalThis", "console"].includes(arg));
239
263
  const argValues = args
@@ -241,13 +265,17 @@ class WebRunner extends node_1.NodeRunner {
241
265
  .join(", ");
242
266
  this.dom.window[scopeKey] = currentModuleScope;
243
267
  this.dom.window["__GLOBAL_SHARED__"] = this.globalContext;
268
+ this.dom.window["__LOCATED_ERROR__"] = locatedError;
269
+ this.dom.window["__FILE__"] = file;
244
270
  return [
245
271
  m,
246
272
  `${proxyCode}
247
- (function(window, self, globalThis, console, ${args.join(", ")}) {
273
+ (function(window, self, globalThis, console, ${args.join(", ")}) { try {
248
274
  ${file.content}
249
- })($$g$$, $$self$$, $$g$$, window["console"], ${argValues});`,
250
- proxyCode.split("\n").length + 1
275
+ } catch (e) {
276
+ throw __LOCATED_ERROR__(e, window["__FILE__"]);
277
+ }})($$g$$, $$self$$, $$g$$, window["console"], ${argValues});`,
278
+ proxyLines.length + 1
251
279
  ];
252
280
  }
253
281
  createJSDOMRequirer() {
@@ -271,7 +299,8 @@ class WebRunner extends node_1.NodeRunner {
271
299
  });
272
300
  }
273
301
  catch (e) {
274
- const error = new Error(`Parse script '${file.path}' failed: ${e.message}`);
302
+ const error = new Error(`Parse script '${file.path}' failed:\n${e.message}`);
303
+ error.stack = `${error.message}\n${e.stack}`;
275
304
  this._options.errors?.push(error);
276
305
  throw error;
277
306
  }
@@ -286,3 +315,29 @@ class WebRunner extends node_1.NodeRunner {
286
315
  }
287
316
  }
288
317
  exports.WebRunner = WebRunner;
318
+ const createLocatedError = (collectedErrors, offset) => {
319
+ return (e, file) => {
320
+ const match = (e.stack || e.message).match(/<anonymous>:(\d+)/);
321
+ if (match) {
322
+ const [, line] = match;
323
+ const realLine = Number(line) - offset;
324
+ const codeLines = file.content.split("\n");
325
+ const lineContents = [
326
+ ...codeLines
327
+ .slice(Math.max(0, realLine - 3), Math.max(0, realLine - 1))
328
+ .map(line => `│ ${line}`),
329
+ `│> ${codeLines[realLine - 1]}`,
330
+ ...codeLines.slice(realLine, realLine + 2).map(line => `│ ${line}`)
331
+ ];
332
+ const message = `Error in JSDOM when running file '${file.path}' at line ${realLine}: ${e.message}\n${lineContents.join("\n")}`;
333
+ const finalError = new Error(message);
334
+ finalError.stack = `${message}\n${e.stack}`;
335
+ collectedErrors.push(finalError);
336
+ return finalError;
337
+ }
338
+ else {
339
+ return e;
340
+ }
341
+ };
342
+ };
343
+ exports.createLocatedError = createLocatedError;
package/dist/type.d.ts CHANGED
@@ -139,6 +139,7 @@ export type TTestConfig = {
139
139
  esmLibPluginOptions?: {
140
140
  preserveModules?: string;
141
141
  };
142
+ resourceLoader?: (url: string, element: HTMLScriptElement) => Buffer | null;
142
143
  };
143
144
  export type TTestFilter = (creatorConfig: Record<string, unknown>, testConfig: TTestConfig) => boolean | string;
144
145
  export interface ITestRunner {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rspack-canary/test-tools",
3
- "version": "1.6.1-canary-a0be7ea2-20251104174026",
3
+ "version": "1.6.1-canary-61cb132a-20251105091940",
4
4
  "license": "MIT",
5
5
  "description": "Test tools for rspack",
6
6
  "main": "dist/index.js",
@@ -68,7 +68,7 @@
68
68
  "@types/jsdom": "^21.1.7",
69
69
  "typescript": "^5.9.3",
70
70
  "wast-loader": "^1.14.1",
71
- "@rspack/core": "npm:@rspack-canary/core@1.6.1-canary-a0be7ea2-20251104174026"
71
+ "@rspack/core": "npm:@rspack-canary/core@1.6.1-canary-61cb132a-20251105091940"
72
72
  },
73
73
  "peerDependencies": {
74
74
  "@rspack/core": ">=1.0.0"