import { describe, expect, it } from "vitest"; import { applyConflictFix, hasApplicableFix } from "./applyFix"; describe("hasApplicableFix", () => { it("requires non-empty original and string replacement", () => { expect(hasApplicableFix({ original: "迈巴赫", replacement: "奔驰" })).toBe(true); // 空串=删除,仍可应用 expect(hasApplicableFix({ original: "删我", replacement: "" })).toBe(true); expect(hasApplicableFix({ original: null, replacement: "奔驰" })).toBe(false); expect(hasApplicableFix({ original: "", replacement: "奔驰" })).toBe(false); expect(hasApplicableFix({ original: "迈巴赫", replacement: null })).toBe(false); expect(hasApplicableFix({ original: undefined, replacement: undefined })).toBe( false, ); }); it("narrows original/replacement to string when true (type predicate)", () => { const patch: { original: string | null; replacement: string | null } = { original: "迈巴赫", replacement: "奔驰", }; if (!hasApplicableFix(patch)) throw new Error("expected applicable"); // 编译期收窄:无需强转即可当 string 拼接(`as string` 已消除)。 const combined: string = patch.original + patch.replacement; expect(combined).toBe("迈巴赫奔驰"); }); }); describe("applyConflictFix", () => { it("replaces the first occurrence of original with replacement", () => { const out = applyConflictFix( "他乘坐迈巴赫扬长而去,迈巴赫的尾灯。", "迈巴赫", "奔驰", ); expect(out.status).toBe("applied"); expect(out.text).toBe("他乘坐奔驰扬长而去,迈巴赫的尾灯。"); }); it("returns not-found and leaves text untouched when original is absent (drift)", () => { const out = applyConflictFix("作者已经手改过的终稿。", "迈巴赫", "奔驰"); expect(out.status).toBe("not-found"); expect(out.text).toBe("作者已经手改过的终稿。"); }); it("returns no-patch when conflict carries no applicable patch", () => { const out = applyConflictFix("正文", null, null); expect(out.status).toBe("no-patch"); expect(out.text).toBe("正文"); }); it("does not mutate the input string", () => { const original = "迈巴赫尾灯"; applyConflictFix(original, "迈巴赫", "奔驰"); expect(original).toBe("迈巴赫尾灯"); }); });