/** * @file LaneDiffView.test.tsx * @description Pins the side-by-side renderer: two independently scrolling * columns (a long line must be reachable, not painted over its neighbour) * whose horizontal scroll is mirrored, so the two halves of a line stay * opposite each other. * @author Nguyễn Ngọc Trí Vĩ */ import { describe, it, expect } from "vitest"; import { fireEvent, render, screen } from "@testing-library/react"; import { LaneDiffView } from "../LaneDiffView"; import type { LaneChangeFile } from "../../../lib/types"; const FILE: LaneChangeFile = { path: "server/lib/git-ops.js", status: " M", untracked: false, added: 1, deleted: 1, binary: false, hunks: [ { header: "@@ -1,2 +1,2 @@", context: "", oldStart: 1, newStart: 1, lines: [ { type: "del", oldLine: 1, newLine: null, text: `const x = "${"a".repeat(400)}";` }, { type: "add", oldLine: null, newLine: 1, text: `const x = "${"b".repeat(400)}";` }, ], }, ], }; describe("LaneDiffView — side by side", () => { it("gives each column its own scroller", () => { render(); expect(screen.getByTestId("lane-diff-split-left").className).toContain("overflow-auto"); expect(screen.getByTestId("lane-diff-split-right").className).toContain("overflow-auto"); }); it("bounds its own height so the horizontal bar stays on screen", () => { // A stacked review list caps each file; the single-file view takes the // height its parent gives it. Either way the diff scrolls itself rather // than growing a 2000-line container whose scrollbar is off the bottom. const { rerender } = render(); expect(screen.getByTestId("lane-diff-view").className).toContain("max-h-[60vh]"); rerender(); expect(screen.getByTestId("lane-diff-view").className).toContain("flex-1"); expect(screen.getByTestId("lane-diff-view").className).not.toContain("max-h-[60vh]"); }); it("mirrors one column's horizontal scroll onto the other", () => { render(); const left = screen.getByTestId("lane-diff-split-left"); const right = screen.getByTestId("lane-diff-split-right"); left.scrollLeft = 320; fireEvent.scroll(left); expect(right.scrollLeft).toBe(320); right.scrollLeft = 0; fireEvent.scroll(right); expect(left.scrollLeft).toBe(0); }); it("keeps the unified layout on one scroller", () => { render(); expect(screen.queryByTestId("lane-diff-split-left")).toBeNull(); expect(screen.getByTestId("lane-diff-view").className).toContain("overflow-auto"); }); });