Skip to content

Commit 08290d2

Browse files
committed
test: add unit tests for color utilities and key text mapping
1 parent 45bb60f commit 08290d2

File tree

1 file changed

+177
-0
lines changed

1 file changed

+177
-0
lines changed
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
import { Image } from './types';
2+
import { getKeyText, instrumentColors, isDarkColor } from './utils';
3+
4+
// Mock canvasFactory
5+
jest.mock('./canvasFactory', () => ({
6+
createCanvas: jest.fn().mockImplementation((width, height) => ({
7+
width,
8+
height,
9+
getContext: jest.fn().mockReturnValue({
10+
fillStyle: '',
11+
fillRect: jest.fn(),
12+
globalCompositeOperation: '',
13+
globalAlpha: 0,
14+
drawImage: jest.fn(),
15+
}),
16+
})),
17+
}));
18+
19+
// Mock Image type
20+
const mockImage: Image = {
21+
width: 100,
22+
height: 100,
23+
};
24+
25+
describe('instrumentColors', () => {
26+
it('should contain 16 color codes', () => {
27+
expect(instrumentColors).toHaveLength(16);
28+
29+
instrumentColors.forEach((color) => {
30+
expect(color).toMatch(/^#[0-9a-f]{6}$/);
31+
});
32+
});
33+
});
34+
35+
describe('getKeyText', () => {
36+
it('should return correct note and octave for given key number', () => {
37+
// Full range of keys from 0 to 87
38+
const testCases = [
39+
{ key: 0, expected: 'A0' },
40+
{ key: 1, expected: 'A#0' },
41+
{ key: 2, expected: 'B0' },
42+
{ key: 3, expected: 'C1' },
43+
{ key: 4, expected: 'C#1' },
44+
{ key: 5, expected: 'D1' },
45+
{ key: 6, expected: 'D#1' },
46+
{ key: 7, expected: 'E1' },
47+
{ key: 8, expected: 'F1' },
48+
{ key: 9, expected: 'F#1' },
49+
{ key: 10, expected: 'G1' },
50+
{ key: 11, expected: 'G#1' },
51+
{ key: 12, expected: 'A1' },
52+
{ key: 13, expected: 'A#1' },
53+
{ key: 14, expected: 'B1' },
54+
{ key: 15, expected: 'C2' },
55+
{ key: 16, expected: 'C#2' },
56+
{ key: 17, expected: 'D2' },
57+
{ key: 18, expected: 'D#2' },
58+
{ key: 19, expected: 'E2' },
59+
{ key: 20, expected: 'F2' },
60+
{ key: 21, expected: 'F#2' },
61+
{ key: 22, expected: 'G2' },
62+
{ key: 23, expected: 'G#2' },
63+
{ key: 24, expected: 'A2' },
64+
{ key: 25, expected: 'A#2' },
65+
{ key: 26, expected: 'B2' },
66+
{ key: 27, expected: 'C3' },
67+
{ key: 28, expected: 'C#3' },
68+
{ key: 29, expected: 'D3' },
69+
{ key: 30, expected: 'D#3' },
70+
{ key: 31, expected: 'E3' },
71+
{ key: 32, expected: 'F3' },
72+
{ key: 33, expected: 'F#3' },
73+
{ key: 34, expected: 'G3' },
74+
{ key: 35, expected: 'G#3' },
75+
{ key: 36, expected: 'A3' },
76+
{ key: 37, expected: 'A#3' },
77+
{ key: 38, expected: 'B3' },
78+
{ key: 39, expected: 'C4' },
79+
{ key: 40, expected: 'C#4' },
80+
{ key: 41, expected: 'D4' },
81+
{ key: 42, expected: 'D#4' },
82+
{ key: 43, expected: 'E4' },
83+
{ key: 44, expected: 'F4' },
84+
{ key: 45, expected: 'F#4' },
85+
{ key: 46, expected: 'G4' },
86+
{ key: 47, expected: 'G#4' },
87+
{ key: 48, expected: 'A4' },
88+
{ key: 49, expected: 'A#4' },
89+
{ key: 50, expected: 'B4' },
90+
{ key: 51, expected: 'C5' },
91+
{ key: 52, expected: 'C#5' },
92+
{ key: 53, expected: 'D5' },
93+
{ key: 54, expected: 'D#5' },
94+
{ key: 55, expected: 'E5' },
95+
{ key: 56, expected: 'F5' },
96+
{ key: 57, expected: 'F#5' },
97+
{ key: 58, expected: 'G5' },
98+
{ key: 59, expected: 'G#5' },
99+
{ key: 60, expected: 'A5' },
100+
{ key: 61, expected: 'A#5' },
101+
{ key: 62, expected: 'B5' },
102+
{ key: 63, expected: 'C6' },
103+
{ key: 64, expected: 'C#6' },
104+
{ key: 65, expected: 'D6' },
105+
{ key: 66, expected: 'D#6' },
106+
{ key: 67, expected: 'E6' },
107+
{ key: 68, expected: 'F6' },
108+
{ key: 69, expected: 'F#6' },
109+
{ key: 70, expected: 'G6' },
110+
{ key: 71, expected: 'G#6' },
111+
{ key: 72, expected: 'A6' },
112+
{ key: 73, expected: 'A#6' },
113+
{ key: 74, expected: 'B6' },
114+
{ key: 75, expected: 'C7' },
115+
{ key: 76, expected: 'C#7' },
116+
{ key: 77, expected: 'D7' },
117+
{ key: 78, expected: 'D#7' },
118+
{ key: 79, expected: 'E7' },
119+
{ key: 80, expected: 'F7' },
120+
{ key: 81, expected: 'F#7' },
121+
{ key: 82, expected: 'G7' },
122+
{ key: 83, expected: 'G#7' },
123+
{ key: 84, expected: 'A7' },
124+
{ key: 85, expected: 'A#7' },
125+
{ key: 86, expected: 'B7' },
126+
{ key: 87, expected: 'C8' },
127+
];
128+
129+
testCases.forEach(({ key, expected }) => {
130+
expect(getKeyText(key)).toBe(expected);
131+
});
132+
});
133+
});
134+
135+
describe('isDarkColor', () => {
136+
it('should correctly identify dark colors', () => {
137+
// Test with default threshold (40)
138+
expect(isDarkColor('#000000')).toBe(true); // black
139+
expect(isDarkColor('#0000FF')).toBe(true); // blue
140+
expect(isDarkColor('#FF0000')).toBe(false); // red
141+
expect(isDarkColor('#00FF00')).toBe(false); // green
142+
expect(isDarkColor('#333333')).toBe(false); // mid gray
143+
expect(isDarkColor('#444444')).toBe(false); // dark gray
144+
expect(isDarkColor('#888888')).toBe(false); // light gray
145+
expect(isDarkColor('#be6b6b')).toBe(false); // light red
146+
expect(isDarkColor('#1964ac')).toBe(false); // first instrument color
147+
expect(isDarkColor('#FFFFFF')).toBe(false); // white
148+
expect(isDarkColor('#F0F0F0')).toBe(false); // light gray
149+
expect(isDarkColor('#be6b6b')).toBe(false); // light red
150+
});
151+
152+
it('should respect custom threshold', () => {
153+
// TODO: Add more test cases for different thresholds
154+
expect(isDarkColor('#888888', 100)).toBe(false);
155+
expect(isDarkColor('#888888', 50)).toBe(false);
156+
expect(isDarkColor('#444444', 50)).toBe(false);
157+
expect(isDarkColor('#444444', 130)).toBe(true);
158+
});
159+
160+
it('should handle invalid color strings', () => {
161+
// This is testing the implementation detail that falls back to empty string
162+
expect(isDarkColor('notacolor')).toBe(true);
163+
expect(isDarkColor('')).toBe(true);
164+
});
165+
});
166+
167+
describe('getLuma', () => {
168+
// Note: getLuma isn't exported, but we can test it through isDarkColor
169+
it('should calculate luma correctly', () => {
170+
// These values are calculated from the formula in the code
171+
expect(isDarkColor('#000000')).toBe(true); // 0
172+
expect(isDarkColor('#FFFFFF')).toBe(false); // 255
173+
expect(isDarkColor('#FF0000')).toBe(false); // ~54.213
174+
expect(isDarkColor('#00FF00')).toBe(false); // ~182.376
175+
expect(isDarkColor('#0000FF')).toBe(true); // ~18.414
176+
});
177+
});

0 commit comments

Comments
 (0)