From 432ffc9d0ff2ade0174c76cc23614e0d76963fb1 Mon Sep 17 00:00:00 2001 From: Tianyu Yao Date: Fri, 10 Mar 2023 17:56:13 -0800 Subject: [PATCH] Convert more Scheduler.unstable_flushAll in tests to new test utils (#26369) `Scheduler.unstable_flushAll` in existing tests doesn't work with microtask. This PR converts most of the remaining `Scheduler.unstable_flushAll()` calls to using internal test utilities to unblock refactoring `ensureRootIsScheduled` with scheduling a microtask. --- .../DOMPluginEventSystem-test.internal.js | 276 ++++++++++-------- .../__tests__/useFocus-test.internal.js | 88 +++--- .../__tests__/useFocusWithin-test.internal.js | 98 +++---- ...rorBoundaryReconciliation-test.internal.js | 35 ++- .../src/__tests__/ReactSuspenseList-test.js | 88 +++--- .../src/__tests__/ReactTestRenderer-test.js | 17 +- 6 files changed, 332 insertions(+), 270 deletions(-) diff --git a/packages/react-dom/src/events/__tests__/DOMPluginEventSystem-test.internal.js b/packages/react-dom/src/events/__tests__/DOMPluginEventSystem-test.internal.js index 37aac3c9a985c..0fefa4831413e 100644 --- a/packages/react-dom/src/events/__tests__/DOMPluginEventSystem-test.internal.js +++ b/packages/react-dom/src/events/__tests__/DOMPluginEventSystem-test.internal.js @@ -80,11 +80,11 @@ describe('DOMPluginEventSystem', () => { ReactDOMClient = require('react-dom/client'); Scheduler = require('scheduler'); ReactDOMServer = require('react-dom/server'); - act = require('internal-test-utils').act; const InternalTestUtils = require('internal-test-utils'); waitForAll = InternalTestUtils.waitForAll; waitFor = InternalTestUtils.waitFor; + act = InternalTestUtils.act; container = document.createElement('div'); document.body.appendChild(container); @@ -635,8 +635,9 @@ describe('DOMPluginEventSystem', () => { // We're going to use a different root as a parent. // This lets us detect whether an event goes through React's event system. const parentRoot = ReactDOMClient.createRoot(parentContainer); - parentRoot.render(); - Scheduler.unstable_flushAll(); + await act(() => { + parentRoot.render(); + }); childSlotRef.current.appendChild(childContainer); @@ -647,9 +648,9 @@ describe('DOMPluginEventSystem', () => { suspend = true; // Hydrate asynchronously. - ReactDOMClient.hydrateRoot(childContainer, ); - jest.runAllTimers(); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOMClient.hydrateRoot(childContainer, ); + }); // The Suspense boundary is not yet hydrated. await act(() => { @@ -1305,7 +1306,7 @@ describe('DOMPluginEventSystem', () => { }); // @gate www - it('can render correctly with the ReactDOMServer hydration', () => { + it('can render correctly with the ReactDOMServer hydration', async () => { const clickEvent = jest.fn(); const spanRef = React.createRef(); const setClick = ReactDOM.unstable_createEventHandle('click'); @@ -1324,14 +1325,15 @@ describe('DOMPluginEventSystem', () => { const output = ReactDOMServer.renderToString(); expect(output).toBe(`
Hello world
`); container.innerHTML = output; - ReactDOM.hydrate(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.hydrate(, container); + }); dispatchClickEvent(spanRef.current); expect(clickEvent).toHaveBeenCalledTimes(1); }); // @gate www - it('should correctly work for a basic "click" listener', () => { + it('should correctly work for a basic "click" listener', async () => { let log = []; const clickEvent = jest.fn(event => { log.push({ @@ -1357,8 +1359,9 @@ describe('DOMPluginEventSystem', () => { ); } - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); expect(container.innerHTML).toBe( '', @@ -1378,15 +1381,17 @@ describe('DOMPluginEventSystem', () => { expect(clickEvent).toBeCalledTimes(1); // Unmounting the container and clicking should not work - ReactDOM.render(null, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(null, container); + }); dispatchClickEvent(divElement); expect(clickEvent).toBeCalledTimes(1); // Re-rendering the container and clicking should work - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); divElement = divRef.current; dispatchClickEvent(divElement); @@ -1421,8 +1426,9 @@ describe('DOMPluginEventSystem', () => { } let clickEvent2 = jest.fn(); - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); divElement = divRef.current; dispatchClickEvent(divElement); @@ -1430,8 +1436,9 @@ describe('DOMPluginEventSystem', () => { // Reset the function we pass in, so it's different clickEvent2 = jest.fn(); - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); divElement = divRef.current; dispatchClickEvent(divElement); @@ -1439,7 +1446,7 @@ describe('DOMPluginEventSystem', () => { }); // @gate www - it('should correctly work for setting and clearing a basic "click" listener', () => { + it('should correctly work for setting and clearing a basic "click" listener', async () => { const clickEvent = jest.fn(); const divRef = React.createRef(); const buttonRef = React.createRef(); @@ -1461,16 +1468,18 @@ describe('DOMPluginEventSystem', () => { ); } - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); let divElement = divRef.current; dispatchClickEvent(divElement); expect(clickEvent).toBeCalledTimes(1); // The listener should get unmounted - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); clickEvent.mockClear(); @@ -1480,7 +1489,7 @@ describe('DOMPluginEventSystem', () => { }); // @gate www - it('should handle the target being a text node', () => { + it('should handle the target being a text node', async () => { const clickEvent = jest.fn(); const buttonRef = React.createRef(); const setClick = ReactDOM.unstable_createEventHandle('click'); @@ -1493,8 +1502,9 @@ describe('DOMPluginEventSystem', () => { return ; } - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); const textNode = buttonRef.current.firstChild; dispatchClickEvent(textNode); @@ -1502,7 +1512,7 @@ describe('DOMPluginEventSystem', () => { }); // @gate www - it('handle propagation of click events', () => { + it('handle propagation of click events', async () => { const buttonRef = React.createRef(); const divRef = React.createRef(); const log = []; @@ -1546,8 +1556,9 @@ describe('DOMPluginEventSystem', () => { ); } - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); const buttonElement = buttonRef.current; dispatchClickEvent(buttonElement); @@ -1571,7 +1582,7 @@ describe('DOMPluginEventSystem', () => { }); // @gate www - it('handle propagation of click events mixed with onClick events', () => { + it('handle propagation of click events mixed with onClick events', async () => { const buttonRef = React.createRef(); const divRef = React.createRef(); const log = []; @@ -1610,8 +1621,9 @@ describe('DOMPluginEventSystem', () => { ); } - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); const buttonElement = buttonRef.current; dispatchClickEvent(buttonElement); @@ -1631,7 +1643,7 @@ describe('DOMPluginEventSystem', () => { }); // @gate www - it('should correctly work for a basic "click" listener on the outer target', () => { + it('should correctly work for a basic "click" listener on the outer target', async () => { const log = []; const clickEvent = jest.fn(event => { log.push({ @@ -1657,8 +1669,9 @@ describe('DOMPluginEventSystem', () => { ); } - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); expect(container.innerHTML).toBe( '', @@ -1682,8 +1695,9 @@ describe('DOMPluginEventSystem', () => { expect(clickEvent).toBeCalledTimes(1); // Re-rendering the container and clicking should work - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); divElement = divRef.current; dispatchClickEvent(divElement); @@ -1696,7 +1710,7 @@ describe('DOMPluginEventSystem', () => { }); // @gate www - it('should correctly handle many nested target listeners', () => { + it('should correctly handle many nested target listeners', async () => { const buttonRef = React.createRef(); const targetListener1 = jest.fn(); const targetListener2 = jest.fn(); @@ -1741,8 +1755,9 @@ describe('DOMPluginEventSystem', () => { return ; } - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); let buttonElement = buttonRef.current; dispatchClickEvent(buttonElement); @@ -1787,8 +1802,9 @@ describe('DOMPluginEventSystem', () => { return ; } - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); buttonElement = buttonRef.current; dispatchClickEvent(buttonElement); @@ -1799,7 +1815,7 @@ describe('DOMPluginEventSystem', () => { }); // @gate www - it('should correctly handle stopPropagation correctly for target events', () => { + it('should correctly handle stopPropagation correctly for target events', async () => { const buttonRef = React.createRef(); const divRef = React.createRef(); const clickEvent = jest.fn(); @@ -1828,8 +1844,9 @@ describe('DOMPluginEventSystem', () => { ); } - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); const divElement = divRef.current; dispatchClickEvent(divElement); @@ -1837,7 +1854,7 @@ describe('DOMPluginEventSystem', () => { }); // @gate www - it('should correctly handle stopPropagation correctly for many target events', () => { + it('should correctly handle stopPropagation correctly for many target events', async () => { const buttonRef = React.createRef(); const targetListener1 = jest.fn(e => e.stopPropagation()); const targetListener2 = jest.fn(e => e.stopPropagation()); @@ -1878,8 +1895,9 @@ describe('DOMPluginEventSystem', () => { return ; } - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); const buttonElement = buttonRef.current; dispatchClickEvent(buttonElement); @@ -1890,7 +1908,7 @@ describe('DOMPluginEventSystem', () => { }); // @gate www - it('should correctly handle stopPropagation for mixed capture/bubbling target listeners', () => { + it('should correctly handle stopPropagation for mixed capture/bubbling target listeners', async () => { const buttonRef = React.createRef(); const targetListener1 = jest.fn(e => e.stopPropagation()); const targetListener2 = jest.fn(e => e.stopPropagation()); @@ -1935,8 +1953,9 @@ describe('DOMPluginEventSystem', () => { return ; } - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); const buttonElement = buttonRef.current; dispatchClickEvent(buttonElement); @@ -1996,7 +2015,7 @@ describe('DOMPluginEventSystem', () => { }); // @gate www - it('should correctly work for a basic "click" window listener', () => { + it('should correctly work for a basic "click" window listener', async () => { const log = []; const clickEvent = jest.fn(event => { log.push({ @@ -2015,8 +2034,9 @@ describe('DOMPluginEventSystem', () => { return ; } - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); expect(container.innerHTML).toBe( '', @@ -2032,22 +2052,24 @@ describe('DOMPluginEventSystem', () => { }); // Unmounting the container and clicking should not work - ReactDOM.render(null, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(null, container); + }); dispatchClickEvent(document.body); expect(clickEvent).toBeCalledTimes(1); // Re-rendering and clicking the body should work again - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); dispatchClickEvent(document.body); expect(clickEvent).toBeCalledTimes(2); }); // @gate www - it('handle propagation of click events on the window', () => { + it('handle propagation of click events on the window', async () => { const buttonRef = React.createRef(); const divRef = React.createRef(); const log = []; @@ -2098,8 +2120,9 @@ describe('DOMPluginEventSystem', () => { ); } - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); const buttonElement = buttonRef.current; dispatchClickEvent(buttonElement); @@ -2127,7 +2150,7 @@ describe('DOMPluginEventSystem', () => { }); // @gate www - it('should correctly handle stopPropagation for mixed listeners', () => { + it('should correctly handle stopPropagation for mixed listeners', async () => { const buttonRef = React.createRef(); const rootListener1 = jest.fn(e => e.stopPropagation()); const rootListener2 = jest.fn(); @@ -2166,8 +2189,9 @@ describe('DOMPluginEventSystem', () => { return ; } - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); const buttonElement = buttonRef.current; dispatchClickEvent(buttonElement); @@ -2178,7 +2202,7 @@ describe('DOMPluginEventSystem', () => { }); // @gate www - it('should correctly handle stopPropagation for delegated listeners', () => { + it('should correctly handle stopPropagation for delegated listeners', async () => { const buttonRef = React.createRef(); const rootListener1 = jest.fn(e => e.stopPropagation()); const rootListener2 = jest.fn(); @@ -2211,9 +2235,9 @@ describe('DOMPluginEventSystem', () => { return ; } - ReactDOM.render(, container); - - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); const buttonElement = buttonRef.current; dispatchClickEvent(buttonElement); @@ -2224,7 +2248,7 @@ describe('DOMPluginEventSystem', () => { }); // @gate www - it('handle propagation of click events on the window and document', () => { + it('handle propagation of click events on the window and document', async () => { const buttonRef = React.createRef(); const divRef = React.createRef(); const log = []; @@ -2282,8 +2306,9 @@ describe('DOMPluginEventSystem', () => { ); } - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); const buttonElement = buttonRef.current; dispatchClickEvent(buttonElement); @@ -2349,7 +2374,7 @@ describe('DOMPluginEventSystem', () => { }); // @gate www - it('beforeblur and afterblur are called after a focused element is unmounted', () => { + it('beforeblur and afterblur are called after a focused element is unmounted', async () => { const log = []; // We have to persist here because we want to read relatedTarget later. const onAfterBlur = jest.fn(e => { @@ -2385,8 +2410,9 @@ describe('DOMPluginEventSystem', () => { ); }; - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); const inner = innerRef.current; const target = createEventTarget(inner); @@ -2394,8 +2420,9 @@ describe('DOMPluginEventSystem', () => { expect(onBeforeBlur).toHaveBeenCalledTimes(0); expect(onAfterBlur).toHaveBeenCalledTimes(0); - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); expect(onBeforeBlur).toHaveBeenCalledTimes(1); expect(onAfterBlur).toHaveBeenCalledTimes(1); @@ -2406,7 +2433,7 @@ describe('DOMPluginEventSystem', () => { }); // @gate www - it('beforeblur and afterblur are called after a nested focused element is unmounted', () => { + it('beforeblur and afterblur are called after a nested focused element is unmounted', async () => { const log = []; // We have to persist here because we want to read relatedTarget later. const onAfterBlur = jest.fn(e => { @@ -2446,8 +2473,9 @@ describe('DOMPluginEventSystem', () => { ); }; - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); const inner = innerRef.current; const target = createEventTarget(inner); @@ -2455,8 +2483,9 @@ describe('DOMPluginEventSystem', () => { expect(onBeforeBlur).toHaveBeenCalledTimes(0); expect(onAfterBlur).toHaveBeenCalledTimes(0); - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); expect(onBeforeBlur).toHaveBeenCalledTimes(1); expect(onAfterBlur).toHaveBeenCalledTimes(1); @@ -2467,7 +2496,7 @@ describe('DOMPluginEventSystem', () => { }); // @gate www - it('beforeblur should skip handlers from a deleted subtree after the focused element is unmounted', () => { + it('beforeblur should skip handlers from a deleted subtree after the focused element is unmounted', async () => { const onBeforeBlur = jest.fn(); const innerRef = React.createRef(); const innerRef2 = React.createRef(); @@ -2505,16 +2534,18 @@ describe('DOMPluginEventSystem', () => { ); }; - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); const inner = innerRef.current; const target = createEventTarget(inner); target.focus(); expect(onBeforeBlur).toHaveBeenCalledTimes(0); - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); expect(onBeforeBlur).toHaveBeenCalledTimes(1); }); @@ -2745,7 +2776,7 @@ describe('DOMPluginEventSystem', () => { }); // @gate www - it('handle propagation of click events between disjointed comment roots', () => { + it('handle propagation of click events between disjointed comment roots', async () => { const buttonRef = React.createRef(); const divRef = React.createRef(); const log = []; @@ -2792,11 +2823,13 @@ describe('DOMPluginEventSystem', () => { const disjointedNode = document.createComment( ' react-mount-point-unstable ', ); - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); buttonRef.current.appendChild(disjointedNode); - ReactDOM.render(, disjointedNode); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, disjointedNode); + }); const buttonElement = buttonRef.current; dispatchClickEvent(buttonElement); @@ -2816,7 +2849,7 @@ describe('DOMPluginEventSystem', () => { }); // @gate www - it('propagates known createEventHandle events through portals without inner listeners', () => { + it('propagates known createEventHandle events through portals without inner listeners', async () => { const buttonRef = React.createRef(); const divRef = React.createRef(); const log = []; @@ -2859,8 +2892,9 @@ describe('DOMPluginEventSystem', () => { ); } - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); const divElement = divRef.current; const buttonElement = buttonRef.current; @@ -2885,10 +2919,11 @@ describe('DOMPluginEventSystem', () => { ReactDOMClient = require('react-dom/client'); Scheduler = require('scheduler'); ReactDOMServer = require('react-dom/server'); + act = require('internal-test-utils').act; }); // @gate www - it('handle propagation of click events on a scope', () => { + it('handle propagation of click events on a scope', async () => { const buttonRef = React.createRef(); const log = []; const onClick = jest.fn(e => @@ -2929,8 +2964,9 @@ describe('DOMPluginEventSystem', () => { ); } - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); const buttonElement = buttonRef.current; dispatchClickEvent(buttonElement); @@ -2944,7 +2980,7 @@ describe('DOMPluginEventSystem', () => { }); // @gate www - it('handle mixed propagation of click events on a scope', () => { + it('handle mixed propagation of click events on a scope', async () => { const buttonRef = React.createRef(); const divRef = React.createRef(); const log = []; @@ -3000,8 +3036,9 @@ describe('DOMPluginEventSystem', () => { ); } - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); const buttonElement = buttonRef.current; dispatchClickEvent(buttonElement); @@ -3035,7 +3072,7 @@ describe('DOMPluginEventSystem', () => { }); // @gate www - it('should not handle the target being a dangling text node within a scope', () => { + it('should not handle the target being a dangling text node within a scope', async () => { const clickEvent = jest.fn(); const buttonRef = React.createRef(); const TestScope = React.unstable_Scope; @@ -3055,8 +3092,9 @@ describe('DOMPluginEventSystem', () => { ); } - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); const textNode = buttonRef.current.firstChild; dispatchClickEvent(textNode); @@ -3066,7 +3104,7 @@ describe('DOMPluginEventSystem', () => { }); // @gate www - it('handle stopPropagation (inner) correctly between scopes', () => { + it('handle stopPropagation (inner) correctly between scopes', async () => { const buttonRef = React.createRef(); const outerOnClick = jest.fn(); const innerOnClick = jest.fn(e => e.stopPropagation()); @@ -3097,8 +3135,9 @@ describe('DOMPluginEventSystem', () => { ); } - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); const buttonElement = buttonRef.current; dispatchClickEvent(buttonElement); @@ -3108,7 +3147,7 @@ describe('DOMPluginEventSystem', () => { }); // @gate www - it('handle stopPropagation (outer) correctly between scopes', () => { + it('handle stopPropagation (outer) correctly between scopes', async () => { const buttonRef = React.createRef(); const outerOnClick = jest.fn(e => e.stopPropagation()); const innerOnClick = jest.fn(); @@ -3139,8 +3178,9 @@ describe('DOMPluginEventSystem', () => { ); } - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); const buttonElement = buttonRef.current; dispatchClickEvent(buttonElement); @@ -3150,7 +3190,7 @@ describe('DOMPluginEventSystem', () => { }); // @gate www - it('handle stopPropagation (inner and outer) correctly between scopes', () => { + it('handle stopPropagation (inner and outer) correctly between scopes', async () => { const buttonRef = React.createRef(); const onClick = jest.fn(e => e.stopPropagation()); const TestScope = React.unstable_Scope; @@ -3180,8 +3220,9 @@ describe('DOMPluginEventSystem', () => { ); } - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); const buttonElement = buttonRef.current; dispatchClickEvent(buttonElement); @@ -3190,7 +3231,7 @@ describe('DOMPluginEventSystem', () => { }); // @gate www - it('should be able to register handlers for events affected by the intervention', () => { + it('should be able to register handlers for events affected by the intervention', async () => { const rootContainer = document.createElement('div'); container.appendChild(rootContainer); @@ -3232,8 +3273,9 @@ describe('DOMPluginEventSystem', () => { return
test
; } - ReactDOM.render(, rootContainer); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, rootContainer); + }); dispatchEvent(ref.current, 'touchstart'); dispatchEvent(ref.current, 'touchmove'); diff --git a/packages/react-interactions/events/src/dom/create-event-handle/__tests__/useFocus-test.internal.js b/packages/react-interactions/events/src/dom/create-event-handle/__tests__/useFocus-test.internal.js index 40e48efda48b7..93204b5f20a6a 100644 --- a/packages/react-interactions/events/src/dom/create-event-handle/__tests__/useFocus-test.internal.js +++ b/packages/react-interactions/events/src/dom/create-event-handle/__tests__/useFocus-test.internal.js @@ -15,7 +15,7 @@ let React; let ReactFeatureFlags; let ReactDOM; let useFocus; -let Scheduler; +let act; function initializeModules(hasPointerEvents) { setPointerEvent(hasPointerEvents); @@ -24,8 +24,7 @@ function initializeModules(hasPointerEvents) { ReactFeatureFlags.enableCreateEventHandleAPI = true; React = require('react'); ReactDOM = require('react-dom'); - Scheduler = require('scheduler'); - + act = require('internal-test-utils').act; // TODO: This import throws outside of experimental mode. Figure out better // strategy for gated imports. if (__EXPERIMENTAL__ || global.__WWW__) { @@ -54,7 +53,7 @@ describe.each(table)(`useFocus hasPointerEvents=%s`, hasPointerEvents => { describe('disabled', () => { let onBlur, onFocus, ref; - const componentInit = () => { + const componentInit = async () => { onBlur = jest.fn(); onFocus = jest.fn(); ref = React.createRef(); @@ -66,13 +65,14 @@ describe.each(table)(`useFocus hasPointerEvents=%s`, hasPointerEvents => { }); return
; }; - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); }; // @gate www - it('does not call callbacks', () => { - componentInit(); + it('does not call callbacks', async () => { + await componentInit(); const target = createEventTarget(ref.current); target.focus(); target.blur(); @@ -84,7 +84,7 @@ describe.each(table)(`useFocus hasPointerEvents=%s`, hasPointerEvents => { describe('onBlur', () => { let onBlur, ref; - const componentInit = () => { + const componentInit = async () => { onBlur = jest.fn(); ref = React.createRef(); const Component = () => { @@ -93,13 +93,14 @@ describe.each(table)(`useFocus hasPointerEvents=%s`, hasPointerEvents => { }); return
; }; - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); }; // @gate www - it('is called after "blur" event', () => { - componentInit(); + it('is called after "blur" event', async () => { + await componentInit(); const target = createEventTarget(ref.current); target.focus(); target.blur(); @@ -110,7 +111,7 @@ describe.each(table)(`useFocus hasPointerEvents=%s`, hasPointerEvents => { describe('onFocus', () => { let onFocus, ref, innerRef; - const componentInit = () => { + const componentInit = async () => { onFocus = jest.fn(); ref = React.createRef(); innerRef = React.createRef(); @@ -124,21 +125,22 @@ describe.each(table)(`useFocus hasPointerEvents=%s`, hasPointerEvents => {
); }; - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); }; // @gate www - it('is called after "focus" event', () => { - componentInit(); + it('is called after "focus" event', async () => { + await componentInit(); const target = createEventTarget(ref.current); target.focus(); expect(onFocus).toHaveBeenCalledTimes(1); }); // @gate www - it('is not called if descendants of target receive focus', () => { - componentInit(); + it('is not called if descendants of target receive focus', async () => { + await componentInit(); const target = createEventTarget(innerRef.current); target.focus(); expect(onFocus).not.toBeCalled(); @@ -148,7 +150,7 @@ describe.each(table)(`useFocus hasPointerEvents=%s`, hasPointerEvents => { describe('onFocusChange', () => { let onFocusChange, ref, innerRef; - const componentInit = () => { + const componentInit = async () => { onFocusChange = jest.fn(); ref = React.createRef(); innerRef = React.createRef(); @@ -162,13 +164,14 @@ describe.each(table)(`useFocus hasPointerEvents=%s`, hasPointerEvents => {
); }; - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); }; // @gate www - it('is called after "blur" and "focus" events', () => { - componentInit(); + it('is called after "blur" and "focus" events', async () => { + await componentInit(); const target = createEventTarget(ref.current); target.focus(); expect(onFocusChange).toHaveBeenCalledTimes(1); @@ -179,8 +182,8 @@ describe.each(table)(`useFocus hasPointerEvents=%s`, hasPointerEvents => { }); // @gate www - it('is not called after "blur" and "focus" events on descendants', () => { - componentInit(); + it('is not called after "blur" and "focus" events on descendants', async () => { + await componentInit(); const target = createEventTarget(innerRef.current); target.focus(); expect(onFocusChange).toHaveBeenCalledTimes(0); @@ -192,7 +195,7 @@ describe.each(table)(`useFocus hasPointerEvents=%s`, hasPointerEvents => { describe('onFocusVisibleChange', () => { let onFocusVisibleChange, ref, innerRef; - const componentInit = () => { + const componentInit = async () => { onFocusVisibleChange = jest.fn(); ref = React.createRef(); innerRef = React.createRef(); @@ -206,13 +209,14 @@ describe.each(table)(`useFocus hasPointerEvents=%s`, hasPointerEvents => { ); }; - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); }; // @gate www - it('is called after "focus" and "blur" if keyboard navigation is active', () => { - componentInit(); + it('is called after "focus" and "blur" if keyboard navigation is active', async () => { + await componentInit(); const target = createEventTarget(ref.current); const containerTarget = createEventTarget(container); // use keyboard first @@ -226,8 +230,8 @@ describe.each(table)(`useFocus hasPointerEvents=%s`, hasPointerEvents => { }); // @gate www - it('is called if non-keyboard event is dispatched on target previously focused with keyboard', () => { - componentInit(); + it('is called if non-keyboard event is dispatched on target previously focused with keyboard', async () => { + await componentInit(); const target = createEventTarget(ref.current); const containerTarget = createEventTarget(container); // use keyboard first @@ -245,8 +249,8 @@ describe.each(table)(`useFocus hasPointerEvents=%s`, hasPointerEvents => { }); // @gate www - it('is not called after "focus" and "blur" events without keyboard', () => { - componentInit(); + it('is not called after "focus" and "blur" events without keyboard', async () => { + await componentInit(); const target = createEventTarget(ref.current); const containerTarget = createEventTarget(container); target.pointerdown(); @@ -257,8 +261,8 @@ describe.each(table)(`useFocus hasPointerEvents=%s`, hasPointerEvents => { }); // @gate www - it('is not called after "blur" and "focus" events on descendants', () => { - componentInit(); + it('is not called after "blur" and "focus" events on descendants', async () => { + await componentInit(); const innerTarget = createEventTarget(innerRef.current); const containerTarget = createEventTarget(container); containerTarget.keydown({key: 'Tab'}); @@ -271,7 +275,7 @@ describe.each(table)(`useFocus hasPointerEvents=%s`, hasPointerEvents => { describe('nested Focus components', () => { // @gate www - it('propagates events in the correct order', () => { + it('propagates events in the correct order', async () => { const events = []; const innerRef = React.createRef(); const outerRef = React.createRef(); @@ -301,9 +305,9 @@ describe.each(table)(`useFocus hasPointerEvents=%s`, hasPointerEvents => { ); }; - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); - + await act(() => { + ReactDOM.render(, container); + }); const innerTarget = createEventTarget(innerRef.current); const outerTarget = createEventTarget(outerRef.current); diff --git a/packages/react-interactions/events/src/dom/create-event-handle/__tests__/useFocusWithin-test.internal.js b/packages/react-interactions/events/src/dom/create-event-handle/__tests__/useFocusWithin-test.internal.js index dc76565c30a73..4d2cd4304151f 100644 --- a/packages/react-interactions/events/src/dom/create-event-handle/__tests__/useFocusWithin-test.internal.js +++ b/packages/react-interactions/events/src/dom/create-event-handle/__tests__/useFocusWithin-test.internal.js @@ -17,7 +17,6 @@ let ReactDOM; let ReactDOMClient; let useFocusWithin; let act; -let Scheduler; function initializeModules(hasPointerEvents) { setPointerEvent(hasPointerEvents); @@ -28,7 +27,6 @@ function initializeModules(hasPointerEvents) { React = require('react'); ReactDOM = require('react-dom'); ReactDOMClient = require('react-dom/client'); - Scheduler = require('scheduler'); act = require('internal-test-utils').act; // TODO: This import throws outside of experimental mode. Figure out better @@ -64,7 +62,7 @@ describe.each(table)(`useFocus`, hasPointerEvents => { describe('disabled', () => { let onFocusWithinChange, onFocusWithinVisibleChange, ref; - const componentInit = () => { + const componentInit = async () => { onFocusWithinChange = jest.fn(); onFocusWithinVisibleChange = jest.fn(); ref = React.createRef(); @@ -76,13 +74,14 @@ describe.each(table)(`useFocus`, hasPointerEvents => { }); return
; }; - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); }; // @gate www - it('prevents custom events being dispatched', () => { - componentInit(); + it('prevents custom events being dispatched', async () => { + await componentInit(); const target = createEventTarget(ref.current); target.focus(); target.blur(); @@ -106,18 +105,19 @@ describe.each(table)(`useFocus`, hasPointerEvents => { ); }; - const componentInit = () => { + const componentInit = async () => { onFocusWithinChange = jest.fn(); ref = React.createRef(); innerRef = React.createRef(); innerRef2 = React.createRef(); - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); }; // @gate www - it('is called after "blur" and "focus" events on focus target', () => { - componentInit(); + it('is called after "blur" and "focus" events on focus target', async () => { + await componentInit(); const target = createEventTarget(ref.current); target.focus(); expect(onFocusWithinChange).toHaveBeenCalledTimes(1); @@ -128,8 +128,8 @@ describe.each(table)(`useFocus`, hasPointerEvents => { }); // @gate www - it('is called after "blur" and "focus" events on descendants', () => { - componentInit(); + it('is called after "blur" and "focus" events on descendants', async () => { + await componentInit(); const target = createEventTarget(innerRef.current); target.focus(); expect(onFocusWithinChange).toHaveBeenCalledTimes(1); @@ -140,8 +140,8 @@ describe.each(table)(`useFocus`, hasPointerEvents => { }); // @gate www - it('is only called once when focus moves within and outside the subtree', () => { - componentInit(); + it('is only called once when focus moves within and outside the subtree', async () => { + await componentInit(); const node = ref.current; const innerNode1 = innerRef.current; const innerNode2 = innerRef.current; @@ -182,18 +182,19 @@ describe.each(table)(`useFocus`, hasPointerEvents => { ); }; - const componentInit = () => { + const componentInit = async () => { onFocusWithinVisibleChange = jest.fn(); ref = React.createRef(); innerRef = React.createRef(); innerRef2 = React.createRef(); - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); }; // @gate www - it('is called after "focus" and "blur" on focus target if keyboard was used', () => { - componentInit(); + it('is called after "focus" and "blur" on focus target if keyboard was used', async () => { + await componentInit(); const target = createEventTarget(ref.current); const containerTarget = createEventTarget(container); // use keyboard first @@ -207,8 +208,8 @@ describe.each(table)(`useFocus`, hasPointerEvents => { }); // @gate www - it('is called after "focus" and "blur" on descendants if keyboard was used', () => { - componentInit(); + it('is called after "focus" and "blur" on descendants if keyboard was used', async () => { + await componentInit(); const innerTarget = createEventTarget(innerRef.current); const containerTarget = createEventTarget(container); // use keyboard first @@ -222,8 +223,8 @@ describe.each(table)(`useFocus`, hasPointerEvents => { }); // @gate www - it('is called if non-keyboard event is dispatched on target previously focused with keyboard', () => { - componentInit(); + it('is called if non-keyboard event is dispatched on target previously focused with keyboard', async () => { + await componentInit(); const node = ref.current; const innerNode1 = innerRef.current; const innerNode2 = innerRef2.current; @@ -260,8 +261,8 @@ describe.each(table)(`useFocus`, hasPointerEvents => { }); // @gate www - it('is not called after "focus" and "blur" events without keyboard', () => { - componentInit(); + it('is not called after "focus" and "blur" events without keyboard', async () => { + await componentInit(); const innerTarget = createEventTarget(innerRef.current); innerTarget.pointerdown(); innerTarget.pointerup(); @@ -270,8 +271,8 @@ describe.each(table)(`useFocus`, hasPointerEvents => { }); // @gate www - it('is only called once when focus moves within and outside the subtree', () => { - componentInit(); + it('is only called once when focus moves within and outside the subtree', async () => { + await componentInit(); const node = ref.current; const innerNode1 = innerRef.current; const innerNode2 = innerRef2.current; @@ -338,7 +339,7 @@ describe.each(table)(`useFocus`, hasPointerEvents => { }); // @gate www - it('is called after a focused element is unmounted', () => { + it('is called after a focused element is unmounted', async () => { const Component = ({show}) => { const focusWithinRef = useFocusWithin(ref, { onBeforeBlurWithin, @@ -352,8 +353,9 @@ describe.each(table)(`useFocus`, hasPointerEvents => { ); }; - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); const inner = innerRef.current; const target = createEventTarget(inner); @@ -370,7 +372,7 @@ describe.each(table)(`useFocus`, hasPointerEvents => { }); // @gate www - it('is called after a nested focused element is unmounted', () => { + it('is called after a nested focused element is unmounted', async () => { const Component = ({show}) => { const focusWithinRef = useFocusWithin(ref, { onBeforeBlurWithin, @@ -388,8 +390,9 @@ describe.each(table)(`useFocus`, hasPointerEvents => { ); }; - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); const inner = innerRef.current; const target = createEventTarget(inner); @@ -406,7 +409,7 @@ describe.each(table)(`useFocus`, hasPointerEvents => { }); // @gate www - it('is called after many elements are unmounted', () => { + it('is called after many elements are unmounted', async () => { const buttonRef = React.createRef(); const inputRef = React.createRef(); @@ -429,8 +432,9 @@ describe.each(table)(`useFocus`, hasPointerEvents => { ); }; - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); inputRef.current.focus(); expect(onBeforeBlurWithin).toHaveBeenCalledTimes(0); @@ -441,7 +445,7 @@ describe.each(table)(`useFocus`, hasPointerEvents => { }); // @gate www - it('is called after a nested focused element is unmounted (with scope query)', () => { + it('is called after a nested focused element is unmounted (with scope query)', async () => { const TestScope = React.unstable_Scope; const testScopeQuery = (type, props) => true; let targetNodes; @@ -464,15 +468,17 @@ describe.each(table)(`useFocus`, hasPointerEvents => { ); }; - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); const inner = innerRef.current; const target = createEventTarget(inner); target.keydown({key: 'Tab'}); target.focus(); - ReactDOM.render(, container); - Scheduler.unstable_flushAll(); + await act(() => { + ReactDOM.render(, container); + }); expect(targetNodes).toEqual([targetNode]); }); @@ -511,7 +517,6 @@ describe.each(table)(`useFocus`, hasPointerEvents => { await act(() => { root.render(); }); - jest.runAllTimers(); expect(container2.innerHTML).toBe('
'); const inner = innerRef.current; @@ -525,7 +530,6 @@ describe.each(table)(`useFocus`, hasPointerEvents => { await act(() => { root.render(); }); - jest.runAllTimers(); expect(container2.innerHTML).toBe( '
Loading...
', ); @@ -570,7 +574,6 @@ describe.each(table)(`useFocus`, hasPointerEvents => { await act(() => { root.render(); }); - jest.runAllTimers(); expect(onBeforeBlurWithin).toHaveBeenCalledTimes(0); expect(onAfterBlurWithin).toHaveBeenCalledTimes(0); @@ -579,14 +582,12 @@ describe.each(table)(`useFocus`, hasPointerEvents => { await act(() => { root.render(); }); - jest.runAllTimers(); expect(onBeforeBlurWithin).toHaveBeenCalledTimes(0); expect(onAfterBlurWithin).toHaveBeenCalledTimes(0); await act(() => { root.render(); }); - jest.runAllTimers(); expect(onBeforeBlurWithin).toHaveBeenCalledTimes(0); expect(onAfterBlurWithin).toHaveBeenCalledTimes(0); @@ -595,7 +596,6 @@ describe.each(table)(`useFocus`, hasPointerEvents => { await act(() => { root.render(); }); - jest.runAllTimers(); expect(onBeforeBlurWithin).toHaveBeenCalledTimes(1); expect(onAfterBlurWithin).toHaveBeenCalledTimes(1); diff --git a/packages/react-reconciler/src/__tests__/ErrorBoundaryReconciliation-test.internal.js b/packages/react-reconciler/src/__tests__/ErrorBoundaryReconciliation-test.internal.js index 58c25dfdc6a4b..71e047afc5ff6 100644 --- a/packages/react-reconciler/src/__tests__/ErrorBoundaryReconciliation-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ErrorBoundaryReconciliation-test.internal.js @@ -5,8 +5,8 @@ describe('ErrorBoundaryReconciliation', () => { let React; let ReactFeatureFlags; let ReactTestRenderer; - let Scheduler; let span; + let act; beforeEach(() => { jest.resetModules(); @@ -16,8 +16,7 @@ describe('ErrorBoundaryReconciliation', () => { ReactFeatureFlags.replayFailedUnitOfWorkWithInvokeGuardedCallback = false; ReactTestRenderer = require('react-test-renderer'); React = require('react'); - Scheduler = require('scheduler'); - + act = require('internal-test-utils').act; DidCatchErrorBoundary = class extends React.Component { state = {error: null}; componentDidCatch(error) { @@ -52,23 +51,27 @@ describe('ErrorBoundaryReconciliation', () => { }); [true, false].forEach(isConcurrent => { - function sharedTest(ErrorBoundary, fallbackTagName) { - const renderer = ReactTestRenderer.create( - - - , - {unstable_isConcurrent: isConcurrent}, - ); - Scheduler.unstable_flushAll(); - expect(renderer).toMatchRenderedOutput(); + async function sharedTest(ErrorBoundary, fallbackTagName) { + let renderer; - expect(() => { - renderer.update( + await act(() => { + renderer = ReactTestRenderer.create( - + , + {unstable_isConcurrent: isConcurrent}, ); - Scheduler.unstable_flushAll(); + }); + expect(renderer).toMatchRenderedOutput(); + + await expect(async () => { + await act(() => { + renderer.update( + + + , + ); + }); }).toErrorDev(isConcurrent ? ['invalid', 'invalid'] : ['invalid']); const Fallback = fallbackTagName; expect(renderer).toMatchRenderedOutput(); diff --git a/packages/react-reconciler/src/__tests__/ReactSuspenseList-test.js b/packages/react-reconciler/src/__tests__/ReactSuspenseList-test.js index 38b37190dc705..39afe75732272 100644 --- a/packages/react-reconciler/src/__tests__/ReactSuspenseList-test.js +++ b/packages/react-reconciler/src/__tests__/ReactSuspenseList-test.js @@ -16,7 +16,6 @@ describe('ReactSuspenseList', () => { React = require('react'); ReactNoop = require('react-noop-renderer'); Scheduler = require('scheduler'); - act = require('internal-test-utils').act; Profiler = React.Profiler; Suspense = React.Suspense; if (gate(flags => flags.enableSuspenseList)) { @@ -27,6 +26,7 @@ describe('ReactSuspenseList', () => { waitForAll = InternalTestUtils.waitForAll; assertLog = InternalTestUtils.assertLog; waitFor = InternalTestUtils.waitFor; + act = InternalTestUtils.act; }); function Text(props) { @@ -53,7 +53,7 @@ describe('ReactSuspenseList', () => { } // @gate enableSuspenseList - it('warns if an unsupported revealOrder option is used', () => { + it('warns if an unsupported revealOrder option is used', async () => { function Foo() { return ( @@ -62,9 +62,11 @@ describe('ReactSuspenseList', () => { ); } - ReactNoop.render(); - - expect(() => Scheduler.unstable_flushAll()).toErrorDev([ + await expect(async () => { + await act(() => { + ReactNoop.render(); + }); + }).toErrorDev([ 'Warning: "something" is not a supported revealOrder on ' + '. Did you mean "together", "forwards" or "backwards"?' + '\n in SuspenseList (at **)' + @@ -73,7 +75,7 @@ describe('ReactSuspenseList', () => { }); // @gate enableSuspenseList - it('warns if a upper case revealOrder option is used', () => { + it('warns if a upper case revealOrder option is used', async () => { function Foo() { return ( @@ -82,9 +84,11 @@ describe('ReactSuspenseList', () => { ); } - ReactNoop.render(); - - expect(() => Scheduler.unstable_flushAll()).toErrorDev([ + await expect(async () => { + await act(() => { + ReactNoop.render(); + }); + }).toErrorDev([ 'Warning: "TOGETHER" is not a valid value for revealOrder on ' + '. Use lowercase "together" instead.' + '\n in SuspenseList (at **)' + @@ -93,7 +97,7 @@ describe('ReactSuspenseList', () => { }); // @gate enableSuspenseList - it('warns if a misspelled revealOrder option is used', () => { + it('warns if a misspelled revealOrder option is used', async () => { function Foo() { return ( @@ -102,9 +106,11 @@ describe('ReactSuspenseList', () => { ); } - ReactNoop.render(); - - expect(() => Scheduler.unstable_flushAll()).toErrorDev([ + await expect(async () => { + await act(() => { + ReactNoop.render(); + }); + }).toErrorDev([ 'Warning: "forward" is not a valid value for revealOrder on ' + '. React uses the -s suffix in the spelling. ' + 'Use "forwards" instead.' + @@ -131,13 +137,15 @@ describe('ReactSuspenseList', () => { // No warning await waitForAll([]); - ReactNoop.render( - - Child - , - ); - - expect(() => Scheduler.unstable_flushAll()).toErrorDev([ + await expect(async () => { + await act(() => { + ReactNoop.render( + + Child + , + ); + }); + }).toErrorDev([ 'Warning: A single row was passed to a . ' + 'This is not useful since it needs multiple rows. ' + 'Did you mean to pass multiple children or an array?' + @@ -147,7 +155,7 @@ describe('ReactSuspenseList', () => { }); // @gate enableSuspenseList - it('warns if a single fragment is passed to a "backwards" list', () => { + it('warns if a single fragment is passed to a "backwards" list', async () => { function Foo() { return ( @@ -156,9 +164,11 @@ describe('ReactSuspenseList', () => { ); } - ReactNoop.render(); - - expect(() => Scheduler.unstable_flushAll()).toErrorDev([ + await expect(async () => { + await act(() => { + ReactNoop.render(); + }); + }).toErrorDev([ 'Warning: A single row was passed to a . ' + 'This is not useful since it needs multiple rows. ' + 'Did you mean to pass multiple children or an array?' + @@ -168,7 +178,7 @@ describe('ReactSuspenseList', () => { }); // @gate enableSuspenseList - it('warns if a nested array is passed to a "forwards" list', () => { + it('warns if a nested array is passed to a "forwards" list', async () => { function Foo({items}) { return ( @@ -182,9 +192,11 @@ describe('ReactSuspenseList', () => { ); } - ReactNoop.render(); - - expect(() => Scheduler.unstable_flushAll()).toErrorDev([ + await expect(async () => { + await act(() => { + ReactNoop.render(); + }); + }).toErrorDev([ 'Warning: A nested array was passed to row #0 in . ' + 'Wrap it in an additional SuspenseList to configure its revealOrder: ' + ' ... ' + @@ -1471,7 +1483,7 @@ describe('ReactSuspenseList', () => { }); // @gate enableSuspenseList - it('warns if an unsupported tail option is used', () => { + it('warns if an unsupported tail option is used', async () => { function Foo() { return ( @@ -1481,9 +1493,11 @@ describe('ReactSuspenseList', () => { ); } - ReactNoop.render(); - - expect(() => Scheduler.unstable_flushAll()).toErrorDev([ + await expect(async () => { + await act(() => { + ReactNoop.render(); + }); + }).toErrorDev([ 'Warning: "collapse" is not a supported value for tail on ' + '. Did you mean "collapsed" or "hidden"?' + '\n in SuspenseList (at **)' + @@ -1492,7 +1506,7 @@ describe('ReactSuspenseList', () => { }); // @gate enableSuspenseList - it('warns if a tail option is used with "together"', () => { + it('warns if a tail option is used with "together"', async () => { function Foo() { return ( @@ -1501,9 +1515,11 @@ describe('ReactSuspenseList', () => { ); } - ReactNoop.render(); - - expect(() => Scheduler.unstable_flushAll()).toErrorDev([ + await expect(async () => { + await act(() => { + ReactNoop.render(); + }); + }).toErrorDev([ 'Warning: is only valid if ' + 'revealOrder is "forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?' + diff --git a/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.js b/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.js index 32118f5befede..0118fa53f3ad3 100644 --- a/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.js +++ b/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.js @@ -13,7 +13,7 @@ let ReactDOM; let React; let ReactCache; let ReactTestRenderer; -let Scheduler; +let waitForAll; describe('ReactTestRenderer', () => { beforeEach(() => { @@ -25,7 +25,8 @@ describe('ReactTestRenderer', () => { React = require('react'); ReactCache = require('react-cache'); ReactTestRenderer = require('react-test-renderer'); - Scheduler = require('scheduler'); + const InternalTestUtils = require('internal-test-utils'); + waitForAll = InternalTestUtils.waitForAll; }); it('should warn if used to render a ReactDOM portal', () => { @@ -85,16 +86,14 @@ describe('ReactTestRenderer', () => { const root = ReactTestRenderer.create(); PendingResources.initial('initial'); - await Promise.resolve(); - Scheduler.unstable_flushAll(); + await waitForAll([]); expect(root.toJSON()).toEqual('initial'); root.update(); expect(root.toJSON()).toEqual('fallback'); PendingResources.dynamic('dynamic'); - await Promise.resolve(); - Scheduler.unstable_flushAll(); + await waitForAll([]); expect(root.toJSON()).toEqual('dynamic'); }); @@ -111,16 +110,14 @@ describe('ReactTestRenderer', () => { const root = ReactTestRenderer.create(); PendingResources.initial('initial'); - await Promise.resolve(); - Scheduler.unstable_flushAll(); + await waitForAll([]); expect(root.toJSON().children).toEqual(['initial']); root.update(); expect(root.toJSON().children).toEqual(['fallback']); PendingResources.dynamic('dynamic'); - await Promise.resolve(); - Scheduler.unstable_flushAll(); + await waitForAll([]); expect(root.toJSON().children).toEqual(['dynamic']); }); });