Skip to content

Commit 55d358d

Browse files
committed
add/test-for-useDebounceCallback 🧊 add: test for useDebouncedCallback
1 parent ca5e974 commit 55d358d

File tree

1 file changed

+123
-0
lines changed

1 file changed

+123
-0
lines changed
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import { act, renderHook } from '@testing-library/react';
2+
import { vi } from 'vitest';
3+
4+
import { useDebounceCallback } from './useDebounceCallback';
5+
6+
beforeEach(() => {
7+
vi.useFakeTimers();
8+
});
9+
10+
afterEach(() => {
11+
vi.useRealTimers();
12+
vi.restoreAllMocks();
13+
});
14+
15+
it('Should use debounce callback', () => {
16+
const { result } = renderHook(() => useDebounceCallback(vi.fn(), 300));
17+
expect(result.current).toBeTypeOf('function');
18+
});
19+
20+
it('Should execute the callback only after delay', () => {
21+
const callback = vi.fn();
22+
const delay = 300;
23+
24+
const { result } = renderHook(() => useDebounceCallback(callback, delay));
25+
const debouncedFn = result.current;
26+
27+
act(() => {
28+
debouncedFn();
29+
vi.advanceTimersByTime(delay - 1);
30+
});
31+
expect(callback).not.toBeCalled();
32+
33+
act(() => {
34+
vi.advanceTimersByTime(1);
35+
});
36+
expect(callback).toBeCalledTimes(1);
37+
});
38+
39+
it('Should сancel the previous callback if a new one occurs before the delay', () => {
40+
const callback = vi.fn();
41+
const delay = 300;
42+
43+
const { result } = renderHook(() => useDebounceCallback(callback, delay));
44+
const debouncedFn = result.current;
45+
46+
act(() => {
47+
debouncedFn();
48+
vi.advanceTimersByTime(delay - 50);
49+
debouncedFn();
50+
vi.advanceTimersByTime(delay - 50);
51+
});
52+
expect(callback).not.toBeCalled();
53+
54+
act(() => {
55+
vi.advanceTimersByTime(50);
56+
});
57+
expect(callback).toBeCalledTimes(1);
58+
});
59+
60+
it('Should pass single argument into callback', () => {
61+
const callback = vi.fn();
62+
const delay = 100;
63+
64+
const { result } = renderHook(() => useDebounceCallback(callback, delay));
65+
const debouncedFn = result.current;
66+
67+
act(() => {
68+
debouncedFn('argument');
69+
vi.advanceTimersByTime(delay);
70+
});
71+
72+
expect(callback).toBeCalledWith('argument');
73+
});
74+
75+
it('Should pass multiple arguments into callback', () => {
76+
const callback = vi.fn();
77+
const delay = 100;
78+
79+
const { result } = renderHook(() => useDebounceCallback(callback, delay));
80+
const debouncedFn = result.current;
81+
82+
act(() => {
83+
debouncedFn(1, 2, 3);
84+
vi.advanceTimersByTime(delay);
85+
});
86+
87+
expect(callback).toBeCalledWith(1, 2, 3);
88+
});
89+
90+
it('Should pass argument and cancel callbacks that called before delay', () => {
91+
const callback = vi.fn();
92+
const delay = 300;
93+
94+
const { result } = renderHook(() => useDebounceCallback(callback, delay));
95+
const debouncedFn = result.current;
96+
97+
act(() => {
98+
debouncedFn('first');
99+
vi.advanceTimersByTime(delay - 100);
100+
debouncedFn('second');
101+
vi.advanceTimersByTime(delay - 100);
102+
debouncedFn('third');
103+
vi.advanceTimersByTime(delay);
104+
});
105+
106+
expect(callback).toBeCalledTimes(1);
107+
expect(callback).toBeCalledWith('third');
108+
});
109+
110+
it('Should keep the same function between renders if delay is unchanged', () => {
111+
const callback = vi.fn();
112+
const delay = 200;
113+
114+
const { result, rerender } = renderHook(({ cb, d }) => useDebounceCallback(cb, d), {
115+
initialProps: { cb: callback, d: delay }
116+
});
117+
const first = result.current;
118+
119+
rerender({ cb: callback, d: delay });
120+
const second = result.current;
121+
122+
expect(first).toBe(second);
123+
});

0 commit comments

Comments
 (0)