as-test 1.1.1 → 1.1.2

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/lib/src/index.ts CHANGED
@@ -6,7 +6,7 @@ import os from "os";
6
6
  import path from "path";
7
7
  import type { Duplex } from "stream";
8
8
  import { pathToFileURL } from "url";
9
- import { WASI } from "wasi";
9
+ import type { WASI } from "wasi";
10
10
  import { buildWebRunnerClientSource } from "./web-runner/client.js";
11
11
  import { buildWebRunnerHtml } from "./web-runner/html.js";
12
12
  import { buildWebRunnerWorkerSource } from "./web-runner/worker.js";
@@ -45,26 +45,22 @@ export async function instantiate(
45
45
  ): Promise<WebAssembly.Instance> {
46
46
  validateImports(imports, "instantiate");
47
47
 
48
- const wasmPath = process.env.AS_TEST_WASM_PATH;
49
- if (!wasmPath || !wasmPath.length) {
50
- throw new Error(
51
- "AS_TEST_WASM_PATH is not set; as-test must resolve the wasm artifact before launching the runner",
52
- );
53
- }
54
- const target = (process.env.AS_TEST_RUNTIME_TARGET || "bindings") as RuntimeTarget;
48
+ const wasmPath = resolveWasmPath();
49
+ const target = resolveRuntimeTarget();
55
50
  if (target == "wasi") {
56
51
  return instantiateWasiInstance(wasmPath, imports);
57
52
  }
58
53
  if (target == "web") {
59
54
  return instantiateWebInstance(wasmPath, imports);
60
55
  }
61
- const kind = (process.env.AS_TEST_BINDINGS_KIND || "none") as BindingsKind;
56
+ const helperPath = resolveBindingsHelperPath(wasmPath);
57
+ const kind = resolveBindingsKind(helperPath);
62
58
 
63
59
  if (kind == "raw") {
64
- return instantiateRawInstance(wasmPath, imports);
60
+ return instantiateRawInstance(wasmPath, helperPath, imports);
65
61
  }
66
62
  if (kind == "esm") {
67
- return instantiateEsmInstance(wasmPath, imports);
63
+ return instantiateEsmInstance(wasmPath, helperPath, imports);
68
64
  }
69
65
  if (kind == "none") {
70
66
  return instantiateNoBindingsInstance(wasmPath, imports);
@@ -72,6 +68,64 @@ export async function instantiate(
72
68
  throw new Error(`unsupported bindings kind "${kind}"`);
73
69
  }
74
70
 
71
+ function resolveRuntimeTarget(): RuntimeTarget {
72
+ const envTarget = process.env.AS_TEST_RUNTIME_TARGET?.trim();
73
+ if (envTarget == "bindings" || envTarget == "wasi" || envTarget == "web") {
74
+ return envTarget;
75
+ }
76
+ const runnerPath = String(process.argv[1] ?? "");
77
+ if (runnerPath.includes(".wasi.")) return "wasi";
78
+ if (runnerPath.includes(".web.")) return "web";
79
+ return "bindings";
80
+ }
81
+
82
+ function resolveWasmPath(): string {
83
+ const envWasmPath = process.env.AS_TEST_WASM_PATH?.trim();
84
+ if (envWasmPath?.length) {
85
+ return path.resolve(envWasmPath);
86
+ }
87
+ const argWasmPath = process.argv[2]?.trim();
88
+ if (argWasmPath?.length) {
89
+ return path.resolve(argWasmPath);
90
+ }
91
+ const runnerPath = String(process.argv[1] ?? "");
92
+ const runnerName = path.basename(runnerPath || "runner.js");
93
+ throw new Error(
94
+ [
95
+ "No wasm artifact was provided for this runner.",
96
+ "",
97
+ `Direct usage: node .as-test/runners/${runnerName} .as-test/build/<artifact>.wasm`,
98
+ "Managed usage: bunx ast test --mode <mode>",
99
+ "",
100
+ "as-test normally sets AS_TEST_WASM_PATH automatically when it launches the runner.",
101
+ ].join("\n"),
102
+ );
103
+ }
104
+
105
+ function resolveBindingsHelperPath(wasmPath: string): string {
106
+ const envHelperPath = process.env.AS_TEST_HELPER_PATH?.trim();
107
+ if (envHelperPath?.length) {
108
+ return path.resolve(envHelperPath);
109
+ }
110
+ const candidate = wasmPath.replace(/\.wasm$/i, ".js");
111
+ return fs.existsSync(candidate) ? candidate : "";
112
+ }
113
+
114
+ function resolveBindingsKind(helperPath: string): BindingsKind {
115
+ const envKind = process.env.AS_TEST_BINDINGS_KIND?.trim();
116
+ if (envKind == "raw" || envKind == "esm" || envKind == "none") {
117
+ return envKind;
118
+ }
119
+ if (!helperPath.length) {
120
+ return "none";
121
+ }
122
+ const source = fs.readFileSync(helperPath, "utf8");
123
+ if (/\bexport\s+(?:async\s+)?function\s+instantiate\b/.test(source)) {
124
+ return "raw";
125
+ }
126
+ return "esm";
127
+ }
128
+
75
129
  function validateImports(
76
130
  imports: WebAssembly.Imports,
77
131
  fnName: string,
@@ -173,16 +227,18 @@ function mergeImports(...groups: unknown[]): AnyImports {
173
227
 
174
228
  async function instantiateRawInstance(
175
229
  wasmPath: string,
230
+ helperPath: string,
176
231
  imports: WebAssembly.Imports,
177
232
  ): Promise<WebAssembly.Instance> {
178
233
  validateImports(imports, "instantiateRawInstance");
179
- const helperPath = process.env.AS_TEST_HELPER_PATH || "";
180
234
  if (!helperPath.length) {
181
235
  throw new Error("bindings kind is raw but AS_TEST_HELPER_PATH is not set");
182
236
  }
183
237
  const binary = fs.readFileSync(wasmPath);
184
238
  const module = new WebAssembly.Module(binary);
185
- const helper = (await import(`${pathToFileURL(helperPath).href}?t=${Date.now()}`)) as {
239
+ const helper = (await import(
240
+ `${pathToFileURL(helperPath).href}?t=${Date.now()}`
241
+ )) as {
186
242
  instantiate?: (
187
243
  module: WebAssembly.Module,
188
244
  imports?: WebAssembly.Imports,
@@ -200,10 +256,10 @@ async function instantiateRawInstance(
200
256
 
201
257
  async function instantiateEsmInstance(
202
258
  wasmPath: string,
259
+ helperPath: string,
203
260
  imports: WebAssembly.Imports,
204
261
  ): Promise<WebAssembly.Instance> {
205
262
  validateImports(imports, "instantiateEsmInstance");
206
- const helperPath = process.env.AS_TEST_HELPER_PATH || "";
207
263
  if (!helperPath.length) {
208
264
  throw new Error("bindings kind is esm but AS_TEST_HELPER_PATH is not set");
209
265
  }
@@ -233,6 +289,7 @@ async function instantiateWasiInstance(
233
289
  ): Promise<WebAssembly.Instance> {
234
290
  validateImports(imports, "instantiateWasiInstance");
235
291
  suppressExperimentalWasiWarning();
292
+ const { WASI } = await import("wasi");
236
293
  const binary = fs.readFileSync(wasmPath);
237
294
  const module = new WebAssembly.Module(binary);
238
295
  const wasi = new WASI({
@@ -259,7 +316,8 @@ async function instantiateWebInstance(
259
316
  );
260
317
  }
261
318
 
262
- const bindingsKind = (process.env.AS_TEST_BINDINGS_KIND || "raw") as BindingsKind;
319
+ const bindingsKind = (process.env.AS_TEST_BINDINGS_KIND ||
320
+ "raw") as BindingsKind;
263
321
  const helperPath = process.env.AS_TEST_HELPER_PATH
264
322
  ? path.resolve(process.cwd(), process.env.AS_TEST_HELPER_PATH)
265
323
  : wasmPath.replace(/\.wasm$/, ".js");
@@ -378,9 +436,11 @@ async function instantiateWebInstance(
378
436
  if (message?.kind == "instantiated") {
379
437
  if (resolved) return;
380
438
  resolved = true;
381
- resolve(createWebInstanceController(() => {
382
- sendControl({ kind: "start" });
383
- }));
439
+ resolve(
440
+ createWebInstanceController(() => {
441
+ sendControl({ kind: "start" });
442
+ }),
443
+ );
384
444
  return;
385
445
  }
386
446
  if (message?.kind == "done") {
@@ -477,9 +537,9 @@ async function instantiateWebInstance(
477
537
  res.end(
478
538
  html.replace(
479
539
  "</body>",
480
- ' <script>window.__AS_TEST_ENV__ = ' +
540
+ " <script>window.__AS_TEST_ENV__ = " +
481
541
  JSON.stringify(webRuntimeEnv) +
482
- ';</script>\n </body>',
542
+ ";</script>\n </body>",
483
543
  ),
484
544
  );
485
545
  return;
@@ -561,11 +621,7 @@ async function instantiateWebInstance(
561
621
  });
562
622
  socket.on("error", (error) => {
563
623
  if (!finished) {
564
- rejectOnce(
565
- error instanceof Error
566
- ? error
567
- : new Error(String(error)),
568
- );
624
+ rejectOnce(error instanceof Error ? error : new Error(String(error)));
569
625
  }
570
626
  });
571
627
  flushPendingFrames();
@@ -622,7 +678,9 @@ async function instantiateWebInstance(
622
678
  return;
623
679
  }
624
680
  if (code && code != 0) {
625
- rejectOnce(new Error(formatBrowserExitError(code, browserStderr)));
681
+ rejectOnce(
682
+ new Error(formatBrowserExitError(code, browserStderr)),
683
+ );
626
684
  return;
627
685
  }
628
686
  if (ready || wsSocket) {
@@ -631,9 +689,7 @@ async function instantiateWebInstance(
631
689
  });
632
690
  }
633
691
  } catch (error) {
634
- rejectOnce(
635
- error instanceof Error ? error : new Error(String(error)),
636
- );
692
+ rejectOnce(error instanceof Error ? error : new Error(String(error)));
637
693
  }
638
694
  });
639
695
  });
@@ -680,7 +736,7 @@ function suppressExperimentalWasiWarning(): void {
680
736
  ? warning
681
737
  : String(
682
738
  warning && typeof warning == "object" && "message" in warning
683
- ? (warning as { message?: unknown }).message ?? ""
739
+ ? ((warning as { message?: unknown }).message ?? "")
684
740
  : "",
685
741
  );
686
742
  if (
@@ -831,7 +887,9 @@ function launchWebBrowser(
831
887
  function openWithReusableBrowserWindow(url: string): ChildProcess | null {
832
888
  if (process.platform != "darwin") return null;
833
889
  if (!hasExecutable("osascript")) return null;
834
- const browserApp = resolveMacBrowserAppName(process.env.BROWSER?.trim() ?? "");
890
+ const browserApp = resolveMacBrowserAppName(
891
+ process.env.BROWSER?.trim() ?? "",
892
+ );
835
893
  if (!browserApp) return null;
836
894
  const script = buildMacBrowserOpenScript(browserApp, url);
837
895
  if (!script.length) return null;
@@ -844,7 +902,9 @@ function openWithReusableBrowserWindow(url: string): ChildProcess | null {
844
902
 
845
903
  function openWithSystemBrowser(url: string): ChildProcess | null {
846
904
  if (process.env.BROWSER) {
847
- return spawnBrowserCommand(process.env.BROWSER, url, false)?.process ?? null;
905
+ return (
906
+ spawnBrowserCommand(process.env.BROWSER, url, false)?.process ?? null
907
+ );
848
908
  }
849
909
  if (process.platform == "darwin") {
850
910
  if (!hasExecutable("open")) return null;
@@ -901,7 +961,7 @@ function buildMacBrowserOpenScript(appName: string, url: string): string[] {
901
961
  return [
902
962
  `tell application "${escapedApp}"`,
903
963
  "activate",
904
- 'if (count of windows) = 0 then make new window',
964
+ "if (count of windows) = 0 then make new window",
905
965
  `set URL of active tab of front window to "${escapedUrl}"`,
906
966
  "end tell",
907
967
  ];
@@ -910,7 +970,7 @@ function buildMacBrowserOpenScript(appName: string, url: string): string[] {
910
970
  return [
911
971
  `tell application "${escapedApp}"`,
912
972
  "activate",
913
- 'if (count of windows) = 0 then make new document',
973
+ "if (count of windows) = 0 then make new document",
914
974
  `set URL of front document to "${escapedUrl}"`,
915
975
  "end tell",
916
976
  ];
@@ -1256,7 +1316,8 @@ async function captureHelperInstance(
1256
1316
  try {
1257
1317
  await runHelper();
1258
1318
  } finally {
1259
- WebAssembly.instantiate = originalInstantiate as typeof WebAssembly.instantiate;
1319
+ WebAssembly.instantiate =
1320
+ originalInstantiate as typeof WebAssembly.instantiate;
1260
1321
  }
1261
1322
 
1262
1323
  if (!instance) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "as-test",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "author": "Jairus Tanaka",
5
5
  "repository": {
6
6
  "type": "git",
@@ -214,7 +214,9 @@ export class CoverageTransform extends Visitor {
214
214
  const ifTrue = node.ifTrue;
215
215
  const ifFalse = node.ifFalse;
216
216
  const path = node.range.source.normalizedPath;
217
- if (ifTrue.kind !== 31 && !isBuiltinStatement(ifTrue)) {
217
+ if (ifTrue &&
218
+ ifTrue.kind !== 31 &&
219
+ !isBuiltinStatement(ifTrue)) {
218
220
  const trueLc = getLineCol(ifTrue);
219
221
  const point = new CoverPoint();
220
222
  point.line = trueLc?.line;