Skip to content

Commit f4595ef

Browse files
committed
Codemod tests to waitFor pattern (9/?)
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.
1 parent d8f9a72 commit f4595ef

20 files changed

+198
-190
lines changed

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ let TextResource;
2020
let textResourceShouldFail;
2121
let waitForAll;
2222
let assertLog;
23+
let waitForThrow;
2324

2425
describe('ReactCache', () => {
2526
beforeEach(() => {
@@ -38,6 +39,7 @@ describe('ReactCache', () => {
3839
const InternalTestUtils = require('internal-test-utils');
3940
waitForAll = InternalTestUtils.waitForAll;
4041
assertLog = InternalTestUtils.assertLog;
42+
waitForThrow = InternalTestUtils.waitForThrow;
4143

4244
TextResource = createResource(
4345
([text, ms = 0]) => {
@@ -150,12 +152,12 @@ describe('ReactCache', () => {
150152
jest.advanceTimersByTime(100);
151153
assertLog(['Promise rejected [Hi]']);
152154

153-
expect(Scheduler).toFlushAndThrow('Failed to load: Hi');
155+
await waitForThrow('Failed to load: Hi');
154156
assertLog(['Error! [Hi]', 'Error! [Hi]']);
155157

156158
// Should throw again on a subsequent read
157159
root.update(<App />);
158-
expect(Scheduler).toFlushAndThrow('Failed to load: Hi');
160+
await waitForThrow('Failed to load: Hi');
159161
assertLog(['Error! [Hi]', 'Error! [Hi]']);
160162
});
161163

packages/react-dom/src/__tests__/ReactDOMFloat-test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4398,7 +4398,7 @@ background-color: green;
43984398
</body>
43994399
</html>,
44004400
);
4401-
expect(Scheduler).toFlushWithoutYielding();
4401+
await waitForAll([]);
44024402
expect(getMeaningfulChildren(document)).toEqual(
44034403
<html>
44044404
<head>

packages/react-dom/src/__tests__/ReactDeprecationWarnings-test.js

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
let React;
1313
let ReactNoop;
14-
let Scheduler;
1514
let JSXDEVRuntime;
1615
let waitForAll;
1716

@@ -20,15 +19,14 @@ describe('ReactDeprecationWarnings', () => {
2019
jest.resetModules();
2120
React = require('react');
2221
ReactNoop = require('react-noop-renderer');
23-
Scheduler = require('scheduler');
2422
const InternalTestUtils = require('internal-test-utils');
2523
waitForAll = InternalTestUtils.waitForAll;
2624
if (__DEV__) {
2725
JSXDEVRuntime = require('react/jsx-dev-runtime');
2826
}
2927
});
3028

31-
it('should warn when given defaultProps', () => {
29+
it('should warn when given defaultProps', async () => {
3230
function FunctionalComponent(props) {
3331
return null;
3432
}
@@ -38,14 +36,14 @@ describe('ReactDeprecationWarnings', () => {
3836
};
3937

4038
ReactNoop.render(<FunctionalComponent />);
41-
expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
39+
await expect(async () => await waitForAll([])).toErrorDev(
4240
'Warning: FunctionalComponent: Support for defaultProps ' +
4341
'will be removed from function components in a future major ' +
4442
'release. Use JavaScript default parameters instead.',
4543
);
4644
});
4745

48-
it('should warn when given defaultProps on a memoized function', () => {
46+
it('should warn when given defaultProps on a memoized function', async () => {
4947
const MemoComponent = React.memo(function FunctionalComponent(props) {
5048
return null;
5149
});
@@ -59,14 +57,14 @@ describe('ReactDeprecationWarnings', () => {
5957
<MemoComponent />
6058
</div>,
6159
);
62-
expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
60+
await expect(async () => await waitForAll([])).toErrorDev(
6361
'Warning: FunctionalComponent: Support for defaultProps ' +
6462
'will be removed from memo components in a future major ' +
6563
'release. Use JavaScript default parameters instead.',
6664
);
6765
});
6866

69-
it('should warn when given string refs', () => {
67+
it('should warn when given string refs', async () => {
7068
class RefComponent extends React.Component {
7169
render() {
7270
return null;
@@ -79,7 +77,7 @@ describe('ReactDeprecationWarnings', () => {
7977
}
8078

8179
ReactNoop.render(<Component />);
82-
expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
80+
await expect(async () => await waitForAll([])).toErrorDev(
8381
'Warning: Component "Component" contains the string ref "refComponent". ' +
8482
'Support for string refs will be removed in a future major release. ' +
8583
'We recommend using useRef() or createRef() instead. ' +
@@ -108,7 +106,7 @@ describe('ReactDeprecationWarnings', () => {
108106
await waitForAll([]);
109107
});
110108

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 () => {
112110
class RefComponent extends React.Component {
113111
render() {
114112
return null;
@@ -121,7 +119,7 @@ describe('ReactDeprecationWarnings', () => {
121119
}
122120

123121
ReactNoop.render(<Component />);
124-
expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev([
122+
await expect(async () => await waitForAll([])).toErrorDev([
125123
'Warning: Component "Component" contains the string ref "refComponent". ' +
126124
'Support for string refs will be removed in a future major release. ' +
127125
'This case cannot be automatically converted to an arrow function. ' +
@@ -132,7 +130,7 @@ describe('ReactDeprecationWarnings', () => {
132130
});
133131

134132
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 () => {
136134
class RefComponent extends React.Component {
137135
render() {
138136
return null;
@@ -152,7 +150,7 @@ describe('ReactDeprecationWarnings', () => {
152150
}
153151

154152
ReactNoop.render(<Component />);
155-
expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
153+
await expect(async () => await waitForAll([])).toErrorDev(
156154
'Warning: Component "Component" contains the string ref "refComponent". ' +
157155
'Support for string refs will be removed in a future major release. ' +
158156
'This case cannot be automatically converted to an arrow function. ' +

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ let Suspense;
66
let scheduleCallback;
77
let NormalPriority;
88
let waitForAll;
9+
let waitFor;
910

1011
describe('ReactSuspenseList', () => {
1112
beforeEach(() => {
@@ -24,6 +25,7 @@ describe('ReactSuspenseList', () => {
2425

2526
const InternalTestUtils = require('internal-test-utils');
2627
waitForAll = InternalTestUtils.waitForAll;
28+
waitFor = InternalTestUtils.waitFor;
2729
});
2830

2931
function Text(props) {
@@ -86,11 +88,11 @@ describe('ReactSuspenseList', () => {
8688
});
8789

8890
// This resolves A and schedules a task for React to retry.
89-
await expect(Scheduler).toFlushAndYieldThrough(['Resolve A']);
91+
await waitFor(['Resolve A']);
9092

9193
// The next task that flushes should be the one that resolves B. The render
9294
// task should not jump the queue ahead of B.
93-
await expect(Scheduler).toFlushAndYieldThrough(['Resolve B']);
95+
await waitFor(['Resolve B']);
9496

9597
await waitForAll(['A', 'B']);
9698
expect(root).toMatchRenderedOutput('AB');

packages/react-reconciler/src/__tests__/ReactFragment-test.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
let React;
1313
let ReactNoop;
14-
let Scheduler;
1514
let waitForAll;
1615

1716
describe('ReactFragment', () => {
@@ -20,7 +19,6 @@ describe('ReactFragment', () => {
2019

2120
React = require('react');
2221
ReactNoop = require('react-noop-renderer');
23-
Scheduler = require('scheduler');
2422

2523
const InternalTestUtils = require('internal-test-utils');
2624
waitForAll = InternalTestUtils.waitForAll;
@@ -707,7 +705,7 @@ describe('ReactFragment', () => {
707705
);
708706
});
709707

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 () => {
711709
const ops = [];
712710

713711
class Stateful extends React.Component {
@@ -742,7 +740,7 @@ describe('ReactFragment', () => {
742740
await waitForAll([]);
743741

744742
ReactNoop.render(<Foo condition={false} />);
745-
expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
743+
await expect(async () => await waitForAll([])).toErrorDev(
746744
'Each child in a list should have a unique "key" prop.',
747745
);
748746

@@ -939,7 +937,7 @@ describe('ReactFragment', () => {
939937
}
940938

941939
ReactNoop.render(<Foo condition={true} />);
942-
expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
940+
await expect(async () => await waitForAll([])).toErrorDev(
943941
'Each child in a list should have a unique "key" prop.',
944942
);
945943

packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js

Lines changed: 44 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ describe('ReactHooksWithNoopRenderer', () => {
209209
}
210210
ReactNoop.render(<BadCounter />);
211211

212-
expect(Scheduler).toFlushAndThrow(
212+
await waitForThrow(
213213
'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' +
214214
' one of the following reasons:\n' +
215215
'1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +
@@ -227,43 +227,43 @@ describe('ReactHooksWithNoopRenderer', () => {
227227
await waitForAll([10]);
228228
});
229229

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(
243244
'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen ' +
244245
'for one of the following reasons:\n' +
245246
'1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +
246247
'2. You might be breaking the Rules of Hooks\n' +
247248
'3. You might have more than one copy of React in the same app\n' +
248249
'See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.',
249250
),
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+
);
257258

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+
});
267267

268268
it('throws when called outside the render phase', async () => {
269269
expect(() => {
@@ -487,20 +487,18 @@ describe('ReactHooksWithNoopRenderer', () => {
487487
assertLog(['Foo [0]', 'Bar']);
488488

489489
// 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+
]);
504502

505503
// It should not warn again (deduplication).
506504
await act(async () => {
@@ -562,7 +560,7 @@ describe('ReactHooksWithNoopRenderer', () => {
562560
return <Text text={count} />;
563561
}
564562
ReactNoop.render(<Counter />);
565-
expect(Scheduler).toFlushAndThrow(
563+
await waitForThrow(
566564
'Too many re-renders. React limits the number of renders to prevent ' +
567565
'an infinite loop.',
568566
);
@@ -3805,7 +3803,7 @@ describe('ReactHooksWithNoopRenderer', () => {
38053803
assertLog(['A: 2, B: 3, C: 4']);
38063804
expect(ReactNoop).toMatchRenderedOutput(<span prop="A: 2, B: 3, C: 4" />);
38073805
ReactNoop.render(<App loadC={false} />);
3808-
expect(Scheduler).toFlushAndThrow(
3806+
await waitForThrow(
38093807
'Rendered fewer hooks than expected. This may be caused by an ' +
38103808
'accidental early return statement.',
38113809
);

packages/react-reconciler/src/__tests__/ReactIncremental-test.js

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1896,7 +1896,7 @@ describe('ReactIncremental', () => {
18961896
});
18971897

18981898
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 () => {
19001900
function Recurse(props, context) {
19011901
return {
19021902
getChildContext() {
@@ -1919,13 +1919,14 @@ describe('ReactIncremental', () => {
19191919
};
19201920

19211921
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+
]),
19291930
).toErrorDev([
19301931
'Warning: The <Recurse /> component appears to be a function component that returns a class instance. ' +
19311932
'Change Recurse to a class that extends React.Component instead. ' +
@@ -2281,7 +2282,7 @@ describe('ReactIncremental', () => {
22812282
instance.setState({
22822283
throwError: true,
22832284
});
2284-
expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
2285+
await expect(async () => await waitForAll([])).toErrorDev(
22852286
'Error boundaries should implement getDerivedStateFromError()',
22862287
);
22872288
});

0 commit comments

Comments
 (0)