@rspack-canary/test-tools 1.6.0-canary-e3199f44-20251020173943 → 1.6.0-canary-0eb13821-20251021173640

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.
@@ -166,13 +166,14 @@ async function checkSnapshot(env, context, name, snapshot, filter) {
166
166
  if (testConfig.snapshotContent) {
167
167
  content = testConfig.snapshotContent(content);
168
168
  }
169
- return `\`\`\`${tag} title=${file}\n${content}\n\`\`\``;
169
+ const filePath = file.replaceAll(path_1.default.sep, "/");
170
+ return `\`\`\`${tag} title=${filePath}\n${content}\n\`\`\``;
170
171
  });
171
172
  fileContents.sort();
172
173
  const content = fileContents.join("\n\n");
173
174
  const snapshotPath = path_1.default.isAbsolute(snapshot)
174
175
  ? snapshot
175
- : path_1.default.resolve(context.getSource(), `./__snapshots__/${snapshot}${total > 1 ? `-${i}` : ""}`);
176
+ : path_1.default.resolve(context.getSource(), path_1.default.join("__snapshots__", `${snapshot}${total > 1 ? `-${i}` : ""}`));
176
177
  env.expect(content).toMatchFileSnapshot(snapshotPath);
177
178
  }
178
179
  }
@@ -25,7 +25,26 @@ const creator = new creator_1.BasicCaseCreator({
25
25
  steps: ({ name }) => [
26
26
  {
27
27
  config: async (context) => {
28
- (0, common_1.configMultiCompiler)(context, name, ["rspack.config.cjs", "rspack.config.js", "webpack.config.js"], defaultOptions, () => { });
28
+ (0, common_1.configMultiCompiler)(context, name, ["rspack.config.cjs", "rspack.config.js", "webpack.config.js"], defaultOptions, (_index, context, options) => {
29
+ const testConfig = context.getTestConfig();
30
+ if (testConfig.esmLibPluginOptions) {
31
+ let target;
32
+ const otherPlugins = options.plugins?.filter(plugin => {
33
+ const isTarget = plugin instanceof core_1.default.experiments.EsmLibraryPlugin;
34
+ if (isTarget) {
35
+ target = plugin;
36
+ }
37
+ return !isTarget;
38
+ });
39
+ options.plugins = [
40
+ ...otherPlugins,
41
+ new core_1.default.experiments.EsmLibraryPlugin({
42
+ ...target.options,
43
+ ...testConfig.esmLibPluginOptions
44
+ })
45
+ ];
46
+ }
47
+ });
29
48
  },
30
49
  compiler: async (context) => {
31
50
  await (0, common_1.compiler)(context, name);
@@ -34,7 +53,11 @@ const creator = new creator_1.BasicCaseCreator({
34
53
  await (0, common_1.build)(context, name);
35
54
  },
36
55
  run: async (env, context) => {
37
- await (0, common_1.run)(env, context, name, (context) => (0, common_1.findMultiCompilerBundle)(context, name, (_index, _context, options) => {
56
+ await (0, common_1.run)(env, context, name, (context) => (0, common_1.findMultiCompilerBundle)(context, name, (_index, context, options) => {
57
+ const testConfig = context.getTestConfig();
58
+ if (typeof testConfig.findBundle === "function") {
59
+ return testConfig.findBundle(_index, options);
60
+ }
38
61
  if (options.output?.filename === "[name].mjs") {
39
62
  return ["main.mjs"];
40
63
  }
@@ -18,8 +18,6 @@ module.exports = async (something, context, unlinked) => {
18
18
  if (unlinked)
19
19
  return m;
20
20
  await m.link(() => { });
21
- if (m.instantiate)
22
- m.instantiate();
23
21
  await m.evaluate();
24
22
  return m;
25
23
  };
@@ -308,7 +308,7 @@ class NodeRunner {
308
308
  };
309
309
  this.requireCache[file.path] = m;
310
310
  if (!this._options.runInNewContext) {
311
- file.content = `Object.assign(global, _globalAssign);\n ${file.content}`;
311
+ file.content = `Object.assign(global, _globalAssign);${file.content}`;
312
312
  }
313
313
  const currentModuleScope = this.createModuleScope(this.getRequire(), m, file);
314
314
  if (this._options.testConfig.moduleScope) {
@@ -396,8 +396,6 @@ class NodeRunner {
396
396
  }), referencingModule.context, true);
397
397
  });
398
398
  }
399
- if (esm.instantiate)
400
- esm.instantiate();
401
399
  await esm.evaluate();
402
400
  if (context.esmMode === type_1.EEsmMode.Evaluated) {
403
401
  return esm;
@@ -7,11 +7,13 @@ 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");
10
+ const node_vm_1 = require("node:vm");
10
11
  const jsdom_1 = require("jsdom");
11
12
  const helper_1 = require("../../helper");
12
13
  const EventSourceForNode_1 = __importDefault(require("../../helper/legacy/EventSourceForNode"));
13
14
  const urlToRelativePath_1 = __importDefault(require("../../helper/legacy/urlToRelativePath"));
14
15
  const node_1 = require("../node");
16
+ const EVAL_LOCATION_REGEX = /<anonymous>:(\d+)/;
15
17
  // Compatibility code to suppress iconv-lite warnings
16
18
  require("iconv-lite").skipDecodeWarning = true;
17
19
  const FAKE_HOSTS = [
@@ -193,6 +195,39 @@ class WebRunner extends node_1.NodeRunner {
193
195
  currentModuleScope.__STATS_I__ = statsIndex;
194
196
  }
195
197
  }
198
+ const createLocatedError = (e, file) => {
199
+ const match = (e.stack || e.message).match(EVAL_LOCATION_REGEX);
200
+ if (match) {
201
+ const [, line] = match;
202
+ const realLine = Number(line) - 34;
203
+ const codeLines = file.content.split("\n");
204
+ const lineContents = [
205
+ ...codeLines
206
+ .slice(Math.max(0, realLine - 3), Math.max(0, realLine - 1))
207
+ .map(line => `│ ${line}`),
208
+ `│> ${codeLines[realLine - 1]}`,
209
+ ...codeLines.slice(realLine, realLine + 2).map(line => `│ ${line}`)
210
+ ];
211
+ const message = `Error in JSDOM when running file '${file.path}' at line ${realLine}: ${e.message}\n${lineContents.join("\n")}`;
212
+ const finalError = new Error(message);
213
+ finalError.stack = undefined;
214
+ return finalError;
215
+ }
216
+ else {
217
+ return e;
218
+ }
219
+ };
220
+ const originIt = currentModuleScope.it;
221
+ currentModuleScope.it = (description, fn) => {
222
+ originIt(description, async () => {
223
+ try {
224
+ await fn();
225
+ }
226
+ catch (err) {
227
+ throw createLocatedError(err, file);
228
+ }
229
+ });
230
+ };
196
231
  const scopeKey = (0, helper_1.escapeSep)(file.path);
197
232
  const args = Object.keys(currentModuleScope).filter(arg => !["window", "self", "globalThis", "console"].includes(arg));
198
233
  const argValues = args
@@ -200,10 +235,11 @@ class WebRunner extends node_1.NodeRunner {
200
235
  .join(", ");
201
236
  this.dom.window[scopeKey] = currentModuleScope;
202
237
  this.dom.window["__GLOBAL_SHARED__"] = this.globalContext;
238
+ this.dom.window["__FILE__"] = file;
239
+ this.dom.window["__CREATE_LOCATED_ERROR__"] = createLocatedError;
203
240
  return [
204
241
  m,
205
- `
206
- // hijack document.currentScript for auto public path
242
+ `// hijack document.currentScript for auto public path
207
243
  var $$g$$ = new Proxy(window, {
208
244
  get(target, prop, receiver) {
209
245
  if (prop === "document") {
@@ -236,9 +272,12 @@ class WebRunner extends node_1.NodeRunner {
236
272
  }
237
273
  });
238
274
  (function(window, self, globalThis, console, ${args.join(", ")}) {
239
- ${file.content}
240
- })($$g$$, $$self$$, $$g$$, window["console"], ${argValues});
241
- `
275
+ try {
276
+ ${file.content}
277
+ } catch (err) {
278
+ throw __CREATE_LOCATED_ERROR__(err, __FILE__);
279
+ }
280
+ })($$g$$, $$self$$, $$g$$, window["console"], ${argValues});`
242
281
  ];
243
282
  }
244
283
  createJSDOMRequirer() {
@@ -252,7 +291,9 @@ class WebRunner extends node_1.NodeRunner {
252
291
  }
253
292
  const [m, code] = this.getModuleContent(file);
254
293
  this.preExecute(code, file);
255
- this.dom.window.eval(code);
294
+ const script = new node_vm_1.Script(code);
295
+ const vmContext = this.dom.getInternalVMContext();
296
+ script.runInContext(vmContext);
256
297
  this.postExecute(m, file);
257
298
  this.requireCache[file.path] = m;
258
299
  return m.exports;
@@ -217,8 +217,11 @@ class BasicCaseCreator {
217
217
  try {
218
218
  await runFn(fn);
219
219
  }
220
- catch (e) {
221
- throw new Error(`Error: ${description} failed\n${e.stack}`);
220
+ catch (err) {
221
+ const e = err;
222
+ const message = `Error: ${description} failed:\n${e.message}`;
223
+ e.message = message;
224
+ throw e;
222
225
  }
223
226
  for (const after of afterTasks) {
224
227
  await runFn(after);
package/dist/type.d.ts CHANGED
@@ -149,6 +149,9 @@ export type TTestConfig<T extends ECompilerType> = {
149
149
  snapshotContent?(content: string): string;
150
150
  checkSteps?: boolean;
151
151
  ignoreNotFriendlyForIncrementalWarnings?: boolean;
152
+ esmLibPluginOptions?: {
153
+ preserveModules?: string;
154
+ };
152
155
  };
153
156
  export type TTestFilter<T extends ECompilerType> = (creatorConfig: Record<string, unknown>, testConfig: TTestConfig<T>) => boolean | string;
154
157
  export interface ITestRunner {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rspack-canary/test-tools",
3
- "version": "1.6.0-canary-e3199f44-20251020173943",
3
+ "version": "1.6.0-canary-0eb13821-20251021173640",
4
4
  "license": "MIT",
5
5
  "description": "Test tools for rspack",
6
6
  "main": "dist/index.js",
@@ -72,7 +72,7 @@
72
72
  "terser": "5.43.1",
73
73
  "typescript": "^5.9.3",
74
74
  "wast-loader": "^1.14.1",
75
- "@rspack/core": "npm:@rspack-canary/core@1.6.0-canary-e3199f44-20251020173943"
75
+ "@rspack/core": "npm:@rspack-canary/core@1.6.0-canary-0eb13821-20251021173640"
76
76
  },
77
77
  "peerDependencies": {
78
78
  "@rspack/core": ">=1.0.0"