import { describe, expect, it } from "vitest"; import { emptyDecisions, setVerdict } from "./decisions"; import { displayOrder, groupConflicts, nextUnresolvedInOrder, } from "./grouping"; import type { ReviewConflict } from "./sse"; function conflict(type: string, suggestion = "x"): ReviewConflict { return { type, where: "", refs: [], suggestion }; } describe("groupConflicts", () => { it("groups by type and carries the original index", () => { const conflicts = [ conflict("性格漂移", "a"), conflict("设定违例", "b"), conflict("性格漂移", "c"), ]; const groups = groupConflicts(conflicts); const drift = groups.find((g) => g.type === "性格漂移"); expect(drift?.items.map((it) => it.index)).toEqual([0, 2]); expect(drift?.items.map((it) => it.conflict.suggestion)).toEqual(["a", "c"]); }); it("orders groups by severity (设定违例 before 性格漂移)", () => { const groups = groupConflicts([ conflict("性格漂移"), conflict("设定违例"), ]); expect(groups.map((g) => g.type)).toEqual(["设定违例", "性格漂移"]); }); it("places unknown types after the known five", () => { const groups = groupConflicts([conflict("排版错误"), conflict("能力不符")]); expect(groups.map((g) => g.type)).toEqual(["能力不符", "排版错误"]); }); it("returns an empty array for no conflicts", () => { expect(groupConflicts([])).toEqual([]); }); }); describe("displayOrder", () => { it("flattens grouped indices in display order", () => { const groups = groupConflicts([ conflict("性格漂移"), conflict("设定违例"), conflict("性格漂移"), ]); // 设定违例(index 1) 先,再 性格漂移(0,2) expect(displayOrder(groups)).toEqual([1, 0, 2]); }); }); describe("nextUnresolvedInOrder", () => { const order = [1, 0, 2]; it("finds the first unresolved when nothing is focused", () => { const drafts = emptyDecisions(3); expect(nextUnresolvedInOrder(order, drafts, null)).toBe(1); }); it("advances to the next unresolved after the focused index", () => { let drafts = emptyDecisions(3); drafts = setVerdict(drafts, 1, "accept"); expect(nextUnresolvedInOrder(order, drafts, 1)).toBe(0); }); it("wraps around to earlier unresolved items", () => { let drafts = emptyDecisions(3); drafts = setVerdict(drafts, 2, "ignore"); expect(nextUnresolvedInOrder(order, drafts, 2)).toBe(1); }); it("returns null when all are resolved", () => { let drafts = emptyDecisions(3); drafts = setVerdict(drafts, 0, "accept"); drafts = setVerdict(drafts, 1, "accept"); drafts = setVerdict(drafts, 2, "accept"); expect(nextUnresolvedInOrder(order, drafts, null)).toBeNull(); }); it("returns null for an empty order", () => { expect(nextUnresolvedInOrder([], [], null)).toBeNull(); }); });