Files
oh-my-pi/packages/coding-agent/test/session-color.test.ts
T
can1357 1379772628 refactor(utils): consolidate color utilities into pi-utils
Move the color math added for the session-accent fix into the shared
@oh-my-pi/pi-utils color module instead of a coding-agent-local file:

- colorLuma, relativeLuminance, and hslToHex now live in
  packages/utils/src/color.ts (hslToHex lifted out of session-color.ts).
- Drop the duplicate hex parser: toRgb reuses the existing hexToRgb and
  paletteToRgb returns the shared RGB type, so hex parsing lives once.
- Delete packages/coding-agent/src/utils/color.ts; theme.ts and
  session-color.ts import from @oh-my-pi/pi-utils.
- Move the color unit test into the utils package; repoint session-color
  test imports.

No behavior change to accent luminance capping.
2026-06-04 05:27:11 +02:00

43 lines
1.7 KiB
TypeScript

import { describe, expect, it } from "bun:test";
import { relativeLuminance } from "@oh-my-pi/pi-utils";
import { getSessionAccentHex } from "../src/utils/session-color";
const lum = (hex: string): number => relativeLuminance(hex) ?? 0;
const contrast = (a: number, b: number): number => (Math.max(a, b) + 0.05) / (Math.min(a, b) + 0.05);
const names = Array.from({ length: 600 }, (_, i) => `analyze-debian-trixie-${i}`);
// Shipped light statusLineBg surfaces (WCAG luminance), near-white through mid-light.
const SURFACES: Record<string, number> = {
"light-catppuccin crust (#dce0e8)": lum("#dce0e8"),
"light-poimandres (#7390aa)": lum("#7390aa"),
};
describe("getSessionAccentHex", () => {
it("is deterministic per name and surface", () => {
expect(getSessionAccentHex("analyze debian trixie")).toBe(getSessionAccentHex("analyze debian trixie"));
expect(getSessionAccentHex("x", 0.7)).toBe(getSessionAccentHex("x", 0.7));
});
it("keeps vivid (bright) accents on dark themes (undefined surface)", () => {
const maxDark = Math.max(...names.map(n => lum(getSessionAccentHex(n))));
expect(maxDark).toBeGreaterThan(0.5);
});
it("clears AA-large WCAG contrast against light surfaces, including mid-light", () => {
for (const bg of Object.values(SURFACES)) {
for (const name of names) {
const hex = getSessionAccentHex(name, bg);
expect(contrast(lum(hex), bg)).toBeGreaterThanOrEqual(2.99); // ~3:1, float margin
}
}
});
it("never produces a lighter accent on light themes than on dark for the same name", () => {
const nearWhite = SURFACES["light-catppuccin crust (#dce0e8)"];
for (const name of names) {
expect(lum(getSessionAccentHex(name, nearWhite))).toBeLessThanOrEqual(lum(getSessionAccentHex(name)) + 1e-9);
}
});
});