Files
edr-platform/apps/edr-freight-web/backoffice/src/components/contracts/ArticleBodyDiff.test.ts

62 lines
2.1 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { diffWords } from "./ArticleBodyDiff";
/** Rebuild each side from the token stream — the diff must lose nothing. */
const rebuild = (
tokens: ReturnType<typeof diffWords>,
side: "before" | "after",
): string =>
tokens
.filter((t) =>
side === "before" ? t.op !== "added" : t.op !== "removed",
)
.map((t) => t.text)
.join("");
describe("diffWords", () => {
it("marks only the words that actually changed", () => {
const tokens = diffWords(
"The carrier shall deliver within 30 days.",
"The carrier shall deliver within 45 days.",
);
expect(tokens.filter((t) => t.op === "removed").map((t) => t.text)).toEqual([
"30",
]);
expect(tokens.filter((t) => t.op === "added").map((t) => t.text)).toEqual([
"45",
]);
});
it("reconstructs both sides losslessly, whitespace included", () => {
const before = "Payment is due\nwithin ten (10) working days.";
const after = "Payment is due\nwithin five (5) working days of invoice.";
const tokens = diffWords(before, after);
expect(rebuild(tokens, "before")).toBe(before);
expect(rebuild(tokens, "after")).toBe(after);
});
it("reports nothing changed for identical text", () => {
const tokens = diffWords("Same clause.", "Same clause.");
expect(tokens.every((t) => t.op === "same")).toBe(true);
});
it("handles a body being emptied or written from scratch", () => {
expect(rebuild(diffWords("Some clause.", ""), "after")).toBe("");
expect(rebuild(diffWords("", "Brand new clause."), "before")).toBe("");
});
it("falls back to a whole-block replace on pathological input", () => {
// Past MAX_TOKENS the LCS table is skipped; the change must still be
// reported truthfully rather than silently dropped.
const before = Array.from({ length: 2000 }, (_, i) => `a${i}`).join(" ");
const after = Array.from({ length: 2000 }, (_, i) => `b${i}`).join(" ");
const tokens = diffWords(before, after);
expect(rebuild(tokens, "before")).toBe(before);
expect(rebuild(tokens, "after")).toBe(after);
});
});