-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
/
Copy pathuseSpring.test.ts
119 lines (96 loc) Β· 3.29 KB
/
useSpring.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
108
109
110
111
112
113
114
115
116
117
118
119
import { act, renderHook } from '@testing-library/react-hooks';
import { Spring } from 'rebound';
import useSpring from '../src/useSpring';
// simulate Spring for testing
const mockSetCurrentValue = jest.fn();
const mockAddListener = jest.fn();
const mockSetEndValue = jest.fn();
const mockRemoveListener = jest.fn();
let triggerSpringUpdate = () => {};
let springListener: Listener = { onSpringUpdate: () => {} };
interface Listener {
onSpringUpdate: (currentSpring: Spring) => void;
}
const mockCreateSpring: Spring = jest.fn().mockImplementation(() => {
let currentValue = 0;
let endValue = 0;
const getCloserValue = (a, b) => Math.round((a + b) / 2);
const getCurrentValue = () => {
currentValue = getCloserValue(currentValue, endValue);
return currentValue;
};
triggerSpringUpdate = () => {
if (currentValue !== endValue) {
springListener.onSpringUpdate({ getCurrentValue } as any);
}
};
return {
setCurrentValue: (val) => {
currentValue = val;
mockSetCurrentValue(val);
},
addListener: (newListener) => {
springListener = newListener;
mockAddListener(newListener);
},
setEndValue: (val) => {
endValue = val;
mockSetEndValue(val);
},
removeListener: mockRemoveListener,
};
}) as any;
jest.mock('rebound', () => {
return {
Sprint: {},
SpringSystem: jest.fn().mockImplementation(() => {
return { createSpring: mockCreateSpring };
}),
};
});
it('should init value to provided target', () => {
const { result } = renderHook(() => useSpring(70));
expect(result.current).toBe(70);
expect(mockSetCurrentValue).toHaveBeenCalledTimes(1);
expect(mockSetCurrentValue).toHaveBeenCalledWith(70);
expect(mockCreateSpring).toHaveBeenCalledTimes(1);
expect(mockCreateSpring).toHaveBeenCalledWith(50, 3);
});
it('should create spring with custom tension and friction args provided', () => {
renderHook(() => useSpring(500, 20, 7));
expect(mockCreateSpring).toHaveBeenCalledTimes(1);
expect(mockCreateSpring).toHaveBeenCalledWith(20, 7);
});
it('should subscribe only once', () => {
const { rerender } = renderHook(() => useSpring());
expect(mockAddListener).toHaveBeenCalledTimes(1);
expect(mockAddListener).toHaveBeenCalledWith(springListener);
rerender();
expect(mockAddListener).toHaveBeenCalledTimes(1);
});
it('should handle spring update', () => {
let targetValue = 70;
let lastSpringValue = targetValue;
const { result, rerender } = renderHook(() => useSpring(targetValue));
targetValue = 100;
rerender();
expect(result.current).toBe(lastSpringValue);
act(() => {
triggerSpringUpdate(); // simulate new spring value
});
expect(result.current).toBeGreaterThan(lastSpringValue);
expect(result.current).toBeLessThanOrEqual(targetValue);
lastSpringValue = result.current;
act(() => {
triggerSpringUpdate(); // simulate another new spring value
});
expect(result.current).toBeGreaterThan(lastSpringValue);
expect(result.current).toBeLessThanOrEqual(targetValue);
});
it('should remove listener on unmount', () => {
const { unmount } = renderHook(() => useSpring());
expect(mockRemoveListener).not.toHaveBeenCalled();
unmount();
expect(mockRemoveListener).toHaveBeenCalledTimes(1);
expect(mockRemoveListener).toHaveBeenCalledWith(springListener);
});