mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-24 06:14:01 +08:00
- Remove C emission, debugging options, and automatic backend fallback. - Complete LLVM lowering and native bootstrap coverage across supported targets. - Link executables and libraries with precompiled C runtime packs, including iOS and Android.
55 lines
2.4 KiB
TypeScript
55 lines
2.4 KiB
TypeScript
import { spawnSync } from "node:child_process";
|
|
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
import { tmpdir } from "node:os";
|
|
import { join } from "node:path";
|
|
import { expect, test } from "vitest";
|
|
import { compile } from "../src/index.js";
|
|
|
|
// A checked assertion intentionally validates more than Node's erased
|
|
// assertion. Test rejection here; valid inputs have differential corpus
|
|
// coverage through LLVM.
|
|
for (const backend of ["llvm"] as const) {
|
|
test(`checked discriminator rejection (${backend})`, async () => {
|
|
const dir = mkdtempSync(join(process.platform === "win32" ? tmpdir() : "/tmp", "scriptc-discriminator-"));
|
|
try {
|
|
const entry = join(dir, "main.ts");
|
|
writeFileSync(entry, `
|
|
export {};
|
|
type Value = { kind: "empty" } | { kind: "value"; value: number };
|
|
function inspect(json: string): void {
|
|
try {
|
|
const value = JSON.parse(json) as Value;
|
|
console.log(value.kind === "value" ? String(value.value) : "empty");
|
|
} catch (error) {
|
|
console.log("rejected");
|
|
}
|
|
}
|
|
inspect('{"kind":"empty"}');
|
|
inspect('{"kind":"value","value":7}');
|
|
inspect('{"kind":"unknown"}');
|
|
inspect('{"kind":"value"}');
|
|
inspect('{"kind":"value","value":"wrong"}');
|
|
inspect('{"kind":true,"value":8}');
|
|
inspect('{}');
|
|
// Same layouts and different literal contracts must remain separate.
|
|
type Other = { kind: "none" } | { kind: "some"; value: number };
|
|
try {
|
|
const other = JSON.parse('{"kind":"value","value":1}') as Other;
|
|
console.log(other.kind);
|
|
} catch { console.log("separate contract"); }
|
|
`);
|
|
const built = await compile(entry, { outDir: dir, outPath: join(dir, "program"), backend,
|
|
dynamic: false, sanitize: process.env["SCRIPTC_SAN"] === "1" });
|
|
if (!built.ok) throw new Error(built.diagnostics.map((d) => d.message).join("\n"));
|
|
expect(built.backend).toBe(backend);
|
|
const result = spawnSync(built.binaryPath, [], { timeout: 30_000 });
|
|
expect(result.error).toBeUndefined();
|
|
expect(result.status, result.stderr.toString()).toBe(0);
|
|
expect(result.stdout.toString()).toBe("empty\n7\nrejected\nrejected\nrejected\nrejected\nrejected\nseparate contract\n");
|
|
expect(result.stderr.toString()).toBe("");
|
|
} finally {
|
|
rmSync(dir, { recursive: true, force: true });
|
|
}
|
|
});
|
|
}
|