@samitouri / QOS-React / commits / 345e0a71ac

Improve tests for 'schedule' module (#12880)

**what is the change?:** Renamed some methods, and made a method to advance a frame in the test environment. **why make this change?:** We often need to simulate a frame passing with some amount of idle time or lack of idle time, and the new method makes it easier to write that out. **test plan:** Run the updated tests. Also temporarily tried breaking the scheduler and verified that the tests will fail. **issue:** See internal task T29442940

Flarnie Marchan committed May 24, 2018 at 10:27 UTC 345e0a71acc12fae78349b6036fa00dbf5300384
1 file changed +33 -29
packages/react-scheduler/src/__tests__/ReactScheduler-test.js
+33 -29
@@ -10,15 +10,25 @@
10 'use strict';
11
12 let ReactScheduler;
13 +type FrameTimeoutConfigType = {
14 + // should only specify one or the other
15 + timeLeftInFrame: ?number,
16 + timePastFrameDeadline: ?number,
17 +};
18
19 describe('ReactScheduler', () => {
20 let rAFCallbacks = [];
21 let postMessageCallback;
22 let postMessageEvents = [];
23
19 - function drainPostMessageQueue() {
20 - // default to this falling about 15 ms before next frame
21 - currentTime = startOfLatestFrame + frameSize - 15;
24 + function runPostMessageCallbacks(config: FrameTimeoutConfigType) {
25 + let timeLeftInFrame = 0;
26 + if (typeof config.timeLeftInFrame === 'number') {
27 + timeLeftInFrame = config.timeLeftInFrame;
28 + } else if (typeof config.timePastFrameDeadline === 'number') {
29 + timeLeftInFrame = -1 * config.timePastFrameDeadline;
30 + }
31 + currentTime = startOfLatestFrame + frameSize - timeLeftInFrame;
32 if (postMessageCallback) {
33 while (postMessageEvents.length) {
34 postMessageCallback(postMessageEvents.shift());
@@ -31,9 +41,9 @@ describe('ReactScheduler', () => {
41 rAFCallbacks.forEach(cb => cb());
42 rAFCallbacks = [];
43 }
34 - function advanceAll() {
44 + function advanceOneFrame(config: FrameTimeoutConfigType = {}) {
45 runRAFCallbacks();
36 - drainPostMessageQueue();
46 + runPostMessageCallbacks(config);
47 }
48
49 let frameSize = 33;
@@ -77,7 +87,7 @@ describe('ReactScheduler', () => {
87 const {scheduleWork} = ReactScheduler;
88 const cb = jest.fn();
89 scheduleWork(cb);
80 - advanceAll();
90 + advanceOneFrame({timeLeftInFrame: 15});
91 expect(cb.mock.calls.length).toBe(1);
92 // should not have timed out and should include a timeRemaining method
93 expect(cb.mock.calls[0][0].didTimeout).toBe(false);
@@ -97,7 +107,7 @@ describe('ReactScheduler', () => {
107 scheduleWork(callbackB);
108 expect(callbackLog).toEqual([]);
109 // after a delay, calls as many callbacks as it has time for
100 - advanceAll();
110 + advanceOneFrame({timeLeftInFrame: 15});
111 expect(callbackLog).toEqual(['A', 'B']);
112 // callbackA should not have timed out and should include a timeRemaining method
113 expect(callbackA.mock.calls[0][0].didTimeout).toBe(false);
@@ -125,16 +135,16 @@ describe('ReactScheduler', () => {
135 scheduleWork(callbackB);
136 expect(callbackLog).toEqual([]);
137 // now it should drain the message queue and do all scheduled work
128 - drainPostMessageQueue();
138 + runPostMessageCallbacks({timeLeftInFrame: 15});
139 expect(callbackLog).toEqual(['A', 'B']);
140
141 // advances timers, now with an empty queue of work (to ensure they don't deadlock)
132 - advanceAll();
142 + advanceOneFrame({timeLeftInFrame: 15});
143
144 // see if more work can be done now.
145 scheduleWork(callbackC);
146 expect(callbackLog).toEqual(['A', 'B']);
137 - advanceAll();
147 + advanceOneFrame({timeLeftInFrame: 15});
148 expect(callbackLog).toEqual(['A', 'B', 'C']);
149 });
150
@@ -163,7 +173,7 @@ describe('ReactScheduler', () => {
173 expect(callbackLog).toEqual([]);
174 // after a delay, calls the scheduled callbacks,
175 // and also calls new callbacks scheduled by current callbacks
166 - advanceAll();
176 + advanceOneFrame({timeLeftInFrame: 15});
177 expect(callbackLog).toEqual(['A', 'B', 'C']);
178 },
179 );
@@ -199,7 +209,7 @@ describe('ReactScheduler', () => {
209 // initially waits to call the callback
210 expect(callbackLog).toEqual([]);
211 // while flushing callbacks, calls as many as it has time for
202 - advanceAll();
212 + advanceOneFrame({timeLeftInFrame: 15});
213 expect(callbackLog).toEqual(['A', 'B', 'C', 'D', 'E', 'F']);
214 });
215
@@ -222,7 +232,7 @@ describe('ReactScheduler', () => {
232 scheduleWork(callbackB);
233 expect(callbackLog).toEqual([]);
234 // after a delay, calls the latest callback passed
225 - advanceAll();
235 + advanceOneFrame({timeLeftInFrame: 15});
236 expect(callbackLog).toEqual(['A0', 'B', 'A1']);
237 });
238 });
@@ -248,24 +258,20 @@ describe('ReactScheduler', () => {
258 scheduleWork(callbackB, {timeout: 100}); // times out later
259 scheduleWork(callbackC, {timeout: 2}); // will time out fast
260
251 - runRAFCallbacks(); // runs rAF callback
261 // push time ahead a bit so that we have no idle time
253 - startOfLatestFrame += 16;
254 - drainPostMessageQueue(); // runs postMessage callback, idleTick
262 + advanceOneFrame({timePastFrameDeadline: 16});
263
264 // callbackC should have timed out
265 expect(callbackLog).toEqual(['C']);
266
259 - runRAFCallbacks(); // runs rAF callback
267 // push time ahead a bit so that we have no idle time
261 - startOfLatestFrame += 16;
262 - drainPostMessageQueue(); // runs postMessage callback, idleTick
268 + advanceOneFrame({timePastFrameDeadline: 16});
269
270 // callbackB should have timed out
271 expect(callbackLog).toEqual(['C', 'B']);
272
267 - runRAFCallbacks(); // runs rAF callback
268 - drainPostMessageQueue(); // runs postMessage callback, idleTick
273 + // let's give ourselves some idle time now
274 + advanceOneFrame({timeLeftInFrame: 16});
275
276 // we should have run callbackA in the idle time
277 expect(callbackLog).toEqual(['C', 'B', 'A']);
@@ -295,27 +301,25 @@ describe('ReactScheduler', () => {
301 scheduleWork(callbackC, {timeout: 2}); // will time out fast
302 scheduleWork(callbackD); // won't time out
303
298 - advanceAll(); // runs rAF and postMessage callbacks
304 + advanceOneFrame({timeLeftInFrame: 15}); // runs rAF and postMessage callbacks
305
306 // callbackC should have timed out
307 // we should have had time to call A also, then we run out of time
308 expect(callbackLog).toEqual(['C', 'A']);
309
304 - runRAFCallbacks(); // runs rAF callback
310 // push time ahead a bit so that we have no idle time
306 - startOfLatestFrame += 16;
307 - drainPostMessageQueue(); // runs postMessage callback, idleTick
311 + advanceOneFrame({timePastFrameDeadline: 16});
312
313 // callbackB should have timed out
314 // but we should not run callbackD because we have no idle time
315 expect(callbackLog).toEqual(['C', 'A', 'B']);
316
313 - advanceAll(); // runs rAF and postMessage callbacks
317 + advanceOneFrame({timeLeftInFrame: 15}); // runs rAF and postMessage callbacks
318
319 // we should have run callbackD in the idle time
320 expect(callbackLog).toEqual(['C', 'A', 'B', 'D']);
321
318 - advanceAll(); // runs rAF and postMessage callbacks
322 + advanceOneFrame({timeLeftInFrame: 15}); // runs rAF and postMessage callbacks
323
324 // we should not have run anything again, nothing is scheduled
325 expect(callbackLog).toEqual(['C', 'A', 'B', 'D']);
@@ -331,7 +335,7 @@ describe('ReactScheduler', () => {
335 const callbackId = scheduleWork(cb);
336 expect(cb.mock.calls.length).toBe(0);
337 cancelScheduledWork(callbackId);
334 - advanceAll();
338 + advanceOneFrame({timeLeftInFrame: 15});
339 expect(cb.mock.calls.length).toBe(0);
340 });
341
@@ -349,7 +353,7 @@ describe('ReactScheduler', () => {
353 callbackBId = scheduleWork(callbackB);
354 // Initially doesn't call anything
355 expect(callbackLog).toEqual([]);
352 - advanceAll();
356 + advanceOneFrame({timeLeftInFrame: 15});
357 // B should not get called because A cancelled B
358 expect(callbackLog).toEqual(['A']);
359 expect(callbackB.mock.calls.length).toBe(0);