import { describe, test, expect } from "bun:test"; import { adaptLegacyTheme, compileDesignSystem, defineDesignSystem, resolveDesignSystem, validateDesignSystem, DesignSystemError, type DesignSystem, } from "../src/index.ts"; const system = (): DesignSystem => ({ schemaVersion: 1, id: "workshop", name: "Workshop", version: "1.0.0", defaultMode: "dark", tokens: { "brand.blue": { type: "color", value: "#2563eb" }, "action.primary": { type: "color", value: { ref: "brand.blue" }, legacy: "color-primary" }, "control.radius": { type: "dimension", value: "0", legacy: "radius-sm" }, "body.font": { type: "fontFamily", value: '"Inter", sans-serif', legacy: "font-sans" }, }, modes: { light: { "brand.blue": { type: "color", value: "#1d4ed8" } }, dark: { "brand.blue": { type: "color", value: "#60a5fa" } }, }, densities: { compact: { "control.radius": { type: "dimension", value: "2px" } } }, }); describe("design-system engine", () => { test("resolves references after mode/density overrides and records provenance", () => { const result = resolveDesignSystem(system(), { mode: "light", density: "compact" }); expect(result.tokens["action.primary"]).toEqual({ type: "color", value: "#1d4ed8", legacy: "color-primary", reference: "brand.blue", source: "workshop.tokens.action.primary", }); expect(result.tokens["control.radius"]?.value).toBe("2px"); expect(result.tokens["control.radius"]?.legacy).toBe("radius-sm"); }); test("merges extensions in declared order, then selected mode", () => { const base = system(); base.id = "base"; const second: DesignSystem = { ...base, id: "second", tokens: { "control.radius": { type: "dimension", value: "4px" } }, modes: {}, }; const child: DesignSystem = { schemaVersion: 1, id: "child", name: "Child", version: "1", extends: ["base", "second"], tokens: {}, }; expect( resolveDesignSystem(child, { registry: { base, second } }).tokens["control.radius"]?.value, ).toBe("4px"); expect( resolveDesignSystem(child, { registry: { base, second } }).tokens["action.primary"]?.value, ).toBe("#60a5fa"); }); test("rejects missing parents, extension cycles and alias cycles", () => { const a = system(); a.extends = ["missing"]; expect(() => resolveDesignSystem(a)).toThrow("WRN-DS-EXTENDS-MISSING"); a.extends = ["workshop"]; expect(() => resolveDesignSystem(a, { registry: { workshop: a } })).toThrow( "WRN-DS-EXTENDS-CYCLE", ); const b = system(); delete b.defaultMode; delete b.modes; b.tokens["brand.blue"]!.value = { ref: "action.primary" }; expect(() => resolveDesignSystem(b)).toThrow("WRN-DS-REFERENCE-CYCLE"); }); test("rejects missing references, type mismatches and unknown axes", () => { const a = system(); a.tokens["action.primary"]!.value = { ref: "missing" }; expect(() => resolveDesignSystem(a)).toThrow("WRN-DS-REFERENCE-MISSING"); a.tokens["action.primary"]!.value = { ref: "control.radius" }; expect(() => resolveDesignSystem(a)).toThrow("WRN-DS-REFERENCE-TYPE"); expect(() => resolveDesignSystem(system(), { mode: "unknown" })).toThrow("WRN-DS-MODE"); expect(() => resolveDesignSystem(system(), { density: "unknown" })).toThrow("WRN-DS-DENSITY"); a.modes!.dark!["control.radius"] = { type: "color", value: "#fff" }; expect(() => resolveDesignSystem(a)).toThrow("WRN-DS-TYPE"); }); test("reports stable schema diagnostics and rejects unsafe values", () => { expect(validateDesignSystem(null)[0]?.code).toBe("WRN-DS-SCHEMA"); for (const value of [ "red;}body{display:none", "url(https://example.com)", "var(--arbitrary)", "#fff", "/* hidden */#fff", ]) { const a = system(); a.tokens["brand.blue"]!.value = value; expect(validateDesignSystem(a).some((d) => d.code === "WRN-DS-VALUE")).toBe(true); } expect(() => defineDesignSystem({ ...system(), schemaVersion: 2 } as never)).toThrow( DesignSystemError, ); expect(validateDesignSystem({ ...system(), layouts: {} })[0]?.code).toBe("WRN-DS-FIELD"); const a = system(); Object.defineProperty(a.tokens, "constructor", { value: { type: "number", value: 2 }, enumerable: true, }); expect(validateDesignSystem(a).some((d) => d.code === "WRN-DS-NAME")).toBe(true); }); test("compiles deterministic CSS regardless of token insertion order", () => { const a = system(); const b = system(); b.tokens = Object.fromEntries(Object.entries(b.tokens).reverse()); expect(compileDesignSystem(a).css).toBe(compileDesignSystem(b).css); expect(compileDesignSystem(a).css).toContain("--wrn-radius-sm:0;"); expect(compileDesignSystem(a).css).toContain(':root[data-theme="light"]'); expect(compileDesignSystem(a, { scope: "preview" }).css).toStartWith( '[data-wrn-design="preview"]', ); expect(() => compileDesignSystem(a, { scope: 'bad"]{}' })).toThrow("WRN-DS-NAME"); }); test("rejects output collisions instead of silently choosing a token", () => { const a = system(); a.tokens["control-radius"] = { type: "dimension", value: "3px" }; expect(() => compileDesignSystem(a)).toThrow("WRN-DS-COLLISION"); delete a.tokens["control-radius"]; a.tokens.other = { type: "dimension", value: "3px", legacy: "radius-sm" }; expect(() => adaptLegacyTheme(a, {})).toThrow("WRN-DS-COLLISION"); }); test("adapter preserves app configuration and explicit mode overrides without mutation", () => { const app = { default: "light", themes: { light: { "radius-sm": "9px" } }, palette: "rose" }; const before = JSON.stringify(app); const result = adaptLegacyTheme(system(), app); expect(result.default).toBe("light"); expect(result.palette).toBe("rose"); expect(result.themes?.light?.["radius-sm"]).toBe("9px"); expect(result.themes?.dark?.["radius-sm"]).toBe("0"); expect(JSON.stringify(app)).toBe(before); }); test("semantic validation checks unselected modes and densities", () => { const a = system(); a.densities!.spacious = { bad: { type: "color", value: { ref: "missing" } } }; expect(validateDesignSystem(a)[0]?.code).toBe("WRN-DS-REFERENCE-MISSING"); delete a.densities; a.modes!.light!.bad = { type: "color", value: { ref: "missing" } }; expect(validateDesignSystem(a)[0]?.code).toBe("WRN-DS-REFERENCE-MISSING"); }); test("validates typed dimensions, typography, duration, shadows and color scheme", () => { const a: DesignSystem = { schemaVersion: 1, id: "types", name: "Types", version: "1", tokens: { size: { type: "dimension", value: "1.5rem" }, weight: { type: "fontWeight", value: 600 }, time: { type: "duration", value: "150ms" }, alpha: { type: "number", value: 0.5 }, shadow: { type: "shadow", value: "0 2px 4px rgba(0, 0, 0, 0.2)" }, scheme: { type: "colorScheme", value: "dark", legacy: "color-scheme" }, color: { type: "color", value: "oklch(65% 0.2 250 / 90%)" }, }, }; expect(validateDesignSystem(a)).toEqual([]); expect(compileDesignSystem(a).css).toContain("color-scheme:dark;"); a.tokens.shadow!.value = "2px invalid"; expect(validateDesignSystem(a)[0]?.code).toBe("WRN-DS-VALUE"); }); test("browser entry bundles without filesystem or provider dependencies", async () => { const build = await Bun.build({ entrypoints: [ new URL("../src/index.ts", import.meta.url).pathname.replace(/^\/([A-Za-z]:)/, "$1"), ], target: "browser", }); expect(build.success).toBe(true); const output = await build.outputs[0]!.text(); expect(output).not.toContain("node:fs"); expect(output).not.toContain("ANTHROPIC_API_KEY"); }); });