import { test } from 'node:test'; import assert from 'node:assert/strict'; import { hexToRgb, lighten, darken, rgba, relativeLuminance, contrastingText, varNameFromToken, derivePrimaryPalette, } from './accentColor'; test('hexToRgb parses 6-digit hex (with/without #, trimmed)', () => { assert.deepEqual(hexToRgb('#ff8800'), { r: 255, g: 136, b: 0 }); assert.deepEqual(hexToRgb('ff8800'), { r: 255, g: 136, b: 0 }); assert.deepEqual(hexToRgb(' #FF8800 '), { r: 255, g: 136, b: 0 }); assert.equal(hexToRgb('#fff'), undefined); // 3-digit not supported assert.equal(hexToRgb('nope'), undefined); }); test('lighten moves channels toward white', () => { assert.deepEqual(lighten({ r: 255, g: 0, b: 0 }, 0.5), { r: 255, g: 127.5, b: 127.5 }); assert.deepEqual(lighten({ r: 0, g: 0, b: 0 }, 1), { r: 255, g: 255, b: 255 }); assert.deepEqual(lighten({ r: 10, g: 20, b: 30 }, 0), { r: 10, g: 20, b: 30 }); }); test('darken moves channels toward black', () => { assert.deepEqual(darken({ r: 200, g: 100, b: 50 }, 0.5), { r: 100, g: 50, b: 25 }); assert.deepEqual(darken({ r: 255, g: 255, b: 255 }, 1), { r: 0, g: 0, b: 0 }); assert.deepEqual(darken({ r: 10, g: 20, b: 30 }, 0), { r: 10, g: 20, b: 30 }); }); test('rgba formats and clamps channels', () => { assert.equal(rgba({ r: 255, g: 136, b: 0 }, 0.5), 'rgba(255, 136, 0, 0.5)'); assert.equal(rgba({ r: 300, g: -5, b: 128 }, 1), 'rgba(255, 0, 128, 1)'); }); test('relativeLuminance: black is 0, white is 1', () => { assert.ok(Math.abs(relativeLuminance({ r: 0, g: 0, b: 0 })) < 1e-9); assert.ok(Math.abs(relativeLuminance({ r: 255, g: 255, b: 255 }) - 1) < 1e-9); // green contributes more than blue (per WCAG coefficients) assert.ok(relativeLuminance({ r: 0, g: 255, b: 0 }) > relativeLuminance({ r: 0, g: 0, b: 255 })); }); test('contrastingText picks black on light, white on dark', () => { assert.equal(contrastingText({ r: 255, g: 255, b: 255 }), '#000'); assert.equal(contrastingText({ r: 0, g: 0, b: 0 }), '#fff'); }); test('varNameFromToken extracts the CSS var name', () => { assert.equal(varNameFromToken('var(--oq6d07f)'), '--oq6d07f'); assert.equal(varNameFromToken('--bare'), undefined); assert.equal(varNameFromToken('not a token'), undefined); }); test('derivePrimaryPalette produces the full Primary token set', () => { const palette = derivePrimaryPalette({ r: 255, g: 136, b: 0 }); assert.equal(Object.keys(palette).length, 10); assert.equal(palette.Main, '#ff8800'); assert.equal(palette.MainLine, '#ff8800'); assert.equal(palette.Container, 'rgba(255, 136, 0, 0.12)'); assert.equal(palette.ContainerLine, 'rgba(255, 136, 0, 0.4)'); assert.equal(palette.OnMain, contrastingText({ r: 255, g: 136, b: 0 })); // hover/active are valid 6-digit hex strings assert.match(palette.MainHover, /^#[0-9a-f]{6}$/); assert.match(palette.MainActive, /^#[0-9a-f]{6}$/); });