@khanacademy/wonder-blocks-timing 5.0.1 → 6.0.0

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.
@@ -1,271 +0,0 @@
1
- import ActionScheduler from "../action-scheduler";
2
- import Timeout from "../timeout";
3
- import Interval from "../interval";
4
- import AnimationFrame from "../animation-frame";
5
- import {SchedulePolicy, ClearPolicy} from "../policies";
6
-
7
- jest.mock("../timeout");
8
- jest.mock("../interval");
9
- jest.mock("../animation-frame");
10
-
11
- describe("ActionScheduler", () => {
12
- afterEach(() => {
13
- jest.resetAllMocks();
14
- });
15
-
16
- describe("constructor", () => {
17
- it("creates instance", () => {
18
- // Arrange
19
-
20
- // Act
21
- const result = new ActionScheduler();
22
-
23
- // Assert
24
- expect(result).toBeDefined();
25
- });
26
- });
27
-
28
- describe("#timeout", () => {
29
- it("should create a timeout", () => {
30
- // Arrange
31
- const actionScheduler = new ActionScheduler();
32
- const action = jest.fn();
33
-
34
- // Act
35
- const result = actionScheduler.timeout(action, 0);
36
-
37
- // Assert
38
- expect(result).toBeDefined();
39
- });
40
-
41
- it("should pass schedule policy to Timeout", () => {
42
- // Arrange
43
- const actionScheduler = new ActionScheduler();
44
- const action = jest.fn();
45
- const options = {
46
- schedulePolicy: SchedulePolicy.Immediately,
47
- } as const;
48
-
49
- // Act
50
- actionScheduler.timeout(action, 42, options);
51
-
52
- // Assert
53
- expect(Timeout).toHaveBeenCalledWith(
54
- action,
55
- 42,
56
- SchedulePolicy.Immediately,
57
- );
58
- });
59
-
60
- it("should pass clear policy to timeout.clear on clearAll", () => {
61
- // Arrange
62
- const actionScheduler = new ActionScheduler();
63
- const action = jest.fn();
64
- const options = {
65
- clearPolicy: ClearPolicy.Resolve,
66
- } as const;
67
- const testTimeout = actionScheduler.timeout(action, 42, options);
68
-
69
- // Act
70
- actionScheduler.clearAll();
71
-
72
- // Assert
73
- expect(testTimeout.clear).toHaveBeenCalledWith(ClearPolicy.Resolve);
74
- });
75
-
76
- describe("when scheduler is disabled", () => {
77
- it("should return a noop timeout", () => {
78
- // Arrange
79
- const actionScheduler = new ActionScheduler();
80
- const action = jest.fn();
81
-
82
- // Act
83
- actionScheduler.disable();
84
- const result = actionScheduler.timeout(action, 42);
85
-
86
- // Assert
87
- expect(result).toBe(ActionScheduler.NoopAction);
88
- });
89
- });
90
- });
91
-
92
- describe("#interval", () => {
93
- it("should create an interval", () => {
94
- // Arrange
95
- const actionScheduler = new ActionScheduler();
96
- const action = jest.fn();
97
-
98
- // Act
99
- const result = actionScheduler.interval(action, 1);
100
-
101
- // Assert
102
- expect(result).toBeDefined();
103
- });
104
-
105
- it("should pass schedule policy to Interval", () => {
106
- // Arrange
107
- const actionScheduler = new ActionScheduler();
108
- const action = jest.fn();
109
- const options = {
110
- schedulePolicy: SchedulePolicy.Immediately,
111
- } as const;
112
-
113
- // Act
114
- actionScheduler.interval(action, 42, options);
115
-
116
- // Assert
117
- expect(Interval).toHaveBeenCalledWith(
118
- action,
119
- 42,
120
- SchedulePolicy.Immediately,
121
- );
122
- });
123
-
124
- it("should pass clear policy to interval.clear on clearAll", () => {
125
- // Arrange
126
- const actionScheduler = new ActionScheduler();
127
- const action = jest.fn();
128
- const options = {
129
- clearPolicy: ClearPolicy.Resolve,
130
- } as const;
131
- const testInterval = actionScheduler.interval(action, 42, options);
132
-
133
- // Act
134
- actionScheduler.clearAll();
135
-
136
- // Assert
137
- expect(testInterval.clear).toHaveBeenCalledWith(
138
- ClearPolicy.Resolve,
139
- );
140
- });
141
-
142
- describe("when scheduler is disabled", () => {
143
- it("should return a noop interval", () => {
144
- // Arrange
145
- const actionScheduler = new ActionScheduler();
146
- const action = jest.fn();
147
-
148
- // Act
149
- actionScheduler.disable();
150
- const result = actionScheduler.interval(action, 42);
151
-
152
- // Assert
153
- expect(result).toBe(ActionScheduler.NoopAction);
154
- });
155
- });
156
- });
157
-
158
- describe("#animationFrame", () => {
159
- it("should create an animationframe", () => {
160
- // Arrange
161
- const actionScheduler = new ActionScheduler();
162
- const action = jest.fn();
163
-
164
- // Act
165
- const result = actionScheduler.animationFrame(action);
166
-
167
- // Assert
168
- expect(result).toBeDefined();
169
- });
170
-
171
- it("should pass schedule policy to AnimationFrame", () => {
172
- // Arrange
173
- const actionScheduler = new ActionScheduler();
174
- const action = jest.fn();
175
- const options = {
176
- schedulePolicy: SchedulePolicy.Immediately,
177
- } as const;
178
-
179
- // Act
180
- actionScheduler.animationFrame(action, options);
181
-
182
- // Assert
183
- expect(AnimationFrame).toHaveBeenCalledWith(
184
- action,
185
- SchedulePolicy.Immediately,
186
- );
187
- });
188
-
189
- it("should pass clear policy to animationFrame.clear on clearAll", () => {
190
- // Arrange
191
- const actionScheduler = new ActionScheduler();
192
- const action = jest.fn();
193
- const options = {
194
- clearPolicy: ClearPolicy.Resolve,
195
- } as const;
196
- const testFrame = actionScheduler.animationFrame(action, options);
197
-
198
- // Act
199
- actionScheduler.clearAll();
200
-
201
- // Assert
202
- expect(testFrame.clear).toHaveBeenCalledWith(ClearPolicy.Resolve);
203
- });
204
-
205
- describe("when scheduler is disabled", () => {
206
- it("should return a noop interval", () => {
207
- // Arrange
208
- const actionScheduler = new ActionScheduler();
209
- const action = jest.fn();
210
-
211
- // Act
212
- actionScheduler.disable();
213
- const result = actionScheduler.animationFrame(action);
214
-
215
- // Assert
216
- expect(result).toBe(ActionScheduler.NoopAction);
217
- });
218
- });
219
- });
220
-
221
- describe("#clearAll", () => {
222
- it("should call clear on all registered items", () => {
223
- // Arrange
224
- const actionScheduler = new ActionScheduler();
225
- const action = jest.fn();
226
- const timeout = actionScheduler.timeout(action, 10);
227
- const interval = actionScheduler.interval(action, 10);
228
- const animationFrame = actionScheduler.animationFrame(action);
229
-
230
- // Act
231
- actionScheduler.clearAll();
232
-
233
- // Assert
234
- expect(timeout.clear).toHaveBeenCalledTimes(1);
235
- expect(interval.clear).toHaveBeenCalledTimes(1);
236
- expect(animationFrame.clear).toHaveBeenCalledTimes(1);
237
- });
238
-
239
- it("should not call clear on items more than once", () => {
240
- // Arrange
241
- const actionScheduler = new ActionScheduler();
242
- const action = jest.fn();
243
- const timeout = actionScheduler.timeout(action, 10);
244
- const interval = actionScheduler.interval(action, 10);
245
- const animationFrame = actionScheduler.animationFrame(action);
246
- actionScheduler.clearAll();
247
-
248
- // Act
249
- actionScheduler.clearAll();
250
-
251
- // Assert
252
- expect(timeout.clear).toHaveBeenCalledTimes(1);
253
- expect(interval.clear).toHaveBeenCalledTimes(1);
254
- expect(animationFrame.clear).toHaveBeenCalledTimes(1);
255
- });
256
- });
257
-
258
- describe("#disable", () => {
259
- it("should clear all scheduled actions", () => {
260
- // Arrange
261
- const actionScheduler = new ActionScheduler();
262
- const clearAllSpy = jest.spyOn(actionScheduler, "clearAll");
263
-
264
- // Act
265
- actionScheduler.disable();
266
-
267
- // Assert
268
- expect(clearAllSpy).toHaveBeenCalledTimes(1);
269
- });
270
- });
271
- });
@@ -1,225 +0,0 @@
1
- import AnimationFrame from "../animation-frame";
2
- import {SchedulePolicy, ClearPolicy} from "../policies";
3
-
4
- describe("AnimationFrame", () => {
5
- beforeEach(() => {
6
- jest.useFakeTimers();
7
-
8
- // Jest doesn't fake out the animation frame API, so we're going to do
9
- // it here and map it to timeouts, that way we can use the fake timer
10
- // API to test our animation frame things.
11
- jest.spyOn(global, "requestAnimationFrame").mockImplementation(
12
- (fn: any, ...args: any) => setTimeout(fn, 0) as any,
13
- );
14
- jest.spyOn(global, "cancelAnimationFrame").mockImplementation(
15
- (id: any, ...args: any) => clearTimeout(id),
16
- );
17
- });
18
-
19
- afterEach(() => {
20
- jest.restoreAllMocks();
21
- });
22
-
23
- describe("constructor", () => {
24
- it("creates instance", () => {
25
- // Arrange
26
-
27
- // Act
28
- const result = new AnimationFrame(() => {});
29
-
30
- // Assert
31
- expect(result).toBeDefined();
32
- });
33
-
34
- it("throws if the action is not a function", () => {
35
- // Arrange
36
-
37
- // Act
38
- const underTest = () => new AnimationFrame(null as any);
39
-
40
- // Assert
41
- expect(underTest).toThrowErrorMatchingInlineSnapshot(
42
- `"Action must be a function"`,
43
- );
44
- });
45
-
46
- it("requests an animation frame when schedule policy is SchedulePolicy.Immediately", () => {
47
- // Arrange
48
- const spy = jest.spyOn(global, "requestAnimationFrame");
49
-
50
- // Act
51
- // eslint-disable-next-line no-new
52
- new AnimationFrame(() => {}, SchedulePolicy.Immediately);
53
-
54
- // Assert
55
- expect(spy).toHaveBeenCalledTimes(1);
56
- });
57
- });
58
-
59
- describe("isSet", () => {
60
- it("is false when the request has not been set", () => {
61
- // Arrange
62
- const animationFrame = new AnimationFrame(() => {},
63
- SchedulePolicy.OnDemand);
64
-
65
- // Act
66
- const result = animationFrame.isSet;
67
-
68
- // Assert
69
- expect(result).toBeFalsy();
70
- });
71
-
72
- it("is true when the request is pending", () => {
73
- // Arrange
74
- const animationFrame = new AnimationFrame(() => {});
75
- animationFrame.set();
76
-
77
- // Act
78
- const result = animationFrame.isSet;
79
-
80
- // Assert
81
- expect(result).toBeTruthy();
82
- });
83
-
84
- it("is false when the request has executed", () => {
85
- // Arrange
86
- const animationFrame = new AnimationFrame(() => {});
87
- animationFrame.set();
88
- jest.runOnlyPendingTimers();
89
-
90
- // Act
91
- const result = animationFrame.isSet;
92
-
93
- // Assert
94
- expect(result).toBeFalsy();
95
- });
96
- });
97
-
98
- describe("#set", () => {
99
- it("should call requestAnimationFrame", () => {
100
- // Arrange
101
- const spy = jest.spyOn(global, "requestAnimationFrame");
102
- const animationFrame = new AnimationFrame(() => {});
103
-
104
- // Act
105
- animationFrame.set();
106
-
107
- // Assert
108
- expect(spy).toHaveBeenNthCalledWith(1, expect.any(Function));
109
- });
110
-
111
- it("should invoke requestAnimationFrame to call the given action", () => {
112
- // Arrange
113
- const spy = jest.spyOn(global, "requestAnimationFrame");
114
- const action = jest.fn();
115
- const animationFrame = new AnimationFrame((time: any) =>
116
- action(time),
117
- );
118
- animationFrame.set();
119
- const scheduledAction = spy.mock.calls[0][0];
120
-
121
- // Act
122
- scheduledAction(2001);
123
-
124
- // Assert
125
- expect(action).toHaveBeenCalledTimes(1);
126
- expect(action).toHaveBeenCalledWith(2001);
127
- });
128
-
129
- it("should clear any pending request", () => {
130
- // Arrange
131
- const action = jest.fn();
132
- const animationFrame = new AnimationFrame(() => action());
133
- animationFrame.set();
134
-
135
- // Act
136
- animationFrame.set();
137
- jest.runOnlyPendingTimers();
138
-
139
- // Assert
140
- expect(action).toHaveBeenCalledTimes(1);
141
- });
142
-
143
- it("should set the timeout again if it has already executed", () => {
144
- // Arrange
145
- const spy = jest.spyOn(global, "requestAnimationFrame");
146
- const action = jest.fn();
147
- const animationFrame = new AnimationFrame(
148
- action,
149
- SchedulePolicy.OnDemand,
150
- );
151
- animationFrame.set();
152
- jest.runOnlyPendingTimers();
153
-
154
- // Act
155
- animationFrame.set();
156
-
157
- // Assert
158
- expect(spy).toHaveBeenCalledTimes(2);
159
- });
160
- });
161
-
162
- describe("#clear", () => {
163
- it("should clear a pending timout", () => {
164
- // Arrange
165
- const action = jest.fn();
166
- const animationFrame = new AnimationFrame(action);
167
- animationFrame.set();
168
-
169
- // Act
170
- animationFrame.clear();
171
- jest.runOnlyPendingTimers();
172
-
173
- // Assert
174
- expect(action).not.toHaveBeenCalled();
175
- });
176
-
177
- it("should invoke the action if clear policy is ClearPolicy.Resolve", () => {
178
- // Arrange
179
- jest.spyOn(performance, "now").mockReturnValue(42);
180
- const action = jest.fn();
181
- const animationFrame = new AnimationFrame(action);
182
- animationFrame.set();
183
-
184
- // Act
185
- animationFrame.clear(ClearPolicy.Resolve);
186
- jest.runOnlyPendingTimers();
187
-
188
- // Assert
189
- expect(action).toHaveBeenCalledTimes(1);
190
- expect(action).toHaveBeenCalledWith(42);
191
- });
192
-
193
- it("should not invoke the action if clear policy is ClearPolicy.Cancel", () => {
194
- // Arrange
195
- const action = jest.fn();
196
- const animationFrame = new AnimationFrame(
197
- action,
198
- SchedulePolicy.Immediately,
199
- );
200
-
201
- // Act
202
- animationFrame.clear(ClearPolicy.Cancel);
203
- jest.runOnlyPendingTimers();
204
-
205
- // Assert
206
- expect(action).not.toHaveBeenCalled();
207
- });
208
-
209
- it("should not invoke the action if timeout is not pending and clear policy is ClearPolicy.Resolve", () => {
210
- // Arrange
211
- const action = jest.fn();
212
- const animationFrame = new AnimationFrame(
213
- action,
214
- SchedulePolicy.OnDemand,
215
- );
216
-
217
- // Act
218
- animationFrame.clear(ClearPolicy.Resolve);
219
- jest.runOnlyPendingTimers();
220
-
221
- // Assert
222
- expect(action).not.toHaveBeenCalled();
223
- });
224
- });
225
- });