import { describe, expect, it } from "vitest"; import { initialReviewState, parseReviewBlock, reduceReview, type ReviewSseEvent, } from "./sse"; const FULL_ISSUE = { character: "沈砚", aspect: "动机一致性", where: "第3段", quote: "他忽然转身。", diagnosis: "动机断裂", suggestion: "扣回护妹动机", confidence: 0.82, }; describe("parseReviewBlock — characterization (灵感③ advisory)", () => { it("parses a characterization frame with a full issue", () => { const evt = parseReviewBlock( `event:characterization\ndata:{"issues":[${JSON.stringify(FULL_ISSUE)}]}`, ); expect(evt).toEqual({ event: "characterization", data: { issues: [FULL_ISSUE] }, }); }); it("defaults missing issue fields (advisory 韧性)", () => { const evt = parseReviewBlock( 'event:characterization\ndata:{"issues":[{"character":"阿黎"}]}', ); expect(evt).toEqual({ event: "characterization", data: { issues: [ { character: "阿黎", aspect: "", where: "", quote: "", diagnosis: "", suggestion: "", confidence: 0, }, ], }, }); }); it("parses an empty issues frame (无明显问题降级)", () => { expect( parseReviewBlock('event:characterization\ndata:{"issues":[]}'), ).toEqual({ event: "characterization", data: { issues: [] } }); }); it("drops non-record issues without dropping the whole frame", () => { const evt = parseReviewBlock( 'event:characterization\ndata:{"issues":["junk",{"character":"沈砚"}]}', ); expect(evt?.event).toBe("characterization"); if (evt?.event === "characterization") { expect(evt.data.issues).toHaveLength(1); expect(evt.data.issues[0]?.character).toBe("沈砚"); } }); }); describe("reduceReview — characterization (replace-style like pace)", () => { it("sets characterization report and marks reviewing", () => { const evt: ReviewSseEvent = { event: "characterization", data: { issues: [FULL_ISSUE] }, }; const out = reduceReview(initialReviewState, evt); expect(out.phase).toBe("reviewing"); expect(out.characterization).toEqual({ issues: [FULL_ISSUE] }); }); it("replaces (not accumulates) the characterization report", () => { const first = reduceReview(initialReviewState, { event: "characterization", data: { issues: [FULL_ISSUE] }, }); const second = reduceReview(first, { event: "characterization", data: { issues: [] }, }); expect(second.characterization).toEqual({ issues: [] }); }); it("leaves characterization untouched on a section event", () => { const seeded = reduceReview(initialReviewState, { event: "characterization", data: { issues: [FULL_ISSUE] }, }); const out = reduceReview(seeded, { event: "section", data: { name: "characterization", status: "done" }, }); expect(out.characterization).toEqual({ issues: [FULL_ISSUE] }); expect(out.sections).toEqual([ { name: "characterization", status: "done" }, ]); }); });