import { existsSync } from "node:fs"; import path from "node:path"; import { describe, expect, it } from "vitest"; import { catalogEntry, FAMILY_LABELS, TEMPLATE_CATALOG } from "./catalog"; import { TEMPLATES } from "./registry"; describe("template catalog", () => { it("has one entry per registered template, in the registry's order, ids unique", () => { expect(TEMPLATE_CATALOG.map((e) => e.id)).toEqual(Object.keys(TEMPLATES)); expect(new Set(TEMPLATE_CATALOG.map((e) => e.id)).size).toBe(TEMPLATE_CATALOG.length); expect(TEMPLATE_CATALOG).toHaveLength(14); }); it("groups the C4 templates into the Ledger and Band families", () => { const byFamily = (f: string) => TEMPLATE_CATALOG.filter((e) => e.family === f).map((e) => e.id); expect(byFamily("ledger")).toEqual(["crimson-grid", "tangerine-ledger"]); expect(byFamily("band")).toEqual(["slate-band", "teal-swoosh"]); expect(byFamily("neutral")).toEqual(["linea", "monogram", "serenity"]); expect(FAMILY_LABELS.ledger).toBe("Ledger"); expect(FAMILY_LABELS.band).toBe("Band"); }); it("lists the standalone templates, Monolith, Cobalt Stripe, Marble and Highlighter, last", () => { expect(TEMPLATE_CATALOG.filter((e) => e.family === "standalone").map((e) => e.id)).toEqual(["monolith", "cobalt-stripe", "marble", "highlighter"]); expect(FAMILY_LABELS.standalone).toBe("Standalone"); }); it("every entry has a name, a family label and a thumbnail on disk; every definition agrees", () => { for (const e of TEMPLATE_CATALOG) { expect(e.name.length, e.id).toBeGreaterThan(0); expect(FAMILY_LABELS[e.family], e.id).toBeTruthy(); expect(e.thumbnail).toBe(`/templates/${e.id}.png`); expect(existsSync(path.join(process.cwd(), "public", e.thumbnail)), e.thumbnail).toBe(true); expect(TEMPLATES[e.id].family).toBe(e.family); expect(TEMPLATES[e.id].name).toBe(e.name); } }); it("falls back to Classic for an unknown id", () => { expect(catalogEntry("no-such").id).toBe("classic"); expect(catalogEntry("slate-band").name).toBe("Slate Band"); }); });