import { debounce } from "../debounce"; describe("debounce", () => { beforeEach(() => { jest.useFakeTimers(); }); afterEach(() => { jest.useRealTimers(); }); it("collapses rapid calls into a single trailing invocation", () => { const fn = jest.fn(); const debounced = debounce(fn, 100); debounced("a"); debounced("b"); debounced("c"); expect(fn).not.toHaveBeenCalled(); jest.advanceTimersByTime(100); expect(fn).toHaveBeenCalledTimes(1); expect(fn).toHaveBeenCalledWith("c"); }); it("cancels a pending invocation when cancel() runs first", () => { const fn = jest.fn(); const debounced = debounce(fn, 100); debounced("a"); debounced.cancel(); jest.advanceTimersByTime(200); expect(fn).not.toHaveBeenCalled(); }); it("re-arms after a successful invocation", () => { const fn = jest.fn(); const debounced = debounce(fn, 50); debounced("a"); jest.advanceTimersByTime(50); debounced("b"); jest.advanceTimersByTime(50); expect(fn).toHaveBeenCalledTimes(2); expect(fn.mock.calls.map((c) => c[0])).toEqual(["a", "b"]); }); });