import { describe, it, expect } from 'vitest'; import { avatarPalette, initials } from './avatar'; describe('avatarPalette', () => { it('returns the neutral palette for empty / nullish names', () => { expect(avatarPalette(null)).toContain('bg-gray-100'); expect(avatarPalette(undefined)).toContain('bg-gray-100'); expect(avatarPalette('')).toContain('bg-gray-100'); }); it('is deterministic for the same name', () => { // Same input, repeated calls AND a separately-constructed equal string — the palette // must be a pure function of the name's characters, not of identity or call order. expect(avatarPalette('Alice')).toBe(avatarPalette('Alice')); expect(avatarPalette('Alice')).toBe(avatarPalette('Ali' + 'ce')); expect(avatarPalette('Zoë Müller')).toBe(avatarPalette('Zoë Müller')); }); it('returns a real palette entry (not neutral) for a non-empty name', () => { expect(avatarPalette('Bob')).toMatch(/bg-(blue|purple|green|amber|rose|teal)-100/); }); it('maps different names to different palette entries', () => { // Without this, `name => name ? PALETTE[0] : NEUTRAL` (i.e. the hash loop deleted) // passes every other test in this file — the palette would be a constant and every // avatar in the app would render the same colour. expect(avatarPalette('Alice')).not.toBe(avatarPalette('Bob')); }); it('spreads names across the whole palette, not just one bucket', () => { const names = [ 'Alice', 'Bob', 'Carol', 'Dave', 'Erin', 'Frank', 'Grace', 'Heidi', 'Ivan', 'Judy', 'Mallory', 'Niaj', 'Olivia', 'Peggy', 'Rupert', 'Sybil', 'Trent', 'Victor', 'Walter', 'Xena' ]; const distinct = new Set(names.map((n) => avatarPalette(n))); // 6 colours in the palette; 20 names must land on more than a couple of them. This // catches a hash that collapses (e.g. always returns index 0, or ignores all but the // first character in a way that clusters). expect(distinct.size).toBeGreaterThanOrEqual(4); }); }); describe('initials', () => { it('returns "?" for empty / nullish / whitespace-only names', () => { expect(initials(null)).toBe('?'); expect(initials(undefined)).toBe('?'); expect(initials('')).toBe('?'); expect(initials(' ')).toBe('?'); }); it('uses the first letter (uppercased) for a single word', () => { expect(initials('alice')).toBe('A'); }); it('uses the first letters of the first two words', () => { expect(initials('Alice Bob Carol')).toBe('AB'); }); it('collapses runs of whitespace between words', () => { expect(initials(' john doe ')).toBe('JD'); }); });