Files
quixos-nix-helpers/component-types.test.mjs
T

60 lines
2.4 KiB
JavaScript
Raw Normal View History

import assert from "node:assert/strict";
import { mkdtemp, writeFile, rm } from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import test from "node:test";
import { checkComponentTypes } from "./component-types.mjs";
const tsc = process.env.QUIXOS_TYPESCRIPT;
if (!tsc) throw Error("Pass the selected TypeScript compiler path");
async function fixture(context, left, right) {
const work = await mkdtemp(path.join(os.tmpdir(), "component-types-"));
context.after(() => rm(work, { recursive: true, force: true }));
await Promise.all(
Object.entries({ "left.ts": left, "right.ts": right, "assets.d.ts": "", "props.d.ts": "" }).map(([file, source]) =>
writeFile(path.join(work, file), source),
),
);
return {
node: process.execPath,
tsc,
work,
witnesses: ["left.ts", "right.ts"],
assets: "assets.d.ts",
props: "props.d.ts",
packageRevision: "test",
};
}
test("shared component typechecking accepts all valid witnesses", async (context) => {
checkComponentTypes(await fixture(context, "export const left: string = 'ok';", "export const right: number = 1;"));
});
test("independently valid ambient declarations use the full individual check fallback", async (context) => {
checkComponentTypes(
await fixture(
context,
"export {}; declare global { interface Application { value: string; } }",
"export {}; declare global { interface Application { value: number; } }",
),
);
});
test("a type error in any witness still rejects the artifact", async (context) => {
const input = await fixture(context, "export const left: string = 'ok';", "export const right: string = 1;");
assert.throws(() => checkComponentTypes(input));
});
test("one witness's globals cannot make an independently invalid witness pass", async (context) => {
const input = await fixture(
context,
"export {}; declare global { interface Application { value: string; } }",
"export const right: Application = {value: 'ok'};",
);
assert.throws(() => checkComponentTypes(input));
});
test("an ambient module from another source closure cannot resolve a missing import", async (context) => {
const input = await fixture(
context,
"declare module 'missing-component-package' { export const value: string; }",
"import {value} from 'missing-component-package'; export const right = value;",
);
assert.throws(() => checkComponentTypes(input));
});