import { expect, test } from "bun:test"; import { parse } from "../src/index.ts"; const page = (inner: string) => `page Repro { apis { ${inner} } view {
x
} } `; test("parses a mode-less entry with its sections", () => { const ast = parse( page(` searchUsers POST /api/users { request { body { name?: string } } response { return data.users } error { return [] } }`), ); const block = ast.dataApis[0]!; expect(block.name).toBe("searchUsers"); expect(block.method).toBe("POST"); expect(block.path).toBe("/api/users"); expect(block.mode).toBe("any"); expect(block.sections?.body).toEqual([{ name: "name", optional: true, type: "string" }]); expect(block.sections?.response.trim()).toBe("return data.users"); expect(block.sections?.error.trim()).toBe("return []"); }); test("parses several entries in one container", () => { const ast = parse( page(` a GET /api/a { response { return data } } b POST /api/b { response { return data } }`), ); expect(ast.dataApis.map((block) => block.name)).toEqual(["a", "b"]); }); test("a GET entry declares parameters", () => { const ast = parse( page(` listTeams GET /api/teams { request { parameters { team: string } } response { return data.teams } }`), ); expect(ast.dataApis[0]!.sections?.parameters).toEqual([ { name: "team", optional: false, type: "string" }, ]); }); test("duplicate names inside one container are rejected", () => { expect(() => parse( page(` dup GET /api/a { response { return data } } dup POST /api/b { response { return data } }`), ), ).toThrow(/duplicate/i); }); test("a bare body inside apis {} is a parse error naming response", () => { expect(() => parse(page(` bare GET /api/z { return data }`))).toThrow(/response/i); }); test("two apis entries of the same name across separate blocks are rejected", () => { const src = `page Repro { apis { foo GET /api/foo { response { return data } } } apis { foo GET /api/foo { response { return data } } } view {
x
} } `; expect(() => parse(src)).toThrow(/duplicate/i); }); test("an explicit empty response section is accepted, unlike a bare body", () => { const ast = parse(page(` empty GET /api/e { response { } }`)); const block = ast.dataApis[0]!; expect(block.name).toBe("empty"); expect(block.sections?.response.trim()).toBe(""); });