import { describe, expect, test } from "bun:test"; import { DEFAULT_ACCENT_HUE, deriveContrastingForeground, getTeamAccentCssVariables, getTeamAccentHue, normalizeAccentHue, parseAccentHue, } from "./team-theme"; describe("accent hue parsing", () => { test("normalizes equivalent hues", () => { expect(normalizeAccentHue(360)).toBe(0); expect(normalizeAccentHue(-15)).toBe(345); expect(normalizeAccentHue(725)).toBe(5); }); test("treats missing or invalid persisted hues as unset", () => { expect(parseAccentHue(null)).toBeNull(); expect(parseAccentHue("")).toBeNull(); expect(parseAccentHue("not-a-color")).toBeNull(); expect(parseAccentHue("361")).toBeNull(); }); }); describe("team accent CSS variables", () => { test("sets the existing accent hue and theme-specific foregrounds", () => { expect(getTeamAccentCssVariables(195)).toEqual({ "--accent-hue": "195", "--team-primary-foreground-light": "oklch(0.1 0 0)", "--team-primary-foreground-dark": "oklch(0.1 0 0)", }); }); test("chooses the higher-contrast neutral foreground", () => { expect( deriveContrastingForeground({ lightness: 0.2, chroma: 0, hue: 0 }), ).toBe("oklch(0.98 0 0)"); expect( deriveContrastingForeground({ lightness: 0.8, chroma: 0, hue: 0 }), ).toBe("oklch(0.1 0 0)"); }); }); describe("team color -> accent hue", () => { test("extracts the hue from a numeric oklch color", () => { expect(getTeamAccentHue("oklch(0.6 0.15 210)")).toBe(210); expect(getTeamAccentHue("oklch(0.55 0.12 34)")).toBe(34); // Out-of-range hue is normalized onto the 0..360 circle. expect(getTeamAccentHue("oklch(0.6 0.15 380)")).toBe(20); }); test("derives a hue from hex colors on the same OKLab circle", () => { const red = getTeamAccentHue("#ff0000"); const green = getTeamAccentHue("#00ff00"); const blue = getTeamAccentHue("#0000ff"); expect(red).toBeGreaterThan(20); expect(red).toBeLessThan(40); expect(green).toBeGreaterThan(135); expect(green).toBeLessThan(150); expect(blue).toBeGreaterThan(255); expect(blue).toBeLessThan(272); }); test("treats shorthand hex the same as full hex", () => { expect(getTeamAccentHue("#f00")).toBeCloseTo( getTeamAccentHue("#ff0000"), 5, ); }); test("falls back to the default hue for achromatic or invalid input", () => { expect(getTeamAccentHue("#808080")).toBe(DEFAULT_ACCENT_HUE); expect(getTeamAccentHue("#000000")).toBe(DEFAULT_ACCENT_HUE); expect(getTeamAccentHue("#ffffff")).toBe(DEFAULT_ACCENT_HUE); expect(getTeamAccentHue("not-a-color")).toBe(DEFAULT_ACCENT_HUE); expect(getTeamAccentHue(null)).toBe(DEFAULT_ACCENT_HUE); expect(getTeamAccentHue(undefined)).toBe(DEFAULT_ACCENT_HUE); }); });