91 lines
3.2 KiB
TypeScript
91 lines
3.2 KiB
TypeScript
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 { <div>Card</div> } }",
|
|
);
|
|
const page = join(root, "app/pages/index.wrn");
|
|
writeFileSync(page, "page Home { view { <Card /> } }");
|
|
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 { <Card /> } }',
|
|
);
|
|
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 {
|
|
<Transition name="fade"><Component is={active}><div data-component-case="Admin">Admin</div></Component></Transition>
|
|
<Portal to="body"><p>Notice</p></Portal>
|
|
<Async source="profile"><Loading>Loading</Loading><Success data="profile">Ready</Success><Error error="error">Failed</Error></Async>
|
|
}
|
|
}`,
|
|
);
|
|
setCompileImportOptions(root, { mode: "explicit" });
|
|
expect(() => compileWrnArtifacts(page, 5)).not.toThrow();
|
|
});
|
|
|
|
test("globally registered plugin components do not require source imports", () => {
|
|
const { root, page } = fixture();
|
|
writeFileSync(page, "page Home { view { <SignIn /> } }");
|
|
setCompileImportOptions(root, { mode: "explicit", globalComponents: ["SignIn"] });
|
|
expect(() => compileWrnArtifacts(page, 6)).not.toThrow();
|
|
});
|
|
|
|
test("component examples in comments do not require imports", () => {
|
|
const { root, page } = fixture();
|
|
writeFileSync(
|
|
page,
|
|
`// Usage: <Home title="Example" />
|
|
page Home { view { <main>Home</main> } }`,
|
|
);
|
|
setCompileImportOptions(root, { mode: "explicit" });
|
|
expect(() => compileWrnArtifacts(page, 6)).not.toThrow();
|
|
});
|