@umituz/react-native-design-system 2.6.48 → 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/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
package/src/molecules/animation/presentation/hooks/__tests__/useAnimation.integration.test.ts
DELETED
|
@@ -1,210 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* useAnimation Hook Integration Tests
|
|
3
|
-
*
|
|
4
|
-
* Integration tests for combined animation functionality.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { renderHook, act } from '@testing-library/react';
|
|
8
|
-
import { useAnimation } from '../useAnimation';
|
|
9
|
-
import { useTimingAnimation } from '../useTimingAnimation';
|
|
10
|
-
import { useSpringAnimation } from '../useSpringAnimation';
|
|
11
|
-
import { useTransformAnimation } from '../useTransformAnimation';
|
|
12
|
-
import { useAnimatedStyle } from 'react-native-reanimated';
|
|
13
|
-
|
|
14
|
-
// Mock react-native-reanimated
|
|
15
|
-
jest.mock('react-native-reanimated', () => ({
|
|
16
|
-
useSharedValue: jest.fn((initialValue) => ({
|
|
17
|
-
value: initialValue,
|
|
18
|
-
})),
|
|
19
|
-
useAnimatedStyle: jest.fn((styleFactory) => styleFactory()),
|
|
20
|
-
withTiming: jest.fn((toValue, config) => ({ toValue, config })),
|
|
21
|
-
withSpring: jest.fn((toValue, config) => ({ toValue, config })),
|
|
22
|
-
withSequence: jest.fn((...animations) => animations),
|
|
23
|
-
withRepeat: jest.fn((animation, count, reverse) => ({ animation, count, reverse })),
|
|
24
|
-
Easing: {
|
|
25
|
-
ease: jest.fn(),
|
|
26
|
-
out: jest.fn((easing) => easing),
|
|
27
|
-
bezier: jest.fn(() => jest.fn()),
|
|
28
|
-
linear: jest.fn(),
|
|
29
|
-
},
|
|
30
|
-
}));
|
|
31
|
-
|
|
32
|
-
// Define singleton mock objects
|
|
33
|
-
const mockTiming = {
|
|
34
|
-
fadeIn: jest.fn(),
|
|
35
|
-
fadeOut: jest.fn(),
|
|
36
|
-
slideInUp: jest.fn(),
|
|
37
|
-
slideInDown: jest.fn(),
|
|
38
|
-
slideInLeft: jest.fn(),
|
|
39
|
-
slideInRight: jest.fn(),
|
|
40
|
-
opacity: { value: 1 },
|
|
41
|
-
translateY: { value: 0 },
|
|
42
|
-
translateX: { value: 0 },
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
const mockSpring = {
|
|
46
|
-
scaleIn: jest.fn(),
|
|
47
|
-
scaleOut: jest.fn(),
|
|
48
|
-
bounce: jest.fn(),
|
|
49
|
-
scale: { value: 1 },
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
const mockTransform = {
|
|
53
|
-
shake: jest.fn(),
|
|
54
|
-
pulse: jest.fn(),
|
|
55
|
-
spin: jest.fn(),
|
|
56
|
-
translateX: { value: 0 },
|
|
57
|
-
scale: { value: 1 },
|
|
58
|
-
rotate: { value: 0 },
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
// Mock all sub-hooks
|
|
62
|
-
jest.mock('../useTimingAnimation', () => ({
|
|
63
|
-
useTimingAnimation: jest.fn(() => mockTiming),
|
|
64
|
-
}));
|
|
65
|
-
|
|
66
|
-
jest.mock('../useSpringAnimation', () => ({
|
|
67
|
-
useSpringAnimation: jest.fn(() => mockSpring),
|
|
68
|
-
}));
|
|
69
|
-
|
|
70
|
-
jest.mock('../useTransformAnimation', () => ({
|
|
71
|
-
useTransformAnimation: jest.fn(() => mockTransform),
|
|
72
|
-
}));
|
|
73
|
-
|
|
74
|
-
describe('useAnimation Integration', () => {
|
|
75
|
-
beforeEach(() => {
|
|
76
|
-
jest.clearAllMocks();
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
it('should integrate all animation hooks', () => {
|
|
80
|
-
renderHook(() => useAnimation());
|
|
81
|
-
|
|
82
|
-
expect(useTimingAnimation).toHaveBeenCalled();
|
|
83
|
-
expect(useSpringAnimation).toHaveBeenCalled();
|
|
84
|
-
expect(useTransformAnimation).toHaveBeenCalled();
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it('should provide all timing animations', () => {
|
|
88
|
-
const { result } = renderHook(() => useAnimation());
|
|
89
|
-
|
|
90
|
-
expect(typeof result.current.fadeIn).toBe('function');
|
|
91
|
-
expect(typeof result.current.fadeOut).toBe('function');
|
|
92
|
-
expect(typeof result.current.slideInUp).toBe('function');
|
|
93
|
-
expect(typeof result.current.slideInDown).toBe('function');
|
|
94
|
-
expect(typeof result.current.slideInLeft).toBe('function');
|
|
95
|
-
expect(typeof result.current.slideInRight).toBe('function');
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
it('should provide all spring animations', () => {
|
|
99
|
-
const { result } = renderHook(() => useAnimation());
|
|
100
|
-
|
|
101
|
-
expect(typeof result.current.scaleIn).toBe('function');
|
|
102
|
-
expect(typeof result.current.scaleOut).toBe('function');
|
|
103
|
-
expect(typeof result.current.bounce).toBe('function');
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
it('should provide all transform animations', () => {
|
|
107
|
-
const { result } = renderHook(() => useAnimation());
|
|
108
|
-
|
|
109
|
-
expect(typeof result.current.shake).toBe('function');
|
|
110
|
-
expect(typeof result.current.pulse).toBe('function');
|
|
111
|
-
expect(typeof result.current.spin).toBe('function');
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it('should provide all shared values', () => {
|
|
115
|
-
const { result } = renderHook(() => useAnimation());
|
|
116
|
-
|
|
117
|
-
expect(result.current.opacity).toBeDefined();
|
|
118
|
-
expect(result.current.translateY).toBeDefined();
|
|
119
|
-
expect(result.current.translateX).toBeDefined();
|
|
120
|
-
expect(result.current.scale).toBeDefined();
|
|
121
|
-
expect(result.current.rotate).toBeDefined();
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
it('should provide animated style', () => {
|
|
125
|
-
const { result } = renderHook(() => useAnimation());
|
|
126
|
-
|
|
127
|
-
expect(typeof result.current.animatedStyle).toBe('function');
|
|
128
|
-
expect(useAnimatedStyle).toHaveBeenCalled();
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
describe('animation combinations', () => {
|
|
132
|
-
it('should allow combining fade and scale animations', () => {
|
|
133
|
-
const { result } = renderHook(() => useAnimation());
|
|
134
|
-
|
|
135
|
-
act(() => {
|
|
136
|
-
result.current.fadeIn();
|
|
137
|
-
result.current.scaleIn();
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
expect(mockTiming.fadeIn).toHaveBeenCalled();
|
|
141
|
-
expect(mockSpring.scaleIn).toHaveBeenCalled();
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
it('should allow combining slide and rotate animations', () => {
|
|
145
|
-
const { result } = renderHook(() => useAnimation());
|
|
146
|
-
|
|
147
|
-
act(() => {
|
|
148
|
-
result.current.slideInUp();
|
|
149
|
-
result.current.spin();
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
expect(mockTiming.slideInUp).toHaveBeenCalled();
|
|
153
|
-
expect(mockTransform.spin).toHaveBeenCalled();
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
it('should allow complex animation sequences', () => {
|
|
157
|
-
const { result } = renderHook(() => useAnimation());
|
|
158
|
-
|
|
159
|
-
act(() => {
|
|
160
|
-
result.current.fadeIn();
|
|
161
|
-
result.current.slideInUp();
|
|
162
|
-
result.current.scaleIn();
|
|
163
|
-
result.current.bounce();
|
|
164
|
-
result.current.shake();
|
|
165
|
-
result.current.pulse();
|
|
166
|
-
result.current.spin();
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
expect(mockTiming.fadeIn).toHaveBeenCalled();
|
|
170
|
-
expect(mockTiming.slideInUp).toHaveBeenCalled();
|
|
171
|
-
expect(mockSpring.scaleIn).toHaveBeenCalled();
|
|
172
|
-
expect(mockSpring.bounce).toHaveBeenCalled();
|
|
173
|
-
expect(mockTransform.shake).toHaveBeenCalled();
|
|
174
|
-
expect(mockTransform.pulse).toHaveBeenCalled();
|
|
175
|
-
expect(mockTransform.spin).toHaveBeenCalled();
|
|
176
|
-
});
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
describe('animated style composition', () => {
|
|
180
|
-
it('should compose styles from all animation types', () => {
|
|
181
|
-
const mockStyle = {
|
|
182
|
-
opacity: 1,
|
|
183
|
-
transform: [
|
|
184
|
-
{ translateY: 0 },
|
|
185
|
-
{ translateX: 0 },
|
|
186
|
-
{ scale: 1 },
|
|
187
|
-
{ rotate: '0deg' },
|
|
188
|
-
],
|
|
189
|
-
};
|
|
190
|
-
|
|
191
|
-
(useAnimatedStyle as jest.Mock).mockReturnValue(mockStyle);
|
|
192
|
-
|
|
193
|
-
const { result } = renderHook(() => useAnimation());
|
|
194
|
-
|
|
195
|
-
expect(result.current.animatedStyle).toBe(mockStyle);
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
it('should prioritize transform values over timing/spring values', () => {
|
|
199
|
-
// Set transform values to non-default
|
|
200
|
-
mockTransform.translateX.value = 50;
|
|
201
|
-
mockTransform.scale.value = 1.5;
|
|
202
|
-
|
|
203
|
-
renderHook(() => useAnimation());
|
|
204
|
-
|
|
205
|
-
expect(useAnimatedStyle).toHaveBeenCalledWith(
|
|
206
|
-
expect.any(Function)
|
|
207
|
-
);
|
|
208
|
-
});
|
|
209
|
-
});
|
|
210
|
-
});
|
|
@@ -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
|
-
});
|