import { describe, test, expect } from "vitest"; import { emitTOML, parseTOML } from "./toml"; describe("emitTOML", () => { test("emits scalar values", () => { const result = emitTOML({ name: "my-project", version: 42, enabled: true, ratio: 3.14, }); expect(result).toBe( `name = "my-project"\nversion = 42\nenabled = true\nratio = 3.14\n`, ); }); test("emits arrays of scalars inline", () => { const result = emitTOML({ schemas: ["public", "audit"], ports: [8080, 9090], }); expect(result).toContain('schemas = ["public", "audit"]'); expect(result).toContain("ports = [8080, 9090]"); }); test("emits nested tables as sections", () => { const result = emitTOML({ name: "proj", flyway: { locations: ["filesystem:sql"], encoding: "UTF-8", }, }); expect(result).toContain('name = "proj"'); expect(result).toContain("[flyway]"); expect(result).toContain('locations = ["filesystem:sql"]'); expect(result).toContain('encoding = "UTF-8"'); }); test("emits deeply nested tables with dotted paths", () => { const result = emitTOML({ environments: { dev: { url: "jdbc:postgresql://localhost:5432/devdb", user: "dev_user", }, }, }); expect(result).toContain("[environments.dev]"); expect(result).toContain('url = "jdbc:postgresql://localhost:5432/devdb"'); }); test("emits array of tables", () => { const result = emitTOML({ servers: [ { host: "alpha", port: 5432 }, { host: "beta", port: 5433 }, ], }); expect(result).toContain("[[servers]]"); expect(result).toContain('host = "alpha"'); expect(result).toContain("port = 5432"); expect(result).toContain('host = "beta"'); expect(result).toContain("port = 5433"); }); test("emits header comment", () => { const result = emitTOML({ name: "test" }, { header: "Generated by Chant" }); expect(result.startsWith("# Generated by Chant\n")).toBe(true); }); test("respects key ordering", () => { const result = emitTOML( { z: 1, a: 2, m: 3 }, { keyOrder: ["a", "m", "z"] }, ); const lines = result.split("\n").filter((l) => l.includes("=")); expect(lines[0]).toContain("a = 2"); expect(lines[1]).toContain("m = 3"); expect(lines[2]).toContain("z = 1"); }); test("escapes special characters in strings", () => { const result = emitTOML({ path: 'C:\\Users\\admin', query: 'SELECT "name" FROM users', }); expect(result).toContain('path = "C:\\\\Users\\\\admin"'); expect(result).toContain('query = "SELECT \\"name\\" FROM users"'); }); test("escapes special characters in keys", () => { const result = emitTOML({ "simple-key": 1, "key with spaces": 2, }); expect(result).toContain("simple-key = 1"); expect(result).toContain('"key with spaces" = 2'); }); test("emits empty arrays", () => { const result = emitTOML({ items: [] }); expect(result).toContain("items = []"); }); test("emits boolean values correctly", () => { const result = emitTOML({ cleanDisabled: true, outOfOrder: false, }); expect(result).toContain("cleanDisabled = true"); expect(result).toContain("outOfOrder = false"); }); test("handles null/undefined values", () => { const result = emitTOML({ present: "yes", absent: null, }); expect(result).toContain('present = "yes"'); expect(result).toContain('absent = ""'); }); test("skips undefined values", () => { const result = emitTOML({ present: "yes", absent: undefined, }); expect(result).toContain('present = "yes"'); expect(result).not.toContain("absent"); }); test("emits Flyway-realistic config", () => { const result = emitTOML({ flyway: { locations: ["filesystem:sql/migrations"], defaultSchema: "public", schemas: ["public", "audit"], encoding: "UTF-8", validateMigrationNaming: true, validateOnMigrate: true, cleanDisabled: true, baselineOnMigrate: false, baselineVersion: "1", sqlMigrationPrefix: "V", sqlMigrationSeparator: "__", sqlMigrationSuffixes: [".sql"], table: "flyway_schema_history", placeholders: { defaultSchema: "public", appName: "myapp", }, }, environments: { dev: { url: "jdbc:postgresql://localhost:5432/devdb", user: "dev_user", schemas: ["public"], }, prod: { url: "jdbc:postgresql://prod-host:5432/proddb", user: "prod_user", schemas: ["public", "audit"], }, }, }); expect(result).toContain("[flyway]"); expect(result).toContain('[flyway.placeholders]'); expect(result).toContain("[environments.dev]"); expect(result).toContain("[environments.prod]"); expect(result).toContain('defaultSchema = "public"'); expect(result).toContain("validateMigrationNaming = true"); }); test("throws for non-object input", () => { expect(() => emitTOML("string" as unknown)).toThrow(); expect(() => emitTOML([1, 2, 3] as unknown)).toThrow(); expect(() => emitTOML(42 as unknown)).toThrow(); }); }); describe("parseTOML", () => { test("parses scalar values", () => { const result = parseTOML(` name = "my-project" version = 42 enabled = true ratio = 3.14 `); expect(result.name).toBe("my-project"); expect(result.version).toBe(42); expect(result.enabled).toBe(true); expect(result.ratio).toBe(3.14); }); test("parses arrays", () => { const result = parseTOML(` schemas = ["public", "audit"] ports = [8080, 9090] `); expect(result.schemas).toEqual(["public", "audit"]); expect(result.ports).toEqual([8080, 9090]); }); test("parses table sections", () => { const result = parseTOML(` [flyway] encoding = "UTF-8" cleanDisabled = true `); const flyway = result.flyway as Record; expect(flyway.encoding).toBe("UTF-8"); expect(flyway.cleanDisabled).toBe(true); }); test("parses dotted table paths", () => { const result = parseTOML(` [environments.dev] url = "jdbc:postgresql://localhost:5432/devdb" user = "dev_user" `); const envs = result.environments as Record; const dev = envs.dev as Record; expect(dev.url).toBe("jdbc:postgresql://localhost:5432/devdb"); expect(dev.user).toBe("dev_user"); }); test("parses array of tables", () => { const result = parseTOML(` [[servers]] host = "alpha" port = 5432 [[servers]] host = "beta" port = 5433 `); const servers = result.servers as Record[]; expect(servers).toHaveLength(2); expect(servers[0].host).toBe("alpha"); expect(servers[0].port).toBe(5432); expect(servers[1].host).toBe("beta"); expect(servers[1].port).toBe(5433); }); test("ignores comments", () => { const result = parseTOML(` # This is a comment name = "test" # inline comment # Another comment version = 1 `); expect(result.name).toBe("test"); expect(result.version).toBe(1); }); test("parses boolean values", () => { const result = parseTOML(` enabled = true disabled = false `); expect(result.enabled).toBe(true); expect(result.disabled).toBe(false); }); test("parses inline tables", () => { const result = parseTOML(` point = { x = 1, y = 2 } `); const point = result.point as Record; expect(point.x).toBe(1); expect(point.y).toBe(2); }); test("parses literal strings (single quotes)", () => { const result = parseTOML(` path = 'C:\\Users\\admin' `); expect(result.path).toBe("C:\\Users\\admin"); }); test("parses escaped strings", () => { const result = parseTOML(` escaped = "line1\\nline2" `); expect(result.escaped).toBe("line1\nline2"); }); test("parses empty values", () => { const result = parseTOML(` empty_string = "" empty_array = [] `); expect(result.empty_string).toBe(""); expect(result.empty_array).toEqual([]); }); test("parses Flyway-realistic config", () => { const result = parseTOML(` [flyway] locations = ["filesystem:sql/migrations"] defaultSchema = "public" schemas = ["public", "audit"] encoding = "UTF-8" validateMigrationNaming = true cleanDisabled = true baselineVersion = "1" table = "flyway_schema_history" [flyway.placeholders] defaultSchema = "public" appName = "myapp" [environments.dev] url = "jdbc:postgresql://localhost:5432/devdb" user = "dev_user" schemas = ["public"] [environments.prod] url = "jdbc:postgresql://prod-host:5432/proddb" user = "prod_user" schemas = ["public", "audit"] `); const flyway = result.flyway as Record; expect(flyway.defaultSchema).toBe("public"); expect(flyway.validateMigrationNaming).toBe(true); expect((flyway.placeholders as Record).appName).toBe("myapp"); const envs = result.environments as Record; const dev = envs.dev as Record; expect(dev.url).toBe("jdbc:postgresql://localhost:5432/devdb"); const prod = envs.prod as Record; expect(prod.schemas).toEqual(["public", "audit"]); }); }); describe("roundtrip", () => { test("emit → parse → emit preserves structure", () => { const original = { name: "roundtrip-test", flyway: { locations: ["filesystem:sql"], encoding: "UTF-8", cleanDisabled: true, baselineVersion: "1", placeholders: { schema: "public", }, }, environments: { dev: { url: "jdbc:postgresql://localhost:5432/db", user: "admin", schemas: ["public"], }, }, }; const toml = emitTOML(original); const parsed = parseTOML(toml); const toml2 = emitTOML(parsed); expect(toml2).toBe(toml); }); test("roundtrip with booleans and numbers", () => { const original = { settings: { enabled: true, disabled: false, count: 42, ratio: 3.14, }, }; const toml = emitTOML(original); const parsed = parseTOML(toml); const settings = parsed.settings as Record; expect(settings.enabled).toBe(true); expect(settings.disabled).toBe(false); expect(settings.count).toBe(42); expect(settings.ratio).toBe(3.14); }); });