import { describe, expect, it } from "vite-plus/test"; import { buildFileDiffRenderKey, buildPatchCacheKey, getDiffLineStat, getRenderablePatch, } from "./diffRendering"; describe("buildPatchCacheKey", () => { it("returns a stable cache key for identical content", () => { const patch = "diff --git a/a.ts b/a.ts\n+console.log('hello')"; expect(buildPatchCacheKey(patch)).toBe(buildPatchCacheKey(patch)); }); it("normalizes outer whitespace before hashing", () => { const patch = "diff --git a/a.ts b/a.ts\n+console.log('hello')"; expect(buildPatchCacheKey(`\n${patch}\n`)).toBe(buildPatchCacheKey(patch)); }); it("changes when diff content changes", () => { const before = "diff --git a/a.ts b/a.ts\n+console.log('hello')"; const after = "diff --git a/a.ts b/a.ts\n+console.log('hello world')"; expect(buildPatchCacheKey(before)).not.toBe(buildPatchCacheKey(after)); }); it("changes when cache scope changes", () => { const patch = "diff --git a/a.ts b/a.ts\n+console.log('hello')"; expect(buildPatchCacheKey(patch, "diff-panel:light")).not.toBe( buildPatchCacheKey(patch, "diff-panel:dark"), ); }); }); describe("getRenderablePatch", () => { it("compacts partial hunk render offsets for virtualized review diffs", () => { const patch = [ "diff --git a/example.ts b/example.ts", "index 1111111..2222222 100644", "--- a/example.ts", "+++ b/example.ts", "@@ -48,4 +48,4 @@", " context", "-before", "+after", " context", " context", "@@ -80,3 +80,4 @@", " context", "+added", " context", " context", ].join("\n"); const parsed = getRenderablePatch(patch, "review", { compactPartialHunkOffsets: true, }); expect(parsed?.kind).toBe("files"); if (parsed?.kind !== "files") return; const file = parsed.files[0]; expect(file?.hunks[0]?.collapsedBefore).toBe(47); expect(file?.hunks[0]?.unifiedLineStart).toBe(0); expect(file?.hunks[1]?.collapsedBefore).toBeGreaterThan(0); expect(file?.hunks[1]?.unifiedLineStart).toBe(file?.hunks[0]?.unifiedLineCount); expect(file?.unifiedLineCount).toBe( file?.hunks.reduce((total, hunk) => total + hunk.unifiedLineCount, 0), ); }); it("retains source-file offsets for checkpoint diffs", () => { const patch = [ "diff --git a/example.ts b/example.ts", "--- a/example.ts", "+++ b/example.ts", "@@ -48,1 +48,1 @@", "-before", "+after", ].join("\n"); const parsed = getRenderablePatch(patch, "checkpoint"); expect(parsed?.kind).toBe("files"); if (parsed?.kind !== "files") return; expect(parsed.files[0]?.hunks[0]?.unifiedLineStart).toBe(47); }); }); describe("buildFileDiffRenderKey", () => { it("keeps file identity stable when Pierre hydrates a partial diff", () => { const patch = [ "diff --git a/example.ts b/example.ts", "--- a/example.ts", "+++ b/example.ts", "@@ -1 +1 @@", "-before", "+after", ].join("\n"); const parsed = getRenderablePatch(patch, "hydrated-key"); expect(parsed?.kind).toBe("files"); if (parsed?.kind !== "files") return; const file = parsed.files[0]; expect(file).toBeDefined(); if (!file) return; const key = buildFileDiffRenderKey(file); file.cacheKey = `${file.cacheKey}:hydrated`; expect(buildFileDiffRenderKey(file)).toBe(key); }); }); describe("getDiffLineStat", () => { it("totals additions and deletions across every file and hunk", () => { const patch = [ "diff --git a/example.ts b/example.ts", "--- a/example.ts", "+++ b/example.ts", "@@ -1,2 +1,3 @@", "-before", "+after", "+added", " context", "@@ -10,2 +11,1 @@", "-removed", " context", "diff --git a/README.md b/README.md", "--- a/README.md", "+++ b/README.md", "@@ -1 +1,2 @@", " title", "+description", ].join("\n"); const parsed = getRenderablePatch(patch); expect(parsed?.kind).toBe("files"); if (parsed?.kind !== "files") return; expect(getDiffLineStat(parsed.files)).toEqual({ additions: 3, deletions: 2 }); }); });