/* Unit tests for grouper covering deterministicGroup. It also guards the documented public contract and regression-sensitive edge cases. Not a contract source of truth — the module under test owns the authoritative behavior; fixtures are minimal scaffolding only. RFC-1311: Compass header sweep — declares the grouper suite's contract for test-file scaffold coverage. */ import { describe, it, expect } from "vitest"; import { deterministicGroup } from "../changelog/agents/grouper-agent.ts"; import type { ClassifiedCommit } from "../changelog/types.ts"; function makeClassified( overrides: Partial & { hash: string; module: string }, ): ClassifiedCommit { return { type: "feat", severity: "minor", summary: "some change", isConventional: true, isBreaking: false, confidence: 0.95, ...overrides, }; } describe("deterministicGroup", () => { it("returns the provided date", () => { const result = deterministicGroup([], "2026-04-10"); expect(result.date).toBe("2026-04-10"); }); it("empty commits → empty groups", () => { const result = deterministicGroup([], "2026-04-10"); expect(result.groups).toHaveLength(0); }); it("single commit → one group with one item", () => { const commits = [makeClassified({ hash: "aaa", module: "auth", summary: "add OAuth" })]; const result = deterministicGroup(commits, "2026-04-10"); expect(result.groups).toHaveLength(1); expect(result.groups[0]!.module).toBe("auth"); expect(result.groups[0]!.items).toHaveLength(1); expect(result.groups[0]!.items[0]!.summary).toBe("add OAuth"); expect(result.groups[0]!.items[0]!.hashes).toEqual(["aaa"]); }); it("commits in the same module → one group", () => { const commits = [ makeClassified({ hash: "aaa", module: "auth", summary: "add OAuth" }), makeClassified({ hash: "bbb", module: "auth", summary: "fix token refresh" }), ]; const result = deterministicGroup(commits, "2026-04-10"); expect(result.groups).toHaveLength(1); expect(result.groups[0]!.items).toHaveLength(2); }); it("commits in different modules → separate groups", () => { const commits = [ makeClassified({ hash: "aaa", module: "auth" }), makeClassified({ hash: "bbb", module: "ui" }), makeClassified({ hash: "ccc", module: "api" }), ]; const result = deterministicGroup(commits, "2026-04-10"); const modules = result.groups.map((g) => g.module); expect(modules).toContain("auth"); expect(modules).toContain("ui"); expect(modules).toContain("api"); expect(result.groups).toHaveLength(3); }); it("group type is taken from the first commit in the module", () => { const commits = [ makeClassified({ hash: "aaa", module: "api", type: "fix" }), makeClassified({ hash: "bbb", module: "api", type: "feat" }), ]; const result = deterministicGroup(commits, "2026-04-10"); expect(result.groups[0]!.type).toBe("fix"); }); it("each item wraps its hash in an array", () => { const commits = [makeClassified({ hash: "deadbeef", module: "core" })]; const result = deterministicGroup(commits, "2026-04-10"); expect(result.groups[0]!.items[0]!.hashes).toEqual(["deadbeef"]); }); });