@samitouri / QOS-React-2 / commits / 25685d8a90

Codemod tests to waitFor pattern (9/?) (#26309)

This converts some of our test suite to use the `waitFor` test pattern, instead of the `expect(Scheduler).toFlushAndYield` pattern. Most of these changes are automated with jscodeshift, with some slight manual cleanup in certain cases. See #26285 for full context.

Andrew Clark committed Mar 4, 2023 at 18:06 UTC 25685d8a90dd83d30cee6bd365bcb0115f1a2ff1
22 files changed +233 -217
packages/react-cache/src/__tests__/ReactCacheOld-test.internal.js
+4 -2
@@ -20,6 +20,7 @@ let TextResource;
20 let textResourceShouldFail;
21 let waitForAll;
22 let assertLog;
23 +let waitForThrow;
24
25 describe('ReactCache', () => {
26 beforeEach(() => {
@@ -38,6 +39,7 @@ describe('ReactCache', () => {
39 const InternalTestUtils = require('internal-test-utils');
40 waitForAll = InternalTestUtils.waitForAll;
41 assertLog = InternalTestUtils.assertLog;
42 + waitForThrow = InternalTestUtils.waitForThrow;
43
44 TextResource = createResource(
45 ([text, ms = 0]) => {
@@ -150,12 +152,12 @@ describe('ReactCache', () => {
152 jest.advanceTimersByTime(100);
153 assertLog(['Promise rejected [Hi]']);
154
153 - expect(Scheduler).toFlushAndThrow('Failed to load: Hi');
155 + await waitForThrow('Failed to load: Hi');
156 assertLog(['Error! [Hi]', 'Error! [Hi]']);
157
158 // Should throw again on a subsequent read
159 root.update(<App />);
158 - expect(Scheduler).toFlushAndThrow('Failed to load: Hi');
160 + await waitForThrow('Failed to load: Hi');
161 assertLog(['Error! [Hi]', 'Error! [Hi]']);
162 });
163
packages/react-dom/src/__tests__/ReactDOMFloat-test.js
+1 -1
@@ -4398,7 +4398,7 @@ background-color: green;
4398 </body>
4399 </html>,
4400 );
4401 - expect(Scheduler).toFlushWithoutYielding();
4401 + await waitForAll([]);
4402 expect(getMeaningfulChildren(document)).toEqual(
4403 <html>
4404 <head>
packages/react-dom/src/__tests__/ReactDOMServerSelectiveHydration-test.internal.js
+25 -21
@@ -1092,8 +1092,8 @@ describe('ReactDOMServerSelectiveHydration', () => {
1092 const innerHTML = ReactDOMServer.renderToString(<InnerApp />);
1093 innerContainer.innerHTML = innerHTML;
1094
1095 - expect(OuterScheduler).toHaveYielded(['Outer']);
1096 - expect(InnerScheduler).toHaveYielded(['Inner']);
1095 + expect(OuterScheduler.unstable_clearYields()).toEqual(['Outer']);
1096 + expect(InnerScheduler.unstable_clearYields()).toEqual(['Inner']);
1097
1098 suspendOuter = true;
1099 suspendInner = true;
@@ -1101,8 +1101,10 @@ describe('ReactDOMServerSelectiveHydration', () => {
1101 OuterReactDOMClient.hydrateRoot(outerContainer, <OuterApp />);
1102 InnerReactDOMClient.hydrateRoot(innerContainer, <InnerApp />);
1103
1104 - expect(OuterScheduler).toFlushAndYield(['Suspend Outer']);
1105 - expect(InnerScheduler).toFlushAndYield(['Suspend Inner']);
1104 + OuterScheduler.unstable_flushAllWithoutAsserting();
1105 + InnerScheduler.unstable_flushAllWithoutAsserting();
1106 + expect(OuterScheduler.unstable_clearYields()).toEqual(['Suspend Outer']);
1107 + expect(InnerScheduler.unstable_clearYields()).toEqual(['Suspend Inner']);
1108
1109 innerDiv = document.querySelector('#inner');
1110
@@ -1115,7 +1117,7 @@ describe('ReactDOMServerSelectiveHydration', () => {
1117 InnerScheduler.unstable_flushAllWithoutAsserting();
1118 });
1119
1118 - expect(OuterScheduler).toHaveYielded(['Suspend Outer']);
1120 + expect(OuterScheduler.unstable_clearYields()).toEqual(['Suspend Outer']);
1121 if (
1122 gate(
1123 flags =>
@@ -1124,10 +1126,12 @@ describe('ReactDOMServerSelectiveHydration', () => {
1126 ) {
1127 // InnerApp doesn't see the event because OuterApp calls stopPropagation in
1128 // capture phase since the event is blocked on suspended component
1127 - expect(InnerScheduler).toHaveYielded([]);
1129 + expect(InnerScheduler.unstable_clearYields()).toEqual([]);
1130 } else {
1131 // no stopPropagation
1130 - expect(InnerScheduler).toHaveYielded(['Suspend Inner']);
1132 + expect(InnerScheduler.unstable_clearYields()).toEqual([
1133 + 'Suspend Inner',
1134 + ]);
1135 }
1136
1137 assertLog([]);
@@ -1149,15 +1153,15 @@ describe('ReactDOMServerSelectiveHydration', () => {
1153 InnerScheduler.unstable_flushAllWithoutAsserting();
1154 });
1155
1152 - expect(OuterScheduler).toHaveYielded(['Suspend Outer']);
1156 + expect(OuterScheduler.unstable_clearYields()).toEqual(['Suspend Outer']);
1157 // Inner App renders because it is unblocked
1154 - expect(InnerScheduler).toHaveYielded(['Inner']);
1158 + expect(InnerScheduler.unstable_clearYields()).toEqual(['Inner']);
1159 // No event is replayed yet
1160 assertLog([]);
1161
1162 dispatchMouseHoverEvent(innerDiv);
1159 - expect(OuterScheduler).toHaveYielded([]);
1160 - expect(InnerScheduler).toHaveYielded([]);
1163 + expect(OuterScheduler.unstable_clearYields()).toEqual([]);
1164 + expect(InnerScheduler.unstable_clearYields()).toEqual([]);
1165 // No event is replayed yet
1166 assertLog([]);
1167
@@ -1172,9 +1176,9 @@ describe('ReactDOMServerSelectiveHydration', () => {
1176
1177 // Nothing happens to inner app yet.
1178 // Its blocked on the outer app replaying the event
1175 - expect(InnerScheduler).toHaveYielded([]);
1179 + expect(InnerScheduler.unstable_clearYields()).toEqual([]);
1180 // Outer hydrates and schedules Replay
1177 - expect(OuterScheduler).toHaveYielded(['Outer']);
1181 + expect(OuterScheduler.unstable_clearYields()).toEqual(['Outer']);
1182 // No event is replayed yet
1183 assertLog([]);
1184
@@ -1203,9 +1207,9 @@ describe('ReactDOMServerSelectiveHydration', () => {
1207 });
1208
1209 // Outer resolves and scheduled replay
1206 - expect(OuterScheduler).toHaveYielded(['Outer']);
1210 + expect(OuterScheduler.unstable_clearYields()).toEqual(['Outer']);
1211 // Inner App is still blocked
1208 - expect(InnerScheduler).toHaveYielded([]);
1212 + expect(InnerScheduler.unstable_clearYields()).toEqual([]);
1213
1214 // Replay outer event
1215 await act(async () => {
@@ -1217,12 +1221,12 @@ describe('ReactDOMServerSelectiveHydration', () => {
1221 // Inner is still blocked so when Outer replays the event in capture phase
1222 // inner ends up caling stopPropagation
1223 assertLog([]);
1220 - expect(OuterScheduler).toHaveYielded([]);
1221 - expect(InnerScheduler).toHaveYielded(['Suspend Inner']);
1224 + expect(OuterScheduler.unstable_clearYields()).toEqual([]);
1225 + expect(InnerScheduler.unstable_clearYields()).toEqual(['Suspend Inner']);
1226
1227 dispatchMouseHoverEvent(innerDiv);
1224 - expect(OuterScheduler).toHaveYielded([]);
1225 - expect(InnerScheduler).toHaveYielded([]);
1228 + expect(OuterScheduler.unstable_clearYields()).toEqual([]);
1229 + expect(InnerScheduler.unstable_clearYields()).toEqual([]);
1230 assertLog([]);
1231
1232 await act(async () => {
@@ -1234,9 +1238,9 @@ describe('ReactDOMServerSelectiveHydration', () => {
1238 });
1239
1240 // Inner hydrates
1237 - expect(InnerScheduler).toHaveYielded(['Inner']);
1241 + expect(InnerScheduler.unstable_clearYields()).toEqual(['Inner']);
1242 // Outer was hydrated earlier
1239 - expect(OuterScheduler).toHaveYielded([]);
1243 + expect(OuterScheduler.unstable_clearYields()).toEqual([]);
1244
1245 await act(async () => {
1246 Scheduler.unstable_flushAllWithoutAsserting();
packages/react-dom/src/__tests__/ReactDeprecationWarnings-test.js
+10 -12
@@ -11,7 +11,6 @@
11
12 let React;
13 let ReactNoop;
14 -let Scheduler;
14 let JSXDEVRuntime;
15 let waitForAll;
16
@@ -20,7 +19,6 @@ describe('ReactDeprecationWarnings', () => {
19 jest.resetModules();
20 React = require('react');
21 ReactNoop = require('react-noop-renderer');
23 - Scheduler = require('scheduler');
22 const InternalTestUtils = require('internal-test-utils');
23 waitForAll = InternalTestUtils.waitForAll;
24 if (__DEV__) {
@@ -28,7 +26,7 @@ describe('ReactDeprecationWarnings', () => {
26 }
27 });
28
31 - it('should warn when given defaultProps', () => {
29 + it('should warn when given defaultProps', async () => {
30 function FunctionalComponent(props) {
31 return null;
32 }
@@ -38,14 +36,14 @@ describe('ReactDeprecationWarnings', () => {
36 };
37
38 ReactNoop.render(<FunctionalComponent />);
41 - expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
39 + await expect(async () => await waitForAll([])).toErrorDev(
40 'Warning: FunctionalComponent: Support for defaultProps ' +
41 'will be removed from function components in a future major ' +
42 'release. Use JavaScript default parameters instead.',
43 );
44 });
45
48 - it('should warn when given defaultProps on a memoized function', () => {
46 + it('should warn when given defaultProps on a memoized function', async () => {
47 const MemoComponent = React.memo(function FunctionalComponent(props) {
48 return null;
49 });
@@ -59,14 +57,14 @@ describe('ReactDeprecationWarnings', () => {
57 <MemoComponent />
58 </div>,
59 );
62 - expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
60 + await expect(async () => await waitForAll([])).toErrorDev(
61 'Warning: FunctionalComponent: Support for defaultProps ' +
62 'will be removed from memo components in a future major ' +
63 'release. Use JavaScript default parameters instead.',
64 );
65 });
66
69 - it('should warn when given string refs', () => {
67 + it('should warn when given string refs', async () => {
68 class RefComponent extends React.Component {
69 render() {
70 return null;
@@ -79,7 +77,7 @@ describe('ReactDeprecationWarnings', () => {
77 }
78
79 ReactNoop.render(<Component />);
82 - expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
80 + await expect(async () => await waitForAll([])).toErrorDev(
81 'Warning: Component "Component" contains the string ref "refComponent". ' +
82 'Support for string refs will be removed in a future major release. ' +
83 'We recommend using useRef() or createRef() instead. ' +
@@ -108,7 +106,7 @@ describe('ReactDeprecationWarnings', () => {
106 await waitForAll([]);
107 });
108
111 - it('should warn when owner and self are different for string refs', () => {
109 + it('should warn when owner and self are different for string refs', async () => {
110 class RefComponent extends React.Component {
111 render() {
112 return null;
@@ -121,7 +119,7 @@ describe('ReactDeprecationWarnings', () => {
119 }
120
121 ReactNoop.render(<Component />);
124 - expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev([
122 + await expect(async () => await waitForAll([])).toErrorDev([
123 'Warning: Component "Component" contains the string ref "refComponent". ' +
124 'Support for string refs will be removed in a future major release. ' +
125 'This case cannot be automatically converted to an arrow function. ' +
@@ -132,7 +130,7 @@ describe('ReactDeprecationWarnings', () => {
130 });
131
132 if (__DEV__) {
135 - it('should warn when owner and self are different for string refs', () => {
133 + it('should warn when owner and self are different for string refs', async () => {
134 class RefComponent extends React.Component {
135 render() {
136 return null;
@@ -152,7 +150,7 @@ describe('ReactDeprecationWarnings', () => {
150 }
151
152 ReactNoop.render(<Component />);
155 - expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
153 + await expect(async () => await waitForAll([])).toErrorDev(
154 'Warning: Component "Component" contains the string ref "refComponent". ' +
155 'Support for string refs will be removed in a future major release. ' +
156 'This case cannot be automatically converted to an arrow function. ' +
packages/react-reconciler/src/__tests__/ReactDisableSchedulerTimeoutBasedOnReactExpirationTime-test.internal.js
+4 -2
@@ -6,6 +6,7 @@ let Suspense;
6 let scheduleCallback;
7 let NormalPriority;
8 let waitForAll;
9 +let waitFor;
10
11 describe('ReactSuspenseList', () => {
12 beforeEach(() => {
@@ -24,6 +25,7 @@ describe('ReactSuspenseList', () => {
25
26 const InternalTestUtils = require('internal-test-utils');
27 waitForAll = InternalTestUtils.waitForAll;
28 + waitFor = InternalTestUtils.waitFor;
29 });
30
31 function Text(props) {
@@ -86,11 +88,11 @@ describe('ReactSuspenseList', () => {
88 });
89
90 // This resolves A and schedules a task for React to retry.
89 - await expect(Scheduler).toFlushAndYieldThrough(['Resolve A']);
91 + await waitFor(['Resolve A']);
92
93 // The next task that flushes should be the one that resolves B. The render
94 // task should not jump the queue ahead of B.
93 - await expect(Scheduler).toFlushAndYieldThrough(['Resolve B']);
95 + await waitFor(['Resolve B']);
96
97 await waitForAll(['A', 'B']);
98 expect(root).toMatchRenderedOutput('AB');
packages/react-reconciler/src/__tests__/ReactFragment-test.js
+3 -5
@@ -11,7 +11,6 @@
11
12 let React;
13 let ReactNoop;
14 -let Scheduler;
14 let waitForAll;
15
16 describe('ReactFragment', () => {
@@ -20,7 +19,6 @@ describe('ReactFragment', () => {
19
20 React = require('react');
21 ReactNoop = require('react-noop-renderer');
23 - Scheduler = require('scheduler');
22
23 const InternalTestUtils = require('internal-test-utils');
24 waitForAll = InternalTestUtils.waitForAll;
@@ -707,7 +705,7 @@ describe('ReactFragment', () => {
705 );
706 });
707
710 - it('should not preserve state when switching to a keyed fragment to an array', async function () {
708 + it('should not preserve state when switching to a keyed fragment to an array', async () => {
709 const ops = [];
710
711 class Stateful extends React.Component {
@@ -742,7 +740,7 @@ describe('ReactFragment', () => {
740 await waitForAll([]);
741
742 ReactNoop.render(<Foo condition={false} />);
745 - expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
743 + await expect(async () => await waitForAll([])).toErrorDev(
744 'Each child in a list should have a unique "key" prop.',
745 );
746
@@ -939,7 +937,7 @@ describe('ReactFragment', () => {
937 }
938
939 ReactNoop.render(<Foo condition={true} />);
942 - expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
940 + await expect(async () => await waitForAll([])).toErrorDev(
941 'Each child in a list should have a unique "key" prop.',
942 );
943
packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js
+44 -46
@@ -209,7 +209,7 @@ describe('ReactHooksWithNoopRenderer', () => {
209 }
210 ReactNoop.render(<BadCounter />);
211
212 - expect(Scheduler).toFlushAndThrow(
212 + await waitForThrow(
213 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' +
214 ' one of the following reasons:\n' +
215 '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +
@@ -227,19 +227,20 @@ describe('ReactHooksWithNoopRenderer', () => {
227 await waitForAll([10]);
228 });
229
230 - if (!require('shared/ReactFeatureFlags').disableModulePatternComponents) {
231 - it('throws inside module-style components', async () => {
232 - function Counter() {
233 - return {
234 - render() {
235 - const [count] = useState(0);
236 - return <Text text={this.props.label + ': ' + count} />;
237 - },
238 - };
239 - }
240 - ReactNoop.render(<Counter />);
241 - expect(() =>
242 - expect(Scheduler).toFlushAndThrow(
230 + // @gate !disableModulePatternComponents
231 + it('throws inside module-style components', async () => {
232 + function Counter() {
233 + return {
234 + render() {
235 + const [count] = useState(0);
236 + return <Text text={this.props.label + ': ' + count} />;
237 + },
238 + };
239 + }
240 + ReactNoop.render(<Counter />);
241 + await expect(
242 + async () =>
243 + await waitForThrow(
244 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen ' +
245 'for one of the following reasons:\n' +
246 '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +
@@ -247,23 +248,22 @@ describe('ReactHooksWithNoopRenderer', () => {
248 '3. You might have more than one copy of React in the same app\n' +
249 'See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.',
250 ),
250 - ).toErrorDev(
251 - 'Warning: The <Counter /> component appears to be a function component that returns a class instance. ' +
252 - 'Change Counter to a class that extends React.Component instead. ' +
253 - "If you can't use a class try assigning the prototype on the function as a workaround. " +
254 - '`Counter.prototype = React.Component.prototype`. ' +
255 - "Don't use an arrow function since it cannot be called with `new` by React.",
256 - );
251 + ).toErrorDev(
252 + 'Warning: The <Counter /> component appears to be a function component that returns a class instance. ' +
253 + 'Change Counter to a class that extends React.Component instead. ' +
254 + "If you can't use a class try assigning the prototype on the function as a workaround. " +
255 + '`Counter.prototype = React.Component.prototype`. ' +
256 + "Don't use an arrow function since it cannot be called with `new` by React.",
257 + );
258
258 - // Confirm that a subsequent hook works properly.
259 - function GoodCounter(props) {
260 - const [count] = useState(props.initialCount);
261 - return <Text text={count} />;
262 - }
263 - ReactNoop.render(<GoodCounter initialCount={10} />);
264 - await waitForAll([10]);
265 - });
266 - }
259 + // Confirm that a subsequent hook works properly.
260 + function GoodCounter(props) {
261 + const [count] = useState(props.initialCount);
262 + return <Text text={count} />;
263 + }
264 + ReactNoop.render(<GoodCounter initialCount={10} />);
265 + await waitForAll([10]);
266 + });
267
268 it('throws when called outside the render phase', async () => {
269 expect(() => {
@@ -487,20 +487,18 @@ describe('ReactHooksWithNoopRenderer', () => {
487 assertLog(['Foo [0]', 'Bar']);
488
489 // Bar will update Foo during its render phase. React should warn.
490 - await act(async () => {
491 - root.render(
492 - <>
493 - <Foo />
494 - <Bar triggerUpdate={true} />
495 - </>,
496 - );
497 - expect(() =>
498 - expect(Scheduler).toFlushAndYield(['Foo [0]', 'Bar', 'Foo [1]']),
499 - ).toErrorDev([
500 - 'Cannot update a component (`Foo`) while rendering a ' +
501 - 'different component (`Bar`). To locate the bad setState() call inside `Bar`',
502 - ]);
503 - });
490 + root.render(
491 + <>
492 + <Foo />
493 + <Bar triggerUpdate={true} />
494 + </>,
495 + );
496 + await expect(
497 + async () => await waitForAll(['Foo [0]', 'Bar', 'Foo [1]']),
498 + ).toErrorDev([
499 + 'Cannot update a component (`Foo`) while rendering a ' +
500 + 'different component (`Bar`). To locate the bad setState() call inside `Bar`',
501 + ]);
502
503 // It should not warn again (deduplication).
504 await act(async () => {
@@ -562,7 +560,7 @@ describe('ReactHooksWithNoopRenderer', () => {
560 return <Text text={count} />;
561 }
562 ReactNoop.render(<Counter />);
565 - expect(Scheduler).toFlushAndThrow(
563 + await waitForThrow(
564 'Too many re-renders. React limits the number of renders to prevent ' +
565 'an infinite loop.',
566 );
@@ -3805,7 +3803,7 @@ describe('ReactHooksWithNoopRenderer', () => {
3803 assertLog(['A: 2, B: 3, C: 4']);
3804 expect(ReactNoop).toMatchRenderedOutput(<span prop="A: 2, B: 3, C: 4" />);
3805 ReactNoop.render(<App loadC={false} />);
3808 - expect(Scheduler).toFlushAndThrow(
3806 + await waitForThrow(
3807 'Rendered fewer hooks than expected. This may be caused by an ' +
3808 'accidental early return statement.',
3809 );
packages/react-reconciler/src/__tests__/ReactIncremental-test.js
+10 -9
@@ -1896,7 +1896,7 @@ describe('ReactIncremental', () => {
1896 });
1897
1898 if (!require('shared/ReactFeatureFlags').disableModulePatternComponents) {
1899 - it('does not leak own context into context provider (factory components)', () => {
1899 + it('does not leak own context into context provider (factory components)', async () => {
1900 function Recurse(props, context) {
1901 return {
1902 getChildContext() {
@@ -1919,13 +1919,14 @@ describe('ReactIncremental', () => {
1919 };
1920
1921 ReactNoop.render(<Recurse />);
1922 - expect(() =>
1923 - expect(Scheduler).toFlushAndYield([
1924 - 'Recurse {}',
1925 - 'Recurse {"n":2}',
1926 - 'Recurse {"n":1}',
1927 - 'Recurse {"n":0}',
1928 - ]),
1922 + await expect(
1923 + async () =>
1924 + await waitForAll([
1925 + 'Recurse {}',
1926 + 'Recurse {"n":2}',
1927 + 'Recurse {"n":1}',
1928 + 'Recurse {"n":0}',
1929 + ]),
1930 ).toErrorDev([
1931 'Warning: The <Recurse /> component appears to be a function component that returns a class instance. ' +
1932 'Change Recurse to a class that extends React.Component instead. ' +
@@ -2281,7 +2282,7 @@ describe('ReactIncremental', () => {
2282 instance.setState({
2283 throwError: true,
2284 });
2284 - expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
2285 + await expect(async () => await waitForAll([])).toErrorDev(
2286 'Error boundaries should implement getDerivedStateFromError()',
2287 );
2288 });
packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js
+39 -40
@@ -1219,7 +1219,7 @@ describe('ReactIncrementalErrorHandling', () => {
1219 expect(ReactNoop).toMatchRenderedOutput(<span prop="a" />);
1220 });
1221
1222 - it('catches reconciler errors in a boundary during mounting', () => {
1222 + it('catches reconciler errors in a boundary during mounting', async () => {
1223 class ErrorBoundary extends React.Component {
1224 state = {error: null};
1225 componentDidCatch(error) {
@@ -1242,7 +1242,7 @@ describe('ReactIncrementalErrorHandling', () => {
1242 <BrokenRender />
1243 </ErrorBoundary>,
1244 );
1245 - expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev([
1245 + await expect(async () => await waitForAll([])).toErrorDev([
1246 'Warning: React.createElement: type is invalid -- expected a string',
1247 // React retries once on error
1248 'Warning: React.createElement: type is invalid -- expected a string',
@@ -1293,7 +1293,7 @@ describe('ReactIncrementalErrorHandling', () => {
1293 <BrokenRender fail={true} />
1294 </ErrorBoundary>,
1295 );
1296 - expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev([
1296 + await expect(async () => await waitForAll([])).toErrorDev([
1297 'Warning: React.createElement: type is invalid -- expected a string',
1298 // React retries once on error
1299 'Warning: React.createElement: type is invalid -- expected a string',
@@ -1319,7 +1319,7 @@ describe('ReactIncrementalErrorHandling', () => {
1319 'Warning: React.createElement: type is invalid -- expected a string',
1320 {withoutStack: true},
1321 );
1322 - expect(Scheduler).toFlushAndThrow(
1322 + await waitForThrow(
1323 'Element type is invalid: expected a string (for built-in components) or ' +
1324 'a class/function (for composite components) but got: undefined.' +
1325 (__DEV__
@@ -1425,7 +1425,7 @@ describe('ReactIncrementalErrorHandling', () => {
1425
1426 // Unmount
1427 ReactNoop.render(<Foo hide={true} />);
1428 - expect(Scheduler).toFlushAndThrow('Detach error');
1428 + await waitForThrow('Detach error');
1429 assertLog([
1430 'barRef detach',
1431 // Bar should unmount even though its ref threw an error while detaching
@@ -1435,16 +1435,16 @@ describe('ReactIncrementalErrorHandling', () => {
1435 expect(ReactNoop).toMatchRenderedOutput(null);
1436 });
1437
1438 - it('handles error thrown by host config while working on failed root', () => {
1438 + it('handles error thrown by host config while working on failed root', async () => {
1439 ReactNoop.render(<errorInBeginPhase />);
1440 - expect(Scheduler).toFlushAndThrow('Error in host config.');
1440 + await waitForThrow('Error in host config.');
1441 });
1442
1443 - it('handles error thrown by top-level callback', () => {
1443 + it('handles error thrown by top-level callback', async () => {
1444 ReactNoop.render(<div />, () => {
1445 throw new Error('Error!');
1446 });
1447 - expect(Scheduler).toFlushAndThrow('Error!');
1447 + await waitForThrow('Error!');
1448 });
1449
1450 it('error boundaries capture non-errors', async () => {
@@ -1758,37 +1758,36 @@ describe('ReactIncrementalErrorHandling', () => {
1758 );
1759 });
1760
1761 - if (!ReactFeatureFlags.disableModulePatternComponents) {
1762 - it('handles error thrown inside getDerivedStateFromProps of a module-style context provider', () => {
1763 - function Provider() {
1764 - return {
1765 - getChildContext() {
1766 - return {foo: 'bar'};
1767 - },
1768 - render() {
1769 - return 'Hi';
1770 - },
1771 - };
1772 - }
1773 - Provider.childContextTypes = {
1774 - x: () => {},
1775 - };
1776 - Provider.getDerivedStateFromProps = () => {
1777 - throw new Error('Oops!');
1761 + // @gate !disableModulePatternComponents
1762 + it('handles error thrown inside getDerivedStateFromProps of a module-style context provider', async () => {
1763 + function Provider() {
1764 + return {
1765 + getChildContext() {
1766 + return {foo: 'bar'};
1767 + },
1768 + render() {
1769 + return 'Hi';
1770 + },
1771 };
1772 + }
1773 + Provider.childContextTypes = {
1774 + x: () => {},
1775 + };
1776 + Provider.getDerivedStateFromProps = () => {
1777 + throw new Error('Oops!');
1778 + };
1779
1780 - ReactNoop.render(<Provider />);
1781 - expect(() => {
1782 - expect(Scheduler).toFlushAndThrow('Oops!');
1783 - }).toErrorDev([
1784 - 'Warning: The <Provider /> component appears to be a function component that returns a class instance. ' +
1785 - 'Change Provider to a class that extends React.Component instead. ' +
1786 - "If you can't use a class try assigning the prototype on the function as a workaround. " +
1787 - '`Provider.prototype = React.Component.prototype`. ' +
1788 - "Don't use an arrow function since it cannot be called with `new` by React.",
1789 - ]);
1790 - });
1791 - }
1780 + ReactNoop.render(<Provider />);
1781 + await expect(async () => {
1782 + await waitForThrow('Oops!');
1783 + }).toErrorDev([
1784 + 'Warning: The <Provider /> component appears to be a function component that returns a class instance. ' +
1785 + 'Change Provider to a class that extends React.Component instead. ' +
1786 + "If you can't use a class try assigning the prototype on the function as a workaround. " +
1787 + '`Provider.prototype = React.Component.prototype`. ' +
1788 + "Don't use an arrow function since it cannot be called with `new` by React.",
1789 + ]);
1790 + });
1791
1792 it('uncaught errors should be discarded if the render is aborted', async () => {
1793 const root = ReactNoop.createRoot();
@@ -1924,10 +1923,10 @@ describe('ReactIncrementalErrorHandling', () => {
1923 });
1924
1925 if (global.__PERSISTENT__) {
1927 - it('regression test: should fatal if error is thrown at the root', () => {
1926 + it('regression test: should fatal if error is thrown at the root', async () => {
1927 const root = ReactNoop.createRoot();
1928 root.render('Error when completing root');
1930 - expect(Scheduler).toFlushAndThrow('Error when completing root');
1929 + await waitForThrow('Error when completing root');
1930 });
1931 }
1932 });
packages/react-reconciler/src/__tests__/ReactIncrementalErrorLogging-test.js
+8 -6
@@ -14,6 +14,7 @@ let React;
14 let ReactNoop;
15 let Scheduler;
16 let waitForAll;
17 +let waitForThrow;
18
19 describe('ReactIncrementalErrorLogging', () => {
20 beforeEach(() => {
@@ -24,6 +25,7 @@ describe('ReactIncrementalErrorLogging', () => {
25
26 const InternalTestUtils = require('internal-test-utils');
27 waitForAll = InternalTestUtils.waitForAll;
28 + waitForThrow = InternalTestUtils.waitForThrow;
29 });
30
31 // Note: in this test file we won't be using toErrorDev() matchers
@@ -39,7 +41,7 @@ describe('ReactIncrementalErrorLogging', () => {
41 oldConsoleError = null;
42 });
43
42 - it('should log errors that occur during the begin phase', () => {
44 + it('should log errors that occur during the begin phase', async () => {
45 class ErrorThrowingComponent extends React.Component {
46 constructor(props) {
47 super(props);
@@ -56,7 +58,7 @@ describe('ReactIncrementalErrorLogging', () => {
58 </span>
59 </div>,
60 );
59 - expect(Scheduler).toFlushAndThrow('constructor error');
61 + await waitForThrow('constructor error');
62 expect(console.error).toHaveBeenCalledTimes(1);
63 expect(console.error).toHaveBeenCalledWith(
64 __DEV__
@@ -76,7 +78,7 @@ describe('ReactIncrementalErrorLogging', () => {
78 );
79 });
80
79 - it('should log errors that occur during the commit phase', () => {
81 + it('should log errors that occur during the commit phase', async () => {
82 class ErrorThrowingComponent extends React.Component {
83 componentDidMount() {
84 throw new Error('componentDidMount error');
@@ -92,7 +94,7 @@ describe('ReactIncrementalErrorLogging', () => {
94 </span>
95 </div>,
96 );
95 - expect(Scheduler).toFlushAndThrow('componentDidMount error');
97 + await waitForThrow('componentDidMount error');
98 expect(console.error).toHaveBeenCalledTimes(1);
99 expect(console.error).toHaveBeenCalledWith(
100 __DEV__
@@ -112,7 +114,7 @@ describe('ReactIncrementalErrorLogging', () => {
114 );
115 });
116
115 - it('should ignore errors thrown in log method to prevent cycle', () => {
117 + it('should ignore errors thrown in log method to prevent cycle', async () => {
118 const logCapturedErrorCalls = [];
119 console.error.mockImplementation(error => {
120 // Test what happens when logging itself is buggy.
@@ -131,7 +133,7 @@ describe('ReactIncrementalErrorLogging', () => {
133 </span>
134 </div>,
135 );
134 - expect(Scheduler).toFlushAndThrow('render error');
136 + await waitForThrow('render error');
137 expect(logCapturedErrorCalls.length).toBe(1);
138 expect(logCapturedErrorCalls[0]).toEqual(
139 __DEV__
packages/react-reconciler/src/__tests__/ReactIncrementalErrorReplay-test.js
+4 -4
@@ -12,23 +12,23 @@
12
13 let React;
14 let ReactNoop;
15 -let Scheduler;
15 let waitForAll;
16 +let waitForThrow;
17
18 describe('ReactIncrementalErrorReplay', () => {
19 beforeEach(() => {
20 jest.resetModules();
21 React = require('react');
22 ReactNoop = require('react-noop-renderer');
23 - Scheduler = require('scheduler');
23
24 const InternalTestUtils = require('internal-test-utils');
25 waitForAll = InternalTestUtils.waitForAll;
26 + waitForThrow = InternalTestUtils.waitForThrow;
27 });
28
29 - it('should fail gracefully on error in the host environment', () => {
29 + it('should fail gracefully on error in the host environment', async () => {
30 ReactNoop.render(<errorInBeginPhase />);
31 - expect(Scheduler).toFlushAndThrow('Error in host config.');
31 + await waitForThrow('Error in host config.');
32 });
33
34 it("should ignore error if it doesn't throw on retry", async () => {
packages/react-reconciler/src/__tests__/ReactIncrementalSideEffects-test.js
+1 -1
@@ -1296,7 +1296,7 @@ describe('ReactIncrementalSideEffects', () => {
1296 }
1297
1298 ReactNoop.render(<Foo show={true} />);
1299 - expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
1299 + await expect(async () => await waitForAll([])).toErrorDev(
1300 'Warning: Function components cannot be given refs. ' +
1301 'Attempts to access this ref will fail. ' +
1302 'Did you mean to use React.forwardRef()?\n\n' +
packages/react-reconciler/src/__tests__/ReactIncrementalUpdates-test.js
+21 -20
@@ -421,27 +421,28 @@ describe('ReactIncrementalUpdates', () => {
421 return {a: 'a'};
422 });
423
424 - expect(() =>
425 - expect(Scheduler).toFlushAndYield(
426 - gate(flags =>
427 - flags.deferRenderPhaseUpdateToNextBatch
428 - ? [
429 - 'setState updater',
430 - // In the new reconciler, updates inside the render phase are
431 - // treated as if they came from an event, so the update gets
432 - // shifted to a subsequent render.
433 - 'render',
434 - 'render',
435 - ]
436 - : [
437 - 'setState updater',
438 - // In the old reconciler, updates in the render phase receive
439 - // the currently rendering expiration time, so the update
440 - // flushes immediately in the same render.
441 - 'render',
442 - ],
424 + await expect(
425 + async () =>
426 + await waitForAll(
427 + gate(flags =>
428 + flags.deferRenderPhaseUpdateToNextBatch
429 + ? [
430 + 'setState updater',
431 + // In the new reconciler, updates inside the render phase are
432 + // treated as if they came from an event, so the update gets
433 + // shifted to a subsequent render.
434 + 'render',
435 + 'render',
436 + ]
437 + : [
438 + 'setState updater',
439 + // In the old reconciler, updates in the render phase receive
440 + // the currently rendering expiration time, so the update
441 + // flushes immediately in the same render.
442 + 'render',
443 + ],
444 + ),
445 ),
444 - ),
446 ).toErrorDev(
447 'An update (setState, replaceState, or forceUpdate) was scheduled ' +
448 'from inside an update function. Update functions should be pure, ' +
packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js
+6 -6
@@ -314,7 +314,7 @@ describe('ReactLazy', () => {
314
315 await resolveFakeImport(T);
316
317 - expect(() => expect(Scheduler).toFlushAndYield(['Hi'])).toErrorDev(
317 + await expect(async () => await waitForAll(['Hi'])).toErrorDev(
318 'Warning: T: Support for defaultProps ' +
319 'will be removed from function components in a future major ' +
320 'release. Use JavaScript default parameters instead.',
@@ -369,8 +369,8 @@ describe('ReactLazy', () => {
369
370 await resolveFakeImport(LazyImpl);
371
372 - expect(() =>
373 - expect(Scheduler).toFlushAndYield(['Lazy', 'Sibling', 'A']),
372 + await expect(
373 + async () => await waitForAll(['Lazy', 'Sibling', 'A']),
374 ).toErrorDev(
375 'Warning: LazyImpl: Support for defaultProps ' +
376 'will be removed from function components in a future major ' +
@@ -676,7 +676,7 @@ describe('ReactLazy', () => {
676 expect(root).not.toMatchRenderedOutput('Hi Bye');
677
678 await resolveFakeImport(T);
679 - expect(() => expect(Scheduler).toFlushAndYield(['Hi Bye'])).toErrorDev(
679 + await expect(async () => await waitForAll(['Hi Bye'])).toErrorDev(
680 'Warning: T: Support for defaultProps ' +
681 'will be removed from function components in a future major ' +
682 'release. Use JavaScript default parameters instead.',
@@ -721,7 +721,7 @@ describe('ReactLazy', () => {
721 <BadLazy />
722 </Suspense>,
723 );
724 - expect(Scheduler).toFlushAndThrow(
724 + await waitForThrow(
725 'Element type is invalid. Received a promise that resolves to: 42. ' +
726 'Lazy element type must resolve to a class or function.',
727 );
@@ -749,7 +749,7 @@ describe('ReactLazy', () => {
749 <Lazy2 text="Hello" />
750 </Suspense>,
751 );
752 - expect(Scheduler).toFlushAndThrow(
752 + await waitForThrow(
753 'Element type is invalid. Received a promise that resolves to: [object Object]. ' +
754 'Lazy element type must resolve to a class or function.' +
755 (__DEV__
packages/react-reconciler/src/__tests__/ReactMemo-test.js
+2 -2
@@ -58,7 +58,7 @@ describe('memo', () => {
58 return <App ref={() => {}} />;
59 }
60 ReactNoop.render(<Outer />);
61 - expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev([
61 + await expect(async () => await waitForAll([])).toErrorDev([
62 'Warning: Function components cannot be given refs. Attempts to access ' +
63 'this ref will fail.',
64 ]);
@@ -76,7 +76,7 @@ describe('memo', () => {
76 return <App ref={() => {}} />;
77 }
78 ReactNoop.render(<Outer />);
79 - expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev([
79 + await expect(async () => await waitForAll([])).toErrorDev([
80 'App: Support for defaultProps will be removed from function components in a future major release. Use JavaScript default parameters instead.',
81 'Warning: Function components cannot be given refs. Attempts to access ' +
82 'this ref will fail.',
packages/react-reconciler/src/__tests__/ReactNewContext-test.js
+15 -13
@@ -16,6 +16,7 @@ let Scheduler;
16 let gen;
17 let waitForAll;
18 let waitFor;
19 +let waitForThrow;
20
21 describe('ReactNewContext', () => {
22 beforeEach(() => {
@@ -30,6 +31,7 @@ describe('ReactNewContext', () => {
31 const InternalTestUtils = require('internal-test-utils');
32 waitForAll = InternalTestUtils.waitForAll;
33 waitFor = InternalTestUtils.waitFor;
34 + waitForThrow = InternalTestUtils.waitForThrow;
35 });
36
37 afterEach(() => {
@@ -850,14 +852,14 @@ describe('ReactNewContext', () => {
852 }
853
854 describe('Context.Provider', () => {
853 - it('warns if no value prop provided', () => {
855 + it('warns if no value prop provided', async () => {
856 const Context = React.createContext();
857
858 ReactNoop.render(
859 <Context.Provider anyPropNameOtherThanValue="value could be anything" />,
860 );
861
860 - expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
862 + await expect(async () => await waitForAll([])).toErrorDev(
863 'The `value` prop is required for the `<Context.Provider>`. Did you misspell it or forget to pass it?',
864 {
865 withoutStack: true,
@@ -1050,11 +1052,11 @@ describe('ReactNewContext', () => {
1052 });
1053
1054 describe('Context.Consumer', () => {
1053 - it('warns if child is not a function', () => {
1055 + it('warns if child is not a function', async () => {
1056 spyOnDev(console, 'error').mockImplementation(() => {});
1057 const Context = React.createContext(0);
1058 ReactNoop.render(<Context.Consumer />);
1057 - expect(Scheduler).toFlushAndThrow('is not a function');
1059 + await waitForThrow('is not a function');
1060 if (__DEV__) {
1061 expect(console.error.mock.calls[0][0]).toContain(
1062 'A context consumer was rendered with multiple children, or a child ' +
@@ -1298,7 +1300,7 @@ describe('ReactNewContext', () => {
1300 expect(ReactNoop).toMatchRenderedOutput(<span prop="goodbye" />);
1301 });
1302
1301 - it('warns when reading context inside render phase class setState updater', () => {
1303 + it('warns when reading context inside render phase class setState updater', async () => {
1304 const ThemeContext = React.createContext('light');
1305
1306 class Cls extends React.Component {
@@ -1312,7 +1314,7 @@ describe('ReactNewContext', () => {
1314 }
1315
1316 ReactNoop.render(<Cls />);
1315 - expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev([
1317 + await expect(async () => await waitForAll([])).toErrorDev([
1318 'Context can only be read while React is rendering',
1319 'Cannot update during an existing state transition',
1320 ]);
@@ -1320,7 +1322,7 @@ describe('ReactNewContext', () => {
1322 });
1323
1324 describe('useContext', () => {
1323 - it('throws when used in a class component', () => {
1325 + it('throws when used in a class component', async () => {
1326 const Context = React.createContext(0);
1327 class Foo extends React.Component {
1328 render() {
@@ -1328,7 +1330,7 @@ describe('ReactNewContext', () => {
1330 }
1331 }
1332 ReactNoop.render(<Foo />);
1331 - expect(Scheduler).toFlushAndThrow(
1333 + await waitForThrow(
1334 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen' +
1335 ' for one of the following reasons:\n' +
1336 '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +
@@ -1338,27 +1340,27 @@ describe('ReactNewContext', () => {
1340 );
1341 });
1342
1341 - it('warns when passed a consumer', () => {
1343 + it('warns when passed a consumer', async () => {
1344 const Context = React.createContext(0);
1345 function Foo() {
1346 return useContext(Context.Consumer);
1347 }
1348 ReactNoop.render(<Foo />);
1347 - expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
1349 + await expect(async () => await waitForAll([])).toErrorDev(
1350 'Calling useContext(Context.Consumer) is not supported, may cause bugs, ' +
1351 'and will be removed in a future major release. ' +
1352 'Did you mean to call useContext(Context) instead?',
1353 );
1354 });
1355
1354 - it('warns when passed a provider', () => {
1356 + it('warns when passed a provider', async () => {
1357 const Context = React.createContext(0);
1358 function Foo() {
1359 useContext(Context.Provider);
1360 return null;
1361 }
1362 ReactNoop.render(<Foo />);
1361 - expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
1363 + await expect(async () => await waitForAll([])).toErrorDev(
1364 'Calling useContext(Context.Provider) is not supported. ' +
1365 'Did you mean to call useContext(Context) instead?',
1366 );
@@ -1420,7 +1422,7 @@ describe('ReactNewContext', () => {
1422 <Context.Provider value={null} />
1423 </errorInCompletePhase>,
1424 );
1423 - expect(Scheduler).toFlushAndThrow('Error in host config.');
1425 + await waitForThrow('Error in host config.');
1426
1427 ReactNoop.render(
1428 <Context.Provider value={10}>
packages/react-reconciler/src/__tests__/ReactTransitionTracing-test.js
+7 -6
@@ -1395,12 +1395,13 @@ describe('ReactInteractionTracing', () => {
1395 root.render(<App navigate={true} markerName="marker two" />);
1396 ReactNoop.expire(1000);
1397 await advanceTimers(1000);
1398 - expect(() =>
1399 - expect(Scheduler).toFlushAndYield([
1400 - 'Suspend [Page Two]',
1401 - 'Loading...',
1402 - 'onMarkerIncomplete(transition one, marker one, 1000, [{endTime: 3000, name: marker one, newName: marker two, type: marker}])',
1403 - ]),
1398 + await expect(
1399 + async () =>
1400 + await waitForAll([
1401 + 'Suspend [Page Two]',
1402 + 'Loading...',
1403 + 'onMarkerIncomplete(transition one, marker one, 1000, [{endTime: 3000, name: marker one, newName: marker two, type: marker}])',
1404 + ]),
1405 ).toErrorDev('');
1406
1407 resolveText('Page Two');
packages/react-reconciler/src/__tests__/useEffectEvent-test.js
+4 -2
@@ -28,6 +28,7 @@ describe('useEffectEvent', () => {
28 let useMemo;
29 let waitForAll;
30 let assertLog;
31 + let waitForThrow;
32
33 beforeEach(() => {
34 React = require('react');
@@ -46,6 +47,7 @@ describe('useEffectEvent', () => {
47 const InternalTestUtils = require('internal-test-utils');
48 waitForAll = InternalTestUtils.waitForAll;
49 assertLog = InternalTestUtils.assertLog;
50 + waitForThrow = InternalTestUtils.waitForThrow;
51 });
52
53 function Text(props) {
@@ -242,7 +244,7 @@ describe('useEffectEvent', () => {
244 });
245
246 // @gate enableUseEffectEventHook
245 - it('throws when called in render', () => {
247 + it('throws when called in render', async () => {
248 class IncrementButton extends React.PureComponent {
249 increment = () => {
250 this.props.onClick();
@@ -269,7 +271,7 @@ describe('useEffectEvent', () => {
271 }
272
273 ReactNoop.render(<Counter incrementBy={1} />);
272 - expect(Scheduler).toFlushAndThrow(
274 + await waitForThrow(
275 "A function wrapped in useEffectEvent can't be called during rendering.",
276 );
277
packages/react-reconciler/src/__tests__/useMutableSource-test.internal.js
+8 -10
@@ -1518,16 +1518,14 @@ describe('useMutableSource', () => {
1518 }
1519
1520 const root = ReactNoop.createRoot();
1521 - await act(async () => {
1522 - root.render(
1523 - <>
1524 - <Read />
1525 - </>,
1526 - );
1527 - expect(() => expect(Scheduler).toFlushAndYield(['a'])).toErrorDev(
1528 - 'Mutable source should not return a function as the snapshot value.',
1529 - );
1530 - });
1521 + root.render(
1522 + <>
1523 + <Read />
1524 + </>,
1525 + );
1526 + await expect(async () => await waitForAll(['a'])).toErrorDev(
1527 + 'Mutable source should not return a function as the snapshot value.',
1528 + );
1529 expect(root).toMatchRenderedOutput('a');
1530 });
1531
packages/react/src/__tests__/ReactProfiler-test.internal.js
+4 -2
@@ -20,6 +20,7 @@ let AdvanceTime;
20 let assertLog;
21 let waitFor;
22 let waitForAll;
23 +let waitForThrow;
24
25 function loadModules({
26 enableProfilerTimer = true,
@@ -56,6 +57,7 @@ function loadModules({
57 assertLog = InternalTestUtils.assertLog;
58 waitFor = InternalTestUtils.waitFor;
59 waitForAll = InternalTestUtils.waitForAll;
60 + waitForThrow = InternalTestUtils.waitForThrow;
61
62 AdvanceTime = class extends React.Component {
63 static defaultProps = {
@@ -1230,7 +1232,7 @@ describe(`onRender`, () => {
1232 <errorInCompletePhase>hi</errorInCompletePhase>
1233 </React.Profiler>,
1234 );
1233 - expect(Scheduler).toFlushAndThrow('Error in host config.');
1235 + await waitForThrow('Error in host config.');
1236
1237 // A similar case we've seen caused by an invariant in ReactDOM.
1238 // It didn't reproduce without a host component inside.
@@ -1241,7 +1243,7 @@ describe(`onRender`, () => {
1243 </errorInCompletePhase>
1244 </React.Profiler>,
1245 );
1244 - expect(Scheduler).toFlushAndThrow('Error in host config.');
1246 + await waitForThrow('Error in host config.');
1247
1248 // So long as the profiler timer's fiber stack is reset correctly,
1249 // Subsequent renders should not error.
packages/scheduler/src/__tests__/SchedulerMock-test.js
+10 -6
@@ -144,7 +144,8 @@ describe('Scheduler', () => {
144 assertLog([]);
145
146 Scheduler.unstable_advanceTime(1);
147 - expect(Scheduler).toFlushExpired(['A']);
147 + Scheduler.unstable_flushExpired();
148 + assertLog(['A']);
149 });
150
151 it('continues working on same task after yielding', async () => {
@@ -221,7 +222,8 @@ describe('Scheduler', () => {
222
223 // Advance time by just a bit more. This should expire all the remaining work.
224 Scheduler.unstable_advanceTime(1);
224 - expect(Scheduler).toFlushExpired(['C', 'D']);
225 + Scheduler.unstable_flushExpired();
226 + assertLog(['C', 'D']);
227 });
228
229 it('continuations are interrupted by higher priority work', async () => {
@@ -326,7 +328,8 @@ describe('Scheduler', () => {
328 // Immediate callback hasn't fired, yet.
329 assertLog([]);
330 // They all flush immediately within the subsequent task.
329 - expect(Scheduler).toFlushExpired(['A', 'B', 'C', 'D']);
331 + Scheduler.unstable_flushExpired();
332 + assertLog(['A', 'B', 'C', 'D']);
333 });
334
335 it('nested immediate callbacks are added to the queue of immediate callbacks', () => {
@@ -345,7 +348,8 @@ describe('Scheduler', () => {
348 );
349 assertLog([]);
350 // C should flush at the end
348 - expect(Scheduler).toFlushExpired(['A', 'B', 'D', 'C']);
351 + Scheduler.unstable_flushExpired();
352 + assertLog(['A', 'B', 'D', 'C']);
353 });
354
355 it('wrapped callbacks have same signature as original callback', () => {
@@ -410,12 +414,12 @@ describe('Scheduler', () => {
414 throw new Error('Oops C');
415 });
416
413 - expect(() => expect(Scheduler).toFlushExpired()).toThrow('Oops A');
417 + expect(() => Scheduler.unstable_flushExpired()).toThrow('Oops A');
418 assertLog(['A']);
419
420 // B and C flush in a subsequent event. That way, the second error is not
421 // swallowed.
418 - expect(() => expect(Scheduler).toFlushExpired()).toThrow('Oops C');
422 + expect(() => Scheduler.unstable_flushExpired()).toThrow('Oops C');
423 assertLog(['B', 'C']);
424 });
425
packages/scheduler/src/__tests__/SchedulerProfiling-test.js
+3 -1
@@ -26,6 +26,7 @@ let cancelCallback;
26 // let shouldYield;
27 let waitForAll;
28 let waitFor;
29 +let waitForThrow;
30
31 function priorityLevelToString(priorityLevel) {
32 switch (priorityLevel) {
@@ -75,6 +76,7 @@ describe('Scheduler', () => {
76 const InternalTestUtils = require('internal-test-utils');
77 waitForAll = InternalTestUtils.waitForAll;
78 waitFor = InternalTestUtils.waitFor;
79 + waitForThrow = InternalTestUtils.waitForThrow;
80 });
81
82 const TaskStartEvent = 1;
@@ -335,7 +337,7 @@ Task 1 [Normal] │██████░░🡐 canceled
337 throw Error('Oops');
338 });
339
338 - expect(Scheduler).toFlushAndThrow('Oops');
340 + await waitForThrow('Oops');
341 Scheduler.unstable_advanceTime(100);
342
343 Scheduler.unstable_advanceTime(1000);