Skip to content

Commit 5b0606f

Browse files
committed
test(themes): add rose theme tests (JhaSourav07#2309)
1 parent e3369ea commit 5b0606f

1 file changed

Lines changed: 97 additions & 0 deletions

File tree

lib/svg/themes/rose.test.ts

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
// lib/svg/themes/rose.test.ts
2+
import { describe, it, expect } from 'vitest';
3+
import { themes } from '../themes';
4+
import { generateSVG } from '../generator';
5+
import type { BadgeParams, ContributionCalendar, StreakStats } from '../../../types';
6+
7+
describe('rose theme', () => {
8+
const hexRegex = /^#[0-9a-f]{6}$/i;
9+
10+
const mockStats: StreakStats = {
11+
currentStreak: 3,
12+
longestStreak: 7,
13+
totalContributions: 42,
14+
todayDate: '2024-06-12',
15+
};
16+
17+
const mockCalendar = {
18+
weeks: [
19+
{
20+
contributionDays: [
21+
{ contributionCount: 0, date: '2024-06-10' },
22+
{ contributionCount: 4, date: '2024-06-11' },
23+
{ contributionCount: 9, date: '2024-06-12' },
24+
],
25+
},
26+
],
27+
} as ContributionCalendar;
28+
29+
it('imports the themes object and asserts the rose key exists', () => {
30+
expect(themes).toHaveProperty('rose');
31+
expect(themes.rose).toBeDefined();
32+
});
33+
34+
it('verifies themes.rose.bg is a valid 6-character hex color', () => {
35+
expect(`#${themes.rose.bg}`, 'rose bg is invalid').toMatch(hexRegex);
36+
});
37+
38+
it('verifies themes.rose.text is a valid 6-character hex color', () => {
39+
expect(`#${themes.rose.text}`, 'rose text is invalid').toMatch(hexRegex);
40+
});
41+
42+
it('verifies themes.rose.accent is a valid 6-character hex color', () => {
43+
expect(`#${themes.rose.accent}`, 'rose accent is invalid').toMatch(hexRegex);
44+
});
45+
46+
it('generates an SVG using the rose theme and asserts theme hex colors appear in the output', () => {
47+
const rose = themes.rose;
48+
49+
const svg = generateSVG(
50+
mockStats,
51+
{
52+
user: 'tester',
53+
bg: rose.bg,
54+
text: rose.text,
55+
accent: rose.accent,
56+
speed: '8s',
57+
scale: 'linear',
58+
} as unknown as BadgeParams,
59+
mockCalendar
60+
);
61+
62+
expect(svg).toBeTypeOf('string');
63+
expect(svg.length).toBeGreaterThan(0);
64+
// The generator prepends '#' to the sanitized hex values
65+
expect(svg).toContain(`#${rose.bg}`);
66+
expect(svg).toContain(`#${rose.text}`);
67+
expect(svg).toContain(`#${rose.accent}`);
68+
});
69+
70+
it('ensures the contrast between rose bg and text is sufficient (WCAG accessibility)', () => {
71+
const hexToRgb = (hex: string): [number, number, number] => {
72+
const h = hex.replace('#', '');
73+
return [
74+
parseInt(h.substring(0, 2), 16),
75+
parseInt(h.substring(2, 4), 16),
76+
parseInt(h.substring(4, 6), 16),
77+
];
78+
};
79+
80+
const luminance = ([r, g, b]: [number, number, number]): number => {
81+
const a = [r, g, b].map((v) => {
82+
const s = v / 255;
83+
return s <= 0.03928 ? s / 12.92 : Math.pow((s + 0.055) / 1.055, 2.4);
84+
});
85+
return 0.2126 * a[0] + 0.7152 * a[1] + 0.0722 * a[2];
86+
};
87+
88+
const bgLum = luminance(hexToRgb(themes.rose.bg));
89+
const textLum = luminance(hexToRgb(themes.rose.text));
90+
const lighter = Math.max(bgLum, textLum);
91+
const darker = Math.min(bgLum, textLum);
92+
const contrastRatio = (lighter + 0.05) / (darker + 0.05);
93+
94+
// WCAG AA requires at least 4.5:1 for normal text
95+
expect(contrastRatio).toBeGreaterThanOrEqual(4.5);
96+
});
97+
});

0 commit comments

Comments
 (0)