Skip to content

Commit ccb2a8a

Browse files
authored
Replace test renderer's fake Scheduler implementation with mock build (#14970)
* Replace test renderer's fake Scheduler implementation with mock build The test renderer has its own mock implementation of the Scheduler interface, with the ability to partially render work in tests. Now that this functionality has been lifted into a proper mock Scheduler build, we can use that instead. * Fix Profiler tests in prod
1 parent 53e787b commit ccb2a8a

16 files changed

+598
-761
lines changed

packages/jest-react/src/JestReact.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ function captureAssertion(fn) {
2626
}
2727

2828
function assertYieldsWereCleared(root) {
29-
const actualYields = root.unstable_clearYields();
29+
const Scheduler = root._Scheduler;
30+
const actualYields = Scheduler.unstable_clearYields();
3031
invariant(
3132
actualYields.length === 0,
3233
'Log of yielded values is not empty. ' +

packages/react-cache/src/__tests__/ReactCache-test.internal.js

Lines changed: 13 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -14,55 +14,15 @@ let createResource;
1414
let React;
1515
let ReactFeatureFlags;
1616
let ReactTestRenderer;
17+
let Scheduler;
1718
let Suspense;
1819
let TextResource;
1920
let textResourceShouldFail;
20-
let flushScheduledWork;
21-
let evictLRU;
2221

2322
describe('ReactCache', () => {
2423
beforeEach(() => {
2524
jest.resetModules();
2625

27-
let currentPriorityLevel = 3;
28-
29-
jest.mock('scheduler', () => {
30-
let callbacks = [];
31-
return {
32-
unstable_scheduleCallback(callback) {
33-
const callbackIndex = callbacks.length;
34-
callbacks.push(callback);
35-
return {callbackIndex};
36-
},
37-
flushScheduledWork() {
38-
while (callbacks.length) {
39-
const callback = callbacks.pop();
40-
callback();
41-
}
42-
},
43-
44-
unstable_ImmediatePriority: 1,
45-
unstable_UserBlockingPriority: 2,
46-
unstable_NormalPriority: 3,
47-
unstable_LowPriority: 4,
48-
unstable_IdlePriority: 5,
49-
50-
unstable_runWithPriority(priorityLevel, fn) {
51-
const prevPriorityLevel = currentPriorityLevel;
52-
currentPriorityLevel = priorityLevel;
53-
try {
54-
return fn();
55-
} finally {
56-
currentPriorityLevel = prevPriorityLevel;
57-
}
58-
},
59-
60-
unstable_getCurrentPriorityLevel() {
61-
return currentPriorityLevel;
62-
},
63-
};
64-
});
65-
6626
ReactFeatureFlags = require('shared/ReactFeatureFlags');
6727
ReactFeatureFlags.debugRenderPhaseSideEffectsForStrictMode = false;
6828
ReactFeatureFlags.replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
@@ -71,8 +31,7 @@ describe('ReactCache', () => {
7131
ReactCache = require('react-cache');
7232
createResource = ReactCache.unstable_createResource;
7333
ReactTestRenderer = require('react-test-renderer');
74-
flushScheduledWork = require('scheduler').flushScheduledWork;
75-
evictLRU = flushScheduledWork;
34+
Scheduler = require('scheduler');
7635

7736
TextResource = createResource(([text, ms = 0]) => {
7837
let listeners = null;
@@ -86,16 +45,12 @@ describe('ReactCache', () => {
8645
listeners = [{resolve, reject}];
8746
setTimeout(() => {
8847
if (textResourceShouldFail) {
89-
ReactTestRenderer.unstable_yield(
90-
`Promise rejected [${text}]`,
91-
);
48+
Scheduler.yieldValue(`Promise rejected [${text}]`);
9249
status = 'rejected';
9350
value = new Error('Failed to load: ' + text);
9451
listeners.forEach(listener => listener.reject(value));
9552
} else {
96-
ReactTestRenderer.unstable_yield(
97-
`Promise resolved [${text}]`,
98-
);
53+
Scheduler.yieldValue(`Promise resolved [${text}]`);
9954
status = 'resolved';
10055
value = text;
10156
listeners.forEach(listener => listener.resolve(value));
@@ -123,21 +78,21 @@ describe('ReactCache', () => {
12378
});
12479

12580
function Text(props) {
126-
ReactTestRenderer.unstable_yield(props.text);
81+
Scheduler.yieldValue(props.text);
12782
return props.text;
12883
}
12984

13085
function AsyncText(props) {
13186
const text = props.text;
13287
try {
13388
TextResource.read([props.text, props.ms]);
134-
ReactTestRenderer.unstable_yield(text);
89+
Scheduler.yieldValue(text);
13590
return text;
13691
} catch (promise) {
13792
if (typeof promise.then === 'function') {
138-
ReactTestRenderer.unstable_yield(`Suspend! [${text}]`);
93+
Scheduler.yieldValue(`Suspend! [${text}]`);
13994
} else {
140-
ReactTestRenderer.unstable_yield(`Error! [${text}]`);
95+
Scheduler.yieldValue(`Error! [${text}]`);
14196
}
14297
throw promise;
14398
}
@@ -201,7 +156,7 @@ describe('ReactCache', () => {
201156
});
202157

203158
function App() {
204-
ReactTestRenderer.unstable_yield('App');
159+
Scheduler.yieldValue('App');
205160
return BadTextResource.read(['Hi', 100]);
206161
}
207162

@@ -284,9 +239,7 @@ describe('ReactCache', () => {
284239
expect(root).toMatchRenderedOutput('145');
285240

286241
// We've now rendered values 1, 2, 3, 4, 5, over our limit of 3. The least
287-
// recently used values are 2 and 3. They will be evicted during the
288-
// next sweep.
289-
evictLRU();
242+
// recently used values are 2 and 3. They should have been evicted.
290243

291244
root.update(
292245
<Suspense fallback={<Text text="Loading..." />}>
@@ -368,13 +321,13 @@ describe('ReactCache', () => {
368321
const text = props.text;
369322
try {
370323
const actualText = BadTextResource.read([props.text, props.ms]);
371-
ReactTestRenderer.unstable_yield(actualText);
324+
Scheduler.yieldValue(actualText);
372325
return actualText;
373326
} catch (promise) {
374327
if (typeof promise.then === 'function') {
375-
ReactTestRenderer.unstable_yield(`Suspend! [${text}]`);
328+
Scheduler.yieldValue(`Suspend! [${text}]`);
376329
} else {
377-
ReactTestRenderer.unstable_yield(`Error! [${text}]`);
330+
Scheduler.yieldValue(`Error! [${text}]`);
378331
}
379332
throw promise;
380333
}

packages/react-reconciler/src/__tests__/ErrorBoundaryReconciliation-test.internal.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ describe('ErrorBoundaryReconciliation', () => {
55
let React;
66
let ReactFeatureFlags;
77
let ReactTestRenderer;
8+
let Scheduler;
89
let span;
910

1011
beforeEach(() => {
@@ -14,6 +15,7 @@ describe('ErrorBoundaryReconciliation', () => {
1415
ReactFeatureFlags.replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
1516
ReactTestRenderer = require('react-test-renderer');
1617
React = require('react');
18+
Scheduler = require('scheduler');
1719

1820
DidCatchErrorBoundary = class extends React.Component {
1921
state = {error: null};
@@ -56,9 +58,7 @@ describe('ErrorBoundaryReconciliation', () => {
5658
</ErrorBoundary>,
5759
{unstable_isConcurrent: isConcurrent},
5860
);
59-
if (isConcurrent) {
60-
renderer.unstable_flushAll();
61-
}
61+
Scheduler.flushAll();
6262
expect(renderer).toMatchRenderedOutput(<span prop="BrokenRender" />);
6363

6464
expect(() => {
@@ -67,9 +67,7 @@ describe('ErrorBoundaryReconciliation', () => {
6767
<BrokenRender fail={true} />
6868
</ErrorBoundary>,
6969
);
70-
if (isConcurrent) {
71-
renderer.unstable_flushAll();
72-
}
70+
Scheduler.flushAll();
7371
}).toWarnDev(isConcurrent ? ['invalid', 'invalid'] : ['invalid']);
7472
const Fallback = fallbackTagName;
7573
expect(renderer).toMatchRenderedOutput(<Fallback prop="ErrorBoundary" />);

packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
let React;
1616
let ReactFeatureFlags;
1717
let ReactTestRenderer;
18+
let Scheduler;
1819
let ReactDOMServer;
1920
let act;
2021

@@ -28,6 +29,7 @@ describe('ReactHooks', () => {
2829
ReactFeatureFlags.debugRenderPhaseSideEffectsForStrictMode = false;
2930
React = require('react');
3031
ReactTestRenderer = require('react-test-renderer');
32+
Scheduler = require('scheduler');
3133
ReactDOMServer = require('react-dom/server');
3234
act = ReactTestRenderer.act;
3335
});
@@ -53,7 +55,7 @@ describe('ReactHooks', () => {
5355
const {useState, useLayoutEffect} = React;
5456

5557
function Child({text}) {
56-
ReactTestRenderer.unstable_yield('Child: ' + text);
58+
Scheduler.yieldValue('Child: ' + text);
5759
return text;
5860
}
5961

@@ -66,9 +68,9 @@ describe('ReactHooks', () => {
6668
setCounter2 = _setCounter2;
6769

6870
const text = `${counter1}, ${counter2}`;
69-
ReactTestRenderer.unstable_yield(`Parent: ${text}`);
71+
Scheduler.yieldValue(`Parent: ${text}`);
7072
useLayoutEffect(() => {
71-
ReactTestRenderer.unstable_yield(`Effect: ${text}`);
73+
Scheduler.yieldValue(`Effect: ${text}`);
7274
});
7375
return <Child text={text} />;
7476
}
@@ -161,7 +163,7 @@ describe('ReactHooks', () => {
161163
const {useState, memo} = React;
162164

163165
function Child({text}) {
164-
ReactTestRenderer.unstable_yield('Child: ' + text);
166+
Scheduler.yieldValue('Child: ' + text);
165167
return text;
166168
}
167169

@@ -174,7 +176,7 @@ describe('ReactHooks', () => {
174176
setCounter2 = _setCounter2;
175177

176178
const text = `${counter1}, ${counter2} (${theme})`;
177-
ReactTestRenderer.unstable_yield(`Parent: ${text}`);
179+
Scheduler.yieldValue(`Parent: ${text}`);
178180
return <Child text={text} />;
179181
}
180182

@@ -243,7 +245,7 @@ describe('ReactHooks', () => {
243245
const [counter, _setCounter] = useState(0);
244246
setCounter = _setCounter;
245247

246-
ReactTestRenderer.unstable_yield(`Count: ${counter}`);
248+
Scheduler.yieldValue(`Count: ${counter}`);
247249
return counter;
248250
}
249251

@@ -277,7 +279,7 @@ describe('ReactHooks', () => {
277279
const [counter, _dispatch] = useReducer((s, a) => a, 0);
278280
dispatch = _dispatch;
279281

280-
ReactTestRenderer.unstable_yield(`Count: ${counter}`);
282+
Scheduler.yieldValue(`Count: ${counter}`);
281283
return counter;
282284
}
283285

@@ -311,15 +313,15 @@ describe('ReactHooks', () => {
311313
let setTheme;
312314
function ThemeProvider({children}) {
313315
const [theme, _setTheme] = useState('light');
314-
ReactTestRenderer.unstable_yield('Theme: ' + theme);
316+
Scheduler.yieldValue('Theme: ' + theme);
315317
setTheme = _setTheme;
316318
return (
317319
<ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>
318320
);
319321
}
320322

321323
function Child({text}) {
322-
ReactTestRenderer.unstable_yield('Child: ' + text);
324+
Scheduler.yieldValue('Child: ' + text);
323325
return text;
324326
}
325327

@@ -331,9 +333,9 @@ describe('ReactHooks', () => {
331333
const theme = useContext(ThemeContext);
332334

333335
const text = `${counter} (${theme})`;
334-
ReactTestRenderer.unstable_yield(`Parent: ${text}`);
336+
Scheduler.yieldValue(`Parent: ${text}`);
335337
useLayoutEffect(() => {
336-
ReactTestRenderer.unstable_yield(`Effect: ${text}`);
338+
Scheduler.yieldValue(`Effect: ${text}`);
337339
});
338340
return <Child text={text} />;
339341
}
@@ -392,17 +394,17 @@ describe('ReactHooks', () => {
392394
const {useState, useLayoutEffect} = React;
393395

394396
function Child({text}) {
395-
ReactTestRenderer.unstable_yield('Child: ' + text);
397+
Scheduler.yieldValue('Child: ' + text);
396398
return text;
397399
}
398400

399401
let setCounter;
400402
function Parent() {
401403
const [counter, _setCounter] = useState(0);
402404
setCounter = _setCounter;
403-
ReactTestRenderer.unstable_yield('Parent: ' + counter);
405+
Scheduler.yieldValue('Parent: ' + counter);
404406
useLayoutEffect(() => {
405-
ReactTestRenderer.unstable_yield('Effect: ' + counter);
407+
Scheduler.yieldValue('Effect: ' + counter);
406408
});
407409
return <Child text={counter} />;
408410
}
@@ -470,15 +472,15 @@ describe('ReactHooks', () => {
470472
const {useState} = React;
471473

472474
function Child({text}) {
473-
ReactTestRenderer.unstable_yield('Child: ' + text);
475+
Scheduler.yieldValue('Child: ' + text);
474476
return text;
475477
}
476478

477479
let setCounter;
478480
function Parent() {
479481
const [counter, _setCounter] = useState(0);
480482
setCounter = _setCounter;
481-
ReactTestRenderer.unstable_yield('Parent: ' + counter);
483+
Scheduler.yieldValue('Parent: ' + counter);
482484
return <Child text={counter} />;
483485
}
484486

@@ -489,9 +491,7 @@ describe('ReactHooks', () => {
489491

490492
const update = value => {
491493
setCounter(previous => {
492-
ReactTestRenderer.unstable_yield(
493-
`Compute state (${previous} -> ${value})`,
494-
);
494+
Scheduler.yieldValue(`Compute state (${previous} -> ${value})`);
495495
return value;
496496
});
497497
};
@@ -530,15 +530,15 @@ describe('ReactHooks', () => {
530530
const {useState} = React;
531531

532532
function Child({text}) {
533-
ReactTestRenderer.unstable_yield('Child: ' + text);
533+
Scheduler.yieldValue('Child: ' + text);
534534
return text;
535535
}
536536

537537
let setCounter;
538538
function Parent() {
539539
const [counter, _setCounter] = useState(1);
540540
setCounter = _setCounter;
541-
ReactTestRenderer.unstable_yield('Parent: ' + counter);
541+
Scheduler.yieldValue('Parent: ' + counter);
542542
return <Child text={counter} />;
543543
}
544544

@@ -550,9 +550,7 @@ describe('ReactHooks', () => {
550550
const update = compute => {
551551
setCounter(previous => {
552552
const value = compute(previous);
553-
ReactTestRenderer.unstable_yield(
554-
`Compute state (${previous} -> ${value})`,
555-
);
553+
Scheduler.yieldValue(`Compute state (${previous} -> ${value})`);
556554
return value;
557555
});
558556
};
@@ -590,9 +588,7 @@ describe('ReactHooks', () => {
590588
const {useLayoutEffect} = React;
591589
function App(props) {
592590
useLayoutEffect(() => {
593-
ReactTestRenderer.unstable_yield(
594-
'Did commit: ' + props.dependencies.join(', '),
595-
);
591+
Scheduler.yieldValue('Did commit: ' + props.dependencies.join(', '));
596592
}, props.dependencies);
597593
return props.dependencies;
598594
}
@@ -613,7 +609,7 @@ describe('ReactHooks', () => {
613609
const {useMemo} = React;
614610
function App({text, hasDeps}) {
615611
const resolvedText = useMemo(() => {
616-
ReactTestRenderer.unstable_yield('Compute');
612+
Scheduler.yieldValue('Compute');
617613
return text.toUpperCase();
618614
}, hasDeps ? null : [text]);
619615
return resolvedText;

0 commit comments

Comments
 (0)