Open History to see the last commit
1import { describe, expect, it, vi } from "vite-plus/test";
2
3import { render } from "../../../test/render";
4import { DiffFileLoadingBoundary } from "./DiffFileLoadingBoundary";
5
6function stubIntersectionObserver() {
7 let observeCount = 0;
8 // Like the real observer, every observe() reports the target's current state; this boundary
9 // is always in range.
10 class InRangeIntersectionObserver {
11 constructor(readonly callback: IntersectionObserverCallback) {}
12 observe(target: Element) {
13 observeCount += 1;
14 this.callback(
15 [{ target, isIntersecting: true } as IntersectionObserverEntry],
16 this as unknown as IntersectionObserver,
17 );
18 }
19 unobserve() {}
20 disconnect() {}
21 }
22 vi.stubGlobal("IntersectionObserver", InRangeIntersectionObserver);
23 return {
24 get observeCount() {
25 return observeCount;
26 },
27 [Symbol.dispose]: () => vi.unstubAllGlobals(),
28 };
29}
30
31describe("DiffFileLoadingBoundary", () => {
32 it("observes once and loads once while its parent re-renders with a new load", async () => {
33 using observer = stubIntersectionObserver();
34 const load = vi.fn();
35 // DiffPanel hands over a new loadNextFiles whenever any file patch changes.
36 await using screen = await render(<DiffFileLoadingBoundary load={() => load()} count={8} />, {
37 router: false, // the boundary does not touch routing
38 });
39 await screen.rerender(<DiffFileLoadingBoundary load={() => load()} count={8} />);
40 await screen.rerender(<DiffFileLoadingBoundary load={() => load()} count={8} />);
41 await screen.rerender(<DiffFileLoadingBoundary load={() => load()} count={8} />);
42
43 await expect.element(screen.getByRole("status", { name: "Loading diff…" })).toBeInTheDocument();
44 expect(observer.observeCount).toBe(1);
45 expect(load).toHaveBeenCalledTimes(1);
46
47 // A settled batch leaves the boundary in range, so it asks for the next one.
48 await screen.rerender(<DiffFileLoadingBoundary load={() => load()} count={4} />);
49 expect(observer.observeCount).toBe(1);
50 expect(load).toHaveBeenCalledTimes(2);
51 });
52});