/** * ───────────────────────────────────────────── * SPB Git — Personal Git Platform * ───────────────────────────────────────────── * Author : Simon-Pierre Boucher * Contact : contact@spboucher.ai * File : test/unit/activity.test.mjs * Purpose : Unit tests — contribution calendar building * License : MIT © Simon-Pierre Boucher * ───────────────────────────────────────────── */ import { describe, it, expect } from 'vitest'; import { bucketByDay, buildCalendar, calendarSvg } from '../../src/stats/activity.mjs'; describe('bucketByDay', () => { it('groups unix timestamps by UTC day', () => { const noon = Date.UTC(2026, 0, 15, 12) / 1000; const evening = Date.UTC(2026, 0, 15, 22) / 1000; const nextDay = Date.UTC(2026, 0, 16, 1) / 1000; const days = bucketByDay([noon, evening, nextDay]); expect(days.get('2026-01-15')).toBe(2); expect(days.get('2026-01-16')).toBe(1); }); }); describe('buildCalendar', () => { it('builds 52 weeks ending today with levels 0-4', () => { const today = new Date(Date.UTC(2026, 7, 9)); const days = new Map([ ['2026-08-09', 12], ['2026-08-08', 3], ['2026-08-01', 1], ]); const cal = buildCalendar(days, today); expect(cal.weeks).toHaveLength(52); expect(cal.total).toBe(16); expect(cal.max).toBe(12); const flat = cal.weeks.flat().filter(Boolean); const busiest = flat.find((d) => d.date === '2026-08-09'); expect(busiest.level).toBe(4); const light = flat.find((d) => d.date === '2026-08-01'); expect(light.level).toBe(1); // Last cell of the grid is today. expect(flat[flat.length - 1].date).toBe('2026-08-09'); }); }); describe('calendarSvg', () => { it('renders an accessible SVG with tooltips', () => { const cal = buildCalendar(new Map([['2026-08-09', 2]]), new Date(Date.UTC(2026, 7, 9))); const svg = calendarSvg(cal); expect(svg).toContain('2 commits on 2026-08-09'); }); });