import { expect, test } from "bun:test";
import { parse } from "@wrnexus/syntax";
import { generate } from "../src/codegen.ts";
const page = (attr: string) => `page Probe {
apis {
listTeams GET /api/teams {
request { parameters { team?: string } }
response { return data.teams }
}
}
view { loading
}
}
`;
test("a bare name binds", () => {
expect(generate(parse(page('api="listTeams"')))).toContain('"/api/teams"');
});
test("an empty call binds identically to a bare name", () => {
const bare = generate(parse(page('api="listTeams"')));
const called = generate(parse(page('api="listTeams()"')));
expect(called).toContain('"/api/teams"');
expect(called.length).toBeGreaterThan(0);
expect(bare).toContain('"/api/teams"');
});
test("an argument expression is carried into the binding", () => {
const generated = generate(parse(page('api="listTeams({ team: \\"platform\\" })"')));
expect(generated).toContain("platform");
});
test("a block that is both bound and called is invoked twice", () => {
// Deliberate: a render-time fetch and a user-triggered fetch are usually
// meant to be different requests. Collapsing them silently would be worse
// than the duplication.
const generated = generate(
parse(`page P {
apis { listTeams GET /api/teams { response { return data.teams } } }
load server x { return await api.listTeams() }
view { loading
}
}
`),
);
// Both call paths are emitted: the load block's call and the binding's.
// The route path itself is declared once, inside the shared server `api`
// object (Task 4) that both call sites invoke -- so the route string alone
// isn't a reliable proxy for "called twice". The call expression is.
const occurrences = generated.split("api.listTeams()").length - 1;
expect(occurrences).toBeGreaterThanOrEqual(2);
});