@umituz/react-native-design-system 2.6.47 → 2.6.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/atoms/skeleton/AtomicSkeleton.tsx +16 -62
- package/src/index.ts +0 -32
- package/src/molecules/bottom-sheet/components/BottomSheetModal.tsx +101 -180
- package/src/molecules/bottom-sheet/components/SafeBottomSheetModalProvider.tsx +8 -14
- package/src/molecules/index.ts +0 -6
- package/src/molecules/animation/core/AnimationCore.ts +0 -29
- package/src/molecules/animation/domain/entities/Animation.ts +0 -81
- package/src/molecules/animation/domain/entities/Fireworks.ts +0 -44
- package/src/molecules/animation/domain/entities/Theme.ts +0 -76
- package/src/molecules/animation/index.ts +0 -146
- package/src/molecules/animation/infrastructure/services/AnimationConfigService.ts +0 -35
- package/src/molecules/animation/infrastructure/services/SpringAnimationConfigService.ts +0 -67
- package/src/molecules/animation/infrastructure/services/TimingAnimationConfigService.ts +0 -57
- package/src/molecules/animation/infrastructure/services/__tests__/SpringAnimationConfigService.test.ts +0 -114
- package/src/molecules/animation/infrastructure/services/__tests__/TimingAnimationConfigService.test.ts +0 -105
- package/src/molecules/animation/presentation/components/Fireworks.tsx +0 -127
- package/src/molecules/animation/presentation/components/__tests__/Fireworks.test.tsx +0 -185
- package/src/molecules/animation/presentation/hooks/__tests__/useAnimation.integration.test.ts +0 -210
- package/src/molecules/animation/presentation/hooks/__tests__/useFireworks.test.ts +0 -242
- package/src/molecules/animation/presentation/hooks/__tests__/useGesture.test.ts +0 -108
- package/src/molecules/animation/presentation/hooks/__tests__/useSpringAnimation.test.ts +0 -127
- package/src/molecules/animation/presentation/hooks/__tests__/useTimingAnimation.test.ts +0 -172
- package/src/molecules/animation/presentation/hooks/__tests__/useTransformAnimation.test.ts +0 -133
- package/src/molecules/animation/presentation/hooks/useAnimation.ts +0 -77
- package/src/molecules/animation/presentation/hooks/useFireworks.ts +0 -144
- package/src/molecules/animation/presentation/hooks/useGesture.ts +0 -57
- package/src/molecules/animation/presentation/hooks/useGestureCreators.ts +0 -163
- package/src/molecules/animation/presentation/hooks/useGestureState.ts +0 -53
- package/src/molecules/animation/presentation/hooks/useIconAnimations.ts +0 -120
- package/src/molecules/animation/presentation/hooks/useModalAnimations.ts +0 -124
- package/src/molecules/animation/presentation/hooks/useReanimatedReady.ts +0 -60
- package/src/molecules/animation/presentation/hooks/useSpringAnimation.ts +0 -69
- package/src/molecules/animation/presentation/hooks/useTimingAnimation.ts +0 -111
- package/src/molecules/animation/presentation/hooks/useTransformAnimation.ts +0 -57
- package/src/molecules/animation/presentation/providers/AnimationThemeProvider.tsx +0 -60
- package/src/molecules/animation/presentation/providers/__tests__/AnimationThemeProvider.test.tsx +0 -165
- package/src/molecules/celebration/domain/entities/CelebrationConfig.ts +0 -17
- package/src/molecules/celebration/domain/entities/FireworksConfig.ts +0 -32
- package/src/molecules/celebration/index.ts +0 -93
- package/src/molecules/celebration/infrastructure/services/FireworksConfigService.ts +0 -49
- package/src/molecules/celebration/presentation/components/CelebrationFireworksOverlay.tsx +0 -33
- package/src/molecules/celebration/presentation/components/CelebrationModal.tsx +0 -81
- package/src/molecules/celebration/presentation/components/CelebrationModalContent.tsx +0 -88
- package/src/molecules/celebration/presentation/hooks/useCelebrationModalAnimation.ts +0 -49
- package/src/molecules/celebration/presentation/hooks/useCelebrationState.ts +0 -45
- package/src/molecules/celebration/presentation/styles/CelebrationModalStyles.ts +0 -65
|
@@ -1,242 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* useFireworks Hook Tests
|
|
3
|
-
*
|
|
4
|
-
* Unit tests for fireworks particle system.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { renderHook, act } from '@testing-library/react';
|
|
8
|
-
import { useFireworks } from '../useFireworks';
|
|
9
|
-
import { FIREWORKS_CONSTANTS } from '../../../domain/entities/Animation';
|
|
10
|
-
|
|
11
|
-
// Mock requestAnimationFrame
|
|
12
|
-
global.requestAnimationFrame = jest.fn((cb) => {
|
|
13
|
-
setTimeout(cb, 16);
|
|
14
|
-
return 1;
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
global.cancelAnimationFrame = jest.fn();
|
|
18
|
-
|
|
19
|
-
describe('useFireworks', () => {
|
|
20
|
-
const mockConfig = {
|
|
21
|
-
colors: ['#FF0000', '#00FF00', '#0000FF'],
|
|
22
|
-
particleCount: 10,
|
|
23
|
-
duration: 1000,
|
|
24
|
-
particleSize: 4,
|
|
25
|
-
spread: 50,
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
beforeEach(() => {
|
|
29
|
-
jest.clearAllMocks();
|
|
30
|
-
jest.useFakeTimers();
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
afterEach(() => {
|
|
34
|
-
jest.useRealTimers();
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it('should initialize with empty particles and inactive state', () => {
|
|
38
|
-
const { result } = renderHook(() => useFireworks(mockConfig));
|
|
39
|
-
|
|
40
|
-
expect(result.current.particles).toEqual([]);
|
|
41
|
-
expect(result.current.isActive).toBe(false);
|
|
42
|
-
expect(typeof result.current.trigger).toBe('function');
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it('should require colors array', () => {
|
|
46
|
-
const { result } = renderHook(() => useFireworks({ colors: [] }));
|
|
47
|
-
|
|
48
|
-
expect(result.current.particles).toEqual([]);
|
|
49
|
-
expect(result.current.trigger).toEqual(expect.any(Function));
|
|
50
|
-
expect(result.current.isActive).toBe(false);
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
describe('trigger', () => {
|
|
54
|
-
it('should create particles with correct count', () => {
|
|
55
|
-
const { result } = renderHook(() => useFireworks(mockConfig));
|
|
56
|
-
|
|
57
|
-
act(() => {
|
|
58
|
-
result.current.trigger(100, 100);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
expect(result.current.particles).toHaveLength(mockConfig.particleCount);
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it('should create particles with correct properties', () => {
|
|
65
|
-
const { result } = renderHook(() => useFireworks(mockConfig));
|
|
66
|
-
|
|
67
|
-
act(() => {
|
|
68
|
-
result.current.trigger(100, 100);
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
const particles = result.current.particles;
|
|
72
|
-
particles.forEach(particle => {
|
|
73
|
-
expect(particle).toHaveProperty('x');
|
|
74
|
-
expect(particle).toHaveProperty('y');
|
|
75
|
-
expect(particle).toHaveProperty('color');
|
|
76
|
-
expect(particle).toHaveProperty('size');
|
|
77
|
-
expect(particle).toHaveProperty('velocityX');
|
|
78
|
-
expect(particle).toHaveProperty('velocityY');
|
|
79
|
-
expect(particle).toHaveProperty('life');
|
|
80
|
-
expect(particle).toHaveProperty('decay');
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
it('should use provided colors', () => {
|
|
85
|
-
const { result } = renderHook(() => useFireworks(mockConfig));
|
|
86
|
-
|
|
87
|
-
act(() => {
|
|
88
|
-
result.current.trigger(100, 100);
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
const particles = result.current.particles;
|
|
92
|
-
const particleColors = particles.map(p => p.color);
|
|
93
|
-
|
|
94
|
-
particleColors.forEach(color => {
|
|
95
|
-
expect(mockConfig.colors).toContain(color);
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
it('should set particles at trigger position', () => {
|
|
100
|
-
const { result } = renderHook(() => useFireworks(mockConfig));
|
|
101
|
-
const triggerX = 150;
|
|
102
|
-
const triggerY = 200;
|
|
103
|
-
|
|
104
|
-
act(() => {
|
|
105
|
-
result.current.trigger(triggerX, triggerY);
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
const particles = result.current.particles;
|
|
109
|
-
particles.forEach(particle => {
|
|
110
|
-
expect(particle.x).toBe(triggerX);
|
|
111
|
-
expect(particle.y).toBe(triggerY);
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
it('should use default position when none provided', () => {
|
|
116
|
-
const { result } = renderHook(() => useFireworks(mockConfig));
|
|
117
|
-
|
|
118
|
-
act(() => {
|
|
119
|
-
result.current.trigger();
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
const particles = result.current.particles;
|
|
123
|
-
particles.forEach(particle => {
|
|
124
|
-
expect(particle.x).toBe(0);
|
|
125
|
-
expect(particle.y).toBe(0);
|
|
126
|
-
});
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
it('should set active state to true', () => {
|
|
130
|
-
const { result } = renderHook(() => useFireworks(mockConfig));
|
|
131
|
-
|
|
132
|
-
act(() => {
|
|
133
|
-
result.current.trigger(100, 100);
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
expect(result.current.isActive).toBe(true);
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
it('should start animation loop', () => {
|
|
140
|
-
const { result } = renderHook(() => useFireworks(mockConfig));
|
|
141
|
-
|
|
142
|
-
act(() => {
|
|
143
|
-
result.current.trigger(100, 100);
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
expect(global.requestAnimationFrame).toHaveBeenCalled();
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
it('should auto-stop after duration', () => {
|
|
150
|
-
const { result } = renderHook(() => useFireworks(mockConfig));
|
|
151
|
-
|
|
152
|
-
act(() => {
|
|
153
|
-
result.current.trigger(100, 100);
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
expect(result.current.isActive).toBe(true);
|
|
157
|
-
|
|
158
|
-
act(() => {
|
|
159
|
-
jest.advanceTimersByTime(mockConfig.duration);
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
expect(result.current.isActive).toBe(false);
|
|
163
|
-
});
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
describe('particle physics', () => {
|
|
167
|
-
it('should update particle positions over time', () => {
|
|
168
|
-
const { result } = renderHook(() => useFireworks(mockConfig));
|
|
169
|
-
|
|
170
|
-
act(() => {
|
|
171
|
-
result.current.trigger(100, 100);
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
const initialParticles = [...result.current.particles];
|
|
175
|
-
|
|
176
|
-
act(() => {
|
|
177
|
-
jest.advanceTimersByTime(16); // One frame
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
const updatedParticles = result.current.particles;
|
|
181
|
-
|
|
182
|
-
updatedParticles.forEach((particle, index) => {
|
|
183
|
-
const initial = initialParticles[index];
|
|
184
|
-
expect(particle.x).not.toBe(initial.x);
|
|
185
|
-
expect(particle.y).not.toBe(initial.y);
|
|
186
|
-
expect(particle.life).toBeLessThan(initial.life);
|
|
187
|
-
});
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
it('should apply gravity to particles', () => {
|
|
191
|
-
const { result } = renderHook(() => useFireworks(mockConfig));
|
|
192
|
-
|
|
193
|
-
act(() => {
|
|
194
|
-
result.current.trigger(100, 100);
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
const initialParticles = [...result.current.particles];
|
|
198
|
-
|
|
199
|
-
act(() => {
|
|
200
|
-
jest.advanceTimersByTime(16);
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
const updatedParticles = result.current.particles;
|
|
204
|
-
|
|
205
|
-
updatedParticles.forEach((particle, index) => {
|
|
206
|
-
const initial = initialParticles[index];
|
|
207
|
-
const expectedY = initial.y + initial.velocityY * 0.1 + FIREWORKS_CONSTANTS.GRAVITY;
|
|
208
|
-
expect(particle.y).toBeCloseTo(expectedY, 1);
|
|
209
|
-
});
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
it('should remove dead particles', () => {
|
|
213
|
-
const { result } = renderHook(() => useFireworks(mockConfig));
|
|
214
|
-
|
|
215
|
-
act(() => {
|
|
216
|
-
result.current.trigger(100, 100);
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
// Simulate particles dying
|
|
220
|
-
act(() => {
|
|
221
|
-
jest.advanceTimersByTime(2000); // Long enough for particles to die
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
expect(result.current.particles).toHaveLength(0);
|
|
225
|
-
expect(result.current.isActive).toBe(false);
|
|
226
|
-
});
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
describe('cleanup', () => {
|
|
230
|
-
it('should cancel animation frame on unmount', () => {
|
|
231
|
-
const { result, unmount } = renderHook(() => useFireworks(mockConfig));
|
|
232
|
-
|
|
233
|
-
act(() => {
|
|
234
|
-
result.current.trigger(100, 100);
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
unmount();
|
|
238
|
-
|
|
239
|
-
expect(global.cancelAnimationFrame).toHaveBeenCalled();
|
|
240
|
-
});
|
|
241
|
-
});
|
|
242
|
-
});
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* useGesture Hook Tests
|
|
3
|
-
*
|
|
4
|
-
* Unit tests for gesture handling functionality.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { renderHook } from '@testing-library/react';
|
|
8
|
-
import { GestureDetector } from 'react-native-gesture-handler';
|
|
9
|
-
import { useGesture } from '../useGesture';
|
|
10
|
-
import { useGestureCreators } from '../useGestureCreators';
|
|
11
|
-
import { useGestureState } from '../useGestureState';
|
|
12
|
-
|
|
13
|
-
// Mock react-native-gesture-handler
|
|
14
|
-
jest.mock('react-native-gesture-handler', () => ({
|
|
15
|
-
GestureDetector: jest.fn(({ children }) => children),
|
|
16
|
-
Gesture: {
|
|
17
|
-
Tap: jest.fn(() => ({
|
|
18
|
-
numberOfTaps: jest.fn().mockReturnThis(),
|
|
19
|
-
maxDuration: jest.fn().mockReturnThis(),
|
|
20
|
-
onStart: jest.fn().mockReturnThis(),
|
|
21
|
-
})),
|
|
22
|
-
Pan: jest.fn(() => ({
|
|
23
|
-
onStart: jest.fn().mockReturnThis(),
|
|
24
|
-
onUpdate: jest.fn().mockReturnThis(),
|
|
25
|
-
onEnd: jest.fn().mockReturnThis(),
|
|
26
|
-
})),
|
|
27
|
-
Pinch: jest.fn(() => ({
|
|
28
|
-
onStart: jest.fn().mockReturnThis(),
|
|
29
|
-
onUpdate: jest.fn().mockReturnThis(),
|
|
30
|
-
onEnd: jest.fn().mockReturnThis(),
|
|
31
|
-
})),
|
|
32
|
-
LongPress: jest.fn(() => ({
|
|
33
|
-
minDuration: jest.fn().mockReturnThis(),
|
|
34
|
-
onStart: jest.fn().mockReturnThis(),
|
|
35
|
-
})),
|
|
36
|
-
},
|
|
37
|
-
}));
|
|
38
|
-
|
|
39
|
-
// Mock useGestureState
|
|
40
|
-
jest.mock('../useGestureState', () => ({
|
|
41
|
-
useGestureState: jest.fn(() => ({
|
|
42
|
-
translateX: { value: 0 },
|
|
43
|
-
translateY: { value: 0 },
|
|
44
|
-
scale: { value: 1 },
|
|
45
|
-
reset: jest.fn(),
|
|
46
|
-
animatedStyle: {},
|
|
47
|
-
})),
|
|
48
|
-
}));
|
|
49
|
-
|
|
50
|
-
// Mock useGestureCreators
|
|
51
|
-
jest.mock('../useGestureCreators', () => ({
|
|
52
|
-
useGestureCreators: jest.fn(() => ({
|
|
53
|
-
createTapGesture: jest.fn(),
|
|
54
|
-
createPanGesture: jest.fn(),
|
|
55
|
-
createPinchGesture: jest.fn(),
|
|
56
|
-
createLongPressGesture: jest.fn(),
|
|
57
|
-
})),
|
|
58
|
-
}));
|
|
59
|
-
|
|
60
|
-
describe('useGesture', () => {
|
|
61
|
-
beforeEach(() => {
|
|
62
|
-
jest.clearAllMocks();
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it('should provide gesture creators', () => {
|
|
66
|
-
const { result } = renderHook(() => useGesture());
|
|
67
|
-
|
|
68
|
-
expect(typeof result.current.createTapGesture).toBe('function');
|
|
69
|
-
expect(typeof result.current.createPanGesture).toBe('function');
|
|
70
|
-
expect(typeof result.current.createPinchGesture).toBe('function');
|
|
71
|
-
expect(typeof result.current.createLongPressGesture).toBe('function');
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
it('should provide shared values', () => {
|
|
75
|
-
const { result } = renderHook(() => useGesture());
|
|
76
|
-
|
|
77
|
-
expect(result.current.translateX).toBeDefined();
|
|
78
|
-
expect(result.current.translateY).toBeDefined();
|
|
79
|
-
expect(result.current.scale).toBeDefined();
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
it('should provide utilities', () => {
|
|
83
|
-
const { result } = renderHook(() => useGesture());
|
|
84
|
-
|
|
85
|
-
expect(typeof result.current.reset).toBe('function');
|
|
86
|
-
expect(result.current.animatedStyle).toBeDefined();
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
it('should export GestureDetector', () => {
|
|
90
|
-
const { result } = renderHook(() => useGesture());
|
|
91
|
-
|
|
92
|
-
expect(result.current.GestureDetector).toBe(GestureDetector);
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
describe('gesture creators integration', () => {
|
|
96
|
-
it('should integrate with useGestureCreators', () => {
|
|
97
|
-
renderHook(() => useGesture());
|
|
98
|
-
|
|
99
|
-
expect(useGestureCreators).toHaveBeenCalled();
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
it('should integrate with useGestureState', () => {
|
|
103
|
-
renderHook(() => useGesture());
|
|
104
|
-
|
|
105
|
-
expect(useGestureState).toHaveBeenCalled();
|
|
106
|
-
});
|
|
107
|
-
});
|
|
108
|
-
});
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* useSpringAnimation Hook Tests
|
|
3
|
-
*
|
|
4
|
-
* Unit tests for spring-based animations (scale, bounce).
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { renderHook, act } from '@testing-library/react';
|
|
8
|
-
import { useSpringAnimation } from '../useSpringAnimation';
|
|
9
|
-
import { ANIMATION_CONSTANTS } from '../../../domain/entities/Animation';
|
|
10
|
-
import { withSpring, withSequence } from 'react-native-reanimated';
|
|
11
|
-
|
|
12
|
-
// Mock react-native-reanimated
|
|
13
|
-
jest.mock('react-native-reanimated', () => ({
|
|
14
|
-
useSharedValue: jest.fn((initialValue) => ({
|
|
15
|
-
value: initialValue,
|
|
16
|
-
})),
|
|
17
|
-
useAnimatedStyle: jest.fn((styleFactory) => styleFactory()),
|
|
18
|
-
withSpring: jest.fn((toValue, config) => ({ toValue, config })),
|
|
19
|
-
withSequence: jest.fn((...animations) => animations),
|
|
20
|
-
}));
|
|
21
|
-
|
|
22
|
-
// Mock SpringAnimationConfigService
|
|
23
|
-
jest.mock('../../../infrastructure/services/SpringAnimationConfigService', () => ({
|
|
24
|
-
SpringAnimationConfigService: {
|
|
25
|
-
getSpringConfig: jest.fn(() => ({
|
|
26
|
-
damping: ANIMATION_CONSTANTS.SPRING.DAMPING,
|
|
27
|
-
stiffness: ANIMATION_CONSTANTS.SPRING.STIFFNESS,
|
|
28
|
-
})),
|
|
29
|
-
},
|
|
30
|
-
}));
|
|
31
|
-
|
|
32
|
-
describe('useSpringAnimation', () => {
|
|
33
|
-
beforeEach(() => {
|
|
34
|
-
jest.clearAllMocks();
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it('should initialize with default values', () => {
|
|
38
|
-
const { result } = renderHook(() => useSpringAnimation());
|
|
39
|
-
|
|
40
|
-
expect(result.current.scale.value).toBe(1);
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it('should provide animation functions', () => {
|
|
44
|
-
const { result } = renderHook(() => useSpringAnimation());
|
|
45
|
-
|
|
46
|
-
expect(typeof result.current.scaleIn).toBe('function');
|
|
47
|
-
expect(typeof result.current.scaleOut).toBe('function');
|
|
48
|
-
expect(typeof result.current.bounce).toBe('function');
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
describe('scaleIn', () => {
|
|
52
|
-
it('should animate scale from 0 to 1 with default config', () => {
|
|
53
|
-
const { result } = renderHook(() => useSpringAnimation());
|
|
54
|
-
|
|
55
|
-
act(() => {
|
|
56
|
-
result.current.scaleIn();
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
expect(withSpring).toHaveBeenCalledWith(1, {
|
|
60
|
-
damping: ANIMATION_CONSTANTS.SPRING.DAMPING,
|
|
61
|
-
stiffness: ANIMATION_CONSTANTS.SPRING.STIFFNESS,
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it('should use custom config when provided', () => {
|
|
66
|
-
const { result } = renderHook(() => useSpringAnimation());
|
|
67
|
-
const customConfig = { damping: 20, stiffness: 200 };
|
|
68
|
-
|
|
69
|
-
act(() => {
|
|
70
|
-
result.current.scaleIn(customConfig);
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
expect(withSpring).toHaveBeenCalledWith(1, customConfig);
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
describe('scaleOut', () => {
|
|
78
|
-
it('should animate scale to 0 with default config', () => {
|
|
79
|
-
const { result } = renderHook(() => useSpringAnimation());
|
|
80
|
-
|
|
81
|
-
act(() => {
|
|
82
|
-
result.current.scaleOut();
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
expect(withSpring).toHaveBeenCalledWith(0, {
|
|
86
|
-
damping: ANIMATION_CONSTANTS.SPRING.DAMPING,
|
|
87
|
-
stiffness: ANIMATION_CONSTANTS.SPRING.STIFFNESS,
|
|
88
|
-
});
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
describe('bounce', () => {
|
|
93
|
-
it('should create bounce animation sequence', () => {
|
|
94
|
-
const { result } = renderHook(() => useSpringAnimation());
|
|
95
|
-
const mockConfig = { damping: 5, stiffness: 120 };
|
|
96
|
-
|
|
97
|
-
act(() => {
|
|
98
|
-
result.current.bounce(mockConfig);
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
expect(withSequence).toHaveBeenCalledWith(
|
|
102
|
-
withSpring(0.8, mockConfig),
|
|
103
|
-
withSpring(1.2, mockConfig),
|
|
104
|
-
withSpring(1, mockConfig)
|
|
105
|
-
);
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
it('should use default config when none provided', () => {
|
|
109
|
-
const { result } = renderHook(() => useSpringAnimation());
|
|
110
|
-
|
|
111
|
-
act(() => {
|
|
112
|
-
result.current.bounce();
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
expect(withSequence).toHaveBeenCalled();
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
describe('shared values', () => {
|
|
120
|
-
it('should expose scale shared value for custom animations', () => {
|
|
121
|
-
const { result } = renderHook(() => useSpringAnimation());
|
|
122
|
-
|
|
123
|
-
expect(result.current.scale).toBeDefined();
|
|
124
|
-
expect(result.current.scale.value).toBe(1);
|
|
125
|
-
});
|
|
126
|
-
});
|
|
127
|
-
});
|
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* useTimingAnimation Hook Tests
|
|
3
|
-
*
|
|
4
|
-
* Unit tests for timing-based animations (fade, slide).
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { renderHook, act } from '@testing-library/react';
|
|
8
|
-
import { useTimingAnimation } from '../useTimingAnimation';
|
|
9
|
-
import { ANIMATION_CONSTANTS } from '../../../domain/entities/Animation';
|
|
10
|
-
import { withTiming } from 'react-native-reanimated';
|
|
11
|
-
|
|
12
|
-
// Mock react-native-reanimated
|
|
13
|
-
jest.mock('react-native-reanimated', () => ({
|
|
14
|
-
useSharedValue: jest.fn((initialValue) => ({
|
|
15
|
-
value: initialValue,
|
|
16
|
-
})),
|
|
17
|
-
useAnimatedStyle: jest.fn((styleFactory) => styleFactory()),
|
|
18
|
-
withTiming: jest.fn((toValue, config) => ({ toValue, config })),
|
|
19
|
-
Easing: {
|
|
20
|
-
ease: jest.fn(),
|
|
21
|
-
out: jest.fn((easing) => easing),
|
|
22
|
-
bezier: jest.fn(() => jest.fn()),
|
|
23
|
-
},
|
|
24
|
-
}));
|
|
25
|
-
|
|
26
|
-
// Mock AnimationConfigService
|
|
27
|
-
jest.mock('../../../infrastructure/services/TimingAnimationConfigService', () => ({
|
|
28
|
-
TimingAnimationConfigService: {
|
|
29
|
-
getTimingConfig: jest.fn(() => ({
|
|
30
|
-
duration: ANIMATION_CONSTANTS.DURATION.NORMAL,
|
|
31
|
-
})),
|
|
32
|
-
},
|
|
33
|
-
}));
|
|
34
|
-
|
|
35
|
-
describe('useTimingAnimation', () => {
|
|
36
|
-
beforeEach(() => {
|
|
37
|
-
jest.clearAllMocks();
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it('should initialize with default values', () => {
|
|
41
|
-
const { result } = renderHook(() => useTimingAnimation());
|
|
42
|
-
|
|
43
|
-
expect(result.current.opacity.value).toBe(1);
|
|
44
|
-
expect(result.current.translateY.value).toBe(0);
|
|
45
|
-
expect(result.current.translateX.value).toBe(0);
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it('should provide animation functions', () => {
|
|
49
|
-
const { result } = renderHook(() => useTimingAnimation());
|
|
50
|
-
|
|
51
|
-
expect(typeof result.current.fadeIn).toBe('function');
|
|
52
|
-
expect(typeof result.current.fadeOut).toBe('function');
|
|
53
|
-
expect(typeof result.current.slideInUp).toBe('function');
|
|
54
|
-
expect(typeof result.current.slideInDown).toBe('function');
|
|
55
|
-
expect(typeof result.current.slideInLeft).toBe('function');
|
|
56
|
-
expect(typeof result.current.slideInRight).toBe('function');
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
describe('fadeIn', () => {
|
|
60
|
-
it('should animate opacity to 1 with default config', () => {
|
|
61
|
-
const { result } = renderHook(() => useTimingAnimation());
|
|
62
|
-
|
|
63
|
-
act(() => {
|
|
64
|
-
result.current.fadeIn();
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
expect(withTiming).toHaveBeenCalledWith(1, {
|
|
68
|
-
duration: ANIMATION_CONSTANTS.DURATION.NORMAL,
|
|
69
|
-
easing: expect.any(Function),
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it('should use custom config when provided', () => {
|
|
74
|
-
const { result } = renderHook(() => useTimingAnimation());
|
|
75
|
-
const customConfig = { duration: 500 };
|
|
76
|
-
|
|
77
|
-
act(() => {
|
|
78
|
-
result.current.fadeIn(customConfig);
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
expect(withTiming).toHaveBeenCalledWith(1, customConfig);
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
describe('fadeOut', () => {
|
|
86
|
-
it('should animate opacity to 0 with default config', () => {
|
|
87
|
-
const { result } = renderHook(() => useTimingAnimation());
|
|
88
|
-
|
|
89
|
-
act(() => {
|
|
90
|
-
result.current.fadeOut();
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
expect(withTiming).toHaveBeenCalledWith(0, {
|
|
94
|
-
duration: ANIMATION_CONSTANTS.DURATION.NORMAL,
|
|
95
|
-
easing: expect.any(Function),
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
describe('slideInUp', () => {
|
|
101
|
-
it('should slide from bottom to top with default distance', () => {
|
|
102
|
-
const { result } = renderHook(() => useTimingAnimation());
|
|
103
|
-
|
|
104
|
-
act(() => {
|
|
105
|
-
result.current.slideInUp();
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
expect(result.current.translateY.value).toBe(0);
|
|
109
|
-
expect(withTiming).toHaveBeenCalledWith(0, {
|
|
110
|
-
duration: ANIMATION_CONSTANTS.DURATION.NORMAL,
|
|
111
|
-
easing: expect.any(Function),
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
it('should use custom distance', () => {
|
|
116
|
-
const { result } = renderHook(() => useTimingAnimation());
|
|
117
|
-
const customDistance = 150;
|
|
118
|
-
|
|
119
|
-
act(() => {
|
|
120
|
-
result.current.slideInUp(customDistance);
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
expect(result.current.translateY.value).toBe(0);
|
|
124
|
-
});
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
describe('slideInDown', () => {
|
|
128
|
-
it('should slide from top to bottom', () => {
|
|
129
|
-
const { result } = renderHook(() => useTimingAnimation());
|
|
130
|
-
|
|
131
|
-
act(() => {
|
|
132
|
-
result.current.slideInDown();
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
expect(result.current.translateY.value).toBe(0);
|
|
136
|
-
});
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
describe('slideInLeft', () => {
|
|
140
|
-
it('should slide from left to right', () => {
|
|
141
|
-
const { result } = renderHook(() => useTimingAnimation());
|
|
142
|
-
|
|
143
|
-
act(() => {
|
|
144
|
-
result.current.slideInLeft();
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
expect(result.current.translateX.value).toBe(0);
|
|
148
|
-
});
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
describe('slideInRight', () => {
|
|
152
|
-
it('should slide from right to left', () => {
|
|
153
|
-
const { result } = renderHook(() => useTimingAnimation());
|
|
154
|
-
|
|
155
|
-
act(() => {
|
|
156
|
-
result.current.slideInRight();
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
expect(result.current.translateX.value).toBe(0);
|
|
160
|
-
});
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
describe('shared values', () => {
|
|
164
|
-
it('should expose shared values for custom animations', () => {
|
|
165
|
-
const { result } = renderHook(() => useTimingAnimation());
|
|
166
|
-
|
|
167
|
-
expect(result.current.opacity).toBeDefined();
|
|
168
|
-
expect(result.current.translateY).toBeDefined();
|
|
169
|
-
expect(result.current.translateX).toBeDefined();
|
|
170
|
-
});
|
|
171
|
-
});
|
|
172
|
-
});
|