import { expect, test } from "bun:test"; import { apiCallCompletions, apiCallHover } from "../src/server.ts"; const SOURCE = `page Search { apis { searchUsers POST /api/users { request { body { name?: string } } response { return data.users } } listTeams GET /api/teams { response { return data.teams } } } functions { client async function go(): Promise { await api. } } view {
x
} } `; test("api. offers every declared block with method and path", () => { const items = apiCallCompletions(SOURCE); const labels = items.map((item) => item.label); expect(labels).toContain("searchUsers"); expect(labels).toContain("listTeams"); const search = items.find((item) => item.label === "searchUsers")!; expect(search.detail).toContain("POST"); expect(search.detail).toContain("/api/users"); }); test("hovering a block name reports its method, path and request fields", () => { const hover = apiCallHover(SOURCE, "searchUsers"); expect(hover).toContain("POST"); expect(hover).toContain("/api/users"); expect(hover).toContain("name"); }); test("a page with no apis block offers nothing", () => { expect(apiCallCompletions(`page P { view {
x
} }`)).toEqual([]); }); test("a badly-broken document (unclosed braces, truncated apis block) answers rather than throwing", () => { const broken = `page Search { apis { searchUsers POST /api/users { request { body { name?: string `; expect(() => apiCallCompletions(broken)).not.toThrow(); expect(apiCallCompletions(broken)).toEqual([]); expect(() => apiCallHover(broken, "searchUsers")).not.toThrow(); expect(apiCallHover(broken, "searchUsers")).toBeUndefined(); }); test("an ssr {} data block, which the parser now rejects with a ParseError, still answers rather than throwing", () => { const legacy = `page Search { ssr { api x GET /api/x { response { return data } } } view {
x
} } `; expect(() => apiCallCompletions(legacy)).not.toThrow(); expect(apiCallCompletions(legacy)).toEqual([]); });