Files
memos/web/tests/near-viewport.test.tsx

52 lines
1.5 KiB
TypeScript

import { act, render, screen } from "@testing-library/react";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { useNearViewport } from "@/hooks/useNearViewport";
let intersectionCallback: IntersectionObserverCallback;
let observerOptions: IntersectionObserverInit | undefined;
class IntersectionObserverMock implements IntersectionObserver {
readonly root = null;
readonly rootMargin = "";
readonly thresholds = [];
constructor(callback: IntersectionObserverCallback, options?: IntersectionObserverInit) {
intersectionCallback = callback;
observerOptions = options;
}
disconnect = vi.fn();
observe = vi.fn();
takeRecords = vi.fn(() => []);
unobserve = vi.fn();
}
const Probe = () => {
const { ref, isNearViewport } = useNearViewport<HTMLDivElement>();
return <div ref={ref}>{isNearViewport ? "near" : "waiting"}</div>;
};
describe("useNearViewport", () => {
beforeEach(() => {
observerOptions = undefined;
vi.stubGlobal("IntersectionObserver", IntersectionObserverMock);
});
afterEach(() => {
vi.unstubAllGlobals();
});
it("stays dormant until the target approaches the viewport", () => {
render(<Probe />);
expect(screen.getByText("waiting")).toBeInTheDocument();
expect(observerOptions).toEqual({ rootMargin: "400px 0px" });
act(() => {
intersectionCallback([{ isIntersecting: true } as IntersectionObserverEntry], {} as IntersectionObserver);
});
expect(screen.getByText("near")).toBeInTheDocument();
});
});