Skip to content

Commit a8875ea

Browse files
acdlitetyao1
andauthored
Update more tests to not rely on sync queuing (#26358)
This fixes a handful of tests that were accidentally relying on React synchronously queuing work in the Scheduler after a setState. Usually this is because they use a lower level SchedulerMock method instead of either `act` or one of the `waitFor` helpers. In some cases, the solution is to switch to those APIs. In other cases, if we're intentionally testing some lower level behavior, we might have to be a bit more clever. Co-authored-by: Tianyu Yao <skyyao@fb.com>
1 parent d1ad984 commit a8875ea

25 files changed

+550
-555
lines changed

packages/react-debug-tools/src/__tests__/ReactDevToolsHooksIntegration-test.js

+24-27
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ describe('React hooks DevTools integration', () => {
1414
let React;
1515
let ReactDebugTools;
1616
let ReactTestRenderer;
17-
let Scheduler;
1817
let act;
1918
let overrideHookState;
2019
let scheduleUpdate;
@@ -40,15 +39,14 @@ describe('React hooks DevTools integration', () => {
4039
React = require('react');
4140
ReactDebugTools = require('react-debug-tools');
4241
ReactTestRenderer = require('react-test-renderer');
43-
Scheduler = require('scheduler');
4442

4543
const InternalTestUtils = require('internal-test-utils');
4644
waitForAll = InternalTestUtils.waitForAll;
4745

4846
act = ReactTestRenderer.act;
4947
});
5048

51-
it('should support editing useState hooks', () => {
49+
it('should support editing useState hooks', async () => {
5250
let setCountFn;
5351

5452
function MyComponent() {
@@ -70,14 +68,14 @@ describe('React hooks DevTools integration', () => {
7068
expect(stateHook.isStateEditable).toBe(true);
7169

7270
if (__DEV__) {
73-
act(() => overrideHookState(fiber, stateHook.id, [], 10));
71+
await act(() => overrideHookState(fiber, stateHook.id, [], 10));
7472
expect(renderer.toJSON()).toEqual({
7573
type: 'div',
7674
props: {},
7775
children: ['count:', '10'],
7876
});
7977

80-
act(() => setCountFn(count => count + 1));
78+
await act(() => setCountFn(count => count + 1));
8179
expect(renderer.toJSON()).toEqual({
8280
type: 'div',
8381
props: {},
@@ -86,7 +84,7 @@ describe('React hooks DevTools integration', () => {
8684
}
8785
});
8886

89-
it('should support editable useReducer hooks', () => {
87+
it('should support editable useReducer hooks', async () => {
9088
const initialData = {foo: 'abc', bar: 123};
9189

9290
function reducer(state, action) {
@@ -122,14 +120,14 @@ describe('React hooks DevTools integration', () => {
122120
expect(reducerHook.isStateEditable).toBe(true);
123121

124122
if (__DEV__) {
125-
act(() => overrideHookState(fiber, reducerHook.id, ['foo'], 'def'));
123+
await act(() => overrideHookState(fiber, reducerHook.id, ['foo'], 'def'));
126124
expect(renderer.toJSON()).toEqual({
127125
type: 'div',
128126
props: {},
129127
children: ['foo:', 'def', ', bar:', '123'],
130128
});
131129

132-
act(() => dispatchFn({type: 'swap'}));
130+
await act(() => dispatchFn({type: 'swap'}));
133131
expect(renderer.toJSON()).toEqual({
134132
type: 'div',
135133
props: {},
@@ -140,7 +138,7 @@ describe('React hooks DevTools integration', () => {
140138

141139
// This test case is based on an open source bug report:
142140
// https://github.com/facebookincubator/redux-react-hook/issues/34#issuecomment-466693787
143-
it('should handle interleaved stateful hooks (e.g. useState) and non-stateful hooks (e.g. useContext)', () => {
141+
it('should handle interleaved stateful hooks (e.g. useState) and non-stateful hooks (e.g. useContext)', async () => {
144142
const MyContext = React.createContext(1);
145143

146144
let setStateFn;
@@ -170,13 +168,13 @@ describe('React hooks DevTools integration', () => {
170168
expect(stateHook.isStateEditable).toBe(true);
171169

172170
if (__DEV__) {
173-
act(() => overrideHookState(fiber, stateHook.id, ['count'], 10));
171+
await act(() => overrideHookState(fiber, stateHook.id, ['count'], 10));
174172
expect(renderer.toJSON()).toEqual({
175173
type: 'div',
176174
props: {},
177175
children: ['count:', '10'],
178176
});
179-
act(() => setStateFn(state => ({count: state.count + 1})));
177+
await act(() => setStateFn(state => ({count: state.count + 1})));
180178
expect(renderer.toJSON()).toEqual({
181179
type: 'div',
182180
props: {},
@@ -185,7 +183,7 @@ describe('React hooks DevTools integration', () => {
185183
}
186184
});
187185

188-
it('should support overriding suspense in legacy mode', () => {
186+
it('should support overriding suspense in legacy mode', async () => {
189187
if (__DEV__) {
190188
// Lock the first render
191189
setSuspenseHandler(() => true);
@@ -206,32 +204,32 @@ describe('React hooks DevTools integration', () => {
206204
if (__DEV__) {
207205
// First render was locked
208206
expect(renderer.toJSON().children).toEqual(['Loading']);
209-
act(() => scheduleUpdate(fiber)); // Re-render
207+
await act(() => scheduleUpdate(fiber)); // Re-render
210208
expect(renderer.toJSON().children).toEqual(['Loading']);
211209

212210
// Release the lock
213211
setSuspenseHandler(() => false);
214-
act(() => scheduleUpdate(fiber)); // Re-render
212+
await act(() => scheduleUpdate(fiber)); // Re-render
215213
expect(renderer.toJSON().children).toEqual(['Done']);
216-
act(() => scheduleUpdate(fiber)); // Re-render
214+
await act(() => scheduleUpdate(fiber)); // Re-render
217215
expect(renderer.toJSON().children).toEqual(['Done']);
218216

219217
// Lock again
220218
setSuspenseHandler(() => true);
221-
act(() => scheduleUpdate(fiber)); // Re-render
219+
await act(() => scheduleUpdate(fiber)); // Re-render
222220
expect(renderer.toJSON().children).toEqual(['Loading']);
223221

224222
// Release the lock again
225223
setSuspenseHandler(() => false);
226-
act(() => scheduleUpdate(fiber)); // Re-render
224+
await act(() => scheduleUpdate(fiber)); // Re-render
227225
expect(renderer.toJSON().children).toEqual(['Done']);
228226

229227
// Ensure it checks specific fibers.
230228
setSuspenseHandler(f => f === fiber || f === fiber.alternate);
231-
act(() => scheduleUpdate(fiber)); // Re-render
229+
await act(() => scheduleUpdate(fiber)); // Re-render
232230
expect(renderer.toJSON().children).toEqual(['Loading']);
233231
setSuspenseHandler(f => f !== fiber && f !== fiber.alternate);
234-
act(() => scheduleUpdate(fiber)); // Re-render
232+
await act(() => scheduleUpdate(fiber)); // Re-render
235233
expect(renderer.toJSON().children).toEqual(['Done']);
236234
} else {
237235
expect(renderer.toJSON().children).toEqual(['Done']);
@@ -267,33 +265,32 @@ describe('React hooks DevTools integration', () => {
267265
if (__DEV__) {
268266
// First render was locked
269267
expect(renderer.toJSON().children).toEqual(['Loading']);
270-
act(() => scheduleUpdate(fiber)); // Re-render
268+
await act(() => scheduleUpdate(fiber)); // Re-render
271269
expect(renderer.toJSON().children).toEqual(['Loading']);
272270

273271
// Release the lock
274272
setSuspenseHandler(() => false);
275-
act(() => scheduleUpdate(fiber)); // Re-render
276-
Scheduler.unstable_flushAll();
273+
await act(() => scheduleUpdate(fiber)); // Re-render
277274
expect(renderer.toJSON().children).toEqual(['Done']);
278-
act(() => scheduleUpdate(fiber)); // Re-render
275+
await act(() => scheduleUpdate(fiber)); // Re-render
279276
expect(renderer.toJSON().children).toEqual(['Done']);
280277

281278
// Lock again
282279
setSuspenseHandler(() => true);
283-
act(() => scheduleUpdate(fiber)); // Re-render
280+
await act(() => scheduleUpdate(fiber)); // Re-render
284281
expect(renderer.toJSON().children).toEqual(['Loading']);
285282

286283
// Release the lock again
287284
setSuspenseHandler(() => false);
288-
act(() => scheduleUpdate(fiber)); // Re-render
285+
await act(() => scheduleUpdate(fiber)); // Re-render
289286
expect(renderer.toJSON().children).toEqual(['Done']);
290287

291288
// Ensure it checks specific fibers.
292289
setSuspenseHandler(f => f === fiber || f === fiber.alternate);
293-
act(() => scheduleUpdate(fiber)); // Re-render
290+
await act(() => scheduleUpdate(fiber)); // Re-render
294291
expect(renderer.toJSON().children).toEqual(['Loading']);
295292
setSuspenseHandler(f => f !== fiber && f !== fiber.alternate);
296-
act(() => scheduleUpdate(fiber)); // Re-render
293+
await act(() => scheduleUpdate(fiber)); // Re-render
297294
expect(renderer.toJSON().children).toEqual(['Done']);
298295
} else {
299296
expect(renderer.toJSON().children).toEqual(['Done']);

packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js

+2-6
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212

1313
let React;
1414
let ReactTestRenderer;
15-
let Scheduler;
1615
let ReactDebugTools;
1716
let act;
1817

@@ -21,7 +20,6 @@ describe('ReactHooksInspectionIntegration', () => {
2120
jest.resetModules();
2221
React = require('react');
2322
ReactTestRenderer = require('react-test-renderer');
24-
Scheduler = require('scheduler');
2523
act = require('internal-test-utils').act;
2624
ReactDebugTools = require('react-debug-tools');
2725
});
@@ -890,10 +888,8 @@ describe('ReactHooksInspectionIntegration', () => {
890888
</Suspense>,
891889
);
892890

893-
await LazyFoo;
894-
895-
expect(() => {
896-
Scheduler.unstable_flushAll();
891+
await expect(async () => {
892+
await act(async () => await LazyFoo);
897893
}).toErrorDev([
898894
'Foo: Support for defaultProps will be removed from function components in a future major release. Use JavaScript default parameters instead.',
899895
]);

0 commit comments

Comments
 (0)