Skip to content

Commit 345e0a7

Browse files
authored
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
1 parent fa7fa81 commit 345e0a7

File tree

1 file changed

+33
-29
lines changed

1 file changed

+33
-29
lines changed

packages/react-scheduler/src/__tests__/ReactScheduler-test.js

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,25 @@
1010
'use strict';
1111

1212
let ReactScheduler;
13+
type FrameTimeoutConfigType = {
14+
// should only specify one or the other
15+
timeLeftInFrame: ?number,
16+
timePastFrameDeadline: ?number,
17+
};
1318

1419
describe('ReactScheduler', () => {
1520
let rAFCallbacks = [];
1621
let postMessageCallback;
1722
let postMessageEvents = [];
1823

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;
2232
if (postMessageCallback) {
2333
while (postMessageEvents.length) {
2434
postMessageCallback(postMessageEvents.shift());
@@ -31,9 +41,9 @@ describe('ReactScheduler', () => {
3141
rAFCallbacks.forEach(cb => cb());
3242
rAFCallbacks = [];
3343
}
34-
function advanceAll() {
44+
function advanceOneFrame(config: FrameTimeoutConfigType = {}) {
3545
runRAFCallbacks();
36-
drainPostMessageQueue();
46+
runPostMessageCallbacks(config);
3747
}
3848

3949
let frameSize = 33;
@@ -77,7 +87,7 @@ describe('ReactScheduler', () => {
7787
const {scheduleWork} = ReactScheduler;
7888
const cb = jest.fn();
7989
scheduleWork(cb);
80-
advanceAll();
90+
advanceOneFrame({timeLeftInFrame: 15});
8191
expect(cb.mock.calls.length).toBe(1);
8292
// should not have timed out and should include a timeRemaining method
8393
expect(cb.mock.calls[0][0].didTimeout).toBe(false);
@@ -97,7 +107,7 @@ describe('ReactScheduler', () => {
97107
scheduleWork(callbackB);
98108
expect(callbackLog).toEqual([]);
99109
// after a delay, calls as many callbacks as it has time for
100-
advanceAll();
110+
advanceOneFrame({timeLeftInFrame: 15});
101111
expect(callbackLog).toEqual(['A', 'B']);
102112
// callbackA should not have timed out and should include a timeRemaining method
103113
expect(callbackA.mock.calls[0][0].didTimeout).toBe(false);
@@ -125,16 +135,16 @@ describe('ReactScheduler', () => {
125135
scheduleWork(callbackB);
126136
expect(callbackLog).toEqual([]);
127137
// now it should drain the message queue and do all scheduled work
128-
drainPostMessageQueue();
138+
runPostMessageCallbacks({timeLeftInFrame: 15});
129139
expect(callbackLog).toEqual(['A', 'B']);
130140

131141
// advances timers, now with an empty queue of work (to ensure they don't deadlock)
132-
advanceAll();
142+
advanceOneFrame({timeLeftInFrame: 15});
133143

134144
// see if more work can be done now.
135145
scheduleWork(callbackC);
136146
expect(callbackLog).toEqual(['A', 'B']);
137-
advanceAll();
147+
advanceOneFrame({timeLeftInFrame: 15});
138148
expect(callbackLog).toEqual(['A', 'B', 'C']);
139149
});
140150

@@ -163,7 +173,7 @@ describe('ReactScheduler', () => {
163173
expect(callbackLog).toEqual([]);
164174
// after a delay, calls the scheduled callbacks,
165175
// and also calls new callbacks scheduled by current callbacks
166-
advanceAll();
176+
advanceOneFrame({timeLeftInFrame: 15});
167177
expect(callbackLog).toEqual(['A', 'B', 'C']);
168178
},
169179
);
@@ -199,7 +209,7 @@ describe('ReactScheduler', () => {
199209
// initially waits to call the callback
200210
expect(callbackLog).toEqual([]);
201211
// while flushing callbacks, calls as many as it has time for
202-
advanceAll();
212+
advanceOneFrame({timeLeftInFrame: 15});
203213
expect(callbackLog).toEqual(['A', 'B', 'C', 'D', 'E', 'F']);
204214
});
205215

@@ -222,7 +232,7 @@ describe('ReactScheduler', () => {
222232
scheduleWork(callbackB);
223233
expect(callbackLog).toEqual([]);
224234
// after a delay, calls the latest callback passed
225-
advanceAll();
235+
advanceOneFrame({timeLeftInFrame: 15});
226236
expect(callbackLog).toEqual(['A0', 'B', 'A1']);
227237
});
228238
});
@@ -248,24 +258,20 @@ describe('ReactScheduler', () => {
248258
scheduleWork(callbackB, {timeout: 100}); // times out later
249259
scheduleWork(callbackC, {timeout: 2}); // will time out fast
250260

251-
runRAFCallbacks(); // runs rAF callback
252261
// 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});
255263

256264
// callbackC should have timed out
257265
expect(callbackLog).toEqual(['C']);
258266

259-
runRAFCallbacks(); // runs rAF callback
260267
// 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});
263269

264270
// callbackB should have timed out
265271
expect(callbackLog).toEqual(['C', 'B']);
266272

267-
runRAFCallbacks(); // runs rAF callback
268-
drainPostMessageQueue(); // runs postMessage callback, idleTick
273+
// let's give ourselves some idle time now
274+
advanceOneFrame({timeLeftInFrame: 16});
269275

270276
// we should have run callbackA in the idle time
271277
expect(callbackLog).toEqual(['C', 'B', 'A']);
@@ -295,27 +301,25 @@ describe('ReactScheduler', () => {
295301
scheduleWork(callbackC, {timeout: 2}); // will time out fast
296302
scheduleWork(callbackD); // won't time out
297303

298-
advanceAll(); // runs rAF and postMessage callbacks
304+
advanceOneFrame({timeLeftInFrame: 15}); // runs rAF and postMessage callbacks
299305

300306
// callbackC should have timed out
301307
// we should have had time to call A also, then we run out of time
302308
expect(callbackLog).toEqual(['C', 'A']);
303309

304-
runRAFCallbacks(); // runs rAF callback
305310
// 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});
308312

309313
// callbackB should have timed out
310314
// but we should not run callbackD because we have no idle time
311315
expect(callbackLog).toEqual(['C', 'A', 'B']);
312316

313-
advanceAll(); // runs rAF and postMessage callbacks
317+
advanceOneFrame({timeLeftInFrame: 15}); // runs rAF and postMessage callbacks
314318

315319
// we should have run callbackD in the idle time
316320
expect(callbackLog).toEqual(['C', 'A', 'B', 'D']);
317321

318-
advanceAll(); // runs rAF and postMessage callbacks
322+
advanceOneFrame({timeLeftInFrame: 15}); // runs rAF and postMessage callbacks
319323

320324
// we should not have run anything again, nothing is scheduled
321325
expect(callbackLog).toEqual(['C', 'A', 'B', 'D']);
@@ -331,7 +335,7 @@ describe('ReactScheduler', () => {
331335
const callbackId = scheduleWork(cb);
332336
expect(cb.mock.calls.length).toBe(0);
333337
cancelScheduledWork(callbackId);
334-
advanceAll();
338+
advanceOneFrame({timeLeftInFrame: 15});
335339
expect(cb.mock.calls.length).toBe(0);
336340
});
337341

@@ -349,7 +353,7 @@ describe('ReactScheduler', () => {
349353
callbackBId = scheduleWork(callbackB);
350354
// Initially doesn't call anything
351355
expect(callbackLog).toEqual([]);
352-
advanceAll();
356+
advanceOneFrame({timeLeftInFrame: 15});
353357
// B should not get called because A cancelled B
354358
expect(callbackLog).toEqual(['A']);
355359
expect(callbackB.mock.calls.length).toBe(0);

0 commit comments

Comments
 (0)