import { expect, test } from "bun:test";
import { NativeCompileError, compileNativeWireFile } from "../src/index.ts";
test("compiles portable wrn markup to React Native components", () => {
const code = compileNativeWireFile(`page Home {
state count = 0
view {
Count {count}
{#if count > 0}Started
{:else}Ready
{/if}
}
style { .screen { padding: 24px; background-color: white; } }
}`);
expect(code).toContain("const [count, setCount] = useState(0)");
expect(code).toContain('');
expect(code).toContain("Count {count}");
expect(code).toContain("onPress={() => { setCount(value => value + 1) }}");
expect(code).toContain('"padding": 24');
expect(() => new Bun.Transpiler({ loader: "tsx" }).transformSync(code)).not.toThrow();
});
test("rejects browser-only elements with an actionable error", () => {
expect(() => compileNativeWireFile("page Data { view { } }")).toThrow(
NativeCompileError,
);
});
test("compiles loops to native JSX", () => {
const code = compileNativeWireFile(
"page List { view { {#each items as item, i}- {item.name}
{:empty}- Empty
{/each}
} }",
);
expect(code).toContain("(items).map((item, i)");
expect(code).toContain("{item.name}");
});
test("selects mobile-only markup and events for native output", () => {
const code = compileNativeWireFile(`page Platforms { view {
Browser help
} }`);
expect(code).toContain("onPress={() => { save() }}");
expect(code).not.toContain("copy()");
expect(code).not.toContain("Browser help");
});
test("rejects declarative Capacitor actions instead of silently dropping them in Expo", () => {
expect(() =>
compileNativeWireFile(
`page Share { view { } }`,
),
).toThrow("currently targets browser/Capacitor pages");
});
test("does not emit native visibility directives as React Native props", () => {
const code = compileNativeWireFile(
`page Support { view { Camera
} }`,
);
expect(code).not.toContain("data-native-requires");
});