|
| 1 | +import { describe, expect, it, vi } from 'vitest' |
| 2 | +vi.mock('@/components/Canvas/styles', () => ({ styles: { colors: { background: '#121213' } } })) |
| 3 | +const { getColor, loadRenderImages } = vi.hoisted(() => ({ |
| 4 | + getColor: vi.fn(() => [40, 8, 8]), |
| 5 | + loadRenderImages: vi.fn(async (sources: string[]) => new Map(sources.map(source => [source, {}]))), |
| 6 | +})) |
| 7 | +vi.mock('colorthief', () => ({ default: class { getColor = getColor } })) |
| 8 | +vi.mock('./iconImages', () => ({ loadRenderImages })) |
| 9 | +import { automaticBuffColor, contrastRatio, FALLBACK_BUFF_COLOR, readableBuffColor, resolveBuffColors } from './buffColors' |
| 10 | + |
| 11 | +describe('icon-derived buff colours', () => { |
| 12 | + it.each(['#280808', '#081828', '#182808', '#000000', '#121213'])('brightens %s to at least 3:1 contrast', color => { |
| 13 | + expect(contrastRatio(readableBuffColor(color), '#121213')).toBeGreaterThanOrEqual(3) |
| 14 | + }) |
| 15 | + it('preserves readable colours and the hue of a dark red', () => { |
| 16 | + expect(readableBuffColor('#f0c674')).toBe('#f0c674') |
| 17 | + const adjusted = readableBuffColor('#280808') |
| 18 | + expect(adjusted.slice(3, 5)).toBe(adjusted.slice(5, 7)) |
| 19 | + expect(parseInt(adjusted.slice(1, 3), 16)).toBeGreaterThan(parseInt(adjusted.slice(3, 5), 16)) |
| 20 | + }) |
| 21 | + it('shares extraction across simultaneous requests for the same icon', async () => { |
| 22 | + const before = getColor.mock.calls.length |
| 23 | + const results = await Promise.all([automaticBuffColor('/red.png'), automaticBuffColor('/red.png')]) |
| 24 | + expect(results[0]).toBe(results[1]) |
| 25 | + expect(getColor.mock.calls.length - before).toBe(1) |
| 26 | + }) |
| 27 | + it('falls back on failure and permits a later retry', async () => { |
| 28 | + loadRenderImages.mockRejectedValueOnce(new Error('Unavailable')) |
| 29 | + expect(await automaticBuffColor('/retry.png')).toBe(FALLBACK_BUFF_COLOR) |
| 30 | + expect(await automaticBuffColor('/retry.png')).not.toBe(FALLBACK_BUFF_COLOR) |
| 31 | + expect(await automaticBuffColor('')).toBe(FALLBACK_BUFF_COLOR) |
| 32 | + }) |
| 33 | + it('resolves only automatic enabled statuses without changing source actions', async () => { |
| 34 | + const statuses = ['auto', '#123456'].map((color, i) => ({ id: String(i), name: 'Buff', imageSrc: '/red.png', color, duration: 20, applicationDelay: 0 })) |
| 35 | + const actions = [{ id: '1', instanceId: '1', type: 'gcd' as const, name: 'Action', imageSrc: '', statusesApplied: [...statuses, { ...statuses[0], enabled: false }] }] |
| 36 | + const resolved = await resolveBuffColors(actions) |
| 37 | + expect(resolved[0].statusesApplied![0].color).not.toBe('auto') |
| 38 | + expect(resolved[0].statusesApplied![1].color).toBe('#123456') |
| 39 | + expect(resolved[0].statusesApplied![2].color).toBe('auto') |
| 40 | + expect(actions[0].statusesApplied[0].color).toBe('auto') |
| 41 | + }) |
| 42 | +}) |
0 commit comments