mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-24 10:12:44 +00:00
Keep diff headers and painted content on the same scroll clock while preserving native scrolling and independent per-file horizontal offsets. Complete review, selection, typography, tree, and palette parity without returning line rendering to React.
82 lines
2.5 KiB
TypeScript
82 lines
2.5 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { FILE_HEADER_HEIGHT } from "./model";
|
|
import {
|
|
buildNativeCanvasSlabs,
|
|
nativeCanvasSlabsForViewport,
|
|
nativeCanvasWindowBucket,
|
|
nativeCanvasWindowTop,
|
|
nativeStickyHeaderIndices,
|
|
} from "./native-slabs";
|
|
import type { DiffDocumentModel } from "./types";
|
|
|
|
function modelWithBodies(
|
|
bodies: Array<{ path: string; bodyTop: number; bottom: number }>,
|
|
): DiffDocumentModel {
|
|
return {
|
|
files: bodies.map((body, fileIndex) => ({
|
|
file: {} as never,
|
|
fileIndex,
|
|
path: body.path,
|
|
top: body.bodyTop - FILE_HEADER_HEIGHT,
|
|
headerHeight: FILE_HEADER_HEIGHT,
|
|
bodyTop: body.bodyTop,
|
|
bodyHeight: body.bottom - body.bodyTop,
|
|
bottom: body.bottom,
|
|
gutterWidth: 48,
|
|
contentWidth: 500,
|
|
rowStart: 0,
|
|
rowEnd: 0,
|
|
isCollapsed: body.bottom === body.bodyTop,
|
|
})),
|
|
rows: [],
|
|
height: bodies.at(-1)?.bottom ?? 0,
|
|
lineHeight: 20,
|
|
layout: "unified",
|
|
wrapLines: false,
|
|
viewportWidth: 400,
|
|
};
|
|
}
|
|
|
|
describe("native canvas slabs", () => {
|
|
it("identifies each direct file header child for native sticky scrolling", () => {
|
|
expect(nativeStickyHeaderIndices(0)).toEqual([]);
|
|
expect(nativeStickyHeaderIndices(3)).toEqual([1, 3, 5]);
|
|
});
|
|
|
|
it("cuts large file bodies into fixed document-positioned slabs", () => {
|
|
const slabs = buildNativeCanvasSlabs(
|
|
modelWithBodies([
|
|
{ path: "small.ts", bodyTop: FILE_HEADER_HEIGHT, bottom: FILE_HEADER_HEIGHT + 200 },
|
|
{
|
|
path: "large.ts",
|
|
bodyTop: FILE_HEADER_HEIGHT * 2 + 200,
|
|
bottom: FILE_HEADER_HEIGHT * 2 + 3400,
|
|
},
|
|
]),
|
|
600,
|
|
);
|
|
|
|
expect(slabs.map(({ path, top, height }) => ({ path, top, height }))).toEqual([
|
|
{ path: "small.ts", top: 30, height: 200 },
|
|
{ path: "large.ts", top: 260, height: 1200 },
|
|
{ path: "large.ts", top: 1460, height: 1200 },
|
|
{ path: "large.ts", top: 2660, height: 800 },
|
|
]);
|
|
});
|
|
|
|
it("retains only viewport-adjacent slabs and updates on half-viewport boundaries", () => {
|
|
const slabs = buildNativeCanvasSlabs(
|
|
modelWithBodies([
|
|
{ path: "large.ts", bodyTop: FILE_HEADER_HEIGHT, bottom: FILE_HEADER_HEIGHT + 4800 },
|
|
]),
|
|
600,
|
|
);
|
|
|
|
expect(nativeCanvasSlabsForViewport(slabs, 1700, 600).map((slab) => slab.top)).toEqual([
|
|
30, 1230, 2430,
|
|
]);
|
|
expect(nativeCanvasWindowBucket(899, 600)).toBe(2);
|
|
expect(nativeCanvasWindowTop(2, 600)).toBe(600);
|
|
});
|
|
});
|