Skip to content

Commit f7e4cad

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 facebook#26285 for full context.
1 parent d8f9a72 commit f7e4cad

20 files changed

Lines changed: 157 additions & 155 deletions

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: 26 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -209,13 +209,13 @@ 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' +
216216
'2. You might be breaking the Rules of Hooks\n' +
217217
'3. You might have more than one copy of React in the same app\n' +
218-
'See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.',
218+
'See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.'
219219
);
220220

221221
// Confirm that a subsequent hook works properly.
@@ -238,15 +238,14 @@ describe('ReactHooksWithNoopRenderer', () => {
238238
};
239239
}
240240
ReactNoop.render(<Counter />);
241-
expect(() =>
242-
expect(Scheduler).toFlushAndThrow(
243-
'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen ' +
244-
'for one of the following reasons:\n' +
245-
'1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +
246-
'2. You might be breaking the Rules of Hooks\n' +
247-
'3. You might have more than one copy of React in the same app\n' +
248-
'See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.',
249-
),
241+
expect(async () => await waitForThrow(
242+
'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen ' +
243+
'for one of the following reasons:\n' +
244+
'1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +
245+
'2. You might be breaking the Rules of Hooks\n' +
246+
'3. You might have more than one copy of React in the same app\n' +
247+
'See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.'
248+
),
250249
).toErrorDev(
251250
'Warning: The <Counter /> component appears to be a function component that returns a class instance. ' +
252251
'Change Counter to a class that extends React.Component instead. ' +
@@ -487,20 +486,18 @@ describe('ReactHooksWithNoopRenderer', () => {
487486
assertLog(['Foo [0]', 'Bar']);
488487

489488
// 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-
});
489+
root.render(
490+
<>
491+
<Foo />
492+
<Bar triggerUpdate={true} />
493+
</>,
494+
);
495+
await expect(
496+
async () => await waitForAll(['Foo [0]', 'Bar', 'Foo [1]']),
497+
).toErrorDev([
498+
'Cannot update a component (`Foo`) while rendering a ' +
499+
'different component (`Bar`). To locate the bad setState() call inside `Bar`',
500+
]);
504501

505502
// It should not warn again (deduplication).
506503
await act(async () => {
@@ -562,10 +559,8 @@ describe('ReactHooksWithNoopRenderer', () => {
562559
return <Text text={count} />;
563560
}
564561
ReactNoop.render(<Counter />);
565-
expect(Scheduler).toFlushAndThrow(
566-
'Too many re-renders. React limits the number of renders to prevent ' +
567-
'an infinite loop.',
568-
);
562+
await waitForThrow('Too many re-renders. React limits the number of renders to prevent ' +
563+
'an infinite loop.');
569564
});
570565

571566
it('works with useReducer', async () => {
@@ -3805,10 +3800,8 @@ describe('ReactHooksWithNoopRenderer', () => {
38053800
assertLog(['A: 2, B: 3, C: 4']);
38063801
expect(ReactNoop).toMatchRenderedOutput(<span prop="A: 2, B: 3, C: 4" />);
38073802
ReactNoop.render(<App loadC={false} />);
3808-
expect(Scheduler).toFlushAndThrow(
3809-
'Rendered fewer hooks than expected. This may be caused by an ' +
3810-
'accidental early return statement.',
3811-
);
3803+
await waitForThrow('Rendered fewer hooks than expected. This may be caused by an ' +
3804+
'accidental early return statement.');
38123805
});
38133806

38143807
it('unmount effects', async () => {

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)