react-native-reanimated-carousel 5.0.0-beta.6 → 5.0.0-beta.8
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/README.md +32 -2
- package/lib/commonjs/components/CarouselLayout.js +1 -1
- package/lib/commonjs/components/CarouselLayout.js.map +1 -1
- package/lib/commonjs/components/ItemRenderer.js +1 -1
- package/lib/commonjs/components/ItemRenderer.js.map +1 -1
- package/lib/commonjs/components/ScrollViewGesture.js +1 -1
- package/lib/commonjs/components/ScrollViewGesture.js.map +1 -1
- package/lib/commonjs/hooks/useOnProgressChange.js +1 -1
- package/lib/commonjs/hooks/useOnProgressChange.js.map +1 -1
- package/lib/commonjs/hooks/usePropsErrorBoundary.js +1 -1
- package/lib/commonjs/hooks/usePropsErrorBoundary.js.map +1 -1
- package/lib/commonjs/hooks/useVisibleRanges.js +1 -1
- package/lib/commonjs/hooks/useVisibleRanges.js.map +1 -1
- package/lib/module/components/CarouselLayout.js +1 -1
- package/lib/module/components/CarouselLayout.js.map +1 -1
- package/lib/module/components/ItemRenderer.js +1 -1
- package/lib/module/components/ItemRenderer.js.map +1 -1
- package/lib/module/components/ScrollViewGesture.js +1 -1
- package/lib/module/components/ScrollViewGesture.js.map +1 -1
- package/lib/module/hooks/useOnProgressChange.js +1 -1
- package/lib/module/hooks/useOnProgressChange.js.map +1 -1
- package/lib/module/hooks/usePropsErrorBoundary.js +1 -1
- package/lib/module/hooks/usePropsErrorBoundary.js.map +1 -1
- package/lib/module/hooks/useVisibleRanges.js +1 -1
- package/lib/module/hooks/useVisibleRanges.js.map +1 -1
- package/lib/typescript/components/CarouselLayout.d.ts.map +1 -1
- package/lib/typescript/components/ItemRenderer.d.ts +1 -0
- package/lib/typescript/components/ItemRenderer.d.ts.map +1 -1
- package/lib/typescript/components/ScrollViewGesture.d.ts.map +1 -1
- package/lib/typescript/hooks/usePropsErrorBoundary.d.ts.map +1 -1
- package/lib/typescript/hooks/useVisibleRanges.d.ts +6 -0
- package/lib/typescript/hooks/useVisibleRanges.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +1 -1
- package/package.json +4 -2
- package/src/components/CarouselLayout.tsx +4 -4
- package/src/components/ItemRenderer.tsx +11 -6
- package/src/components/ScrollViewGesture.tsx +8 -11
- package/src/hooks/useOnProgressChange.ts +1 -1
- package/src/hooks/usePropsErrorBoundary.ts +4 -3
- package/src/hooks/useVisibleRanges.tsx +80 -54
- package/src/types.ts +1 -1
- package/src/components/Carousel.test.tsx +0 -1215
- package/src/components/LazyView.test.tsx +0 -61
- package/src/components/Pagination/Pagination.test.tsx +0 -178
- package/src/components/rnr-demo.test.tsx +0 -53
- package/src/hooks/useAutoPlay.test.ts +0 -194
- package/src/hooks/useCarouselController.test.tsx +0 -1158
- package/src/hooks/useCheckMounted.test.ts +0 -47
- package/src/hooks/useCommonVariables.test.tsx +0 -384
- package/src/hooks/useInitProps.test.tsx +0 -134
- package/src/hooks/useLayoutConfig.test.tsx +0 -247
- package/src/hooks/useOffsetX.test.ts +0 -54
- package/src/hooks/useOnProgressChange.test.tsx +0 -207
- package/src/hooks/usePanGestureProxy.test.tsx +0 -368
- package/src/hooks/useUpdateGestureConfig.test.ts +0 -89
- package/src/hooks/useVisibleRanges.test.tsx +0 -347
- package/src/layouts/parallax.test.ts +0 -239
- package/src/layouts/stack.test.ts +0 -252
- package/src/store/index.test.tsx +0 -314
- package/src/utils/compute-gesture-translation.test.ts +0 -70
- package/src/utils/compute-offset-if-data-changed.test.ts +0 -133
- package/src/utils/compute-offset-if-size-changed.test.ts +0 -78
- package/src/utils/computed-with-auto-fill-data.test.ts +0 -298
- package/src/utils/deal-with-animation.test.ts +0 -181
- package/src/utils/handleroffset-direction.test.ts +0 -124
- package/src/utils/index.test.ts +0 -90
- package/src/utils/log.test.ts +0 -134
- package/src/utils/sanitize-animation-style.test.ts +0 -40
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { render } from "@testing-library/react-native";
|
|
2
|
-
import React from "react";
|
|
3
|
-
import { Text } from "react-native";
|
|
4
|
-
|
|
5
|
-
import { LazyView } from "./LazyView";
|
|
6
|
-
|
|
7
|
-
describe("LazyView", () => {
|
|
8
|
-
it("should render children when shouldUpdate is true", () => {
|
|
9
|
-
const { getByText } = render(
|
|
10
|
-
<LazyView shouldUpdate={true}>
|
|
11
|
-
<Text>Test Child</Text>
|
|
12
|
-
</LazyView>
|
|
13
|
-
);
|
|
14
|
-
|
|
15
|
-
expect(getByText("Test Child")).toBeTruthy();
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
it("should not render children when shouldUpdate is false", () => {
|
|
19
|
-
const { queryByText } = render(
|
|
20
|
-
<LazyView shouldUpdate={false}>
|
|
21
|
-
<Text>Test Child</Text>
|
|
22
|
-
</LazyView>
|
|
23
|
-
);
|
|
24
|
-
|
|
25
|
-
expect(queryByText("Test Child")).toBeNull();
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it("should render empty fragment when shouldUpdate is false", () => {
|
|
29
|
-
const { toJSON } = render(
|
|
30
|
-
<LazyView shouldUpdate={false}>
|
|
31
|
-
<Text>Test Child</Text>
|
|
32
|
-
</LazyView>
|
|
33
|
-
);
|
|
34
|
-
|
|
35
|
-
expect(toJSON()).toBeNull();
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
it("should handle multiple children when shouldUpdate is true", () => {
|
|
39
|
-
const { getByText } = render(
|
|
40
|
-
<LazyView shouldUpdate={true}>
|
|
41
|
-
<Text>First Child</Text>
|
|
42
|
-
<Text>Second Child</Text>
|
|
43
|
-
</LazyView>
|
|
44
|
-
);
|
|
45
|
-
|
|
46
|
-
expect(getByText("First Child")).toBeTruthy();
|
|
47
|
-
expect(getByText("Second Child")).toBeTruthy();
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it("should not render multiple children when shouldUpdate is false", () => {
|
|
51
|
-
const { queryByText } = render(
|
|
52
|
-
<LazyView shouldUpdate={false}>
|
|
53
|
-
<Text>First Child</Text>
|
|
54
|
-
<Text>Second Child</Text>
|
|
55
|
-
</LazyView>
|
|
56
|
-
);
|
|
57
|
-
|
|
58
|
-
expect(queryByText("First Child")).toBeNull();
|
|
59
|
-
expect(queryByText("Second Child")).toBeNull();
|
|
60
|
-
});
|
|
61
|
-
});
|
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
import { act, fireEvent, render } from "@testing-library/react-native";
|
|
2
|
-
import { View } from "react-native";
|
|
3
|
-
import { useSharedValue } from "react-native-reanimated";
|
|
4
|
-
|
|
5
|
-
import { Pagination } from ".";
|
|
6
|
-
|
|
7
|
-
jest.mock("react-native-worklets", () => ({
|
|
8
|
-
scheduleOnRN: (fn: (...args: unknown[]) => void, ...args: unknown[]) => fn(...args),
|
|
9
|
-
}));
|
|
10
|
-
|
|
11
|
-
// Use fake timers so the reanimated mapper's mockedRequestAnimationFrame
|
|
12
|
-
// (a setTimeout-based RAF) doesn't fire outside of act().
|
|
13
|
-
beforeEach(() => {
|
|
14
|
-
jest.useFakeTimers();
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
afterEach(() => {
|
|
18
|
-
jest.useRealTimers();
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
describe("Pagination.Basic", () => {
|
|
22
|
-
it("throws when size/dot width/height are non-number", () => {
|
|
23
|
-
const Test = () => {
|
|
24
|
-
const progress = useSharedValue(0);
|
|
25
|
-
return (
|
|
26
|
-
<Pagination.Basic
|
|
27
|
-
data={[1, 2]}
|
|
28
|
-
progress={progress}
|
|
29
|
-
// @ts-expect-error intentional invalid type
|
|
30
|
-
size={"12px"}
|
|
31
|
-
/>
|
|
32
|
-
);
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
expect(() => render(<Test />)).toThrow("size/width/height must be a number");
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
it("renders dots and calls onPress", async () => {
|
|
39
|
-
const handlePress = jest.fn();
|
|
40
|
-
const Test = () => {
|
|
41
|
-
const progress = useSharedValue(0);
|
|
42
|
-
return (
|
|
43
|
-
<Pagination.Basic
|
|
44
|
-
data={[1, 2, 3]}
|
|
45
|
-
progress={progress}
|
|
46
|
-
onPress={handlePress}
|
|
47
|
-
carouselName="Demo"
|
|
48
|
-
/>
|
|
49
|
-
);
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
const { UNSAFE_root } = render(<Test />);
|
|
53
|
-
await act(async () => {
|
|
54
|
-
jest.advanceTimersByTime(100);
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
const buttons = UNSAFE_root.findAll(
|
|
58
|
-
(node) =>
|
|
59
|
-
node?.props?.accessibilityRole === "button" &&
|
|
60
|
-
typeof node?.props?.accessibilityLabel === "string" &&
|
|
61
|
-
node.props.accessibilityLabel.startsWith("Slide ")
|
|
62
|
-
);
|
|
63
|
-
|
|
64
|
-
const uniqueByLabel = Array.from(
|
|
65
|
-
new Map(buttons.map((b) => [b.props.accessibilityLabel, b])).values()
|
|
66
|
-
);
|
|
67
|
-
|
|
68
|
-
expect(uniqueByLabel).toHaveLength(3);
|
|
69
|
-
|
|
70
|
-
await act(async () => {
|
|
71
|
-
fireEvent.press(uniqueByLabel[1]);
|
|
72
|
-
jest.advanceTimersByTime(100);
|
|
73
|
-
});
|
|
74
|
-
expect(handlePress).toHaveBeenCalledWith(1);
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
it("does not include undefined in default accessibilityLabel when carouselName is omitted", async () => {
|
|
78
|
-
const Test = () => {
|
|
79
|
-
const progress = useSharedValue(0);
|
|
80
|
-
return <Pagination.Basic data={[1, 2]} progress={progress} />;
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
const { UNSAFE_root } = render(<Test />);
|
|
84
|
-
await act(async () => {
|
|
85
|
-
jest.advanceTimersByTime(100);
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
const buttons = UNSAFE_root.findAll(
|
|
89
|
-
(node) =>
|
|
90
|
-
node?.props?.accessibilityRole === "button" &&
|
|
91
|
-
typeof node?.props?.accessibilityLabel === "string" &&
|
|
92
|
-
node.props.accessibilityLabel.startsWith("Slide ")
|
|
93
|
-
);
|
|
94
|
-
|
|
95
|
-
const uniqueByLabel = Array.from(
|
|
96
|
-
new Map(buttons.map((b) => [b.props.accessibilityLabel, b])).values()
|
|
97
|
-
);
|
|
98
|
-
|
|
99
|
-
expect(uniqueByLabel[0].props.accessibilityLabel).toBe("Slide 1 of 2");
|
|
100
|
-
expect(uniqueByLabel[0].props.accessibilityLabel).not.toContain("undefined");
|
|
101
|
-
});
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
describe("Pagination.Custom", () => {
|
|
105
|
-
it("throws when any size-related prop is non-number", () => {
|
|
106
|
-
const Test = () => {
|
|
107
|
-
const progress = useSharedValue(0);
|
|
108
|
-
return (
|
|
109
|
-
<Pagination.Custom
|
|
110
|
-
data={[1]}
|
|
111
|
-
progress={progress}
|
|
112
|
-
// @ts-expect-error intentional invalid type
|
|
113
|
-
activeDotStyle={{ width: "10px" }}
|
|
114
|
-
/>
|
|
115
|
-
);
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
expect(() => render(<Test />)).toThrow("size/width/height must be a number");
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
it("uses max item dimensions for container min sizes", async () => {
|
|
122
|
-
const Test = () => {
|
|
123
|
-
const progress = useSharedValue(0);
|
|
124
|
-
return (
|
|
125
|
-
<Pagination.Custom
|
|
126
|
-
data={[1, 2]}
|
|
127
|
-
progress={progress}
|
|
128
|
-
size={12}
|
|
129
|
-
dotStyle={{ width: 14, height: 8 }}
|
|
130
|
-
activeDotStyle={{ width: 16, height: 20 }}
|
|
131
|
-
/>
|
|
132
|
-
);
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
const { UNSAFE_root } = render(<Test />);
|
|
136
|
-
await act(async () => {
|
|
137
|
-
jest.advanceTimersByTime(100);
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
// @ts-expect-error
|
|
141
|
-
const container = UNSAFE_root.findByType(View);
|
|
142
|
-
const flattened = Array.isArray(container.props.style)
|
|
143
|
-
? Object.assign({}, ...container.props.style.filter(Boolean))
|
|
144
|
-
: container.props.style;
|
|
145
|
-
|
|
146
|
-
expect(flattened.minWidth).toBe(16);
|
|
147
|
-
expect(flattened.minHeight).toBe(20);
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
it("allows overriding pagination item accessibility props", async () => {
|
|
151
|
-
const Test = () => {
|
|
152
|
-
const progress = useSharedValue(0);
|
|
153
|
-
return (
|
|
154
|
-
<Pagination.Custom
|
|
155
|
-
data={[1, 2]}
|
|
156
|
-
progress={progress}
|
|
157
|
-
paginationItemAccessibility={(index: number, length: number) => ({
|
|
158
|
-
accessibilityLabel: `Page ${index + 1}/${length}`,
|
|
159
|
-
accessibilityHint: `Jump to ${index + 1}`,
|
|
160
|
-
accessibilityRole: "link",
|
|
161
|
-
})}
|
|
162
|
-
/>
|
|
163
|
-
);
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
const { UNSAFE_root } = render(<Test />);
|
|
167
|
-
await act(async () => {
|
|
168
|
-
jest.advanceTimersByTime(100);
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
const item = UNSAFE_root.find(
|
|
172
|
-
(node) =>
|
|
173
|
-
node?.props?.accessibilityLabel === "Page 1/2" && node?.props?.accessibilityRole === "link"
|
|
174
|
-
);
|
|
175
|
-
|
|
176
|
-
expect(item.props.accessibilityHint).toBe("Jump to 1");
|
|
177
|
-
});
|
|
178
|
-
});
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { render } from "@testing-library/react-native";
|
|
2
|
-
import type { FC } from "react";
|
|
3
|
-
import React from "react";
|
|
4
|
-
import Animated, { useAnimatedStyle, useSharedValue, withTiming } from "react-native-reanimated";
|
|
5
|
-
|
|
6
|
-
describe("Carousel Animations", () => {
|
|
7
|
-
beforeEach(() => {
|
|
8
|
-
jest.useFakeTimers();
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
afterEach(() => {
|
|
12
|
-
jest.runOnlyPendingTimers();
|
|
13
|
-
jest.useRealTimers();
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
it("animates opacity with timing", () => {
|
|
17
|
-
const TestComponent: FC<{ value: number }> = ({ value }) => {
|
|
18
|
-
const sharedValue = useSharedValue(value);
|
|
19
|
-
|
|
20
|
-
// Using withTiming to wrap the value change, so it can be tested
|
|
21
|
-
const animatedStyle = useAnimatedStyle(() => ({
|
|
22
|
-
opacity: withTiming(sharedValue.value, { duration: 500 }),
|
|
23
|
-
}));
|
|
24
|
-
|
|
25
|
-
// When the prop changes, update the shared value
|
|
26
|
-
React.useEffect(() => {
|
|
27
|
-
sharedValue.value = value;
|
|
28
|
-
}, [value, sharedValue]);
|
|
29
|
-
|
|
30
|
-
return <Animated.View testID="animated-view" style={animatedStyle} />;
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const initialValue = 0;
|
|
34
|
-
const updatedValue = 1;
|
|
35
|
-
|
|
36
|
-
const { getByTestId, rerender } = render(<TestComponent value={initialValue} />);
|
|
37
|
-
const view = getByTestId("animated-view");
|
|
38
|
-
|
|
39
|
-
// Verify the initial state
|
|
40
|
-
expect(view).toHaveAnimatedStyle({ opacity: initialValue });
|
|
41
|
-
|
|
42
|
-
// Trigger the value change
|
|
43
|
-
rerender(<TestComponent value={updatedValue} />);
|
|
44
|
-
|
|
45
|
-
// Advance the animation to the middle point
|
|
46
|
-
jest.advanceTimersByTime(250);
|
|
47
|
-
expect(view).toHaveAnimatedStyle({ opacity: 0.5 }); // Animation middle value
|
|
48
|
-
|
|
49
|
-
// Advance the animation to the completion
|
|
50
|
-
jest.advanceTimersByTime(250);
|
|
51
|
-
expect(view).toHaveAnimatedStyle({ opacity: updatedValue }); // Animation completion
|
|
52
|
-
});
|
|
53
|
-
});
|
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
import { act, renderHook } from "@testing-library/react-hooks";
|
|
2
|
-
|
|
3
|
-
import { useAutoPlay } from "./useAutoPlay";
|
|
4
|
-
|
|
5
|
-
describe("useAutoPlay", () => {
|
|
6
|
-
// Mock timer
|
|
7
|
-
beforeEach(() => {
|
|
8
|
-
jest.useFakeTimers();
|
|
9
|
-
jest.clearAllMocks();
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
afterEach(() => {
|
|
13
|
-
jest.clearAllTimers();
|
|
14
|
-
jest.useRealTimers();
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
// Mock carousel controller
|
|
18
|
-
const mockCarouselController = {
|
|
19
|
-
prev: jest.fn(),
|
|
20
|
-
next: jest.fn(),
|
|
21
|
-
getCurrentIndex: jest.fn(),
|
|
22
|
-
getSharedIndex: jest.fn(),
|
|
23
|
-
scrollTo: jest.fn(),
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
it("should start autoplay when autoPlay is true", () => {
|
|
27
|
-
renderHook(() =>
|
|
28
|
-
useAutoPlay({
|
|
29
|
-
autoPlay: true,
|
|
30
|
-
autoPlayInterval: 1000,
|
|
31
|
-
carouselController: mockCarouselController,
|
|
32
|
-
})
|
|
33
|
-
);
|
|
34
|
-
|
|
35
|
-
act(() => {
|
|
36
|
-
jest.runOnlyPendingTimers();
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
expect(mockCarouselController.next).toHaveBeenCalledTimes(1);
|
|
40
|
-
expect(mockCarouselController.next).toHaveBeenCalledWith(
|
|
41
|
-
expect.objectContaining({
|
|
42
|
-
onFinished: expect.any(Function),
|
|
43
|
-
})
|
|
44
|
-
);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it("should not start autoplay when autoPlay is false", () => {
|
|
48
|
-
renderHook(() =>
|
|
49
|
-
useAutoPlay({
|
|
50
|
-
autoPlay: false,
|
|
51
|
-
autoPlayInterval: 1000,
|
|
52
|
-
carouselController: mockCarouselController,
|
|
53
|
-
})
|
|
54
|
-
);
|
|
55
|
-
|
|
56
|
-
act(() => {
|
|
57
|
-
jest.runOnlyPendingTimers();
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
expect(mockCarouselController.next).not.toHaveBeenCalled();
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it("should play in reverse when autoPlayReverse is true", () => {
|
|
64
|
-
renderHook(() =>
|
|
65
|
-
useAutoPlay({
|
|
66
|
-
autoPlay: true,
|
|
67
|
-
autoPlayReverse: true,
|
|
68
|
-
autoPlayInterval: 1000,
|
|
69
|
-
carouselController: mockCarouselController,
|
|
70
|
-
})
|
|
71
|
-
);
|
|
72
|
-
|
|
73
|
-
act(() => {
|
|
74
|
-
jest.runOnlyPendingTimers();
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
expect(mockCarouselController.prev).toHaveBeenCalledTimes(1);
|
|
78
|
-
expect(mockCarouselController.next).not.toHaveBeenCalled();
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
it("should clear timer on unmount", () => {
|
|
82
|
-
const { unmount } = renderHook(() =>
|
|
83
|
-
useAutoPlay({
|
|
84
|
-
autoPlay: true,
|
|
85
|
-
autoPlayInterval: 1000,
|
|
86
|
-
carouselController: mockCarouselController,
|
|
87
|
-
})
|
|
88
|
-
);
|
|
89
|
-
|
|
90
|
-
// Run the timer once to ensure it's set
|
|
91
|
-
act(() => {
|
|
92
|
-
jest.runOnlyPendingTimers();
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
// Clear previous call records
|
|
96
|
-
mockCarouselController.next.mockClear();
|
|
97
|
-
|
|
98
|
-
// Then unmount the component and run the timer again
|
|
99
|
-
act(() => {
|
|
100
|
-
unmount();
|
|
101
|
-
jest.runOnlyPendingTimers();
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
expect(mockCarouselController.next).not.toHaveBeenCalled();
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
it("should pause and resume autoplay", () => {
|
|
108
|
-
const { result } = renderHook(() =>
|
|
109
|
-
useAutoPlay({
|
|
110
|
-
autoPlay: true,
|
|
111
|
-
autoPlayInterval: 1000,
|
|
112
|
-
carouselController: mockCarouselController,
|
|
113
|
-
})
|
|
114
|
-
);
|
|
115
|
-
|
|
116
|
-
// Run the timer once to ensure it's set
|
|
117
|
-
act(() => {
|
|
118
|
-
jest.runOnlyPendingTimers();
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
// Clear previous call records
|
|
122
|
-
mockCarouselController.next.mockClear();
|
|
123
|
-
|
|
124
|
-
// Pause autoplay
|
|
125
|
-
act(() => {
|
|
126
|
-
result.current.pause();
|
|
127
|
-
jest.runOnlyPendingTimers();
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
expect(mockCarouselController.next).not.toHaveBeenCalled();
|
|
131
|
-
|
|
132
|
-
// Resume autoplay
|
|
133
|
-
act(() => {
|
|
134
|
-
result.current.start();
|
|
135
|
-
jest.runOnlyPendingTimers();
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
expect(mockCarouselController.next).toHaveBeenCalledTimes(1);
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
it("should respect autoPlayInterval timing", () => {
|
|
142
|
-
renderHook(() =>
|
|
143
|
-
useAutoPlay({
|
|
144
|
-
autoPlay: true,
|
|
145
|
-
autoPlayInterval: 2000,
|
|
146
|
-
carouselController: mockCarouselController,
|
|
147
|
-
})
|
|
148
|
-
);
|
|
149
|
-
|
|
150
|
-
// Advance less than interval
|
|
151
|
-
act(() => {
|
|
152
|
-
jest.advanceTimersByTime(1500);
|
|
153
|
-
});
|
|
154
|
-
expect(mockCarouselController.next).not.toHaveBeenCalled();
|
|
155
|
-
|
|
156
|
-
// Advance to complete interval
|
|
157
|
-
act(() => {
|
|
158
|
-
jest.advanceTimersByTime(500);
|
|
159
|
-
});
|
|
160
|
-
expect(mockCarouselController.next).toHaveBeenCalledTimes(1);
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
it("should chain autoplay calls correctly", () => {
|
|
164
|
-
renderHook(() =>
|
|
165
|
-
useAutoPlay({
|
|
166
|
-
autoPlay: true,
|
|
167
|
-
autoPlayInterval: 1000,
|
|
168
|
-
carouselController: mockCarouselController,
|
|
169
|
-
})
|
|
170
|
-
);
|
|
171
|
-
|
|
172
|
-
// First interval
|
|
173
|
-
act(() => {
|
|
174
|
-
jest.runOnlyPendingTimers();
|
|
175
|
-
});
|
|
176
|
-
expect(mockCarouselController.next).toHaveBeenCalledTimes(1);
|
|
177
|
-
|
|
178
|
-
// Trigger onFinished callback to start the next timer
|
|
179
|
-
const onFinished = mockCarouselController.next.mock.calls[0][0].onFinished;
|
|
180
|
-
act(() => {
|
|
181
|
-
onFinished();
|
|
182
|
-
jest.runOnlyPendingTimers();
|
|
183
|
-
});
|
|
184
|
-
expect(mockCarouselController.next).toHaveBeenCalledTimes(2);
|
|
185
|
-
|
|
186
|
-
// Trigger onFinished callback to start the next timer
|
|
187
|
-
const onFinished2 = mockCarouselController.next.mock.calls[1][0].onFinished;
|
|
188
|
-
act(() => {
|
|
189
|
-
onFinished2();
|
|
190
|
-
jest.runOnlyPendingTimers();
|
|
191
|
-
});
|
|
192
|
-
expect(mockCarouselController.next).toHaveBeenCalledTimes(3);
|
|
193
|
-
});
|
|
194
|
-
});
|