2022-02-23 10:29:50 +00:00
|
|
|
/**
|
2022-07-07 05:23:54 +00:00
|
|
|
* @vitest-environment jsdom
|
2022-02-23 10:29:50 +00:00
|
|
|
*/
|
2023-02-13 07:18:16 +00:00
|
|
|
import { renderHook } from "@testing-library/react";
|
2022-07-07 05:23:54 +00:00
|
|
|
import { describe, expect, it, vi } from "vitest";
|
2022-02-23 10:29:50 +00:00
|
|
|
import useSetTimeout from "./useSetTimeout";
|
|
|
|
|
2022-07-07 05:23:54 +00:00
|
|
|
vi.useFakeTimers();
|
2022-02-23 10:29:50 +00:00
|
|
|
|
|
|
|
describe("useSetTimeout", () => {
|
|
|
|
it("schedules timeouts and triggers the callbacks", () => {
|
|
|
|
const { result } = renderHook(() => useSetTimeout());
|
2022-07-07 05:23:54 +00:00
|
|
|
const setTimeoutSpy = vi.spyOn(global, "setTimeout");
|
2022-02-23 10:29:50 +00:00
|
|
|
|
|
|
|
// Schedule some timeouts...
|
2022-07-07 05:23:54 +00:00
|
|
|
const callback1 = vi.fn();
|
|
|
|
const callback2 = vi.fn();
|
2022-02-23 10:29:50 +00:00
|
|
|
result.current(callback1, 1000);
|
|
|
|
result.current(callback2, 500);
|
|
|
|
|
|
|
|
// Ensure that setTimeout was actually called with the correct arguments.
|
|
|
|
expect(setTimeoutSpy).toHaveBeenCalledTimes(2);
|
|
|
|
expect(setTimeoutSpy).toBeCalledWith(expect.any(Function), 1000);
|
|
|
|
expect(setTimeoutSpy).toBeCalledWith(expect.any(Function), 500);
|
|
|
|
|
|
|
|
// Ensure callbacks are called after timers run.
|
|
|
|
expect(callback2).not.toBeCalled();
|
2022-07-07 05:23:54 +00:00
|
|
|
vi.advanceTimersByTime(500);
|
2022-02-23 10:29:50 +00:00
|
|
|
expect(callback1).not.toBeCalled();
|
|
|
|
expect(callback2).toBeCalled();
|
2022-07-07 05:23:54 +00:00
|
|
|
vi.advanceTimersByTime(500);
|
2022-02-23 10:29:50 +00:00
|
|
|
expect(callback1).toBeCalled();
|
|
|
|
|
|
|
|
setTimeoutSpy.mockRestore();
|
|
|
|
});
|
|
|
|
|
|
|
|
it("throws if a timeout is scheduled after the component has unmounted", () => {
|
|
|
|
const { result, unmount } = renderHook(() => useSetTimeout());
|
|
|
|
|
|
|
|
unmount();
|
|
|
|
|
2022-07-07 05:23:54 +00:00
|
|
|
expect(() => result.current(vi.fn(), 1000)).toThrowError(
|
2023-07-11 14:03:21 +00:00
|
|
|
"Can't schedule a timeout on an unmounted component.",
|
2022-02-23 10:29:50 +00:00
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
it("clears a timeout if the component unmounts", () => {
|
|
|
|
const { result, unmount } = renderHook(() => useSetTimeout());
|
2022-07-07 05:23:54 +00:00
|
|
|
const setTimeoutSpy = vi.spyOn(global, "setTimeout");
|
|
|
|
const clearTimeoutSpy = vi.spyOn(global, "clearTimeout");
|
|
|
|
const callback = vi.fn();
|
2022-02-23 14:46:26 +00:00
|
|
|
|
|
|
|
result.current(callback, 1000);
|
2022-02-23 10:29:50 +00:00
|
|
|
|
2022-02-23 14:46:26 +00:00
|
|
|
// Timeout should be cleared after unmounting.
|
2022-02-23 10:29:50 +00:00
|
|
|
unmount();
|
2022-02-23 14:46:26 +00:00
|
|
|
expect(clearTimeoutSpy).toBeCalled();
|
|
|
|
|
|
|
|
// And the callback should no longer be called.
|
2022-07-07 05:23:54 +00:00
|
|
|
vi.runOnlyPendingTimers();
|
2022-02-23 14:46:26 +00:00
|
|
|
expect(callback).not.toBeCalled();
|
|
|
|
|
|
|
|
setTimeoutSpy.mockRestore();
|
|
|
|
clearTimeoutSpy.mockRestore();
|
|
|
|
});
|
|
|
|
|
|
|
|
it("clears a timeout when cancelled", () => {
|
|
|
|
const { result } = renderHook(() => useSetTimeout());
|
2022-07-07 05:23:54 +00:00
|
|
|
const setTimeoutSpy = vi.spyOn(global, "setTimeout");
|
|
|
|
const clearTimeoutSpy = vi.spyOn(global, "clearTimeout");
|
|
|
|
const callback = vi.fn();
|
2022-02-23 14:46:26 +00:00
|
|
|
const cancel = result.current(callback, 1000);
|
|
|
|
|
|
|
|
// Timeout should be cleared when cancelling.
|
|
|
|
cancel();
|
|
|
|
expect(clearTimeoutSpy).toBeCalled();
|
2022-02-23 10:29:50 +00:00
|
|
|
|
2022-02-23 14:46:26 +00:00
|
|
|
// And the callback should no longer be called.
|
2022-07-07 05:23:54 +00:00
|
|
|
vi.runOnlyPendingTimers();
|
2022-02-23 14:46:26 +00:00
|
|
|
expect(callback).not.toBeCalled();
|
2022-02-23 10:29:50 +00:00
|
|
|
|
|
|
|
setTimeoutSpy.mockRestore();
|
2022-02-23 14:46:26 +00:00
|
|
|
clearTimeoutSpy.mockRestore();
|
2022-02-23 10:29:50 +00:00
|
|
|
});
|
|
|
|
});
|