import { describe, expect, it } from "vitest"; import { buildSiteThemeStyleText, buildSiteThemeTokens } from "@/lib/site-theme"; const CHANNEL = /^\d+ \d+% \d+%$/; describe("buildSiteThemeTokens", () => { it("converts pure red to the expected HSL channels", () => { const tokens = buildSiteThemeTokens("#ff0000"); expect(tokens.light.primary).toBe("0 100% 50%"); // dark primary lightens by 6 and clamps saturation into [40,95] expect(tokens.dark.primary).toBe("0 95% 56%"); }); it("produces zero saturation for a neutral gray", () => { const tokens = buildSiteThemeTokens("#808080"); expect(tokens.light.primary.startsWith("0 0%")).toBe(true); }); it("emits well-formed channel strings for every token", () => { const tokens = buildSiteThemeTokens("#dc5a35"); for (const value of [ tokens.light.primary, tokens.light.secondary, tokens.dark.primary, tokens.dark.secondary, ]) { expect(value).toMatch(CHANNEL); } }); it("derives distinct dark and secondary variants", () => { const tokens = buildSiteThemeTokens("#dc5a35"); expect(tokens.dark.primary).not.toBe(tokens.light.primary); expect(tokens.light.secondary).not.toBe(tokens.light.primary); }); it("falls back to the default brand color for invalid input", () => { expect(buildSiteThemeTokens("not-a-color")).toEqual(buildSiteThemeTokens("#dc5a35")); expect(buildSiteThemeTokens("")).toEqual(buildSiteThemeTokens("#dc5a35")); }); }); describe("buildSiteThemeStyleText", () => { it("emits :root and .dark blocks with the derived channels", () => { const css = buildSiteThemeStyleText("#ff0000"); expect(css).toContain(":root {"); expect(css).toContain(".dark {"); expect(css).toContain("--primary: 0 100% 50%;"); expect(css).toContain("--brand-secondary:"); expect(css).toContain("--sidebar-ring:"); }); });