import { afterEach, expect, test } from "bun:test";
import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
import { join } from "node:path";
import { tmpdir } from "node:os";
import {
compileWrnArtifacts,
setCompileCacheDir,
setCompileImportOptions,
} from "../src/pipeline.ts";
const roots: string[] = [];
afterEach(() => {
for (const root of roots.splice(0)) rmSync(root, { recursive: true, force: true });
});
function fixture(): { root: string; page: string } {
const root = mkdtempSync(join(tmpdir(), "wrn-import-mode-"));
roots.push(root);
mkdirSync(join(root, "app/pages"), { recursive: true });
mkdirSync(join(root, "app/components"), { recursive: true });
writeFileSync(
join(root, "app/components/Card.wrn"),
"component Card { view {
Card
} }",
);
const page = join(root, "app/pages/index.wrn");
writeFileSync(page, "page Home { view { } }");
setCompileCacheDir(join(root, ".wrnexus"));
return { root, page };
}
test("legacy, compatible, and explicit import modes are enforced from app config", () => {
const { root, page } = fixture();
setCompileImportOptions(root, { mode: "legacy" });
expect(() => compileWrnArtifacts(page, 1)).not.toThrow();
const warnings: string[] = [];
const originalWarn = console.warn;
console.warn = (...args) => warnings.push(args.join(" "));
try {
setCompileImportOptions(root, { mode: "compatible" });
expect(() => compileWrnArtifacts(page, 2)).not.toThrow();
expect(warnings.some((message) => message.includes("WRN-IMPORT-IMPLICIT"))).toBe(true);
setCompileImportOptions(root, { mode: "explicit" });
expect(() => compileWrnArtifacts(page, 3)).toThrow("WRN-IMPORT-IMPLICIT");
writeFileSync(
page,
'import Card from "@/components/Card.wrn"\npage Home { view { } }',
);
expect(() => compileWrnArtifacts(page, 4)).not.toThrow();
} finally {
console.warn = originalWarn;
}
});
test("compiler-native reactive elements do not require application imports", () => {
const { root, page } = fixture();
writeFileSync(
page,
`page Home {
state active = "Admin"
view {
Admin
Notice
LoadingReadyFailed
}
}`,
);
setCompileImportOptions(root, { mode: "explicit" });
expect(() => compileWrnArtifacts(page, 5)).not.toThrow();
});
test("component examples in comments do not require imports", () => {
const { root, page } = fixture();
writeFileSync(
page,
`// Usage:
page Home { view { Home } }`,
);
setCompileImportOptions(root, { mode: "explicit" });
expect(() => compileWrnArtifacts(page, 6)).not.toThrow();
});