Skip to content
Source
Sign inSign up

pullRequestDiffDebug.test.ts

82 lines3.2 KB

1import { expect, it, vi } from "vite-plus/test";
2​
3vi.mock("react-native", () => ({ View: () => null }));
4vi.mock("expo", () => ({ requireNativeView: vi.fn() }));
5vi.mock("../../components/ui/EmptyState", () => ({ EmptyState: () => null }));
6​
7import {
8 handlePullRequestDiffDebugEvent,
9 pullRequestDiffInitialPosition,
10} from "./pullRequestDiffDebug";
11import { createReviewDiffHighlightScheduler } from "../review/reviewDiffHighlightScheduler";
12import type { NativeReviewDiffViewProps } from "../diffs/nativeReviewDiffSurface";
13​
14it("enters at a file header without changing guide focus positioning", () => {
15 expect(pullRequestDiffInitialPosition("last-file", -1)).toEqual({
16 initialFileId: "last-file",
17 initialRowIndex: -1,
18 });
19 expect(pullRequestDiffInitialPosition("last-file", 904)).toEqual({
20 initialFileId: "",
21 initialRowIndex: 901,
22 });
23 expect(pullRequestDiffInitialPosition(undefined, -1)).toEqual({
24 initialFileId: "",
25 initialRowIndex: -1,
26 });
27});
28​
29it.each([true, false])(
30 "starts warm highlighting at the declared file without a JS jump (iOS: %s)",
31 async (isIos) => {
32 vi.useFakeTimers();
33 // A warm engine can issue its source RPC immediately when the scheduler flushes.
34 const sourceRequest = vi.fn();
35 const scheduler = createReviewDiffHighlightScheduler(sourceRequest);
36 const scrollToFile = vi.fn(async () => {});
37 const loadMore = vi.fn();
38 const onDebug: NonNullable<NativeReviewDiffViewProps["onDebug"]> = ({ nativeEvent }) => {
39 if (nativeEvent.message === "visible-range")
40 scheduler.update({
41 firstRowIndex: nativeEvent.firstRowIndex as number,
42 lastRowIndex: nativeEvent.lastRowIndex as number,
43 });
44 };
45 const emit = (nativeEvent: Record<string, unknown>) =>
46 handlePullRequestDiffDebugEvent({ nativeEvent } as Parameters<typeof onDebug>[0], {
47 rowCount: 1000,
48 targetFileId: "last-file",
49 focusIndex: -1,
50 isIos,
51 nativeView: { current: { scrollToFile, scrollToTop: vi.fn(async () => {}) } },
52 jumpStarted: () => true,
53 setJumpStarted: () => {},
54 onDebug,
55 loadMore,
56 });
57 try {
58 const position = pullRequestDiffInitialPosition("last-file", -1);
59 emit({ message: "rows-decoded", rows: 1000 });
60 // Native applies the declared file before publishing its viewport. A later
61 // imperative bridge command cannot retract an RPC started from a top range.
62 const first = position.initialFileId === "last-file" ? 900 : 0;
63 emit({
64 message: "visible-range",
65 firstRowIndex: first,
66 lastRowIndex: first + 40,
67 totalRows: 1000,
68 });
69 await vi.runOnlyPendingTimersAsync();
70 expect(sourceRequest.mock.calls).toEqual([[{ firstRowIndex: 900, lastRowIndex: 940 }]]);
71 expect(scrollToFile).not.toHaveBeenCalled();
72 // Near-end pagination and stale-payload filtering still use native ranges.
73 emit({ message: "visible-range", firstRowIndex: 950, lastRowIndex: 990, totalRows: 999 });
74 expect(loadMore).not.toHaveBeenCalled();
75 emit({ message: "visible-range", firstRowIndex: 950, lastRowIndex: 990, totalRows: 1000 });
76 expect(loadMore).toHaveBeenCalledOnce();
77 } finally {
78 scheduler.cancel();
79 vi.useRealTimers();
80 }
81 },
82);