62 lines
2.4 KiB
TypeScript
62 lines
2.4 KiB
TypeScript
import { expect, test } from "bun:test";
|
|
import { NativeCompileError, compileNativeWrnFile } from "../src/index.ts";
|
|
|
|
test("compiles portable wrn markup to React Native components", () => {
|
|
const code = compileNativeWrnFile(`page Home {
|
|
state count = 0
|
|
view {
|
|
<main class="screen">
|
|
<h1>Count {count}</h1>
|
|
<button @click="count++">Add</button>
|
|
{#if count > 0}<p>Started</p>{:else}<p>Ready</p>{/if}
|
|
</main>
|
|
}
|
|
style { .screen { padding: 24px; background-color: white; } }
|
|
}`);
|
|
expect(code).toContain("const [count, setCount] = useState(0)");
|
|
expect(code).toContain('<View style={[styles["screen"] ]}>');
|
|
expect(code).toContain("<Text>Count {count}</Text>");
|
|
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(() => compileNativeWrnFile("page Data { view { <table></table> } }")).toThrow(
|
|
NativeCompileError,
|
|
);
|
|
});
|
|
|
|
test("compiles loops to native JSX", () => {
|
|
const code = compileNativeWrnFile(
|
|
"page List { view { <ul>{#each items as item, i}<li>{item.name}</li>{:empty}<li>Empty</li>{/each}</ul> } }",
|
|
);
|
|
expect(code).toContain("(items).map((item, i)");
|
|
expect(code).toContain("<Text>{item.name}</Text>");
|
|
});
|
|
|
|
test("selects mobile-only markup and events for native output", () => {
|
|
const code = compileNativeWrnFile(`page Platforms { view {
|
|
<button data-native-only="mobile" @mobile-click="save()" @browser-click="copy()">Save</button>
|
|
<p data-native-only="browser">Browser help</p>
|
|
} }`);
|
|
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(() =>
|
|
compileNativeWrnFile(
|
|
`page Share { view { <button data-native-mobile="share">Share</button> } }`,
|
|
),
|
|
).toThrow("currently targets browser/Capacitor pages");
|
|
});
|
|
|
|
test("does not emit native visibility directives as React Native props", () => {
|
|
const code = compileNativeWrnFile(
|
|
`page Support { view { <p data-native-requires="camera">Camera</p> } }`,
|
|
);
|
|
expect(code).not.toContain("data-native-requires");
|
|
});
|