Files
scriptc/tests/harness/three-library.test.ts
Chris Tate c08ab955ae Enforce linting and consistent source formatting
- Enforce oxlint and oxfmt for owned JavaScript and TypeScript with independent CI checks.
- Preserve compiler import boundaries and protected fixtures while cleaning up lint findings.
- Standardize source formatting and validate import, fixture, and embedded-source protections.
2026-10-05 17:51:24 -05:00

81 lines
2.8 KiB
TypeScript

import { spawnSync } from "node:child_process";
import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
import { join } from "node:path";
import { compileLibrary } from "@scriptc/compiler";
import { expect, test } from "vitest";
const fixture = join(import.meta.dirname, "../library-mode/wasm");
const hasClang = spawnSync("clang", ["--version"]).status === 0;
test.skipIf(!hasClang).each(["dev", "release"] as const)(
"three.js sends animated geometry, materials and resource lifecycle to a native host in %s",
async (optimization) => {
const directory = await mkdtemp("/tmp/scriptc-three-library-");
const sanitize = process.env["SCRIPTC_SAN"] === "1";
try {
const profile = JSON.parse(await readFile(join(fixture, "three.json"), "utf8"));
const profilePath = join(directory, "profile.json");
await writeFile(
profilePath,
JSON.stringify({
...profile,
name: "three-native-embedding",
entry: join(fixture, "three.mjs"),
optimization,
}),
);
const built = await compileLibrary({ profilePath, outDir: directory, sanitize });
if (!built.ok)
throw new Error(
built.diagnostics
.map((diagnostic) => `${diagnostic.code}: ${diagnostic.message}`)
.join("\n"),
);
const binary = join(directory, "host");
const linked = spawnSync(
"clang",
[
"-std=c11",
...(sanitize ? ["-fsanitize=address,undefined"] : []),
join(fixture, "three-native.c"),
built.archivePath,
"-lm",
"-o",
binary,
],
{ encoding: "utf8" },
);
expect(linked.status, linked.stderr).toBe(0);
const actual = spawnSync(binary, [], { encoding: "utf8", timeout: 30_000 });
expect(actual.status, actual.stderr).toBe(0);
const reference = spawnSync(
process.execPath,
[
"--no-warnings",
"--input-type=module",
"-e",
`
const events=[];
for (const name of ["vertex","surface","resource"]) globalThis[name]=(...values)=>events.push([name,...values.map(value=>Number(value.toFixed(9)))]);
const {frame,dispose}=await import(${JSON.stringify(join(fixture, "three.mjs"))});
for (const time of [0,123,2000]) frame(time,1.5);
dispose();
console.log(JSON.stringify(events));
`,
],
{ encoding: "utf8" },
);
expect(reference.status, reference.stderr).toBe(0);
const events = JSON.parse(reference.stdout);
expect(
actual.stdout
.trim()
.split("\n")
.map((line) => JSON.parse(line)),
).toEqual([...events, ...events]);
} finally {
await rm(directory, { recursive: true, force: true });
}
},
600_000,
);