-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
/
Copy pathuseStateValidator.test.ts
107 lines (87 loc) Β· 3.38 KB
/
useStateValidator.test.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import { act, renderHook, RenderHookResult } from '@testing-library/react-hooks';
import { useState } from 'react';
import useStateValidator, {
StateValidator,
UseStateValidatorReturn,
} from '../src/useStateValidator';
interface Mock extends jest.Mock {}
describe('useStateValidator', () => {
it('should be defined', () => {
expect(useStateValidator).toBeDefined();
});
function getHook(
fn: StateValidator<[boolean], number> = jest.fn((state): [boolean] => [!!(state % 2)])
): [jest.Mock | Function, RenderHookResult<any, [Function, UseStateValidatorReturn<any>]>] {
return [
fn,
renderHook(() => {
const [state, setState] = useState(1);
return [setState, useStateValidator(state, fn)];
}),
];
}
it('should return an array of two elements', () => {
const [, hook] = getHook();
const res = hook.result.current[1];
expect(Array.isArray(res)).toBe(true);
expect(res[0]).toEqual([true]);
expect(typeof res[1]).toBe('function');
});
it('first element should represent current validity state', () => {
const [, hook] = getHook();
let [setState, [validity]] = hook.result.current;
expect(validity).toEqual([true]);
act(() => setState(3));
[setState, [validity]] = hook.result.current;
expect(validity).toEqual([true]);
act(() => setState(4));
[setState, [validity]] = hook.result.current;
expect(validity).toEqual([false]);
});
it('second element should re-call validation', () => {
const [spy, hook] = getHook();
const [, [, revalidate]] = hook.result.current;
expect(spy).toHaveBeenCalledTimes(1);
act(() => revalidate());
expect(spy).toHaveBeenCalledTimes(2);
});
it('validator have to be called on init plus on each state update', () => {
const [spy, hook] = getHook(jest.fn());
const [setState] = hook.result.current;
expect(spy).toHaveBeenCalledTimes(1);
act(() => setState(4));
expect(spy).toHaveBeenCalledTimes(2);
act(() => setState((prevState) => prevState + 1));
expect(spy).toHaveBeenCalledTimes(3);
});
it('should pass to validator one parameter - current state', () => {
const [spy, hook] = getHook(jest.fn());
const [setState] = hook.result.current;
act(() => setState(4));
act(() => setState(5));
expect((spy as Mock).mock.calls[0].length).toBe(1);
expect((spy as Mock).mock.calls[0].length).toBe(1);
expect((spy as Mock).mock.calls[0][0]).toBe(1);
expect((spy as Mock).mock.calls[1].length).toBe(1);
expect((spy as Mock).mock.calls[1][0]).toBe(4);
expect((spy as Mock).mock.calls[2].length).toBe(1);
expect((spy as Mock).mock.calls[2][0]).toBe(5);
});
it('if validator expects 2nd parameter it should pass a validity setter there', () => {
const [spy, hook] = getHook(
jest.fn((state, setValidity): void => {
setValidity([state % 2 === 0]);
}) as unknown as StateValidator<[boolean], number>
);
let [setState, [[isValid]]] = hook.result.current;
expect((spy as Mock).mock.calls[0].length).toBe(2);
expect(typeof (spy as Mock).mock.calls[0][1]).toBe('function');
expect(isValid).toBe(false);
act(() => setState((prevState) => prevState + 1));
[setState, [[isValid]]] = hook.result.current;
expect(isValid).toBe(true);
act(() => setState(5));
[setState, [[isValid]]] = hook.result.current;
expect(isValid).toBe(false);
});
});