import { describe, expect, it, vi } from "vitest"; import { collectCommitHistory, COMMIT_HISTORY_DAYS, COMMIT_HISTORY_TIME_ZONE, parseArgs, renderCsv, renderSvg, toBerlinDateKey } from "./commit-history.mjs"; const TIP = "dddddddddddddddddddddddddddddddddddddddd"; function fixtureHistory() { const rows = Array.from({ length: COMMIT_HISTORY_DAYS }, (_, index) => ({ count: index === 57 ? 151 : index === 59 ? 75 : index % 9, date: new Date(Date.UTC(2026, 5, 3 + index, 12)).toISOString().slice(0, 10), })); return { days: COMMIT_HISTORY_DAYS, endDate: "2026-08-01", resolvedRef: TIP, rows, startDate: "2026-06-03", tipTimestamp: "2026-08-01T14:17:15+02:00", }; } describe("commit-history", () => { it("defaults to a 60-day Berlin calendar window", () => { expect(parseArgs([])).toEqual({ days: 60, label: "origin/main", outputDir: "docs/metrics", ref: "origin/main", }); expect(COMMIT_HISTORY_TIME_ZONE).toBe("Europe/Berlin"); expect(() => parseArgs(["--days", "0"])).toThrow("--days must be an integer between 1 and 365"); }); it("groups offsets by their Berlin calendar date", () => { expect(toBerlinDateKey("2026-07-31T23:30:00Z")).toBe("2026-08-01"); expect(toBerlinDateKey("2026-10-25T00:30:00Z")).toBe("2026-10-25"); }); it("counts every reachable commit and preserves zero-commit days", () => { const calls = []; const runGit = vi.fn((args) => { calls.push(args); if (args[0] === "rev-parse") return `${TIP}\n`; if (args[0] === "show") return "2026-08-01T14:17:15+02:00\n"; if (args[0] === "log") { return [ `${TIP}\t2026-08-01T14:17:15+02:00`, `cccccccccccccccccccccccccccccccccccccccc\t2026-07-31T23:30:00Z`, `bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\t2026-07-30T18:00:00+02:00`, `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\t2026-07-01T10:00:00+02:00`, ].join("\n"); } throw new Error(`Unexpected Git call: ${args.join(" ")}`); }); const history = collectCommitHistory("HEAD", { days: 3, runGit }); expect(history.rows).toEqual([ { count: 1, date: "2026-07-30" }, { count: 0, date: "2026-07-31" }, { count: 2, date: "2026-08-01" }, ]); const logCall = calls.find((args) => args[0] === "log"); expect(logCall).not.toContain("--first-parent"); expect(logCall).toContain(TIP); }); it("renders deterministic CSV metadata and the approved SVG metrics", () => { const history = fixtureHistory(); const csv = renderCsv(history, "origin/main"); const svg = renderSvg(history, "origin/main"); expect(renderCsv(history, "origin/main")).toBe(csv); expect(renderSvg(history, "origin/main")).toBe(svg); expect(csv).toContain("# window_days=60"); expect(csv).toContain("# timezone=Europe/Berlin"); expect(csv).toContain("2026-08-01,75"); expect(svg).toContain("HiveGrid · Commit-Aktivität"); expect(svg).toContain("Ø PRO TAG · 60 TAGE"); expect(svg).toContain("PEAK · 30.07."); expect(svg).toContain(">151 Commits<"); expect(svg).toContain(">75 Commits<"); expect(svg).toContain("7-Tage-Durchschnitt"); }); });