import { describe, expect, it } from "vitest"; import { hueMatrix, levelTone, resolveTone, TONES, toneFilters, toneWash } from "./tone.js"; describe("toneFilters", () => { it("writes each layer's filter as literal values", () => { const filters = toneFilters(TONES.regular.dark); expect(filters.body.full).toBe("blur(1px) saturate(1.325) contrast(0.781) brightness(0.7915)"); expect(filters.shade.full).toBe("brightness(1.33)"); expect(filters.glow.full).toBe("saturate(1.1) brightness(1.3)"); expect(filters.edge.full).toBe("brightness(0.66)"); expect(filters.highlight.full).toBe("contrast(1.1) brightness(2.4)"); }); it("diffuses floating glass more", () => { expect(toneFilters(TONES.regular.dark, true).body.full).toBe("blur(6px) saturate(1.45) contrast(0.724) brightness(0.7445)"); expect(toneFilters(TONES.regular.light, true).body.full).toBe("blur(4.5px) saturate(1.35) contrast(0.5) brightness(1.355)"); }); it("drops identity functions and clears the same list", () => { expect(toneFilters(TONES.regular.light).body).toEqual({ full: "blur(1px) saturate(1.3)", clear: "blur(0px) saturate(1)" }); expect(toneFilters(TONES.clear.dark).body).toEqual({ full: "saturate(1.05) contrast(0.97) brightness(0.96)", clear: "saturate(1) contrast(1) brightness(1)", }); expect(toneFilters(TONES.clear.light).glow).toEqual({ full: "brightness(1.02)", clear: "brightness(1)" }); }); it("leaves a layer unfiltered when every value is identity", () => { expect(toneFilters(TONES.lens.light).body).toEqual({ full: "none", clear: "none" }); }); }); describe("levelTone", () => { it("runs from More Clear through the default to More Tinted", () => { expect(levelTone("light", 0)).toMatchObject({ blur: 0, tint: 0.04 }); expect(levelTone("light", 0.5)).toMatchObject({ blur: 1, saturate: 1.3, tint: 0.175 }); expect(levelTone("light", 1)).toMatchObject({ blur: 5, contrast: 0.744, brightness: 1.173, tint: 0.4 }); expect(levelTone("dark", 1).brightness).toBeLessThan(levelTone("dark", 0).brightness); }); it("keeps floating glass frosted at every level", () => { expect(levelTone("dark", 0).floatingBlur).toBeGreaterThan(0); expect(levelTone("light", 0).floatingBlur).toBeGreaterThan(0); }); it("clamps levels outside 0–1", () => { expect(levelTone("dark", -1)).toEqual(levelTone("dark", 0)); expect(levelTone("dark", 3)).toEqual(levelTone("dark", 1)); }); }); describe("resolveTone", () => { it("overrides only the given appearance", () => { const overrides = { dark: { tint: 0.5 } }; expect(resolveTone("regular", "dark", overrides).tint).toBe(0.5); expect(resolveTone("regular", "light", overrides).tint).toBe(TONES.regular.light.tint); }); it("takes regular glass's level, and leaves the other variants as they are", () => { expect(resolveTone("regular", "light", undefined, 1).tint).toBe(0.4); expect(resolveTone("clear", "light", undefined, 1)).toEqual(TONES.clear.light); }); }); describe("toneWash", () => { it("mixes the tint by the tone's share", () => { expect(toneWash(TONES.regular.light, "var(--surface)")).toBe("color-mix(in srgb, var(--surface) 17.5%, transparent)"); expect(toneWash(TONES.regular.dark, "black")).toBe("color-mix(in srgb, black 23.5%, transparent)"); expect(toneWash(TONES.regular.dark, "black", true)).toBe("color-mix(in srgb, black 31%, transparent)"); expect(toneWash(TONES.lens.dark, "black")).toBe("transparent"); }); }); describe("hueMatrix", () => { it("leaves neutral colours untinted", () => { expect(hueMatrix([128, 128, 128], 1)).toBeNull(); expect(hueMatrix([255, 255, 255], 1)).toBeNull(); }); it("keeps alpha and shifts channels toward the hue", () => { const rows = hueMatrix([20, 30, 60], 1)?.split(" ").map(Number) ?? []; expect(rows).toHaveLength(20); expect(rows.slice(15)).toEqual([0, 0, 0, 1, 0]); // Blue gains, red loses: the blue row's own weight rises above red's. expect(rows[12]).toBeGreaterThan(rows[0] ?? 0); }); it("scales with strength", () => { const full = hueMatrix([20, 30, 60], 1)?.split(" ").map(Number) ?? []; const half = hueMatrix([20, 30, 60], 0.5)?.split(" ").map(Number) ?? []; expect(Math.abs((half[12] ?? 0) - 1)).toBeCloseTo(Math.abs((full[12] ?? 0) - 1) / 2, 3); }); });