mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-15 04:50:40 +08:00
- Retain representative Darwin kqueue coverage in the default gate. - Schedule native runtime tests by host and make Linux clang invocations portable. - Resolve canonical OCI manifest digests for direct and indexed images.
80 lines
3.5 KiB
TypeScript
80 lines
3.5 KiB
TypeScript
import { execFile } from "node:child_process";
|
|
import { mkdir } from "node:fs/promises";
|
|
import { join } from "node:path";
|
|
import { promisify } from "node:util";
|
|
import { beforeAll, expect, test } from "vitest";
|
|
|
|
const execFileAsync = promisify(execFile);
|
|
const testDir = import.meta.dirname;
|
|
const bin = join(testDir, "build", "test_url");
|
|
|
|
// Compiled once with ASan + the RC audit (leak/double-free coverage over
|
|
// every bridge call, thrown TypeErrors included).
|
|
beforeAll(async () => {
|
|
await mkdir(join(testDir, "build"), { recursive: true });
|
|
await execFileAsync("clang", [
|
|
"-std=c11", "-O1", "-Wall", "-Wextra",
|
|
"-fsanitize=address", "-DSCR_RC_AUDIT",
|
|
...(process.platform === "linux" ? ["-D_GNU_SOURCE"] : []),
|
|
"-o", bin,
|
|
join(testDir, "test_url.c"),
|
|
join(testDir, "../src/scr_url.c"),
|
|
join(testDir, "../src/scr_path.c"),
|
|
join(testDir, "../src/scr_string.c"),
|
|
join(testDir, "../src/scr_number.c"),
|
|
join(testDir, "../src/scr_array.c"),
|
|
join(testDir, "../src/scr_bytes.c"),
|
|
join(testDir, "../src/scr_error.c"),
|
|
join(testDir, "../src/scr_exception.c"),
|
|
join(testDir, "../src/scr_object.c"),
|
|
join(testDir, "../src/scr_cycle.c"),
|
|
...(process.platform === "linux" ? ["-lm"] : []),
|
|
]);
|
|
});
|
|
|
|
// Runs against the committed case file (generated from Node v24's own
|
|
// fileURLToPath/pathToFileURL with { windows: true } — the exact code
|
|
// Windows Node dispatches to — via gen-url-cases.mjs; see that file for
|
|
// the excluded documented divergences). Covers the win32 arm's drive
|
|
// letters, UNC hosts, \\?\UNC\ prefixes, encoded-separator TypeErrors,
|
|
// and the UNC-malformation TypeErrors, plus posix-arm legs pinning the
|
|
// shared encoding rework.
|
|
// One committed case bakes the GENERATING platform into its bytes: Node's
|
|
// non-localhost file-URL host TypeError names the host OS, the oracle was
|
|
// generated on darwin, and scr_url.c mirrors Node by naming the RUNTIME
|
|
// platform. On Linux the native message is byte-exact against what Linux
|
|
// Node itself says — pin exactly that one darwin→linux substitution and
|
|
// nothing else.
|
|
const LINUX_PLATFORM_MESSAGE_CASES: ReadonlyMap<string, string> = new Map([
|
|
[
|
|
// u2p-posix("file://host/a")
|
|
"u2p-posix(66696c653a2f2f686f73742f61)",
|
|
Buffer.from('ERR:TypeError: File URL host must be "localhost" or empty on linux').toString("hex"),
|
|
],
|
|
]);
|
|
|
|
test("file-URL bridge win32 arm matches Node on committed oracle cases", async () => {
|
|
const r = await execFileAsync(bin, [join(testDir, "url-cases.txt")]).then(
|
|
(v) => ({ stderr: v.stderr }),
|
|
(e: Error & { stderr?: string }) => ({ stderr: e.stderr ?? "" }),
|
|
);
|
|
const stderr = r.stderr.trim();
|
|
if (process.platform !== "linux") {
|
|
expect(stderr).toMatch(/^(\d+)\/\1 cases passed$/);
|
|
return;
|
|
}
|
|
const lines = stderr.split("\n");
|
|
const mismatches = lines.filter((l) => l.startsWith("MISMATCH "));
|
|
for (const line of mismatches) {
|
|
const m = /^MISMATCH (.+) expected=[0-9a-f]* got=([0-9a-f]*)$/.exec(line);
|
|
expect(m, `unparseable mismatch line: ${line}`).not.toBeNull();
|
|
expect(LINUX_PLATFORM_MESSAGE_CASES.get(m![1]!), line).toBe(m![2]);
|
|
}
|
|
// The pass-count tail proves nothing beyond the printed (allowlisted)
|
|
// set failed (the harness caps mismatch printing at 20 lines).
|
|
const t = /^(\d+)\/(\d+) cases passed$/.exec(lines.at(-1) ?? "");
|
|
expect(t, `missing pass-count line: ${lines.at(-1)}`).not.toBeNull();
|
|
expect(Number(t![2]) - Number(t![1]), "failed-case count").toBe(mismatches.length);
|
|
expect(mismatches.length).toBeLessThanOrEqual(LINUX_PLATFORM_MESSAGE_CASES.size);
|
|
});
|