import { describe, expect, it } from "vite-plus/test"; import type { NativeReviewDiffRow } from "./nativeReviewDiffSurface"; import type { NativeReviewDiffFile } from "./nativeReviewDiffTypes"; import { highlightNativeReviewDiffVisibleRows } from "./nativeReviewDiffHighlighter"; const TYPESCRIPT_FILE: NativeReviewDiffFile = { id: "file-1", path: "example.ts", language: "typescript", additions: 0, deletions: 0, }; function makeLine( input: Pick, ): NativeReviewDiffRow { return { kind: "line", fileId: TYPESCRIPT_FILE.id, ...input, }; } function makeHunk(id: string): NativeReviewDiffRow { return { kind: "hunk", id, fileId: TYPESCRIPT_FILE.id, text: "@@", }; } function highlight( rows: ReadonlyArray, alreadyHighlightedRowIds?: ReadonlySet, ) { return highlightNativeReviewDiffVisibleRows({ rows, files: [TYPESCRIPT_FILE], scheme: "dark", engine: "javascript", firstRowIndex: 0, lastRowIndex: rows.length - 1, overscanRows: 0, maxRows: 100, alreadyHighlightedRowIds, }); } describe("highlightNativeReviewDiffVisibleRows", () => { it("does not carry grammar state across hunk boundaries", async () => { const exportRow = makeLine({ id: "export-row", content: "export async function run() {}", change: "add", oldLineNumber: null, newLineNumber: 100, }); const rows = [ makeHunk("hunk-1"), makeLine({ id: "import-open", content: "import {", change: "context", oldLineNumber: 1, newLineNumber: 1, }), makeLine({ id: "import-entry", content: " Model,", change: "context", oldLineNumber: 2, newLineNumber: 2, }), makeHunk("hunk-2"), exportRow, ]; const [highlighted, standalone] = await Promise.all([ highlight(rows), highlight([makeHunk("standalone-hunk"), exportRow]), ]); expect(highlighted.tokensByRowId[exportRow.id]).toEqual(standalone.tokensByRowId[exportRow.id]); }); it("keeps grammar state across inline comment rows", async () => { const openingRow = makeLine({ id: "template-open", content: "const message = `open", change: "add", oldLineNumber: null, newLineNumber: 1, }); const closingRow = makeLine({ id: "template-close", content: "closed`;", change: "add", oldLineNumber: null, newLineNumber: 2, }); const trailingRow = makeLine({ id: "trailing-row", content: "export const answer = 42;", change: "add", oldLineNumber: null, newLineNumber: 3, }); const commentRow: NativeReviewDiffRow = { kind: "comment", id: "comment-1", fileId: TYPESCRIPT_FILE.id, commentText: "Review note", }; const [withComment, contiguous] = await Promise.all([ highlight([openingRow, commentRow, closingRow, trailingRow]), highlight([openingRow, closingRow, trailingRow]), ]); expect(withComment.tokensByRowId).toEqual(contiguous.tokensByRowId); }); it("does not join unhighlighted rows across cached gaps", async () => { const trailingRow = makeLine({ id: "trailing-row", content: "export const answer = 42;", change: "add", oldLineNumber: null, newLineNumber: 3, }); const rows = [ makeLine({ id: "template-open", content: "const message = `open", change: "add", oldLineNumber: null, newLineNumber: 1, }), makeLine({ id: "template-close", content: "closed`;", change: "add", oldLineNumber: null, newLineNumber: 2, }), trailingRow, ]; const [highlighted, standalone] = await Promise.all([ highlight(rows, new Set(["template-close"])), highlight([trailingRow]), ]); expect(highlighted.tokensByRowId[trailingRow.id]).toEqual( standalone.tokensByRowId[trailingRow.id], ); }); it("keeps deletion grammar state out of addition rows", async () => { const additionRow = makeLine({ id: "addition-row", content: "export const answer = 42;", change: "add", oldLineNumber: null, newLineNumber: 1, }); const rows = [ makeLine({ id: "deletion-row", content: "const removed = `open", change: "delete", oldLineNumber: 1, newLineNumber: null, }), additionRow, ]; const [highlighted, standalone] = await Promise.all([ highlight(rows), highlight([additionRow]), ]); expect(highlighted.tokensByRowId[additionRow.id]).toEqual( standalone.tokensByRowId[additionRow.id], ); }); });