Skip to content

Commit 44aa647

Browse files
authored
test(themes): add forest theme tests (JhaSourav07#2308) (JhaSourav07#3124)
## Description Fixes JhaSourav07#2308 Created a dedicated unit test file `lib/svg/themes/forest.test.ts` to verify the color variables and configuration of the `forest` theme, as outlined in the issue. ### Implementation Steps Covered - ✅ Imports the `themes` object from `lib/svg/themes.ts` - ✅ Asserts the `forest` key exists - ✅ Verifies `themes.forest.bg`, `themes.forest.text`, and `themes.forest.accent` are valid 6-character hex strings (using regex) - ✅ Generates a dummy SVG using `generateSVG` configured with the forest theme and asserts the theme's hex colors appear in the output - ✅ Ensures the contrast between `bg` and `text` meets WCAG AA accessibility criteria (≥ 4.5:1) ### 6 Tests Added — All Passing ✅ 1. ✅ **imports the themes object and asserts the forest key exists** 2. ✅ **verifies `themes.forest.bg` is a valid 6-character hex color** 3. ✅ **verifies `themes.forest.text` is a valid 6-character hex color** 4. ✅ **verifies `themes.forest.accent` is a valid 6-character hex color** 5. ✅ **generates an SVG using the forest theme and asserts theme hex colors appear in the output** 6. ✅ **ensures the contrast between forest bg and text is sufficient (WCAG accessibility)** **Test Summary:** - Test Files: `1 passed (1)` - Tests: `6 passed (6)` - Command used: `npx vitest run lib/svg/themes/forest.test.ts` ## Pillar - [x] 🎨 Pillar 1 — New Theme Design - [ ] 📐 Pillar 2 — Geometric SVG Improvement - [ ] 🕐 Pillar 3 — Timezone Logic Optimization - [ ] 🛠️ Other (Bug fix, refactoring, docs) ## Visual Preview _No visual changes — this PR adds test coverage only (no UI/SVG output modifications)._ ## Checklist before requesting a review: - [x] I have read the `CONTRIBUTING.md` file. - [x] I have tested these changes locally (`npx vitest run lib/svg/themes/forest.test.ts` — all 6 tests pass). - [x] I have run `npm run format` and `npm run lint` locally and resolved all errors (CI will fail otherwise). - [x] My commits follow the Conventional Commits format (e.g., `feat(themes): ...`, `fix(calculate): ...`). - [ ] I have updated `README.md` if I added a new theme or URL parameter. - [ ] I have started the repo. - [x] I have made sure that i have only one commit to merge in this PR. - [x] The SVG output matches the CommitPulse "premium quality" aesthetic standard (no raw elements, smooth animations, correct fonts). - [ ] (Recommended) I joined the CommitPulse Discord community for contributor discussions, mentorship, and faster PR support.
2 parents 14b45a4 + 5a1a76c commit 44aa647

1 file changed

Lines changed: 97 additions & 0 deletions

File tree

lib/svg/themes/forest.test.ts

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
// lib/svg/themes/forest.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('forest 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 forest key exists', () => {
30+
expect(themes).toHaveProperty('forest');
31+
expect(themes.forest).toBeDefined();
32+
});
33+
34+
it('verifies themes.forest.bg is a valid 6-character hex color', () => {
35+
expect(`#${themes.forest.bg}`, 'forest bg is invalid').toMatch(hexRegex);
36+
});
37+
38+
it('verifies themes.forest.text is a valid 6-character hex color', () => {
39+
expect(`#${themes.forest.text}`, 'forest text is invalid').toMatch(hexRegex);
40+
});
41+
42+
it('verifies themes.forest.accent is a valid 6-character hex color', () => {
43+
expect(`#${themes.forest.accent}`, 'forest accent is invalid').toMatch(hexRegex);
44+
});
45+
46+
it('generates an SVG using the forest theme and asserts theme hex colors appear in the output', () => {
47+
const forest = themes.forest;
48+
49+
const svg = generateSVG(
50+
mockStats,
51+
{
52+
user: 'tester',
53+
bg: forest.bg,
54+
text: forest.text,
55+
accent: forest.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(`#${forest.bg}`);
66+
expect(svg).toContain(`#${forest.text}`);
67+
expect(svg).toContain(`#${forest.accent}`);
68+
});
69+
70+
it('ensures the contrast between forest 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.forest.bg));
89+
const textLum = luminance(hexToRgb(themes.forest.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)