DiffResult.test.tsx (3454B)
1 import { describe, it, expect, beforeAll } from "vitest"; 2 import { render } from "@testing-library/react"; 3 import { DiffResult } from "./DiffResult"; 4 import { parseUnifiedDiff } from "./diffParser"; 5 6 // Mock canvas for @git-diff-view/react (uses measureText in jsdom) 7 beforeAll(() => { 8 HTMLCanvasElement.prototype.getContext = vi.fn(() => ({ 9 measureText: vi.fn(() => ({ width: 0 })), 10 fillText: vi.fn(), 11 fillRect: vi.fn(), 12 clearRect: vi.fn(), 13 createImageData: vi.fn(), 14 putImageData: vi.fn(), 15 getImageData: vi.fn(() => ({ data: [] })), 16 setTransform: vi.fn(), 17 resetTransform: vi.fn(), 18 drawImage: vi.fn(), 19 save: vi.fn(), 20 restore: vi.fn(), 21 beginPath: vi.fn(), 22 closePath: vi.fn(), 23 moveTo: vi.fn(), 24 lineTo: vi.fn(), 25 clip: vi.fn(), 26 stroke: vi.fn(), 27 fill: vi.fn(), 28 rect: vi.fn(), 29 arc: vi.fn(), 30 font: "", 31 fillStyle: "", 32 strokeStyle: "", 33 lineWidth: 1, 34 globalAlpha: 1, 35 textAlign: "start" as CanvasTextAlign, 36 textBaseline: "alphabetic" as CanvasTextBaseline, 37 })) as any; 38 }); 39 40 const SIMPLE_DIFF = `--- a/file.ts 41 +++ b/file.ts 42 @@ -1,3 +1,4 @@ 43 line1 44 +added line 45 line2 46 line3`; 47 48 const MULTI_HUNK_DIFF = `--- a/file.ts 49 +++ b/file.ts 50 @@ -1,3 +1,4 @@ 51 line1 52 +added line 53 line2 54 @@ -10,3 +11,4 @@ 55 line10 56 +another added 57 line11 58 line12`; 59 60 const NO_FILENAME_DIFF = `@@ -1,3 +1,4 @@ 61 line1 62 +added line 63 line2 64 line3`; 65 66 describe("parseUnifiedDiff", () => { 67 it("extracts old and new filenames", () => { 68 const result = parseUnifiedDiff(SIMPLE_DIFF); 69 expect(result.oldFileName).toBe("a/file.ts"); 70 expect(result.newFileName).toBe("b/file.ts"); 71 }); 72 73 it("extracts hunks as separate strings", () => { 74 const result = parseUnifiedDiff(SIMPLE_DIFF); 75 expect(result.hunks.length).toBe(1); 76 expect(result.hunks[0]).toContain("@@"); 77 }); 78 79 it("handles multiple hunks", () => { 80 const result = parseUnifiedDiff(MULTI_HUNK_DIFF); 81 expect(result.hunks.length).toBe(2); 82 }); 83 84 it("handles diff without filenames", () => { 85 const result = parseUnifiedDiff(NO_FILENAME_DIFF); 86 expect(result.oldFileName).toBeNull(); 87 expect(result.newFileName).toBeNull(); 88 expect(result.hunks.length).toBe(1); 89 }); 90 91 it("handles empty string", () => { 92 const result = parseUnifiedDiff(""); 93 expect(result.oldFileName).toBeNull(); 94 expect(result.hunks.length).toBe(0); 95 }); 96 }); 97 98 describe("DiffResult", () => { 99 it("renders a diff with diff view", () => { 100 const { container } = render(<DiffResult content={SIMPLE_DIFF} />); 101 expect(container.querySelector("[data-testid='diff-view']")).toBeTruthy(); 102 }); 103 104 it("renders diff view container", () => { 105 const { container } = render(<DiffResult content={SIMPLE_DIFF} />); 106 // Content renders via canvas which jsdom can't fully simulate; 107 // verify the diff view container is present 108 expect(container.querySelector("[data-testid='diff-view']")).toBeTruthy(); 109 }); 110 111 it("renders invalid diff as plain text fallback", () => { 112 const { container } = render(<DiffResult content="not a diff at all" />); 113 // Should fall back to <pre> since no hunks 114 expect(container.querySelector("pre")).toBeTruthy(); 115 expect(container.textContent).toContain("not a diff at all"); 116 }); 117 118 it("renders empty diff as plain text fallback", () => { 119 const { container } = render(<DiffResult content="" />); 120 expect(container.querySelector("pre")).toBeTruthy(); 121 }); 122 });