@khanacademy/wonder-blocks-timing 5.0.0 → 5.0.2
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/CHANGELOG.md +12 -0
- package/package.json +2 -2
- package/src/components/__tests__/action-scheduler-provider.test.tsx +0 -36
- package/src/components/__tests__/with-action-scheduler.test.tsx +0 -22
- package/src/components/action-scheduler-provider.ts +0 -35
- package/src/components/with-action-scheduler.tsx +0 -36
- package/src/hooks/__tests__/use-interval.test.ts +0 -520
- package/src/hooks/__tests__/use-timeout.test.ts +0 -489
- package/src/hooks/use-interval.ts +0 -101
- package/src/hooks/use-timeout.ts +0 -101
- package/src/index.ts +0 -17
- package/src/util/__tests__/action-scheduler.test.ts +0 -271
- package/src/util/__tests__/animation-frame.test.ts +0 -225
- package/src/util/__tests__/interval.test.ts +0 -234
- package/src/util/__tests__/timeout.test.ts +0 -224
- package/src/util/action-scheduler.ts +0 -89
- package/src/util/animation-frame.ts +0 -103
- package/src/util/interval.ts +0 -102
- package/src/util/policies.ts +0 -14
- package/src/util/timeout.ts +0 -108
- package/src/util/types.ts +0 -256
- package/src/util/types.typestest.tsx +0 -72
- package/tsconfig-build.json +0 -9
- package/tsconfig-build.tsbuildinfo +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @khanacademy/wonder-blocks-timing
|
|
2
2
|
|
|
3
|
+
## 5.0.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 02a1b298: Make sure we don't package tsconfig and tsbuildinfo files
|
|
8
|
+
|
|
9
|
+
## 5.0.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 559e82d5: Update to build tooling, generating smaller output
|
|
14
|
+
|
|
3
15
|
## 5.0.0
|
|
4
16
|
|
|
5
17
|
### Major Changes
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@khanacademy/wonder-blocks-timing",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "5.0.
|
|
4
|
+
"version": "5.0.2",
|
|
5
5
|
"design": "v1",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"react": "16.14.0"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
20
|
-
"@khanacademy/wb-dev-build-settings": "^1.0.
|
|
20
|
+
"@khanacademy/wb-dev-build-settings": "^1.0.1"
|
|
21
21
|
},
|
|
22
22
|
"author": "",
|
|
23
23
|
"license": "MIT"
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import {render} from "@testing-library/react";
|
|
3
|
-
|
|
4
|
-
import ActionSchedulerProvider from "../action-scheduler-provider";
|
|
5
|
-
import ActionScheduler from "../../util/action-scheduler";
|
|
6
|
-
|
|
7
|
-
jest.mock("../../util/action-scheduler");
|
|
8
|
-
|
|
9
|
-
describe("ActionSchedulerProvider", () => {
|
|
10
|
-
it("should render children with action scheduler instance", () => {
|
|
11
|
-
// Arrange
|
|
12
|
-
const childrenMock = jest.fn().mockReturnValueOnce(null);
|
|
13
|
-
|
|
14
|
-
// Act
|
|
15
|
-
render(
|
|
16
|
-
<ActionSchedulerProvider>{childrenMock}</ActionSchedulerProvider>,
|
|
17
|
-
);
|
|
18
|
-
|
|
19
|
-
// Assert
|
|
20
|
-
expect(childrenMock).toHaveBeenCalledWith(expect.any(ActionScheduler));
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
it("should call disable on the action scheduler at unmount", () => {
|
|
24
|
-
// Arrange
|
|
25
|
-
const childrenMock = jest.fn().mockReturnValueOnce(null);
|
|
26
|
-
const {unmount} = render(
|
|
27
|
-
<ActionSchedulerProvider>{childrenMock}</ActionSchedulerProvider>,
|
|
28
|
-
);
|
|
29
|
-
|
|
30
|
-
// Act
|
|
31
|
-
unmount();
|
|
32
|
-
|
|
33
|
-
// Assert
|
|
34
|
-
expect(childrenMock.mock.calls[0][0].disable).toHaveBeenCalledTimes(1);
|
|
35
|
-
});
|
|
36
|
-
});
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import {render, screen} from "@testing-library/react";
|
|
3
|
-
|
|
4
|
-
import withActionScheduler from "../with-action-scheduler";
|
|
5
|
-
|
|
6
|
-
import type {WithActionSchedulerProps} from "../../util/types";
|
|
7
|
-
|
|
8
|
-
describe("withActionScheduler", () => {
|
|
9
|
-
it("should provide wrapped component with IScheduleActions instance", () => {
|
|
10
|
-
// Arrange
|
|
11
|
-
const Component = (props: WithActionSchedulerProps) => (
|
|
12
|
-
<>{props.schedule != null ? "true" : "false"}</>
|
|
13
|
-
);
|
|
14
|
-
|
|
15
|
-
// Act
|
|
16
|
-
const WithScheduler = withActionScheduler(Component);
|
|
17
|
-
render(<WithScheduler />);
|
|
18
|
-
|
|
19
|
-
// Assert
|
|
20
|
-
expect(screen.getByText("true")).toBeInTheDocument();
|
|
21
|
-
});
|
|
22
|
-
});
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import ActionScheduler from "../util/action-scheduler";
|
|
3
|
-
|
|
4
|
-
import type {IScheduleActions} from "../util/types";
|
|
5
|
-
|
|
6
|
-
type Props = {
|
|
7
|
-
/**
|
|
8
|
-
* A function that, when given an instance of `IScheduleActions` will
|
|
9
|
-
* render a `React.Node`.
|
|
10
|
-
*/
|
|
11
|
-
children: (arg1: IScheduleActions) => React.ReactNode;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* A provider component that passes our action scheduling API to its children
|
|
16
|
-
* and ensures that all scheduled actions are cleared on unmount.
|
|
17
|
-
*
|
|
18
|
-
* ```jsx
|
|
19
|
-
* <ActionSchedulerProvider>
|
|
20
|
-
* {schedule => this.renderThingThatNeedsTimers(schedule)}
|
|
21
|
-
* </ActionSchedulerProvider>
|
|
22
|
-
* ```
|
|
23
|
-
*/
|
|
24
|
-
export default class ActionSchedulerProvider extends React.Component<Props> {
|
|
25
|
-
componentWillUnmount() {
|
|
26
|
-
this._actionScheduler.disable();
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
_actionScheduler: ActionScheduler = new ActionScheduler();
|
|
30
|
-
|
|
31
|
-
render(): React.ReactNode {
|
|
32
|
-
const {children} = this.props;
|
|
33
|
-
return children(this._actionScheduler);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
|
|
3
|
-
import ActionSchedulerProvider from "./action-scheduler-provider";
|
|
4
|
-
|
|
5
|
-
import type {IScheduleActions, WithActionSchedulerProps} from "../util/types";
|
|
6
|
-
|
|
7
|
-
type WithoutActionScheduler<T> = Omit<T, "schedule">;
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* A higher order component that attaches the given component to an
|
|
11
|
-
* `IScheduleActions` instance. Any actions scheduled will automatically be
|
|
12
|
-
* cleared on unmount.
|
|
13
|
-
*
|
|
14
|
-
* @template TOwnProps The own props of the component being rendered, without
|
|
15
|
-
* the additional action scheduler prop. To attach the additional prop to
|
|
16
|
-
* these props use the `WithActionScheduler` type.
|
|
17
|
-
*/
|
|
18
|
-
export default function withActionScheduler<
|
|
19
|
-
Props extends WithActionSchedulerProps,
|
|
20
|
-
>(WrappedComponent: React.ComponentType<Props>) {
|
|
21
|
-
const displayName = `withActionScheduler(${
|
|
22
|
-
WrappedComponent.displayName || WrappedComponent.name
|
|
23
|
-
})`;
|
|
24
|
-
|
|
25
|
-
const C = (props: WithoutActionScheduler<Props>) => (
|
|
26
|
-
<ActionSchedulerProvider>
|
|
27
|
-
{(schedule: IScheduleActions) => (
|
|
28
|
-
<WrappedComponent {...(props as Props)} schedule={schedule} />
|
|
29
|
-
)}
|
|
30
|
-
</ActionSchedulerProvider>
|
|
31
|
-
);
|
|
32
|
-
|
|
33
|
-
C.displayName = displayName;
|
|
34
|
-
|
|
35
|
-
return C;
|
|
36
|
-
}
|
|
@@ -1,520 +0,0 @@
|
|
|
1
|
-
import {renderHook, act} from "@testing-library/react-hooks";
|
|
2
|
-
import {SchedulePolicy, ClearPolicy, ActionPolicy} from "../../util/policies";
|
|
3
|
-
|
|
4
|
-
import {useInterval} from "../use-interval";
|
|
5
|
-
|
|
6
|
-
describe("useInterval", () => {
|
|
7
|
-
beforeEach(() => {
|
|
8
|
-
jest.useFakeTimers();
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
afterEach(() => {
|
|
12
|
-
jest.restoreAllMocks();
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it("throws if the action is not a function", () => {
|
|
16
|
-
// Arrange
|
|
17
|
-
|
|
18
|
-
// Act
|
|
19
|
-
const {result} = renderHook(() => useInterval(null as any, 1000));
|
|
20
|
-
|
|
21
|
-
// Assert
|
|
22
|
-
expect(result.error).toEqual(Error("Action must be a function"));
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it("throws if the period is less than 1", () => {
|
|
26
|
-
// Arrange
|
|
27
|
-
|
|
28
|
-
// Act
|
|
29
|
-
const {result} = renderHook(() => useInterval(() => {}, 0));
|
|
30
|
-
|
|
31
|
-
// Assert
|
|
32
|
-
expect(result.error).toEqual(Error("Interval period must be >= 1"));
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
it("sets an interval when schedule policy is SchedulePolicy.Immediately", () => {
|
|
36
|
-
// Arrange
|
|
37
|
-
const intervalSpy = jest.spyOn(global, "setInterval");
|
|
38
|
-
|
|
39
|
-
// Act
|
|
40
|
-
renderHook(() => useInterval(() => {}, 1000));
|
|
41
|
-
|
|
42
|
-
// Assert
|
|
43
|
-
expect(intervalSpy).toHaveBeenCalledTimes(1);
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it("should call the action before unmounting when clear policy is Resolve", () => {
|
|
47
|
-
const action = jest.fn();
|
|
48
|
-
const {unmount} = renderHook(() =>
|
|
49
|
-
useInterval(action, 1000, {
|
|
50
|
-
clearPolicy: ClearPolicy.Resolve,
|
|
51
|
-
}),
|
|
52
|
-
);
|
|
53
|
-
|
|
54
|
-
act(() => {
|
|
55
|
-
unmount();
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
expect(action).toHaveBeenCalled();
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it("should call the current action", () => {
|
|
62
|
-
// Arrange
|
|
63
|
-
const action1 = jest.fn();
|
|
64
|
-
const action2 = jest.fn();
|
|
65
|
-
const {rerender} = renderHook(
|
|
66
|
-
({action}: any) => useInterval(action, 500),
|
|
67
|
-
{
|
|
68
|
-
initialProps: {action: action1},
|
|
69
|
-
},
|
|
70
|
-
);
|
|
71
|
-
|
|
72
|
-
// Act
|
|
73
|
-
rerender({action: action2});
|
|
74
|
-
jest.advanceTimersByTime(501);
|
|
75
|
-
|
|
76
|
-
// Assert
|
|
77
|
-
expect(action2).toHaveBeenCalledTimes(1);
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
it("should only call setInterval once even if action changes", () => {
|
|
81
|
-
// Arrange
|
|
82
|
-
const intervalSpy = jest.spyOn(global, "setInterval");
|
|
83
|
-
const action1 = jest.fn();
|
|
84
|
-
const action2 = jest.fn();
|
|
85
|
-
const {rerender} = renderHook(
|
|
86
|
-
({action}: any) => useInterval(action, 500),
|
|
87
|
-
{
|
|
88
|
-
initialProps: {action: action1},
|
|
89
|
-
},
|
|
90
|
-
);
|
|
91
|
-
|
|
92
|
-
// Act
|
|
93
|
-
rerender({action: action2});
|
|
94
|
-
|
|
95
|
-
// Assert
|
|
96
|
-
expect(intervalSpy).toHaveBeenCalledTimes(1);
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
it("should not reset the interval if the action changes", () => {
|
|
100
|
-
// Arrange
|
|
101
|
-
const action1 = jest.fn();
|
|
102
|
-
const action2 = jest.fn();
|
|
103
|
-
const {rerender} = renderHook(
|
|
104
|
-
({action}: any) => useInterval(action, 500),
|
|
105
|
-
{
|
|
106
|
-
initialProps: {action: action1},
|
|
107
|
-
},
|
|
108
|
-
);
|
|
109
|
-
|
|
110
|
-
// Act
|
|
111
|
-
jest.advanceTimersByTime(250);
|
|
112
|
-
rerender({action: action2});
|
|
113
|
-
jest.advanceTimersByTime(751);
|
|
114
|
-
|
|
115
|
-
// Assert
|
|
116
|
-
expect(action1).not.toHaveBeenCalled();
|
|
117
|
-
expect(action2).toHaveBeenCalledTimes(2);
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
it("should reset the interval if the action changes and the action policy is Reset", () => {
|
|
121
|
-
// Arrange
|
|
122
|
-
const action1 = jest.fn();
|
|
123
|
-
const action2 = jest.fn();
|
|
124
|
-
const {rerender} = renderHook(
|
|
125
|
-
({action}: any) =>
|
|
126
|
-
useInterval(action, 500, {actionPolicy: ActionPolicy.Reset}),
|
|
127
|
-
{
|
|
128
|
-
initialProps: {action: action1},
|
|
129
|
-
},
|
|
130
|
-
);
|
|
131
|
-
|
|
132
|
-
// Act
|
|
133
|
-
jest.advanceTimersByTime(250);
|
|
134
|
-
rerender({action: action2});
|
|
135
|
-
jest.advanceTimersByTime(751);
|
|
136
|
-
|
|
137
|
-
// Assert
|
|
138
|
-
expect(action1).not.toHaveBeenCalled();
|
|
139
|
-
expect(action2).toHaveBeenCalledTimes(1);
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
it("should use the new interval period after changing it", () => {
|
|
143
|
-
// Arrange
|
|
144
|
-
const action = jest.fn();
|
|
145
|
-
const {rerender} = renderHook(
|
|
146
|
-
({intervalMs}: any) => useInterval(action, intervalMs),
|
|
147
|
-
{
|
|
148
|
-
initialProps: {intervalMs: 500},
|
|
149
|
-
},
|
|
150
|
-
);
|
|
151
|
-
rerender({intervalMs: 1000});
|
|
152
|
-
|
|
153
|
-
// Act
|
|
154
|
-
jest.advanceTimersByTime(1501);
|
|
155
|
-
|
|
156
|
-
// Assert
|
|
157
|
-
expect(action).toHaveBeenCalledTimes(1);
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
it("should restart the interval if intervalMs changes", () => {
|
|
161
|
-
// Arrange
|
|
162
|
-
const intervalSpy = jest.spyOn(global, "setInterval");
|
|
163
|
-
const {rerender} = renderHook(
|
|
164
|
-
({intervalMs}: any) => useInterval(() => {}, intervalMs),
|
|
165
|
-
{
|
|
166
|
-
initialProps: {intervalMs: 500},
|
|
167
|
-
},
|
|
168
|
-
);
|
|
169
|
-
|
|
170
|
-
// Act
|
|
171
|
-
rerender({intervalMs: 1000});
|
|
172
|
-
|
|
173
|
-
// Assert
|
|
174
|
-
expect(intervalSpy).toHaveBeenCalledWith(expect.any(Function), 500);
|
|
175
|
-
expect(intervalSpy).toHaveBeenCalledWith(expect.any(Function), 1000);
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
describe("isSet", () => {
|
|
179
|
-
it("is false when the interval has not been set [SchedulePolicy.OnDemand]", () => {
|
|
180
|
-
// Arrange
|
|
181
|
-
const {result} = renderHook(() =>
|
|
182
|
-
useInterval(() => {}, 1000, {
|
|
183
|
-
schedulePolicy: SchedulePolicy.OnDemand,
|
|
184
|
-
}),
|
|
185
|
-
);
|
|
186
|
-
|
|
187
|
-
// Act
|
|
188
|
-
const isSet = result.current.isSet;
|
|
189
|
-
|
|
190
|
-
// Assert
|
|
191
|
-
expect(isSet).toBeFalsy();
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
it("is true when the interval is active", () => {
|
|
195
|
-
// Arrange
|
|
196
|
-
const {result} = renderHook(() => useInterval(() => {}, 1000));
|
|
197
|
-
act(() => {
|
|
198
|
-
result.current.set();
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
// Act
|
|
202
|
-
const isSet = result.current.isSet;
|
|
203
|
-
|
|
204
|
-
// Assert
|
|
205
|
-
expect(isSet).toBeTruthy();
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
it("is false when the interval is cleared", () => {
|
|
209
|
-
// Arrange
|
|
210
|
-
const {result} = renderHook(() => useInterval(() => {}, 1000));
|
|
211
|
-
act(() => {
|
|
212
|
-
result.current.set();
|
|
213
|
-
result.current.clear();
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
// Act
|
|
217
|
-
const isSet = result.current.isSet;
|
|
218
|
-
|
|
219
|
-
// Assert
|
|
220
|
-
expect(isSet).toBeFalsy();
|
|
221
|
-
});
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
describe("#set", () => {
|
|
225
|
-
it("should call setInterval", () => {
|
|
226
|
-
// Arrange
|
|
227
|
-
const intervalSpy = jest.spyOn(global, "setInterval");
|
|
228
|
-
const {result} = renderHook(() =>
|
|
229
|
-
useInterval(() => {}, 500, {
|
|
230
|
-
schedulePolicy: SchedulePolicy.OnDemand,
|
|
231
|
-
}),
|
|
232
|
-
);
|
|
233
|
-
|
|
234
|
-
// Act
|
|
235
|
-
act(() => {
|
|
236
|
-
result.current.set();
|
|
237
|
-
});
|
|
238
|
-
|
|
239
|
-
// Assert
|
|
240
|
-
expect(intervalSpy).toHaveBeenNthCalledWith(
|
|
241
|
-
1,
|
|
242
|
-
expect.any(Function),
|
|
243
|
-
500,
|
|
244
|
-
);
|
|
245
|
-
});
|
|
246
|
-
|
|
247
|
-
it("should invoke setInterval to call the given action", () => {
|
|
248
|
-
// Arrange
|
|
249
|
-
const intervalSpy = jest.spyOn(global, "setInterval");
|
|
250
|
-
const action = jest.fn();
|
|
251
|
-
const {result} = renderHook(() =>
|
|
252
|
-
useInterval(action, 500, {
|
|
253
|
-
schedulePolicy: SchedulePolicy.OnDemand,
|
|
254
|
-
}),
|
|
255
|
-
);
|
|
256
|
-
|
|
257
|
-
act(() => {
|
|
258
|
-
result.current.set();
|
|
259
|
-
});
|
|
260
|
-
const scheduledAction = intervalSpy.mock.calls[0][0];
|
|
261
|
-
|
|
262
|
-
// Act
|
|
263
|
-
scheduledAction();
|
|
264
|
-
|
|
265
|
-
// Assert
|
|
266
|
-
expect(action).toHaveBeenCalledTimes(1);
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
it("should clear the active interval", () => {
|
|
270
|
-
// Arrange
|
|
271
|
-
const action = jest.fn();
|
|
272
|
-
const {result} = renderHook(() =>
|
|
273
|
-
useInterval(action, 500, {
|
|
274
|
-
schedulePolicy: SchedulePolicy.OnDemand,
|
|
275
|
-
}),
|
|
276
|
-
);
|
|
277
|
-
act(() => {
|
|
278
|
-
result.current.set();
|
|
279
|
-
});
|
|
280
|
-
|
|
281
|
-
// Act
|
|
282
|
-
act(() => {
|
|
283
|
-
result.current.set();
|
|
284
|
-
jest.advanceTimersByTime(501);
|
|
285
|
-
});
|
|
286
|
-
|
|
287
|
-
// Assert
|
|
288
|
-
expect(action).toHaveBeenCalledTimes(1);
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
it("should set an interval that stays active while not cleared", () => {
|
|
292
|
-
// Arrange
|
|
293
|
-
const action = jest.fn();
|
|
294
|
-
const {result} = renderHook(() =>
|
|
295
|
-
useInterval(action, 500, {
|
|
296
|
-
schedulePolicy: SchedulePolicy.OnDemand,
|
|
297
|
-
}),
|
|
298
|
-
);
|
|
299
|
-
act(() => {
|
|
300
|
-
result.current.set();
|
|
301
|
-
});
|
|
302
|
-
|
|
303
|
-
// Act
|
|
304
|
-
act(() => {
|
|
305
|
-
jest.advanceTimersByTime(1501);
|
|
306
|
-
});
|
|
307
|
-
|
|
308
|
-
// Assert
|
|
309
|
-
expect(action).toHaveBeenCalledTimes(3);
|
|
310
|
-
});
|
|
311
|
-
|
|
312
|
-
it("should continue to be set after calling it multiple times", () => {
|
|
313
|
-
// Arrange
|
|
314
|
-
const action = jest.fn();
|
|
315
|
-
const {result} = renderHook(() =>
|
|
316
|
-
useInterval(action, 500, {
|
|
317
|
-
schedulePolicy: SchedulePolicy.OnDemand,
|
|
318
|
-
}),
|
|
319
|
-
);
|
|
320
|
-
act(() => {
|
|
321
|
-
result.current.set();
|
|
322
|
-
});
|
|
323
|
-
|
|
324
|
-
// Act
|
|
325
|
-
act(() => {
|
|
326
|
-
result.current.set();
|
|
327
|
-
});
|
|
328
|
-
act(() => {
|
|
329
|
-
jest.advanceTimersByTime(501);
|
|
330
|
-
});
|
|
331
|
-
|
|
332
|
-
// Assert
|
|
333
|
-
expect(action).toHaveBeenCalled();
|
|
334
|
-
});
|
|
335
|
-
|
|
336
|
-
it("should set the interval after clearing it", () => {
|
|
337
|
-
// Arrange
|
|
338
|
-
const action = jest.fn();
|
|
339
|
-
const {result} = renderHook(() =>
|
|
340
|
-
useInterval(action, 500, {
|
|
341
|
-
schedulePolicy: SchedulePolicy.OnDemand,
|
|
342
|
-
}),
|
|
343
|
-
);
|
|
344
|
-
act(() => {
|
|
345
|
-
result.current.clear();
|
|
346
|
-
});
|
|
347
|
-
|
|
348
|
-
// Act
|
|
349
|
-
act(() => {
|
|
350
|
-
result.current.set();
|
|
351
|
-
});
|
|
352
|
-
act(() => {
|
|
353
|
-
jest.advanceTimersByTime(501);
|
|
354
|
-
});
|
|
355
|
-
|
|
356
|
-
// Assert
|
|
357
|
-
expect(action).toHaveBeenCalled();
|
|
358
|
-
});
|
|
359
|
-
|
|
360
|
-
it("should reset the inteval after calling set() again", () => {
|
|
361
|
-
// Arrange
|
|
362
|
-
const action = jest.fn();
|
|
363
|
-
const {result} = renderHook(() =>
|
|
364
|
-
useInterval(action, 750, {
|
|
365
|
-
schedulePolicy: SchedulePolicy.OnDemand,
|
|
366
|
-
}),
|
|
367
|
-
);
|
|
368
|
-
|
|
369
|
-
// Act
|
|
370
|
-
act(() => {
|
|
371
|
-
result.current.set();
|
|
372
|
-
jest.advanceTimersByTime(501);
|
|
373
|
-
result.current.set();
|
|
374
|
-
jest.advanceTimersByTime(501);
|
|
375
|
-
});
|
|
376
|
-
|
|
377
|
-
// Assert
|
|
378
|
-
expect(action).not.toHaveBeenCalled();
|
|
379
|
-
});
|
|
380
|
-
|
|
381
|
-
it("shouldn't throw an error if called after the component unmounted", () => {
|
|
382
|
-
const action = jest.fn();
|
|
383
|
-
const {result, unmount} = renderHook(() =>
|
|
384
|
-
useInterval(action, 500),
|
|
385
|
-
);
|
|
386
|
-
act(() => {
|
|
387
|
-
unmount();
|
|
388
|
-
});
|
|
389
|
-
|
|
390
|
-
// Act
|
|
391
|
-
const underTest = () => result.current.set();
|
|
392
|
-
|
|
393
|
-
// Assert
|
|
394
|
-
expect(underTest).not.toThrow();
|
|
395
|
-
});
|
|
396
|
-
});
|
|
397
|
-
|
|
398
|
-
describe("#clear", () => {
|
|
399
|
-
it("should clear an active interval", () => {
|
|
400
|
-
// Arrange
|
|
401
|
-
const action = jest.fn();
|
|
402
|
-
const {result} = renderHook(() => useInterval(action, 500));
|
|
403
|
-
act(() => {
|
|
404
|
-
result.current.set();
|
|
405
|
-
});
|
|
406
|
-
|
|
407
|
-
// Act
|
|
408
|
-
act(() => {
|
|
409
|
-
result.current.clear();
|
|
410
|
-
});
|
|
411
|
-
act(() => {
|
|
412
|
-
jest.advanceTimersByTime(501);
|
|
413
|
-
});
|
|
414
|
-
|
|
415
|
-
// Assert
|
|
416
|
-
expect(action).not.toHaveBeenCalled();
|
|
417
|
-
});
|
|
418
|
-
|
|
419
|
-
it("should invoke the action if clear policy is ClearPolicy.Resolve", () => {
|
|
420
|
-
// Arrange
|
|
421
|
-
const action = jest.fn();
|
|
422
|
-
const {result} = renderHook(() => useInterval(action, 500));
|
|
423
|
-
act(() => {
|
|
424
|
-
result.current.set();
|
|
425
|
-
});
|
|
426
|
-
|
|
427
|
-
// Act
|
|
428
|
-
act(() => {
|
|
429
|
-
result.current.clear(ClearPolicy.Resolve);
|
|
430
|
-
});
|
|
431
|
-
act(() => {
|
|
432
|
-
jest.advanceTimersByTime(501);
|
|
433
|
-
});
|
|
434
|
-
|
|
435
|
-
// Assert
|
|
436
|
-
expect(action).toHaveBeenCalledTimes(1);
|
|
437
|
-
});
|
|
438
|
-
|
|
439
|
-
it("should not invoke the action if clear policy is ClearPolicy.Cancel", () => {
|
|
440
|
-
// Arrange
|
|
441
|
-
const action = jest.fn();
|
|
442
|
-
const {result} = renderHook(() =>
|
|
443
|
-
useInterval(action, 500, {
|
|
444
|
-
schedulePolicy: SchedulePolicy.Immediately,
|
|
445
|
-
}),
|
|
446
|
-
);
|
|
447
|
-
act(() => {
|
|
448
|
-
result.current.set();
|
|
449
|
-
});
|
|
450
|
-
|
|
451
|
-
// Act
|
|
452
|
-
act(() => {
|
|
453
|
-
result.current.clear(ClearPolicy.Cancel);
|
|
454
|
-
});
|
|
455
|
-
act(() => {
|
|
456
|
-
jest.advanceTimersByTime(501);
|
|
457
|
-
});
|
|
458
|
-
|
|
459
|
-
// Assert
|
|
460
|
-
expect(action).not.toHaveBeenCalled();
|
|
461
|
-
});
|
|
462
|
-
|
|
463
|
-
it("should not invoke the action if interval is inactive and clear policy is ClearPolicy.Resolve", () => {
|
|
464
|
-
// Arrange
|
|
465
|
-
const action = jest.fn();
|
|
466
|
-
const {result} = renderHook(() =>
|
|
467
|
-
useInterval(action, 500, {
|
|
468
|
-
schedulePolicy: SchedulePolicy.OnDemand,
|
|
469
|
-
}),
|
|
470
|
-
);
|
|
471
|
-
|
|
472
|
-
// Act
|
|
473
|
-
act(() => {
|
|
474
|
-
result.current.clear(ClearPolicy.Resolve);
|
|
475
|
-
jest.advanceTimersByTime(501);
|
|
476
|
-
});
|
|
477
|
-
|
|
478
|
-
// Assert
|
|
479
|
-
expect(action).not.toHaveBeenCalled();
|
|
480
|
-
});
|
|
481
|
-
|
|
482
|
-
it("should not call the action on unmount if the interval is not running when the clearPolicy is ClearPolicy.Resolve", async () => {
|
|
483
|
-
// Arrange
|
|
484
|
-
const action = jest.fn();
|
|
485
|
-
const {result, unmount} = renderHook(() =>
|
|
486
|
-
useInterval(action, 500, {
|
|
487
|
-
clearPolicy: ClearPolicy.Resolve,
|
|
488
|
-
}),
|
|
489
|
-
);
|
|
490
|
-
|
|
491
|
-
// Act
|
|
492
|
-
act(() => {
|
|
493
|
-
result.current.clear();
|
|
494
|
-
});
|
|
495
|
-
act(() => {
|
|
496
|
-
unmount();
|
|
497
|
-
});
|
|
498
|
-
|
|
499
|
-
// Assert
|
|
500
|
-
expect(action).not.toHaveBeenCalled();
|
|
501
|
-
});
|
|
502
|
-
|
|
503
|
-
it("should not error if calling clear() after unmounting", () => {
|
|
504
|
-
// Arrange
|
|
505
|
-
const action = jest.fn();
|
|
506
|
-
const {result, unmount} = renderHook(() =>
|
|
507
|
-
useInterval(action, 500),
|
|
508
|
-
);
|
|
509
|
-
act(() => {
|
|
510
|
-
unmount();
|
|
511
|
-
});
|
|
512
|
-
|
|
513
|
-
// Act
|
|
514
|
-
const underTest = () => result.current.clear();
|
|
515
|
-
|
|
516
|
-
// Assert
|
|
517
|
-
expect(underTest).not.toThrow();
|
|
518
|
-
});
|
|
519
|
-
});
|
|
520
|
-
});
|