|
| 1 | +import { describe, it, expect } from 'vitest'; |
| 2 | +import { themes } from './themes'; |
| 3 | +import { generateSVG } from './generator'; |
| 4 | +import { getLuminance } from './sanitizer'; |
| 5 | +import type { BadgeParams, ContributionCalendar, StreakStats } from '../../types'; |
| 6 | + |
| 7 | +describe('Nord Theme', () => { |
| 8 | + const mockStats: StreakStats = { |
| 9 | + currentStreak: 5, |
| 10 | + longestStreak: 10, |
| 11 | + totalContributions: 100, |
| 12 | + todayDate: '2024-06-12', |
| 13 | + }; |
| 14 | + |
| 15 | + const mockCalendar: ContributionCalendar = { |
| 16 | + weeks: [ |
| 17 | + { |
| 18 | + contributionDays: [{ contributionCount: 5, date: '2024-06-12' }], |
| 19 | + }, |
| 20 | + ], |
| 21 | + } as ContributionCalendar; |
| 22 | + |
| 23 | + it('should exist as a theme key', () => { |
| 24 | + expect(themes.nord).toBeDefined(); |
| 25 | + }); |
| 26 | + |
| 27 | + it('should have valid hex background color', () => { |
| 28 | + expect(themes.nord.bg).toMatch(/^[0-9a-f]{6}$/i); |
| 29 | + }); |
| 30 | + |
| 31 | + it('should have valid hex text color', () => { |
| 32 | + expect(themes.nord.text).toMatch(/^[0-9a-f]{6}$/i); |
| 33 | + }); |
| 34 | + |
| 35 | + it('should have valid hex accent color', () => { |
| 36 | + expect(themes.nord.accent).toMatch(/^[0-9a-f]{6}$/i); |
| 37 | + }); |
| 38 | + |
| 39 | + it('should generate SVG containing nord theme colors', () => { |
| 40 | + const svg = generateSVG( |
| 41 | + mockStats, |
| 42 | + { |
| 43 | + user: 'octocat', |
| 44 | + bg: themes.nord.bg, |
| 45 | + text: themes.nord.text, |
| 46 | + accent: themes.nord.accent, |
| 47 | + } as BadgeParams, |
| 48 | + mockCalendar |
| 49 | + ); |
| 50 | + |
| 51 | + expect(svg).toContain('<svg'); |
| 52 | + expect(svg).toContain('</svg>'); |
| 53 | + expect(svg.toLowerCase()).toContain(themes.nord.bg.toLowerCase()); |
| 54 | + expect(svg.toLowerCase()).toContain(themes.nord.text.toLowerCase()); |
| 55 | + expect(svg.toLowerCase()).toContain(themes.nord.accent.toLowerCase()); |
| 56 | + }); |
| 57 | + |
| 58 | + it('should provide sufficient contrast between bg and text', () => { |
| 59 | + const bgLum = getLuminance(themes.nord.bg); |
| 60 | + const textLum = getLuminance(themes.nord.text); |
| 61 | + |
| 62 | + const lighter = Math.max(bgLum, textLum); |
| 63 | + const darker = Math.min(bgLum, textLum); |
| 64 | + |
| 65 | + const contrastRatio = (lighter + 0.05) / (darker + 0.05); |
| 66 | + |
| 67 | + expect(contrastRatio).toBeGreaterThan(4.5); |
| 68 | + }); |
| 69 | +}); |
0 commit comments