Skip to content

Commit 0636cd8

Browse files
committed
chore(useUpdate): improve useUpdate test suite
1 parent a087deb commit 0636cd8

File tree

3 files changed

+62
-27
lines changed

3 files changed

+62
-27
lines changed

src/misc/util.ts

+1
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,5 @@ export function off<T extends Window | Document | HTMLElement | EventTarget>(
1919
}
2020

2121
export const isBrowser = typeof window !== 'undefined';
22+
2223
export const isNavigator = typeof navigator !== 'undefined';

src/useUpdate.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@ import { useReducer } from 'react';
22

33
const updateReducer = (num: number): number => (num + 1) % 1_000_000;
44

5-
const useUpdate = () => {
5+
export default function useUpdate(): () => void {
66
const [, update] = useReducer(updateReducer, 0);
7-
return update as () => void;
8-
};
97

10-
export default useUpdate;
8+
return update;
9+
}

tests/useUpdate.test.ts

+58-23
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,70 @@
11
import { act, renderHook } from '@testing-library/react-hooks';
22
import useUpdate from '../src/useUpdate';
33

4-
it('should init update function', () => {
5-
const { result } = renderHook(() => useUpdate());
6-
const update = result.current;
4+
describe('useUpdate', () => {
5+
it('should be defined', () => {
6+
expect(useUpdate).toBeDefined();
7+
});
78

8-
expect(update).toBeInstanceOf(Function);
9-
});
9+
it('should return a function', () => {
10+
const { result } = renderHook(() => useUpdate());
1011

11-
it('should forces a re-render every time update function is called', () => {
12-
let renderCount = 0;
13-
const { result } = renderHook(() => {
14-
renderCount++;
15-
return useUpdate();
16-
});
17-
const update = result.current;
12+
expect(typeof result.current).toBe('function');
13+
})
1814

19-
expect(renderCount).toBe(1);
15+
it('should re-render component each time returned function is called', () => {
16+
let renders = 0;
17+
const { result: { current: update } } = renderHook(() => {
18+
renders++;
19+
return useUpdate();
20+
});
2021

21-
act(() => update());
22-
expect(renderCount).toBe(2);
22+
expect(renders).toBe(1);
2323

24-
act(() => update());
25-
expect(renderCount).toBe(3);
26-
});
24+
act(() => update());
25+
expect(renders).toBe(2);
26+
27+
act(() => update());
28+
expect(renders).toBe(3);
29+
})
30+
31+
it('should return exact same function in between renders', () => {
32+
let renders = 0;
33+
const { result } = renderHook(() => {
34+
renders++;
35+
return useUpdate();
36+
});
37+
let initialUpdateFn = result.current;
38+
39+
expect(renders).toBe(1);
40+
41+
act(() => result.current());
42+
expect(renders).toBe(2);
43+
expect(initialUpdateFn).toBe(result.current);
44+
45+
act(() => result.current());
46+
expect(renders).toBe(3);
47+
expect(initialUpdateFn).toBe(result.current);
48+
})
49+
50+
it('passing the argument to returned function should not affect the use', () => {
51+
let renders = 0;
52+
const { result } = renderHook(() => {
53+
renders++;
54+
return useUpdate();
55+
});
56+
let initialUpdateFn = result.current;
2757

28-
it('should return same update function instance on each update', () => {
29-
const { result, rerender } = renderHook(() => useUpdate());
30-
const { current: updateCb } = result;
58+
expect(renders).toBe(1);
3159

32-
rerender();
60+
/* @ts-expect-error */
61+
act(() => result.current(1));
62+
expect(renders).toBe(2);
63+
expect(initialUpdateFn).toBe(result.current);
3364

34-
expect(Object.is(result.current, updateCb)).toBe(true);
65+
/* @ts-expect-error */
66+
act(() => result.current(1));
67+
expect(renders).toBe(3);
68+
expect(initialUpdateFn).toBe(result.current);
69+
})
3570
});

0 commit comments

Comments
 (0)