@samitouri / QOS-React / commits / d7dce572c7

Remove internal `act` builds from public modules (#21721)

* Move internal version of act to shared module No reason to have three different copies of this anymore. I've left the the renderer-specific `act` entry points because legacy mode tests need to also be wrapped in `batchedUpdates`. Next, I'll update the tests to use `batchedUpdates` manually when needed. * Migrates tests to use internal module directly Instead of the `unstable_concurrentAct` exports. Now we can drop those from the public builds. I put it in the jest-react package since that's where we put our other testing utilities (like `toFlushAndYield`). Not so much so it can be consumed publicly (nobody uses that package except us), but so it works with our build tests. * Remove unused internal fields These were used by the old act implementation. No longer needed.

Andrew Clark committed Jun 22, 2021 at 17:29 UTC d7dce572c7453737a685e791e7afcbc7e2b2fe16
81 files changed +574 -842
packages/jest-react/src/JestReact.js
+2
@@ -10,6 +10,8 @@ import {REACT_ELEMENT_TYPE, REACT_FRAGMENT_TYPE} from 'shared/ReactSymbols';
10 import invariant from 'shared/invariant';
11 import isArray from 'shared/isArray';
12
13 +export {act} from './internalAct';
14 +
15 function captureAssertion(fn) {
16 // Trick to use a Jest matcher inside another Jest matcher. `fn` contains an
17 // assertion; if it throws, we capture the error and return it, so the stack
packages/jest-react/src/internalAct.js renamed
+11 -26
@@ -4,36 +4,27 @@
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 - * @flow
7 + * @flow strict
8 */
9
10 -import type {Thenable} from 'shared/ReactTypes';
11 -
12 -import * as ReactDOM from 'react-dom';
13 -import ReactSharedInternals from 'shared/ReactSharedInternals';
14 -import enqueueTask from 'shared/enqueueTask';
15 -import * as Scheduler from 'scheduler';
16 -
17 -const SecretInternals =
18 - ReactDOM.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
19 -const IsThisRendererActing = SecretInternals.IsThisRendererActing;
20 -
21 -const batchedUpdates = ReactDOM.unstable_batchedUpdates;
22 -
23 -const {IsSomeRendererActing, ReactCurrentActQueue} = ReactSharedInternals;
24 -
10 // This version of `act` is only used by our tests. Unlike the public version
11 // of `act`, it's designed to work identically in both production and
12 // development. It may have slightly different behavior from the public
13 // version, too, since our constraints in our test suite are not the same as
14 // those of developers using React — we're testing React itself, as opposed to
15 // building an app with React.
31 -// TODO: Replace the internal "concurrent" implementations of `act` with a
32 -// single shared module.
16 +
17 +import type {Thenable} from 'shared/ReactTypes';
18 +
19 +import * as Scheduler from 'scheduler/unstable_mock';
20 +
21 +import ReactSharedInternals from 'shared/ReactSharedInternals';
22 +import enqueueTask from 'shared/enqueueTask';
23 +const {ReactCurrentActQueue} = ReactSharedInternals;
24
25 let actingUpdatesScopeDepth = 0;
26
36 -export function unstable_concurrentAct(scope: () => Thenable<mixed> | void) {
27 +export function act(scope: () => Thenable<mixed> | void) {
28 if (Scheduler.unstable_flushAllWithoutAsserting === undefined) {
29 throw Error(
30 'This version of `act` requires a special mock build of Scheduler.',
@@ -47,10 +38,6 @@ export function unstable_concurrentAct(scope: () => Thenable<mixed> | void) {
38 }
39
40 const previousActingUpdatesScopeDepth = actingUpdatesScopeDepth;
50 - const previousIsSomeRendererActing = IsSomeRendererActing.current;
51 - const previousIsThisRendererActing = IsThisRendererActing.current;
52 - IsSomeRendererActing.current = true;
53 - IsThisRendererActing.current = true;
41 actingUpdatesScopeDepth++;
42 if (__DEV__ && actingUpdatesScopeDepth === 1) {
43 ReactCurrentActQueue.disableActWarning = true;
@@ -61,8 +48,6 @@ export function unstable_concurrentAct(scope: () => Thenable<mixed> | void) {
48 ReactCurrentActQueue.disableActWarning = false;
49 }
50 actingUpdatesScopeDepth--;
64 - IsSomeRendererActing.current = previousIsSomeRendererActing;
65 - IsThisRendererActing.current = previousIsThisRendererActing;
51
52 if (__DEV__) {
53 if (actingUpdatesScopeDepth > previousActingUpdatesScopeDepth) {
@@ -80,7 +65,7 @@ export function unstable_concurrentAct(scope: () => Thenable<mixed> | void) {
65 // returned and 2) we could use async/await. Since it's only our used in
66 // our test suite, we should be able to.
67 try {
83 - const thenable = batchedUpdates(scope);
68 + const thenable = scope();
69 if (
70 typeof thenable === 'object' &&
71 thenable !== null &&
packages/react-client/src/__tests__/ReactFlight-test.js
+1 -1
@@ -26,7 +26,7 @@ describe('ReactFlight', () => {
26 ReactNoop = require('react-noop-renderer');
27 ReactNoopFlightServer = require('react-noop-renderer/flight-server');
28 ReactNoopFlightClient = require('react-noop-renderer/flight-client');
29 - act = ReactNoop.act;
29 + act = require('jest-react').act;
30
31 ErrorBoundary = class extends React.Component {
32 state = {hasError: false, error: null};
packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js
+1 -1
@@ -22,7 +22,7 @@ describe('ReactHooksInspectionIntegration', () => {
22 React = require('react');
23 ReactTestRenderer = require('react-test-renderer');
24 Scheduler = require('scheduler');
25 - act = ReactTestRenderer.unstable_concurrentAct;
25 + act = require('jest-react').act;
26 ReactDebugTools = require('react-debug-tools');
27 });
28
packages/react-devtools-shared/src/__tests__/inspectedElement-test.js
+2 -4
@@ -26,7 +26,6 @@ describe('InspectedElement', () => {
26 let InspectedElementContext;
27 let InspectedElementContextController;
28 let StoreContext;
29 - let TestUtils;
29 let TreeContextController;
30
31 let TestUtilsAct;
@@ -45,10 +44,9 @@ describe('InspectedElement', () => {
44 React = require('react');
45 ReactDOM = require('react-dom');
46 PropTypes = require('prop-types');
48 - TestUtils = require('react-dom/test-utils');
49 - TestUtilsAct = TestUtils.unstable_concurrentAct;
47 + TestUtilsAct = require('jest-react').act;
48 TestRenderer = utils.requireTestRenderer();
51 - TestRendererAct = TestUtils.unstable_concurrentAct;
49 + TestRendererAct = require('jest-react').act;
50
51 BridgeContext = require('react-devtools-shared/src/devtools/views/context')
52 .BridgeContext;
packages/react-devtools-shared/src/__tests__/storeComponentFilters-test.js
+3 -3
@@ -13,14 +13,14 @@ import type Store from 'react-devtools-shared/src/devtools/store';
13 describe('Store component filters', () => {
14 let React;
15 let ReactDOM;
16 - let TestUtils;
16 let Types;
17 let bridge: FrontendBridge;
18 let store: Store;
19 let utils;
20 + let internalAct;
21
22 const act = (callback: Function) => {
23 - TestUtils.unstable_concurrentAct(() => {
23 + internalAct(() => {
24 callback();
25 });
26 jest.runAllTimers(); // Flush Bridge operations
@@ -35,9 +35,9 @@ describe('Store component filters', () => {
35
36 React = require('react');
37 ReactDOM = require('react-dom');
38 - TestUtils = require('react-dom/test-utils');
38 Types = require('react-devtools-shared/src/types');
39 utils = require('./utils');
40 + internalAct = require('jest-react').act;
41 });
42
43 it('should throw if filters are updated while profiling', () => {
packages/react-dom/src/__tests__/ReactDOMFiberAsync-test.js
+1 -1
@@ -28,7 +28,7 @@ describe('ReactDOMFiberAsync', () => {
28 container = document.createElement('div');
29 React = require('react');
30 ReactDOM = require('react-dom');
31 - act = require('react-dom/test-utils').unstable_concurrentAct;
31 + act = require('jest-react').act;
32 Scheduler = require('scheduler');
33
34 document.body.appendChild(container);
packages/react-dom/src/__tests__/ReactDOMHooks-test.js
+1 -1
@@ -23,7 +23,7 @@ describe('ReactDOMHooks', () => {
23 React = require('react');
24 ReactDOM = require('react-dom');
25 Scheduler = require('scheduler');
26 - act = require('react-dom/test-utils').unstable_concurrentAct;
26 + act = require('jest-react').act;
27
28 container = document.createElement('div');
29 document.body.appendChild(container);
packages/react-dom/src/__tests__/ReactDOMNativeEventHeuristic-test.js
+1 -1
@@ -24,7 +24,7 @@ describe('ReactDOMNativeEventHeuristic-test', () => {
24 React = require('react');
25 ReactDOM = require('react-dom');
26 Scheduler = require('scheduler');
27 - act = require('react-dom/test-utils').unstable_concurrentAct;
27 + act = require('jest-react').act;
28
29 document.body.appendChild(container);
30 });
packages/react-dom/src/__tests__/ReactDOMNestedEvents-test.js
+1 -3
@@ -13,7 +13,6 @@ describe('ReactDOMNestedEvents', () => {
13 let React;
14 let ReactDOM;
15 let Scheduler;
16 - let TestUtils;
16 let act;
17 let useState;
18
@@ -22,8 +21,7 @@ describe('ReactDOMNestedEvents', () => {
21 React = require('react');
22 ReactDOM = require('react-dom');
23 Scheduler = require('scheduler');
25 - TestUtils = require('react-dom/test-utils');
26 - act = TestUtils.unstable_concurrentAct;
24 + act = require('jest-react').act;
25 useState = React.useState;
26 });
27
packages/react-dom/src/__tests__/ReactDOMRoot-test.js
+1 -1
@@ -25,7 +25,7 @@ describe('ReactDOMRoot', () => {
25 ReactDOM = require('react-dom');
26 ReactDOMServer = require('react-dom/server');
27 Scheduler = require('scheduler');
28 - act = require('react-dom/test-utils').unstable_concurrentAct;
28 + act = require('jest-react').act;
29 });
30
31 it('renders children', () => {
packages/react-dom/src/__tests__/ReactDOMServerIntegrationHooks-test.js
+1 -1
@@ -44,7 +44,7 @@ function initModules() {
44 ReactDOMServer = require('react-dom/server');
45 ReactTestUtils = require('react-dom/test-utils');
46 Scheduler = require('scheduler');
47 - act = ReactTestUtils.unstable_concurrentAct;
47 + act = require('jest-react').act;
48 useState = React.useState;
49 useReducer = React.useReducer;
50 useEffect = React.useEffect;
packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js
+1 -1
@@ -80,7 +80,7 @@ describe('ReactDOMServerPartialHydration', () => {
80
81 React = require('react');
82 ReactDOM = require('react-dom');
83 - act = require('react-dom/test-utils').unstable_concurrentAct;
83 + act = require('jest-react').act;
84 ReactDOMServer = require('react-dom/server');
85 Scheduler = require('scheduler');
86 Suspense = React.Suspense;
packages/react-dom/src/__tests__/ReactDOMServerSelectiveHydration-test.internal.js
+1 -3
@@ -14,7 +14,6 @@ import {createEventTarget} from 'dom-event-testing-library';
14 let React;
15 let ReactDOM;
16 let ReactDOMServer;
17 -let ReactTestUtils;
17 let Scheduler;
18 let Suspense;
19 let act;
@@ -118,8 +117,7 @@ describe('ReactDOMServerSelectiveHydration', () => {
117 React = require('react');
118 ReactDOM = require('react-dom');
119 ReactDOMServer = require('react-dom/server');
121 - ReactTestUtils = require('react-dom/test-utils');
122 - act = ReactTestUtils.unstable_concurrentAct;
120 + act = require('jest-react').act;
121 Scheduler = require('scheduler');
122 Suspense = React.Suspense;
123
packages/react-dom/src/__tests__/ReactDOMServerSuspense-test.internal.js
+1 -1
@@ -25,7 +25,7 @@ function initModules() {
25 ReactDOM = require('react-dom');
26 ReactDOMServer = require('react-dom/server');
27 ReactTestUtils = require('react-dom/test-utils');
28 - act = ReactTestUtils.unstable_concurrentAct;
28 + act = require('jest-react').act;
29
30 // Make them available to the helpers.
31 return {
packages/react-dom/src/__tests__/ReactDOMSuspensePlaceholder-test.js
+1 -3
@@ -13,7 +13,6 @@ let React;
13 let ReactDOM;
14 let Suspense;
15 let ReactCache;
16 -let ReactTestUtils;
16 let Scheduler;
17 let TextResource;
18 let act;
@@ -26,9 +25,8 @@ describe('ReactDOMSuspensePlaceholder', () => {
25 React = require('react');
26 ReactDOM = require('react-dom');
27 ReactCache = require('react-cache');
29 - ReactTestUtils = require('react-dom/test-utils');
28 Scheduler = require('scheduler');
31 - act = ReactTestUtils.unstable_concurrentAct;
29 + act = require('jest-react').act;
30 Suspense = React.Suspense;
31 container = document.createElement('div');
32 document.body.appendChild(container);
packages/react-dom/src/__tests__/ReactErrorBoundaries-test.internal.js
+1 -1
@@ -45,7 +45,7 @@ describe('ReactErrorBoundaries', () => {
45 ReactFeatureFlags.skipUnmountedBoundaries = true;
46 ReactDOM = require('react-dom');
47 React = require('react');
48 - act = require('react-dom/test-utils').unstable_concurrentAct;
48 + act = require('jest-react').act;
49 Scheduler = require('scheduler');
50
51 BrokenConstructor = class extends React.Component {
packages/react-dom/src/__tests__/ReactUpdates-test.js
+1 -1
@@ -21,7 +21,7 @@ describe('ReactUpdates', () => {
21 React = require('react');
22 ReactDOM = require('react-dom');
23 ReactTestUtils = require('react-dom/test-utils');
24 - act = ReactTestUtils.unstable_concurrentAct;
24 + act = require('jest-react').act;
25 Scheduler = require('scheduler');
26 });
27
packages/react-dom/src/__tests__/ReactWrongReturnPointer-test.js
+7 -5
@@ -10,6 +10,7 @@
10 let React;
11 let ReactNoop;
12 let Scheduler;
13 +let act;
14 let Suspense;
15 let SuspenseList;
16 let getCacheForType;
@@ -20,6 +21,7 @@ beforeEach(() => {
21 React = require('react');
22 ReactNoop = require('react-noop-renderer');
23 Scheduler = require('scheduler');
24 + act = require('jest-react').act;
25
26 Suspense = React.Suspense;
27 SuspenseList = React.SuspenseList;
@@ -180,12 +182,12 @@ test('warns in DEV if return pointer is inconsistent', async () => {
182 }
183
184 const root = ReactNoop.createRoot();
183 - await ReactNoop.act(async () => {
185 + await act(async () => {
186 root.render(<App text="A" />);
187 });
188
189 spyOnDev(console, 'error');
188 - await ReactNoop.act(async () => {
190 + await act(async () => {
191 root.render(<App text="B" />);
192 });
193 expect(console.error.calls.count()).toBe(1);
@@ -225,7 +227,7 @@ test('regression (#20932): return pointer is correct before entering deleted tre
227 }
228
229 const root = ReactNoop.createRoot();
228 - await ReactNoop.act(async () => {
230 + await act(async () => {
231 root.render(<App />);
232 });
233 expect(Scheduler).toHaveYielded([
@@ -233,11 +235,11 @@ test('regression (#20932): return pointer is correct before entering deleted tre
235 'Loading Async...',
236 'Loading Tail...',
237 ]);
236 - await ReactNoop.act(async () => {
238 + await act(async () => {
239 resolveText(0);
240 });
241 expect(Scheduler).toHaveYielded([0, 'Tail']);
240 - await ReactNoop.act(async () => {
242 + await act(async () => {
243 setAsyncText(x => x + 1);
244 });
245 expect(Scheduler).toHaveYielded([
packages/react-dom/src/__tests__/utils/ReactDOMServerIntegrationTestUtils.js
+5 -4
@@ -15,10 +15,11 @@ const shouldIgnoreConsoleError = require('../../../../../scripts/jest/shouldIgno
15 module.exports = function(initModules) {
16 let ReactDOM;
17 let ReactDOMServer;
18 - let ReactTestUtils;
18 + let act;
19
20 function resetModules() {
21 - ({ReactDOM, ReactDOMServer, ReactTestUtils} = initModules());
21 + ({ReactDOM, ReactDOMServer} = initModules());
22 + act = require('jest-react').act;
23 }
24
25 function shouldUseDocument(reactElement) {
@@ -50,11 +51,11 @@ module.exports = function(initModules) {
51 function asyncReactDOMRender(reactElement, domElement, forceHydrate) {
52 return new Promise(resolve => {
53 if (forceHydrate) {
53 - ReactTestUtils.unstable_concurrentAct(() => {
54 + act(() => {
55 ReactDOM.hydrate(reactElement, domElement);
56 });
57 } else {
57 - ReactTestUtils.unstable_concurrentAct(() => {
58 + act(() => {
59 ReactDOM.render(reactElement, domElement);
60 });
61 }
packages/react-dom/src/client/ReactDOM.js
-3
@@ -28,7 +28,6 @@ import {
28 flushSync,
29 flushControlled,
30 injectIntoDevTools,
31 - IsThisRendererActing,
31 attemptSynchronousHydration,
32 attemptDiscreteHydration,
33 attemptContinuousHydration,
@@ -164,8 +163,6 @@ const Internals = {
163 restoreStateIfNeeded,
164 batchedUpdates,
165 ],
167 - // TODO: Temporary. Only used by our internal version of `act. Will remove.
168 - IsThisRendererActing,
166 };
167
168 export {
packages/react-dom/src/events/__tests__/DOMPluginEventSystem-test.internal.js
+2 -4
@@ -16,7 +16,6 @@ let ReactFeatureFlags;
16 let ReactDOM;
17 let ReactDOMServer;
18 let Scheduler;
19 -let ReactTestUtils;
19 let act;
20
21 function dispatchEvent(element, type) {
@@ -67,7 +66,7 @@ describe('DOMPluginEventSystem', () => {
66 ReactDOM = require('react-dom');
67 Scheduler = require('scheduler');
68 ReactDOMServer = require('react-dom/server');
70 - act = require('react-dom/test-utils').unstable_concurrentAct;
69 + act = require('jest-react').act;
70 container = document.createElement('div');
71 document.body.appendChild(container);
72 startNativeEventListenerClearDown();
@@ -1253,8 +1252,7 @@ describe('DOMPluginEventSystem', () => {
1252 ReactDOM = require('react-dom');
1253 Scheduler = require('scheduler');
1254 ReactDOMServer = require('react-dom/server');
1256 - ReactTestUtils = require('react-dom/test-utils');
1257 - act = ReactTestUtils.unstable_concurrentAct;
1255 + act = require('jest-react').act;
1256 });
1257
1258 // @gate www
packages/react-dom/src/events/plugins/__tests__/ChangeEventPlugin-test.js
+2 -3
@@ -11,9 +11,9 @@
11
12 let React;
13 let ReactDOM;
14 -let TestUtils;
14 let ReactFeatureFlags;
15 let Scheduler;
16 +let act;
17
18 const setUntrackedChecked = Object.getOwnPropertyDescriptor(
19 HTMLInputElement.prototype,
@@ -56,7 +56,7 @@ describe('ChangeEventPlugin', () => {
56 };
57 React = require('react');
58 ReactDOM = require('react-dom');
59 - TestUtils = require('react-dom/test-utils');
59 + act = require('jest-react').act;
60 Scheduler = require('scheduler');
61 container = document.createElement('div');
62 document.body.appendChild(container);
@@ -727,7 +727,6 @@ describe('ChangeEventPlugin', () => {
727 });
728
729 it('mouse enter/leave should be user-blocking but not discrete', async () => {
730 - const {unstable_concurrentAct: act} = TestUtils;
730 const {useState} = React;
731
732 const root = ReactDOM.createRoot(container);
packages/react-dom/src/events/plugins/__tests__/SimpleEventPlugin-test.js
+1 -1
@@ -237,7 +237,7 @@ describe('SimpleEventPlugin', function() {
237 ReactDOM = require('react-dom');
238 Scheduler = require('scheduler');
239
240 - act = require('react-dom/test-utils').unstable_concurrentAct;
240 + act = require('jest-react').act;
241 });
242
243 it('flushes pending interactive work before exiting event handler', async () => {
packages/react-dom/src/test-utils/ReactTestUtils.js
-2
@@ -18,7 +18,6 @@ import {
18 import {SyntheticEvent} from '../events/SyntheticEvent';
19 import invariant from 'shared/invariant';
20 import {ELEMENT_NODE} from '../shared/HTMLNodeType';
21 -import {unstable_concurrentAct} from './ReactTestUtilsInternalAct';
21 import {
22 rethrowCaughtError,
23 invokeGuardedCallbackAndCatchFirstError,
@@ -732,5 +731,4 @@ export {
731 nativeTouchData,
732 Simulate,
733 act,
735 - unstable_concurrentAct,
734 };
packages/react-interactions/events/src/dom/create-event-handle/__tests__/useFocusWithin-test.internal.js
+1 -3
@@ -15,7 +15,6 @@ let React;
15 let ReactFeatureFlags;
16 let ReactDOM;
17 let useFocusWithin;
18 -let ReactTestRenderer;
18 let act;
19 let Scheduler;
20
@@ -27,9 +26,8 @@ function initializeModules(hasPointerEvents) {
26 ReactFeatureFlags.enableCreateEventHandleAPI = true;
27 React = require('react');
28 ReactDOM = require('react-dom');
30 - ReactTestRenderer = require('react-test-renderer');
29 Scheduler = require('scheduler');
32 - act = ReactTestRenderer.unstable_concurrentAct;
30 + act = require('jest-react').act;
31
32 // TODO: This import throws outside of experimental mode. Figure out better
33 // strategy for gated imports.
packages/react-noop-renderer/src/createReactNoop.js
+1 -130
@@ -16,7 +16,7 @@
16
17 import type {Fiber} from 'react-reconciler/src/ReactInternalTypes';
18 import type {UpdateQueue} from 'react-reconciler/src/ReactUpdateQueue';
19 -import type {ReactNodeList, Thenable} from 'shared/ReactTypes';
19 +import type {ReactNodeList} from 'shared/ReactTypes';
20 import type {RootTag} from 'react-reconciler/src/ReactRootTags';
21
22 import * as Scheduler from 'scheduler/unstable_mock';
@@ -29,10 +29,6 @@ import {
29 LegacyRoot,
30 } from 'react-reconciler/constants';
31
32 -import ReactSharedInternals from 'shared/ReactSharedInternals';
33 -import enqueueTask from 'shared/enqueueTask';
34 -const {IsSomeRendererActing, ReactCurrentActQueue} = ReactSharedInternals;
35 -
32 type Container = {
33 rootID: string,
34 children: Array<Instance | TextInstance>,
@@ -927,8 +923,6 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
923
924 flushPassiveEffects: NoopRenderer.flushPassiveEffects,
925
930 - act: noopAct,
931 -
926 // Logs the current state of the tree.
927 dumpTree(rootID: string = DEFAULT_ROOT_ID) {
928 const root = roots.get(rootID);
@@ -1042,129 +1036,6 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
1036 },
1037 };
1038
1045 - // This version of `act` is only used by our tests. Unlike the public version
1046 - // of `act`, it's designed to work identically in both production and
1047 - // development. It may have slightly different behavior from the public
1048 - // version, too, since our constraints in our test suite are not the same as
1049 - // those of developers using React — we're testing React itself, as opposed to
1050 - // building an app with React.
1051 - // TODO: Replace the internal "concurrent" implementations of `act` with a
1052 - // single shared module.
1053 -
1054 - const {batchedUpdates, IsThisRendererActing} = NoopRenderer;
1055 - let actingUpdatesScopeDepth = 0;
1056 -
1057 - function noopAct(scope: () => Thenable<mixed> | void) {
1058 - if (Scheduler.unstable_flushAllWithoutAsserting === undefined) {
1059 - throw Error(
1060 - 'This version of `act` requires a special mock build of Scheduler.',
1061 - );
1062 - }
1063 - if (setTimeout._isMockFunction !== true) {
1064 - throw Error(
1065 - "This version of `act` requires Jest's timer mocks " +
1066 - '(i.e. jest.useFakeTimers).',
1067 - );
1068 - }
1069 -
1070 - const previousActingUpdatesScopeDepth = actingUpdatesScopeDepth;
1071 - const previousIsSomeRendererActing = IsSomeRendererActing.current;
1072 - const previousIsThisRendererActing = IsThisRendererActing.current;
1073 - IsSomeRendererActing.current = true;
1074 - IsThisRendererActing.current = true;
1075 - actingUpdatesScopeDepth++;
1076 - if (__DEV__ && actingUpdatesScopeDepth === 1) {
1077 - ReactCurrentActQueue.disableActWarning = true;
1078 - }
1079 -
1080 - const unwind = () => {
1081 - if (__DEV__ && actingUpdatesScopeDepth === 1) {
1082 - ReactCurrentActQueue.disableActWarning = false;
1083 - }
1084 - actingUpdatesScopeDepth--;
1085 - IsSomeRendererActing.current = previousIsSomeRendererActing;
1086 - IsThisRendererActing.current = previousIsThisRendererActing;
1087 -
1088 - if (__DEV__) {
1089 - if (actingUpdatesScopeDepth > previousActingUpdatesScopeDepth) {
1090 - // if it's _less than_ previousActingUpdatesScopeDepth, then we can
1091 - // assume the 'other' one has warned
1092 - console.error(
1093 - 'You seem to have overlapping act() calls, this is not supported. ' +
1094 - 'Be sure to await previous act() calls before making a new one. ',
1095 - );
1096 - }
1097 - }
1098 - };
1099 -
1100 - // TODO: This would be way simpler if 1) we required a promise to be
1101 - // returned and 2) we could use async/await. Since it's only our used in
1102 - // our test suite, we should be able to.
1103 - try {
1104 - const thenable = batchedUpdates(scope);
1105 - if (
1106 - typeof thenable === 'object' &&
1107 - thenable !== null &&
1108 - typeof thenable.then === 'function'
1109 - ) {
1110 - return {
1111 - then(resolve: () => void, reject: (error: mixed) => void) {
1112 - thenable.then(
1113 - () => {
1114 - flushActWork(
1115 - () => {
1116 - unwind();
1117 - resolve();
1118 - },
1119 - error => {
1120 - unwind();
1121 - reject(error);
1122 - },
1123 - );
1124 - },
1125 - error => {
1126 - unwind();
1127 - reject(error);
1128 - },
1129 - );
1130 - },
1131 - };
1132 - } else {
1133 - try {
1134 - // TODO: Let's not support non-async scopes at all in our tests. Need to
1135 - // migrate existing tests.
1136 - let didFlushWork;
1137 - do {
1138 - didFlushWork = Scheduler.unstable_flushAllWithoutAsserting();
1139 - } while (didFlushWork);
1140 - } finally {
1141 - unwind();
1142 - }
1143 - }
1144 - } catch (error) {
1145 - unwind();
1146 - throw error;
1147 - }
1148 - }
1149 -
1150 - function flushActWork(resolve, reject) {
1151 - // Flush suspended fallbacks
1152 - // $FlowFixMe: Flow doesn't know about global Jest object
1153 - jest.runOnlyPendingTimers();
1154 - enqueueTask(() => {
1155 - try {
1156 - const didFlushWork = Scheduler.unstable_flushAllWithoutAsserting();
1157 - if (didFlushWork) {
1158 - flushActWork(resolve, reject);
1159 - } else {
1160 - resolve();
1161 - }
1162 - } catch (error) {
1163 - reject(error);
1164 - }
1165 - });
1166 - }
1167 -
1039 return ReactNoop;
1040 }
1041
packages/react-reconciler/src/ReactFiberReconciler.js
-5
@@ -26,7 +26,6 @@ import {
26 flushControlled as flushControlled_old,
27 flushSync as flushSync_old,
28 flushPassiveEffects as flushPassiveEffects_old,
29 - IsThisRendererActing as IsThisRendererActing_old,
29 getPublicRootInstance as getPublicRootInstance_old,
30 attemptSynchronousHydration as attemptSynchronousHydration_old,
31 attemptDiscreteHydration as attemptDiscreteHydration_old,
@@ -66,7 +65,6 @@ import {
65 flushControlled as flushControlled_new,
66 flushSync as flushSync_new,
67 flushPassiveEffects as flushPassiveEffects_new,
69 - IsThisRendererActing as IsThisRendererActing_new,
68 getPublicRootInstance as getPublicRootInstance_new,
69 attemptSynchronousHydration as attemptSynchronousHydration_new,
70 attemptDiscreteHydration as attemptDiscreteHydration_new,
@@ -125,9 +123,6 @@ export const flushSync = enableNewReconciler ? flushSync_new : flushSync_old;
123 export const flushPassiveEffects = enableNewReconciler
124 ? flushPassiveEffects_new
125 : flushPassiveEffects_old;
128 -export const IsThisRendererActing = enableNewReconciler
129 - ? IsThisRendererActing_new
130 - : IsThisRendererActing_old;
126 export const getPublicRootInstance = enableNewReconciler
127 ? getPublicRootInstance_new
128 : getPublicRootInstance_old;
packages/react-reconciler/src/ReactFiberReconciler.new.js
-2
@@ -60,7 +60,6 @@ import {
60 discreteUpdates,
61 flushDiscreteUpdates,
62 flushPassiveEffects,
63 - IsThisRendererActing,
63 } from './ReactFiberWorkLoop.new';
64 import {
65 createUpdate,
@@ -337,7 +336,6 @@ export {
336 flushControlled,
337 flushSync,
338 flushPassiveEffects,
340 - IsThisRendererActing,
339 };
340
341 export function getPublicRootInstance(
packages/react-reconciler/src/ReactFiberReconciler.old.js
-2
@@ -60,7 +60,6 @@ import {
60 discreteUpdates,
61 flushDiscreteUpdates,
62 flushPassiveEffects,
63 - IsThisRendererActing,
63 } from './ReactFiberWorkLoop.old';
64 import {
65 createUpdate,
@@ -337,7 +336,6 @@ export {
336 flushControlled,
337 flushSync,
338 flushPassiveEffects,
340 - IsThisRendererActing,
339 };
340
341 export function getPublicRootInstance(
packages/react-reconciler/src/ReactFiberWorkLoop.new.js
-3
@@ -2767,9 +2767,6 @@ function warnAboutRenderPhaseUpdatesInDEV(fiber) {
2767 }
2768 }
2769
2770 -// a 'shared' variable that changes when act() opens/closes in tests.
2771 -export const IsThisRendererActing = {current: (false: boolean)};
2772 -
2770 export function restorePendingUpdaters(root: FiberRoot, lanes: Lanes): void {
2771 if (enableUpdaterTracking) {
2772 if (isDevToolsPresent) {
packages/react-reconciler/src/ReactFiberWorkLoop.old.js
-3
@@ -2767,9 +2767,6 @@ function warnAboutRenderPhaseUpdatesInDEV(fiber) {
2767 }
2768 }
2769
2770 -// a 'shared' variable that changes when act() opens/closes in tests.
2771 -export const IsThisRendererActing = {current: (false: boolean)};
2772 -
2770 export function restorePendingUpdaters(root: FiberRoot, lanes: Lanes): void {
2771 if (enableUpdaterTracking) {
2772 if (isDevToolsPresent) {
packages/react-reconciler/src/__tests__/ReactCPUSuspense-test.js
+8 -6
@@ -1,6 +1,7 @@
1 let React;
2 let ReactNoop;
3 let Scheduler;
4 +let act;
5 let Suspense;
6 let useState;
7 let textCache;
@@ -16,6 +17,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
17 React = require('react');
18 ReactNoop = require('react-noop-renderer');
19 Scheduler = require('scheduler');
20 + act = require('jest-react').act;
21 Suspense = React.Suspense;
22 useState = React.useState;
23
@@ -123,7 +125,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
125 }
126
127 const root = ReactNoop.createRoot();
126 - await ReactNoop.act(async () => {
128 + await act(async () => {
129 root.render(<App />);
130 expect(Scheduler).toFlushUntilNextPaint(['Outer', 'Loading...']);
131 expect(root).toMatchRenderedOutput(
@@ -165,7 +167,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
167
168 // Initial mount
169 const root = ReactNoop.createRoot();
168 - await ReactNoop.act(async () => {
170 + await act(async () => {
171 root.render(<App />);
172 });
173 // Inner contents finish in separate commit from outer
@@ -178,7 +180,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
180 );
181
182 // Update
181 - await ReactNoop.act(async () => {
183 + await act(async () => {
184 setCount(1);
185 });
186 // Entire update finishes in a single commit
@@ -208,7 +210,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
210 }
211
212 const root = ReactNoop.createRoot();
211 - await ReactNoop.act(async () => {
213 + await act(async () => {
214 root.render(<App />);
215 expect(Scheduler).toFlushUntilNextPaint(['Outer', 'Loading...']);
216 expect(root).toMatchRenderedOutput(
@@ -228,7 +230,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
230 );
231
232 // Resolve the data and finish rendering
231 - await ReactNoop.act(async () => {
233 + await act(async () => {
234 await resolveText('Inner');
235 });
236 expect(Scheduler).toHaveYielded(['Inner']);
@@ -264,7 +266,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
266 }
267
268 const root = ReactNoop.createRoot();
267 - await ReactNoop.act(async () => {
269 + await act(async () => {
270 root.render(<App />);
271 });
272 // Each level commits separately
packages/react-reconciler/src/__tests__/ReactCache-test.js
+52 -50
@@ -3,6 +3,7 @@ let ReactNoop;
3 let Cache;
4 let getCacheForType;
5 let Scheduler;
6 +let act;
7 let Suspense;
8 let useCacheRefresh;
9 let startTransition;
@@ -19,6 +20,7 @@ describe('ReactCache', () => {
20 ReactNoop = require('react-noop-renderer');
21 Cache = React.unstable_Cache;
22 Scheduler = require('scheduler');
23 + act = require('jest-react').act;
24 Suspense = React.Suspense;
25 getCacheForType = React.unstable_getCacheForType;
26 useCacheRefresh = React.unstable_useCacheRefresh;
@@ -152,7 +154,7 @@ describe('ReactCache', () => {
154 // @gate experimental || www
155 test('render Cache component', async () => {
156 const root = ReactNoop.createRoot();
155 - await ReactNoop.act(async () => {
157 + await act(async () => {
158 root.render(<Cache>Hi</Cache>);
159 });
160 expect(root).toMatchRenderedOutput('Hi');
@@ -161,7 +163,7 @@ describe('ReactCache', () => {
163 // @gate experimental || www
164 test('mount new data', async () => {
165 const root = ReactNoop.createRoot();
164 - await ReactNoop.act(async () => {
166 + await act(async () => {
167 root.render(
168 <Cache>
169 <Suspense fallback={<Text text="Loading..." />}>
@@ -173,7 +175,7 @@ describe('ReactCache', () => {
175 expect(Scheduler).toHaveYielded(['Cache miss! [A]', 'Loading...']);
176 expect(root).toMatchRenderedOutput('Loading...');
177
176 - await ReactNoop.act(async () => {
178 + await act(async () => {
179 resolveMostRecentTextCache('A');
180 });
181 expect(Scheduler).toHaveYielded(['A']);
@@ -183,7 +185,7 @@ describe('ReactCache', () => {
185 // @gate experimental || www
186 test('root acts as implicit cache boundary', async () => {
187 const root = ReactNoop.createRoot();
186 - await ReactNoop.act(async () => {
188 + await act(async () => {
189 root.render(
190 <Suspense fallback={<Text text="Loading..." />}>
191 <AsyncText text="A" />
@@ -193,7 +195,7 @@ describe('ReactCache', () => {
195 expect(Scheduler).toHaveYielded(['Cache miss! [A]', 'Loading...']);
196 expect(root).toMatchRenderedOutput('Loading...');
197
196 - await ReactNoop.act(async () => {
198 + await act(async () => {
199 resolveMostRecentTextCache('A');
200 });
201 expect(Scheduler).toHaveYielded(['A']);
@@ -220,7 +222,7 @@ describe('ReactCache', () => {
222 }
223
224 const root = ReactNoop.createRoot();
223 - await ReactNoop.act(async () => {
225 + await act(async () => {
226 root.render(<App showMore={false} />);
227 });
228 // Even though there are two new <Cache /> trees, they should share the same
@@ -232,7 +234,7 @@ describe('ReactCache', () => {
234 ]);
235 expect(root).toMatchRenderedOutput('Loading...Loading...');
236
235 - await ReactNoop.act(async () => {
237 + await act(async () => {
238 resolveMostRecentTextCache('A');
239 });
240 expect(Scheduler).toHaveYielded(['A', 'A']);
@@ -256,7 +258,7 @@ describe('ReactCache', () => {
258 }
259
260 const root = ReactNoop.createRoot();
259 - await ReactNoop.act(async () => {
261 + await act(async () => {
262 root.render(<App />);
263 });
264 // Even though there are two new <Cache /> trees, they should share the same
@@ -264,7 +266,7 @@ describe('ReactCache', () => {
266 expect(Scheduler).toHaveYielded(['Cache miss! [A]', 'Loading...']);
267 expect(root).toMatchRenderedOutput('Loading...');
268
267 - await ReactNoop.act(async () => {
269 + await act(async () => {
270 resolveMostRecentTextCache('A');
271 });
272 expect(Scheduler).toHaveYielded(['A', 'A']);
@@ -290,7 +292,7 @@ describe('ReactCache', () => {
292 }
293
294 const root = ReactNoop.createRoot();
293 - await ReactNoop.act(async () => {
295 + await act(async () => {
296 seedNextTextCache('A');
297 root.render(<App showMore={false} />);
298 });
@@ -298,7 +300,7 @@ describe('ReactCache', () => {
300 expect(root).toMatchRenderedOutput('A [v1]');
301
302 // Add a new cache boundary
301 - await ReactNoop.act(async () => {
303 + await act(async () => {
304 root.render(<App showMore={true} />);
305 });
306 expect(Scheduler).toHaveYielded([
@@ -331,7 +333,7 @@ describe('ReactCache', () => {
333 }
334
335 const root = ReactNoop.createRoot();
334 - await ReactNoop.act(async () => {
336 + await act(async () => {
337 seedNextTextCache('A');
338 root.render(<App showMore={false} />);
339 });
@@ -339,7 +341,7 @@ describe('ReactCache', () => {
341 expect(root).toMatchRenderedOutput('A [v1]');
342
343 // Add a new cache boundary
342 - await ReactNoop.act(async () => {
344 + await act(async () => {
345 root.render(<App showMore={true} />);
346 });
347 expect(Scheduler).toHaveYielded([
@@ -349,7 +351,7 @@ describe('ReactCache', () => {
351 'Loading...',
352 ]);
353 expect(root).toMatchRenderedOutput('A [v1]Loading...');
352 - await ReactNoop.act(async () => {
354 + await act(async () => {
355 resolveMostRecentTextCache('A');
356 });
357 expect(Scheduler).toHaveYielded(['A [v2]']);
@@ -396,13 +398,13 @@ describe('ReactCache', () => {
398 return <Text text="Content" />;
399 }
400
399 - await ReactNoop.act(async () => {
401 + await act(async () => {
402 root.render(<App />);
403 });
404 expect(Scheduler).toHaveYielded(['Cache miss! [A]', 'Loading shell...']);
405 expect(root).toMatchRenderedOutput('Loading shell...');
406
405 - await ReactNoop.act(async () => {
407 + await act(async () => {
408 resolveMostRecentTextCache('A');
409 });
410 expect(Scheduler).toHaveYielded([
@@ -419,7 +421,7 @@ describe('ReactCache', () => {
421 </>,
422 );
423
422 - await ReactNoop.act(async () => {
424 + await act(async () => {
425 resolveMostRecentTextCache('B');
426 });
427 expect(Scheduler).toHaveYielded(['Content']);
@@ -441,7 +443,7 @@ describe('ReactCache', () => {
443
444 // Mount initial data
445 const root = ReactNoop.createRoot();
444 - await ReactNoop.act(async () => {
446 + await act(async () => {
447 root.render(
448 <Cache>
449 <Suspense fallback={<Text text="Loading..." />}>
@@ -453,20 +455,20 @@ describe('ReactCache', () => {
455 expect(Scheduler).toHaveYielded(['Cache miss! [A]', 'Loading...']);
456 expect(root).toMatchRenderedOutput('Loading...');
457
456 - await ReactNoop.act(async () => {
458 + await act(async () => {
459 resolveMostRecentTextCache('A');
460 });
461 expect(Scheduler).toHaveYielded(['A [v1]']);
462 expect(root).toMatchRenderedOutput('A [v1]');
463
464 // Fefresh for new data.
463 - await ReactNoop.act(async () => {
465 + await act(async () => {
466 startTransition(() => refresh());
467 });
468 expect(Scheduler).toHaveYielded(['Cache miss! [A]', 'Loading...']);
469 expect(root).toMatchRenderedOutput('A [v1]');
470
469 - await ReactNoop.act(async () => {
471 + await act(async () => {
472 resolveMostRecentTextCache('A');
473 });
474 // Note that the version has updated
@@ -484,7 +486,7 @@ describe('ReactCache', () => {
486
487 // Mount initial data
488 const root = ReactNoop.createRoot();
487 - await ReactNoop.act(async () => {
489 + await act(async () => {
490 root.render(
491 <Suspense fallback={<Text text="Loading..." />}>
492 <App />
@@ -494,20 +496,20 @@ describe('ReactCache', () => {
496 expect(Scheduler).toHaveYielded(['Cache miss! [A]', 'Loading...']);
497 expect(root).toMatchRenderedOutput('Loading...');
498
497 - await ReactNoop.act(async () => {
499 + await act(async () => {
500 resolveMostRecentTextCache('A');
501 });
502 expect(Scheduler).toHaveYielded(['A [v1]']);
503 expect(root).toMatchRenderedOutput('A [v1]');
504
505 // Refresh for new data.
504 - await ReactNoop.act(async () => {
506 + await act(async () => {
507 startTransition(() => refresh());
508 });
509 expect(Scheduler).toHaveYielded(['Cache miss! [A]', 'Loading...']);
510 expect(root).toMatchRenderedOutput('A [v1]');
511
510 - await ReactNoop.act(async () => {
512 + await act(async () => {
513 resolveMostRecentTextCache('A');
514 });
515 // Note that the version has updated
@@ -525,7 +527,7 @@ describe('ReactCache', () => {
527
528 // Mount initial data
529 const root = ReactNoop.createRoot();
528 - await ReactNoop.act(async () => {
530 + await act(async () => {
531 root.render(
532 <Cache>
533 <Suspense fallback={<Text text="Loading..." />}>
@@ -537,14 +539,14 @@ describe('ReactCache', () => {
539 expect(Scheduler).toHaveYielded(['Cache miss! [A]', 'Loading...']);
540 expect(root).toMatchRenderedOutput('Loading...');
541
540 - await ReactNoop.act(async () => {
542 + await act(async () => {
543 resolveMostRecentTextCache('A');
544 });
545 expect(Scheduler).toHaveYielded(['A [v1]']);
546 expect(root).toMatchRenderedOutput('A [v1]');
547
548 // Refresh for new data.
547 - await ReactNoop.act(async () => {
549 + await act(async () => {
550 // Refresh the cache with seeded data, like you would receive from a
551 // server mutation.
552 // TODO: Seeding multiple typed caches. Should work by calling `refresh`
@@ -585,7 +587,7 @@ describe('ReactCache', () => {
587 }
588
589 const root = ReactNoop.createRoot();
588 - await ReactNoop.act(async () => {
590 + await act(async () => {
591 seedNextTextCache('A');
592 root.render(<App showMore={false} />);
593 });
@@ -593,7 +595,7 @@ describe('ReactCache', () => {
595 expect(root).toMatchRenderedOutput('A [v1]');
596
597 // Add a new cache boundary
596 - await ReactNoop.act(async () => {
598 + await act(async () => {
599 seedNextTextCache('A');
600 root.render(<App showMore={true} />);
601 });
@@ -606,7 +608,7 @@ describe('ReactCache', () => {
608
609 // Now refresh the shell. This should also cause the "Show More" contents to
610 // refresh, since its cache is nested inside the outer one.
609 - await ReactNoop.act(async () => {
611 + await act(async () => {
612 startTransition(() => refreshShell());
613 });
614 expect(Scheduler).toHaveYielded([
@@ -616,7 +618,7 @@ describe('ReactCache', () => {
618 ]);
619 expect(root).toMatchRenderedOutput('A [v1]A [v2]');
620
619 - await ReactNoop.act(async () => {
621 + await act(async () => {
622 resolveMostRecentTextCache('A');
623 });
624 expect(Scheduler).toHaveYielded(['A [v3]', 'A [v3]']);
@@ -657,12 +659,12 @@ describe('ReactCache', () => {
659 // treated like sibling providers that happen to share an underlying
660 // cache, as opposed to consumers of the root-level cache.
661 const root = ReactNoop.createRoot();
660 - await ReactNoop.act(async () => {
662 + await act(async () => {
663 root.render(<App showMore={false} />);
664 });
665
666 // Now reveal the boundaries. In a real app this would be a navigation.
665 - await ReactNoop.act(async () => {
667 + await act(async () => {
668 root.render(<App showMore={true} />);
669 });
670
@@ -675,7 +677,7 @@ describe('ReactCache', () => {
677 ]);
678 expect(root).toMatchRenderedOutput('Loading...Loading...');
679
678 - await ReactNoop.act(async () => {
680 + await act(async () => {
681 resolveMostRecentTextCache('A');
682 });
683 expect(Scheduler).toHaveYielded(['A [v1]', 'A [v1]']);
@@ -683,12 +685,12 @@ describe('ReactCache', () => {
685
686 // Refresh the first boundary. It should not refresh the second boundary,
687 // even though they previously shared the same underlying cache.
686 - await ReactNoop.act(async () => {
688 + await act(async () => {
689 await refreshFirstBoundary();
690 });
691 expect(Scheduler).toHaveYielded(['Cache miss! [A]', 'Loading...']);
692
691 - await ReactNoop.act(async () => {
693 + await act(async () => {
694 resolveMostRecentTextCache('A');
695 });
696 expect(Scheduler).toHaveYielded(['A [v2]']);
@@ -723,7 +725,7 @@ describe('ReactCache', () => {
725 }
726
727 const root = ReactNoop.createRoot();
726 - await ReactNoop.act(async () => {
728 + await act(async () => {
729 root.render(<App showMore={false} />);
730 });
731 expect(Scheduler).toHaveYielded([
@@ -732,7 +734,7 @@ describe('ReactCache', () => {
734 'Loading...',
735 ]);
736
735 - await ReactNoop.act(async () => {
737 + await act(async () => {
738 // This will resolve the content in the first cache
739 resolveMostRecentTextCache('A');
740 resolveMostRecentTextCache('B');
@@ -750,7 +752,7 @@ describe('ReactCache', () => {
752 ]);
753
754 // Now resolve the second tree
753 - await ReactNoop.act(async () => {
755 + await act(async () => {
756 resolveMostRecentTextCache('A');
757 });
758 expect(Scheduler).toHaveYielded(['A [v2]']);
@@ -769,7 +771,7 @@ describe('ReactCache', () => {
771 }
772
773 const root = ReactNoop.createRoot();
772 - await ReactNoop.act(async () => {
774 + await act(async () => {
775 root.render(
776 <Suspense fallback={<Text text="Loading..." />}>(empty)</Suspense>,
777 );
@@ -777,7 +779,7 @@ describe('ReactCache', () => {
779 expect(Scheduler).toHaveYielded([]);
780 expect(root).toMatchRenderedOutput('(empty)');
781
780 - await ReactNoop.act(async () => {
782 + await act(async () => {
783 startTransition(() => {
784 root.render(
785 <Suspense fallback={<Text text="Loading..." />}>
@@ -789,7 +791,7 @@ describe('ReactCache', () => {
791 expect(Scheduler).toHaveYielded(['Cache miss! [A]', 'Loading...']);
792 expect(root).toMatchRenderedOutput('(empty)');
793
792 - await ReactNoop.act(async () => {
794 + await act(async () => {
795 startTransition(() => {
796 root.render(
797 <Suspense fallback={<Text text="Loading..." />}>
@@ -806,14 +808,14 @@ describe('ReactCache', () => {
808 expect(root).toMatchRenderedOutput('(empty)');
809
810 // Resolve the request
809 - await ReactNoop.act(async () => {
811 + await act(async () => {
812 resolveMostRecentTextCache('A');
813 });
814 expect(Scheduler).toHaveYielded(['A [v1]', 'A [v1]']);
815 expect(root).toMatchRenderedOutput('A [v1]A [v1]');
816
817 // Now do another transition
816 - await ReactNoop.act(async () => {
818 + await act(async () => {
819 startTransition(() => {
820 root.render(
821 <Suspense fallback={<Text text="Loading..." />}>
@@ -834,7 +836,7 @@ describe('ReactCache', () => {
836 ]);
837 expect(root).toMatchRenderedOutput('A [v1]A [v1]');
838
837 - await ReactNoop.act(async () => {
839 + await act(async () => {
840 resolveMostRecentTextCache('A');
841 });
842 expect(Scheduler).toHaveYielded(['A [v1]', 'A [v1]', 'A [v2]']);
@@ -877,13 +879,13 @@ describe('ReactCache', () => {
879 }
880
881 const root = ReactNoop.createRoot();
880 - await ReactNoop.act(async () => {
882 + await act(async () => {
883 root.render(<App showMore={false} />);
884 });
885 expect(Scheduler).toHaveYielded(['0']);
886 expect(root).toMatchRenderedOutput('0');
887
886 - await ReactNoop.act(async () => {
888 + await act(async () => {
889 startTransition(() => {
890 showMore();
891 });
@@ -891,7 +893,7 @@ describe('ReactCache', () => {
893 expect(Scheduler).toHaveYielded(['Cache miss! [A]', 'Loading...']);
894 expect(root).toMatchRenderedOutput('0');
895
894 - await ReactNoop.act(async () => {
896 + await act(async () => {
897 updateUnrelated(1);
898 });
899 expect(Scheduler).toHaveYielded([
@@ -903,7 +905,7 @@ describe('ReactCache', () => {
905 ]);
906 expect(root).toMatchRenderedOutput('1');
907
906 - await ReactNoop.act(async () => {
908 + await act(async () => {
909 resolveMostRecentTextCache('A');
910 });
911 expect(Scheduler).toHaveYielded(['A']);
packages/react-reconciler/src/__tests__/ReactClassSetStateCallback-test.js
+4 -2
@@ -1,6 +1,7 @@
1 let React;
2 let ReactNoop;
3 let Scheduler;
4 +let act;
5
6 describe('ReactClassSetStateCallback', () => {
7 beforeEach(() => {
@@ -9,6 +10,7 @@ describe('ReactClassSetStateCallback', () => {
10 React = require('react');
11 ReactNoop = require('react-noop-renderer');
12 Scheduler = require('scheduler');
13 + act = require('jest-react').act;
14 });
15
16 function Text({text}) {
@@ -27,12 +29,12 @@ describe('ReactClassSetStateCallback', () => {
29 }
30
31 const root = ReactNoop.createRoot();
30 - await ReactNoop.act(async () => {
32 + await act(async () => {
33 root.render(<App />);
34 });
35 expect(Scheduler).toHaveYielded([0]);
36
35 - await ReactNoop.act(async () => {
37 + await act(async () => {
38 app.setState({step: 1}, () =>
39 Scheduler.unstable_yieldValue('Callback 1'),
40 );
packages/react-reconciler/src/__tests__/ReactContextPropagation-test.js
+34 -32
@@ -1,6 +1,7 @@
1 let React;
2 let ReactNoop;
3 let Scheduler;
4 +let act;
5 let useState;
6 let useContext;
7 let Suspense;
@@ -16,6 +17,7 @@ describe('ReactLazyContextPropagation', () => {
17 React = require('react');
18 ReactNoop = require('react-noop-renderer');
19 Scheduler = require('scheduler');
20 + act = require('jest-react').act;
21 useState = React.useState;
22 useContext = React.useContext;
23 Suspense = React.Suspense;
@@ -195,13 +197,13 @@ describe('ReactLazyContextPropagation', () => {
197 return <Text text={value} />;
198 }
199
198 - await ReactNoop.act(async () => {
200 + await act(async () => {
201 root.render(<App />);
202 });
203 expect(Scheduler).toHaveYielded([0]);
204 expect(root).toMatchRenderedOutput('0');
205
204 - await ReactNoop.act(async () => {
206 + await act(async () => {
207 setValue(1);
208 });
209 expect(Scheduler).toHaveYielded([1]);
@@ -237,13 +239,13 @@ describe('ReactLazyContextPropagation', () => {
239 return <Text text={value} />;
240 }
241
240 - await ReactNoop.act(async () => {
242 + await act(async () => {
243 root.render(<App />);
244 });
245 expect(Scheduler).toHaveYielded([0]);
246 expect(root).toMatchRenderedOutput('0');
247
246 - await ReactNoop.act(async () => {
248 + await act(async () => {
249 setValue(1);
250 });
251 expect(Scheduler).toHaveYielded([1]);
@@ -280,13 +282,13 @@ describe('ReactLazyContextPropagation', () => {
282 return <Text text={value} />;
283 }
284
283 - await ReactNoop.act(async () => {
285 + await act(async () => {
286 root.render(<App />);
287 });
288 expect(Scheduler).toHaveYielded([0]);
289 expect(root).toMatchRenderedOutput('0');
290
289 - await ReactNoop.act(async () => {
291 + await act(async () => {
292 setValue(1);
293 });
294 expect(Scheduler).toHaveYielded([1]);
@@ -318,13 +320,13 @@ describe('ReactLazyContextPropagation', () => {
320 return <Text text={value} />;
321 });
322
321 - await ReactNoop.act(async () => {
323 + await act(async () => {
324 root.render(<App />);
325 });
326 expect(Scheduler).toHaveYielded(['Consumer', 0]);
327 expect(root).toMatchRenderedOutput('0');
328
327 - await ReactNoop.act(async () => {
329 + await act(async () => {
330 // Intentionally calling setState to some other arbitrary value before
331 // setting it back to the current one. That way an update is scheduled,
332 // but we'll bail out during render when nothing has changed.
@@ -380,13 +382,13 @@ describe('ReactLazyContextPropagation', () => {
382 }
383
384 await seedNextTextCache('A');
383 - await ReactNoop.act(async () => {
385 + await act(async () => {
386 root.render(<App />);
387 });
388 expect(Scheduler).toHaveYielded(['A', 'A']);
389 expect(root).toMatchRenderedOutput('AA');
390
389 - await ReactNoop.act(async () => {
391 + await act(async () => {
392 // Intentionally not wrapping in startTransition, so that the fallback
393 // the fallback displays despite this being a refresh.
394 setContext('B');
@@ -394,7 +396,7 @@ describe('ReactLazyContextPropagation', () => {
396 expect(Scheduler).toHaveYielded(['Suspend! [B]', 'Loading...', 'B']);
397 expect(root).toMatchRenderedOutput('Loading...B');
398
397 - await ReactNoop.act(async () => {
399 + await act(async () => {
400 await resolveText('B');
401 });
402 expect(Scheduler).toHaveYielded(['B']);
@@ -460,13 +462,13 @@ describe('ReactLazyContextPropagation', () => {
462 }
463
464 await seedNextTextCache('A');
463 - await ReactNoop.act(async () => {
465 + await act(async () => {
466 root.render(<App />);
467 });
468 expect(Scheduler).toHaveYielded(['A', 'A', 'A']);
469 expect(root).toMatchRenderedOutput('AAA');
470
469 - await ReactNoop.act(async () => {
471 + await act(async () => {
472 // Intentionally not wrapping in startTransition, so that the fallback
473 // the fallback displays despite this being a refresh.
474 setContext('B');
@@ -474,7 +476,7 @@ describe('ReactLazyContextPropagation', () => {
476 expect(Scheduler).toHaveYielded(['Suspend! [B]', 'Loading...', 'B']);
477 expect(root).toMatchRenderedOutput('Loading...B');
478
477 - await ReactNoop.act(async () => {
479 + await act(async () => {
480 await resolveText('B');
481 });
482 expect(Scheduler).toHaveYielded(['B', 'B']);
@@ -521,13 +523,13 @@ describe('ReactLazyContextPropagation', () => {
523 }
524
525 await seedNextTextCache('A');
524 - await ReactNoop.act(async () => {
526 + await act(async () => {
527 root.render(<App />);
528 });
529 expect(Scheduler).toHaveYielded(['A', 'A']);
530 expect(root).toMatchRenderedOutput('AA');
531
530 - await ReactNoop.act(async () => {
532 + await act(async () => {
533 // Intentionally not wrapping in startTransition, so that the fallback
534 // the fallback displays despite this being a refresh.
535 setContext('B');
@@ -535,7 +537,7 @@ describe('ReactLazyContextPropagation', () => {
537 expect(Scheduler).toHaveYielded(['Suspend! [B]', 'Loading...', 'B']);
538 expect(root).toMatchRenderedOutput('Loading...B');
539
538 - await ReactNoop.act(async () => {
540 + await act(async () => {
541 await resolveText('B');
542 });
543 expect(Scheduler).toHaveYielded(['B']);
@@ -575,13 +577,13 @@ describe('ReactLazyContextPropagation', () => {
577 }
578
579 await seedNextTextCache('A');
578 - await ReactNoop.act(async () => {
580 + await act(async () => {
581 root.render(<App />);
582 });
583 expect(Scheduler).toHaveYielded(['A', 'A']);
584 expect(root).toMatchRenderedOutput('AA');
585
584 - await ReactNoop.act(async () => {
586 + await act(async () => {
587 setContext('B');
588 });
589 expect(Scheduler).toHaveYielded(['B', 'B']);
@@ -636,13 +638,13 @@ describe('ReactLazyContextPropagation', () => {
638 }
639
640 await seedNextTextCache('A');
639 - await ReactNoop.act(async () => {
641 + await act(async () => {
642 root.render(<App />);
643 });
644 expect(Scheduler).toHaveYielded(['A', 'A', 'A']);
645 expect(root).toMatchRenderedOutput('AAA');
646
645 - await ReactNoop.act(async () => {
647 + await act(async () => {
648 setContext('B');
649 });
650 expect(Scheduler).toHaveYielded(['B', 'B', 'B']);
@@ -677,13 +679,13 @@ describe('ReactLazyContextPropagation', () => {
679 }
680
681 const root = ReactNoop.createRoot();
680 - await ReactNoop.act(async () => {
682 + await act(async () => {
683 root.render(<App />);
684 });
685 expect(Scheduler).toHaveYielded(['A', 'A']);
686 expect(root).toMatchRenderedOutput('AA');
687
686 - await ReactNoop.act(async () => {
688 + await act(async () => {
689 setContext('B');
690 });
691 expect(Scheduler).toHaveYielded(['B', 'B']);
@@ -731,13 +733,13 @@ describe('ReactLazyContextPropagation', () => {
733 }
734
735 const root = ReactNoop.createRoot();
734 - await ReactNoop.act(async () => {
736 + await act(async () => {
737 root.render(<App />);
738 });
739 expect(Scheduler).toHaveYielded(['A', 'A']);
740 expect(root).toMatchRenderedOutput('AA');
741
740 - await ReactNoop.act(async () => {
742 + await act(async () => {
743 setContext('B');
744 });
745 expect(Scheduler).toHaveYielded(['B', 'B']);
@@ -794,19 +796,19 @@ describe('ReactLazyContextPropagation', () => {
796
797 const root = ReactNoop.createRoot();
798 await seedNextTextCache('A');
797 - await ReactNoop.act(async () => {
799 + await act(async () => {
800 root.render(<App />);
801 });
802 expect(Scheduler).toHaveYielded(['A', 'A']);
803 expect(root).toMatchRenderedOutput('AA');
804
803 - await ReactNoop.act(async () => {
805 + await act(async () => {
806 setContext('B');
807 });
808 expect(Scheduler).toHaveYielded(['Suspend! [B]', 'Loading...']);
809 expect(root).toMatchRenderedOutput('Loading...');
810
809 - await ReactNoop.act(async () => {
811 + await act(async () => {
812 await resolveText('B');
813 });
814 expect(Scheduler).toHaveYielded(['B', 'B']);
@@ -855,13 +857,13 @@ describe('ReactLazyContextPropagation', () => {
857 }
858
859 const root = ReactNoop.createRoot();
858 - await ReactNoop.act(async () => {
860 + await act(async () => {
861 root.render(<App />);
862 });
863 expect(Scheduler).toHaveYielded(['A', 'A']);
864 expect(root).toMatchRenderedOutput('AA');
865
864 - await ReactNoop.act(async () => {
866 + await act(async () => {
867 setContext('B');
868 });
869 expect(Scheduler).toHaveYielded(['B', 'B']);
@@ -904,13 +906,13 @@ describe('ReactLazyContextPropagation', () => {
906 }
907
908 const root = ReactNoop.createRoot();
907 - await ReactNoop.act(async () => {
909 + await act(async () => {
910 root.render(<App />);
911 });
912 expect(Scheduler).toHaveYielded(['A', 'A']);
913 expect(root).toMatchRenderedOutput('AA');
914
913 - await ReactNoop.act(async () => {
915 + await act(async () => {
916 setContext('B');
917 });
918 expect(Scheduler).toHaveYielded(['B', 'B']);
packages/react-reconciler/src/__tests__/ReactEffectOrdering-test.js
+6 -4
@@ -15,6 +15,7 @@
15 let React;
16 let ReactNoop;
17 let Scheduler;
18 +let act;
19 let useEffect;
20 let useLayoutEffect;
21
@@ -26,6 +27,7 @@ describe('ReactHooksWithNoopRenderer', () => {
27 React = require('react');
28 ReactNoop = require('react-noop-renderer');
29 Scheduler = require('scheduler');
30 + act = require('jest-react').act;
31 useEffect = React.useEffect;
32 useLayoutEffect = React.useLayoutEffect;
33 });
@@ -47,11 +49,11 @@ describe('ReactHooksWithNoopRenderer', () => {
49 return 'Child';
50 }
51
50 - await ReactNoop.act(async () => {
52 + await act(async () => {
53 root.render(<Parent />);
54 });
55 expect(root).toMatchRenderedOutput('Child');
54 - await ReactNoop.act(async () => {
56 + await act(async () => {
57 root.render(null);
58 });
59 expect(Scheduler).toHaveYielded(['Unmount parent', 'Unmount child']);
@@ -74,11 +76,11 @@ describe('ReactHooksWithNoopRenderer', () => {
76 return 'Child';
77 }
78
77 - await ReactNoop.act(async () => {
79 + await act(async () => {
80 root.render(<Parent />);
81 });
82 expect(root).toMatchRenderedOutput('Child');
81 - await ReactNoop.act(async () => {
83 + await act(async () => {
84 root.render(null);
85 });
86 expect(Scheduler).toHaveYielded(['Unmount parent', 'Unmount child']);
packages/react-reconciler/src/__tests__/ReactExpiration-test.js
+16 -14
@@ -12,6 +12,7 @@
12 let React;
13 let ReactNoop;
14 let Scheduler;
15 +let act;
16 let readText;
17 let resolveText;
18 let startTransition;
@@ -25,6 +26,7 @@ describe('ReactExpiration', () => {
26 React = require('react');
27 ReactNoop = require('react-noop-renderer');
28 Scheduler = require('scheduler');
29 + act = require('jest-react').act;
30 startTransition = React.startTransition;
31 useState = React.useState;
32 useEffect = React.useEffect;
@@ -496,14 +498,14 @@ describe('ReactExpiration', () => {
498 }
499
500 const root = ReactNoop.createRoot();
499 - await ReactNoop.act(async () => {
501 + await act(async () => {
502 root.render(<App />);
503 });
504 expect(Scheduler).toHaveYielded(['Sync pri: 0', 'Normal pri: 0']);
505 expect(root).toMatchRenderedOutput('Sync pri: 0, Normal pri: 0');
506
507 // First demonstrate what happens when there's no starvation
506 - await ReactNoop.act(async () => {
508 + await act(async () => {
509 if (gate(flags => flags.enableSyncDefaultUpdates)) {
510 React.startTransition(() => {
511 updateNormalPri();
@@ -527,7 +529,7 @@ describe('ReactExpiration', () => {
529 expect(root).toMatchRenderedOutput('Sync pri: 1, Normal pri: 1');
530
531 // Do the same thing, but starve the first update
530 - await ReactNoop.act(async () => {
532 + await act(async () => {
533 if (gate(flags => flags.enableSyncDefaultUpdates)) {
534 React.startTransition(() => {
535 updateNormalPri();
@@ -575,14 +577,14 @@ describe('ReactExpiration', () => {
577 }
578
579 const root = ReactNoop.createRoot();
578 - await ReactNoop.act(async () => {
580 + await act(async () => {
581 root.render(<App />);
582 });
583 expect(Scheduler).toHaveYielded(['Sync pri: 0', 'Idle pri: 0']);
584 expect(root).toMatchRenderedOutput('Sync pri: 0, Idle pri: 0');
585
586 // First demonstrate what happens when there's no starvation
585 - await ReactNoop.act(async () => {
587 + await act(async () => {
588 updateIdlePri();
589 expect(Scheduler).toFlushAndYieldThrough(['Sync pri: 0']);
590 updateSyncPri();
@@ -598,7 +600,7 @@ describe('ReactExpiration', () => {
600 expect(root).toMatchRenderedOutput('Sync pri: 1, Idle pri: 1');
601
602 // Do the same thing, but starve the first update
601 - await ReactNoop.act(async () => {
603 + await act(async () => {
604 updateIdlePri();
605 expect(Scheduler).toFlushAndYieldThrough(['Sync pri: 1']);
606
@@ -638,13 +640,13 @@ describe('ReactExpiration', () => {
640 }
641
642 const root = ReactNoop.createRoot();
641 - await ReactNoop.act(async () => {
643 + await act(async () => {
644 root.render(<App />);
645 });
646 expect(Scheduler).toHaveYielded(['A0', 'B0', 'C']);
647 expect(root).toMatchRenderedOutput('A0B0C');
648
647 - await ReactNoop.act(async () => {
649 + await act(async () => {
650 startTransition(() => {
651 setA(1);
652 });
@@ -682,14 +684,14 @@ describe('ReactExpiration', () => {
684 }
685
686 const root = ReactNoop.createRoot();
685 - await ReactNoop.act(async () => {
687 + await act(async () => {
688 await resolveText('A0');
689 root.render(<App step={0} />);
690 });
691 expect(Scheduler).toHaveYielded(['A0', 'B', 'C']);
692 expect(root).toMatchRenderedOutput('A0BC');
693
692 - await ReactNoop.act(async () => {
694 + await act(async () => {
695 if (gate(flags => flags.enableSyncDefaultUpdates)) {
696 React.startTransition(() => {
697 root.render(<App step={1} />);
@@ -741,12 +743,12 @@ describe('ReactExpiration', () => {
743 }
744
745 const root = ReactNoop.createRoot();
744 - await ReactNoop.act(async () => {
746 + await act(async () => {
747 root.render(<App />);
748 });
749 expect(Scheduler).toHaveYielded(['A0', 'B0']);
750
749 - await ReactNoop.act(async () => {
751 + await act(async () => {
752 startTransition(() => {
753 setA(1);
754 });
@@ -782,13 +784,13 @@ describe('ReactExpiration', () => {
784 }
785
786 const root = ReactNoop.createRoot();
785 - await ReactNoop.act(async () => {
787 + await act(async () => {
788 root.render(<App step={0} />);
789 });
790 expect(Scheduler).toHaveYielded(['A0', 'B0', 'C0', 'Effect: 0']);
791 expect(root).toMatchRenderedOutput('A0B0C0');
792
791 - await ReactNoop.act(async () => {
793 + await act(async () => {
794 startTransition(() => {
795 root.render(<App step={1} />);
796 });
packages/react-reconciler/src/__tests__/ReactFlushSync-test.js
+8 -6
@@ -1,6 +1,7 @@
1 let React;
2 let ReactNoop;
3 let Scheduler;
4 +let act;
5 let useState;
6 let useEffect;
7 let startTransition;
@@ -12,6 +13,7 @@ describe('ReactFlushSync', () => {
13 React = require('react');
14 ReactNoop = require('react-noop-renderer');
15 Scheduler = require('scheduler');
16 + act = require('jest-react').act;
17 useState = React.useState;
18 useEffect = React.useEffect;
19 startTransition = React.startTransition;
@@ -36,7 +38,7 @@ describe('ReactFlushSync', () => {
38 }
39
40 const root = ReactNoop.createRoot();
39 - await ReactNoop.act(async () => {
41 + await act(async () => {
42 if (gate(flags => flags.enableSyncDefaultUpdates)) {
43 React.startTransition(() => {
44 root.render(<App />);
@@ -75,13 +77,13 @@ describe('ReactFlushSync', () => {
77 }
78
79 const root = ReactNoop.createRoot();
78 - await ReactNoop.act(async () => {
80 + await act(async () => {
81 root.render(<App />);
82 });
83 expect(Scheduler).toHaveYielded(['0, 0']);
84 expect(root).toMatchRenderedOutput('0, 0');
85
84 - await ReactNoop.act(async () => {
86 + await act(async () => {
87 ReactNoop.flushSync(() => {
88 startTransition(() => {
89 // This should be async even though flushSync is on the stack, because
@@ -112,7 +114,7 @@ describe('ReactFlushSync', () => {
114 }
115
116 const root = ReactNoop.createRoot();
115 - await ReactNoop.act(async () => {
117 + await act(async () => {
118 ReactNoop.flushSync(() => {
119 root.render(<App />);
120 });
@@ -135,7 +137,7 @@ describe('ReactFlushSync', () => {
137 }
138
139 const root = ReactNoop.createLegacyRoot();
138 - await ReactNoop.act(async () => {
140 + await act(async () => {
141 ReactNoop.flushSync(() => {
142 root.render(<App />);
143 });
@@ -159,7 +161,7 @@ describe('ReactFlushSync', () => {
161 }
162
163 const root = ReactNoop.createRoot();
162 - await ReactNoop.act(async () => {
164 + await act(async () => {
165 root.render(<App />);
166 expect(Scheduler).toFlushUntilNextPaint([
167 'Child',
packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js
+10 -8
@@ -31,7 +31,7 @@ describe('ReactHooks', () => {
31 ReactTestRenderer = require('react-test-renderer');
32 Scheduler = require('scheduler');
33 ReactDOMServer = require('react-dom/server');
34 - act = ReactTestRenderer.unstable_concurrentAct;
34 + act = require('jest-react').act;
35 });
36
37 if (__DEV__) {
@@ -1775,13 +1775,15 @@ describe('ReactHooks', () => {
1775 }
1776
1777 await act(async () => {
1778 - ReactTestRenderer.create(
1779 - <>
1780 - <A />
1781 - <B />
1782 - </>,
1783 - );
1784 - expect(() => Scheduler.unstable_flushAll()).toThrow('Hello');
1778 + ReactTestRenderer.unstable_batchedUpdates(() => {
1779 + ReactTestRenderer.create(
1780 + <>
1781 + <A />
1782 + <B />
1783 + </>,
1784 + );
1785 + expect(() => Scheduler.unstable_flushAll()).toThrow('Hello');
1786 + });
1787 });
1788
1789 if (__DEV__) {
packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js
+15 -15
@@ -42,6 +42,7 @@ describe('ReactHooksWithNoopRenderer', () => {
42 React = require('react');
43 ReactNoop = require('react-noop-renderer');
44 Scheduler = require('scheduler');
45 + act = require('jest-react').act;
46 useState = React.useState;
47 useReducer = React.useReducer;
48 useEffect = React.useEffect;
@@ -55,7 +56,6 @@ describe('ReactHooksWithNoopRenderer', () => {
56 useTransition = React.useTransition;
57 useDeferredValue = React.useDeferredValue;
58 Suspense = React.Suspense;
58 - act = ReactNoop.act;
59 ContinuousEventPriority = require('react-reconciler/constants')
60 .ContinuousEventPriority;
61
@@ -500,7 +500,7 @@ describe('ReactHooksWithNoopRenderer', () => {
500
501 const root = ReactNoop.createRoot();
502
503 - await ReactNoop.act(async () => {
503 + await act(async () => {
504 root.render(
505 <>
506 <Foo />
@@ -511,7 +511,7 @@ describe('ReactHooksWithNoopRenderer', () => {
511 expect(Scheduler).toHaveYielded(['Foo [0]', 'Bar']);
512
513 // Bar will update Foo during its render phase. React should warn.
514 - await ReactNoop.act(async () => {
514 + await act(async () => {
515 root.render(
516 <>
517 <Foo />
@@ -527,7 +527,7 @@ describe('ReactHooksWithNoopRenderer', () => {
527 });
528
529 // It should not warn again (deduplication).
530 - await ReactNoop.act(async () => {
530 + await act(async () => {
531 root.render(
532 <>
533 <Foo />
@@ -675,7 +675,7 @@ describe('ReactHooksWithNoopRenderer', () => {
675
676 // Test that it works on update, too. This time the log is a bit different
677 // because we started with reducerB instead of reducerA.
678 - ReactNoop.act(() => {
678 + act(() => {
679 counter.current.dispatch('reset');
680 });
681 ReactNoop.render(<Counter ref={counter} />);
@@ -787,7 +787,7 @@ describe('ReactHooksWithNoopRenderer', () => {
787 expect(Scheduler).toFlushAndYield(['A:0']);
788 expect(root).toMatchRenderedOutput(<span prop="A:0" />);
789
790 - await ReactNoop.act(async () => {
790 + await act(async () => {
791 if (gate(flags => flags.enableSyncDefaultUpdates)) {
792 React.startTransition(() => {
793 root.render(<Foo signal={false} />);
@@ -3492,7 +3492,7 @@ describe('ReactHooksWithNoopRenderer', () => {
3492 }
3493
3494 const root = ReactNoop.createRoot(null);
3495 - await ReactNoop.act(async () => {
3495 + await act(async () => {
3496 root.render(
3497 <>
3498 <CounterA />
@@ -3507,7 +3507,7 @@ describe('ReactHooksWithNoopRenderer', () => {
3507 'Commit B: 0',
3508 ]);
3509
3510 - await ReactNoop.act(async () => {
3510 + await act(async () => {
3511 setCounterA(1);
3512
3513 // In the same batch, update B twice. To trigger the condition we're
@@ -3714,7 +3714,7 @@ describe('ReactHooksWithNoopRenderer', () => {
3714 }
3715
3716 const root = ReactNoop.createRoot();
3717 - await ReactNoop.act(async () => {
3717 + await act(async () => {
3718 root.render(<App />);
3719 });
3720 expect(Scheduler).toHaveYielded([
@@ -3724,7 +3724,7 @@ describe('ReactHooksWithNoopRenderer', () => {
3724 'Mount B',
3725 ]);
3726
3727 - await ReactNoop.act(async () => {
3727 + await act(async () => {
3728 await resolveText('A');
3729 });
3730 expect(Scheduler).toHaveYielded([
@@ -3733,7 +3733,7 @@ describe('ReactHooksWithNoopRenderer', () => {
3733 'Suspend! [B]',
3734 ]);
3735
3736 - await ReactNoop.act(async () => {
3736 + await act(async () => {
3737 root.render(null);
3738 });
3739 // In the regression, SuspenseList would cause the children to "forget" that
@@ -3760,25 +3760,25 @@ describe('ReactHooksWithNoopRenderer', () => {
3760 return <Text text={`Render: ${count}`} />;
3761 }
3762
3763 - ReactNoop.act(() => {
3763 + act(() => {
3764 ReactNoop.render(<Test />);
3765 });
3766
3767 expect(Scheduler).toHaveYielded(['Render: 0', 'Effect: 0']);
3768
3769 - ReactNoop.act(() => {
3769 + act(() => {
3770 handleClick();
3771 });
3772
3773 expect(Scheduler).toHaveYielded(['Render: 0']);
3774
3775 - ReactNoop.act(() => {
3775 + act(() => {
3776 handleClick();
3777 });
3778
3779 expect(Scheduler).toHaveYielded(['Render: 0']);
3780
3781 - ReactNoop.act(() => {
3781 + act(() => {
3782 handleClick();
3783 });
3784
packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js
+5 -3
@@ -15,6 +15,7 @@ let PropTypes;
15 let React;
16 let ReactNoop;
17 let Scheduler;
18 +let act;
19
20 describe('ReactIncrementalErrorHandling', () => {
21 beforeEach(() => {
@@ -25,6 +26,7 @@ describe('ReactIncrementalErrorHandling', () => {
26 React = require('react');
27 ReactNoop = require('react-noop-renderer');
28 Scheduler = require('scheduler');
29 + act = require('jest-react').act;
30 });
31
32 function div(...children) {
@@ -1843,7 +1845,7 @@ describe('ReactIncrementalErrorHandling', () => {
1845 throw Error('Oops');
1846 }
1847
1846 - await ReactNoop.act(async () => {
1848 + await act(async () => {
1849 if (gate(flags => flags.enableSyncDefaultUpdates)) {
1850 React.startTransition(() => {
1851 root.render(<Oops />);
@@ -1886,11 +1888,11 @@ describe('ReactIncrementalErrorHandling', () => {
1888 return 'Everything is fine.';
1889 }
1890
1889 - await ReactNoop.act(async () => {
1891 + await act(async () => {
1892 root.render(<Oops />);
1893 });
1894
1893 - await ReactNoop.act(async () => {
1895 + await act(async () => {
1896 // Schedule a default pri and a low pri update on the root.
1897 root.render(<Oops />);
1898 React.startTransition(() => {
packages/react-reconciler/src/__tests__/ReactIncrementalScheduling-test.js
+4 -2
@@ -13,6 +13,7 @@
13 let React;
14 let ReactNoop;
15 let Scheduler;
16 +let act;
17
18 describe('ReactIncrementalScheduling', () => {
19 beforeEach(() => {
@@ -21,6 +22,7 @@ describe('ReactIncrementalScheduling', () => {
22 React = require('react');
23 ReactNoop = require('react-noop-renderer');
24 Scheduler = require('scheduler');
25 + act = require('jest-react').act;
26 });
27
28 function span(prop) {
@@ -94,7 +96,7 @@ describe('ReactIncrementalScheduling', () => {
96 return text;
97 }
98
97 - ReactNoop.act(() => {
99 + act(() => {
100 ReactNoop.renderToRootWithID(<Text text="a:1" />, 'a');
101 ReactNoop.renderToRootWithID(<Text text="b:1" />, 'b');
102 ReactNoop.renderToRootWithID(<Text text="c:1" />, 'c');
@@ -106,7 +108,7 @@ describe('ReactIncrementalScheduling', () => {
108 expect(ReactNoop.getChildrenAsJSX('c')).toEqual('c:1');
109
110 // Schedule deferred work in the reverse order
109 - ReactNoop.act(() => {
111 + act(() => {
112 if (gate(flags => flags.enableSyncDefaultUpdates)) {
113 React.startTransition(() => {
114 ReactNoop.renderToRootWithID(<Text text="c:2" />, 'c');
packages/react-reconciler/src/__tests__/ReactIncrementalUpdates-test.js
+10 -8
@@ -14,6 +14,7 @@ let React;
14 let ReactNoop;
15 let Scheduler;
16 let ContinuousEventPriority;
17 +let act;
18
19 describe('ReactIncrementalUpdates', () => {
20 beforeEach(() => {
@@ -22,6 +23,7 @@ describe('ReactIncrementalUpdates', () => {
23 React = require('react');
24 ReactNoop = require('react-noop-renderer');
25 Scheduler = require('scheduler');
26 + act = require('jest-react').act;
27 ContinuousEventPriority = require('react-reconciler/constants')
28 .ContinuousEventPriority;
29 });
@@ -556,7 +558,7 @@ describe('ReactIncrementalUpdates', () => {
558 return null;
559 }
560
559 - ReactNoop.act(() => {
561 + act(() => {
562 if (gate(flags => flags.enableSyncDefaultUpdates)) {
563 React.startTransition(() => {
564 ReactNoop.render(<App />);
@@ -664,13 +666,13 @@ describe('ReactIncrementalUpdates', () => {
666 }
667
668 const root = ReactNoop.createRoot();
667 - await ReactNoop.act(async () => {
669 + await act(async () => {
670 root.render(<App />);
671 });
672 expect(Scheduler).toHaveYielded(['Committed: ']);
673 expect(root).toMatchRenderedOutput('');
674
673 - await ReactNoop.act(async () => {
675 + await act(async () => {
676 if (gate(flags => flags.enableSyncDefaultUpdates)) {
677 React.startTransition(() => {
678 pushToLog('A');
@@ -725,13 +727,13 @@ describe('ReactIncrementalUpdates', () => {
727 }
728
729 const root = ReactNoop.createRoot();
728 - await ReactNoop.act(async () => {
730 + await act(async () => {
731 root.render(<App />);
732 });
733 expect(Scheduler).toHaveYielded([]);
734 expect(root).toMatchRenderedOutput('');
735
734 - await ReactNoop.act(async () => {
736 + await act(async () => {
737 if (gate(flags => flags.enableSyncDefaultUpdates)) {
738 React.startTransition(() => {
739 pushToLog('A');
@@ -788,20 +790,20 @@ describe('ReactIncrementalUpdates', () => {
790 }
791
792 const root = ReactNoop.createRoot();
791 - await ReactNoop.act(async () => {
793 + await act(async () => {
794 root.render(<App prop="A" />);
795 });
796 expect(root).toMatchRenderedOutput('0');
797
798 // Changing the prop causes the count to increase by 100
797 - await ReactNoop.act(async () => {
799 + await act(async () => {
800 root.render(<App prop="B" />);
801 });
802 expect(root).toMatchRenderedOutput('100');
803
804 // Now increment the count by 1 with a state update. And, in the same
805 // batch, change the prop back to its original value.
804 - await ReactNoop.act(async () => {
806 + await act(async () => {
807 root.render(<App prop="A" />);
808 app.setState(state => ({count: state.count + 1}));
809 });
packages/react-reconciler/src/__tests__/ReactInterleavedUpdates-test.js
+6 -4
@@ -4,6 +4,7 @@ let Scheduler;
4 let startTransition;
5 let useState;
6 let useEffect;
7 +let act;
8
9 describe('ReactInterleavedUpdates', () => {
10 beforeEach(() => {
@@ -12,6 +13,7 @@ describe('ReactInterleavedUpdates', () => {
13 React = require('react');
14 ReactNoop = require('react-noop-renderer');
15 Scheduler = require('scheduler');
16 + act = require('jest-react').act;
17 startTransition = React.startTransition;
18 useState = React.useState;
19 useEffect = React.useEffect;
@@ -42,7 +44,7 @@ describe('ReactInterleavedUpdates', () => {
44
45 const root = ReactNoop.createRoot();
46
45 - await ReactNoop.act(async () => {
47 + await act(async () => {
48 root.render(
49 <>
50 <Child />
@@ -54,7 +56,7 @@ describe('ReactInterleavedUpdates', () => {
56 expect(Scheduler).toHaveYielded([0, 0, 0]);
57 expect(root).toMatchRenderedOutput('000');
58
57 - await ReactNoop.act(async () => {
59 + await act(async () => {
60 if (gate(flags => flags.enableSyncDefaultUpdates)) {
61 React.startTransition(() => {
62 updateChildren(1);
@@ -107,7 +109,7 @@ describe('ReactInterleavedUpdates', () => {
109
110 const root = ReactNoop.createRoot();
111
110 - await ReactNoop.act(async () => {
112 + await act(async () => {
113 root.render(
114 <>
115 <Child />
@@ -119,7 +121,7 @@ describe('ReactInterleavedUpdates', () => {
121 expect(Scheduler).toHaveYielded([0, 0, 0]);
122 expect(root).toMatchRenderedOutput('000');
123
122 - await ReactNoop.act(async () => {
124 + await act(async () => {
125 updateChildren(1);
126 // Partially render the children. Only the first one.
127 expect(Scheduler).toFlushAndYieldThrough([1]);
packages/react-reconciler/src/__tests__/ReactMemo-test.js
+6 -4
@@ -17,6 +17,7 @@ let React;
17 let ReactNoop;
18 let Suspense;
19 let Scheduler;
20 +let act;
21
22 describe('memo', () => {
23 beforeEach(() => {
@@ -26,6 +27,7 @@ describe('memo', () => {
27 React = require('react');
28 ReactNoop = require('react-noop-renderer');
29 Scheduler = require('scheduler');
30 + act = require('jest-react').act;
31 ({Suspense} = React);
32 });
33
@@ -447,12 +449,12 @@ describe('memo', () => {
449 }
450
451 const root = ReactNoop.createRoot();
450 - await ReactNoop.act(async () => {
452 + await act(async () => {
453 root.render(<App />);
454 });
455 expect(root).toMatchRenderedOutput('0');
456
455 - await ReactNoop.act(async () => {
457 + await act(async () => {
458 setCounter(1);
459 ReactNoop.discreteUpdates(() => {
460 root.render(<App />);
@@ -483,12 +485,12 @@ describe('memo', () => {
485 }
486
487 const root = ReactNoop.createRoot();
486 - await ReactNoop.act(async () => {
488 + await act(async () => {
489 root.render(<App />);
490 });
491 expect(root).toMatchRenderedOutput('0');
492
491 - await ReactNoop.act(async () => {
493 + await act(async () => {
494 setCounter(1);
495 ReactNoop.discreteUpdates(() => {
496 root.render(<App />);
packages/react-reconciler/src/__tests__/ReactNoopRendererAct-test.js
+8 -4
@@ -7,13 +7,17 @@
7 * @jest-environment node
8 */
9
10 -// sanity tests for ReactNoop.act()
10 +// sanity tests for act()
11
12 const React = require('react');
13 const ReactNoop = require('react-noop-renderer');
14 const Scheduler = require('scheduler');
15 +const act = require('jest-react').act;
16
16 -describe('ReactNoop.act()', () => {
17 +// TODO: These tests are no longer specific to the noop renderer
18 +// implementation. They test the internal implementation we use in the React
19 +// test suite.
20 +describe('internal act()', () => {
21 it('can use act to flush effects', async () => {
22 function App(props) {
23 React.useEffect(props.callback);
@@ -21,7 +25,7 @@ describe('ReactNoop.act()', () => {
25 }
26
27 const calledLog = [];
24 - ReactNoop.act(() => {
28 + act(() => {
29 ReactNoop.render(
30 <App
31 callback={() => {
@@ -49,7 +53,7 @@ describe('ReactNoop.act()', () => {
53 }, []);
54 return ctr;
55 }
52 - await ReactNoop.act(async () => {
56 + await act(async () => {
57 ReactNoop.render(<App />);
58 });
59 expect(Scheduler).toHaveYielded(['stage 1', 'stage 2']);
packages/react-reconciler/src/__tests__/ReactOffscreen-test.js
+17 -15
@@ -1,6 +1,7 @@
1 let React;
2 let ReactNoop;
3 let Scheduler;
4 +let act;
5 let LegacyHidden;
6 let Offscreen;
7 let useState;
@@ -13,6 +14,7 @@ describe('ReactOffscreen', () => {
14 React = require('react');
15 ReactNoop = require('react-noop-renderer');
16 Scheduler = require('scheduler');
17 + act = require('jest-react').act;
18 LegacyHidden = React.unstable_LegacyHidden;
19 Offscreen = React.unstable_Offscreen;
20 useState = React.useState;
@@ -39,7 +41,7 @@ describe('ReactOffscreen', () => {
41
42 // Test the initial mount
43 const root = ReactNoop.createRoot();
42 - await ReactNoop.act(async () => {
44 + await act(async () => {
45 root.render(<App mode="unstable-defer-without-hiding" />);
46 expect(Scheduler).toFlushUntilNextPaint(['Normal']);
47 expect(root).toMatchRenderedOutput(<span prop="Normal" />);
@@ -53,7 +55,7 @@ describe('ReactOffscreen', () => {
55 );
56
57 // Now try after an update
56 - await ReactNoop.act(async () => {
58 + await act(async () => {
59 root.render(<App mode="visible" />);
60 });
61 expect(Scheduler).toHaveYielded(['Normal', 'Deferred']);
@@ -64,7 +66,7 @@ describe('ReactOffscreen', () => {
66 </>,
67 );
68
67 - await ReactNoop.act(async () => {
69 + await act(async () => {
70 root.render(<App mode="unstable-defer-without-hiding" />);
71 expect(Scheduler).toFlushUntilNextPaint(['Normal']);
72 expect(root).toMatchRenderedOutput(
@@ -93,7 +95,7 @@ describe('ReactOffscreen', () => {
95 }
96
97 const root = ReactNoop.createLegacyRoot();
96 - await ReactNoop.act(async () => {
98 + await act(async () => {
99 root.render(
100 <>
101 <LegacyHidden mode="hidden">
@@ -116,7 +118,7 @@ describe('ReactOffscreen', () => {
118 );
119
120 // Test that the children can be updated
119 - await ReactNoop.act(async () => {
121 + await act(async () => {
122 setState('B');
123 });
124 expect(Scheduler).toHaveYielded(['B']);
@@ -138,7 +140,7 @@ describe('ReactOffscreen', () => {
140 }
141
142 const root = ReactNoop.createRoot();
141 - await ReactNoop.act(async () => {
143 + await act(async () => {
144 root.render(
145 <>
146 <LegacyHidden mode="hidden">
@@ -162,7 +164,7 @@ describe('ReactOffscreen', () => {
164 );
165
166 // Test that the children can be updated
165 - await ReactNoop.act(async () => {
167 + await act(async () => {
168 setState('B');
169 });
170 expect(Scheduler).toHaveYielded(['B']);
@@ -190,7 +192,7 @@ describe('ReactOffscreen', () => {
192 const root = ReactNoop.createRoot();
193
194 // Mount hidden tree.
193 - await ReactNoop.act(async () => {
195 + await act(async () => {
196 root.render(
197 <Offscreen mode="hidden">
198 <Child />
@@ -205,7 +207,7 @@ describe('ReactOffscreen', () => {
207 expect(root).toMatchRenderedOutput(<span prop="Child" />);
208
209 // Unhide the tree. The layout effect is mounted.
208 - await ReactNoop.act(async () => {
210 + await act(async () => {
211 root.render(
212 <Offscreen mode="visible">
213 <Child />
@@ -230,7 +232,7 @@ describe('ReactOffscreen', () => {
232 }
233
234 const root = ReactNoop.createRoot();
233 - await ReactNoop.act(async () => {
235 + await act(async () => {
236 root.render(
237 <Offscreen mode="visible">
238 <Child />
@@ -241,7 +243,7 @@ describe('ReactOffscreen', () => {
243 expect(root).toMatchRenderedOutput(<span prop="Child" />);
244
245 // Hide the tree. The layout effect is unmounted.
244 - await ReactNoop.act(async () => {
246 + await act(async () => {
247 root.render(
248 <Offscreen mode="hidden">
249 <Child />
@@ -255,7 +257,7 @@ describe('ReactOffscreen', () => {
257 expect(root).toMatchRenderedOutput(<span prop="Child" />);
258
259 // Unhide the tree. The layout effect is re-mounted.
258 - await ReactNoop.act(async () => {
260 + await act(async () => {
261 root.render(
262 <Offscreen mode="visible">
263 <Child />
@@ -280,7 +282,7 @@ describe('ReactOffscreen', () => {
282 }
283
284 const root = ReactNoop.createRoot();
283 - await ReactNoop.act(async () => {
285 + await act(async () => {
286 // Start the tree hidden. The layout effect is not mounted.
287 root.render(
288 <Offscreen mode="hidden">
@@ -295,7 +297,7 @@ describe('ReactOffscreen', () => {
297 expect(root).toMatchRenderedOutput(<span prop="Child" />);
298
299 // Show the tree. The layout effect is mounted.
298 - await ReactNoop.act(async () => {
300 + await act(async () => {
301 root.render(
302 <Offscreen mode="visible">
303 <Child />
@@ -306,7 +308,7 @@ describe('ReactOffscreen', () => {
308 expect(root).toMatchRenderedOutput(<span prop="Child" />);
309
310 // Hide the tree again. The layout effect is un-mounted.
309 - await ReactNoop.act(async () => {
311 + await act(async () => {
312 root.render(
313 <Offscreen mode="hidden">
314 <Child />
packages/react-reconciler/src/__tests__/ReactSchedulerIntegration-test.js
+7 -5
@@ -13,6 +13,7 @@
13 let React;
14 let ReactNoop;
15 let Scheduler;
16 +let act;
17 let NormalPriority;
18 let IdlePriority;
19 let runWithPriority;
@@ -25,6 +26,7 @@ describe('ReactSchedulerIntegration', () => {
26 React = require('react');
27 ReactNoop = require('react-noop-renderer');
28 Scheduler = require('scheduler');
29 + act = require('jest-react').act;
30 NormalPriority = Scheduler.unstable_NormalPriority;
31 IdlePriority = Scheduler.unstable_IdlePriority;
32 runWithPriority = Scheduler.unstable_runWithPriority;
@@ -71,11 +73,11 @@ describe('ReactSchedulerIntegration', () => {
73 });
74 return null;
75 }
74 - await ReactNoop.act(async () => {
76 + await act(async () => {
77 ReactNoop.render(<CleanupEffect />);
78 });
79 expect(Scheduler).toHaveYielded([]);
78 - await ReactNoop.act(async () => {
80 + await act(async () => {
81 ReactNoop.render(<Effects />);
82 });
83 expect(Scheduler).toHaveYielded([
@@ -139,7 +141,7 @@ describe('ReactSchedulerIntegration', () => {
141 }
142
143 const root = ReactNoop.createRoot();
142 - await ReactNoop.act(async () => {
144 + await act(async () => {
145 root.render(<App label="A" />);
146
147 // Commit the visible content
@@ -244,7 +246,7 @@ describe(
246 return null;
247 }
248
247 - await ReactNoop.act(async () => {
249 + await act(async () => {
250 ReactNoop.render(<App />);
251 expect(Scheduler).toFlushUntilNextPaint([]);
252 expect(Scheduler).toFlushUntilNextPaint([]);
@@ -273,7 +275,7 @@ describe(
275 );
276 }
277
276 - await ReactNoop.act(async () => {
278 + await act(async () => {
279 // Partially render the tree, then yield
280 startTransition(() => {
281 ReactNoop.render(<App />);
packages/react-reconciler/src/__tests__/ReactSubtreeFlagsWarning-test.js
+4 -2
@@ -1,6 +1,7 @@
1 let React;
2 let ReactNoop;
3 let Scheduler;
4 +let act;
5 let Suspense;
6 let useEffect;
7 let getCacheForType;
@@ -15,6 +16,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
16 React = require('react');
17 ReactNoop = require('react-noop-renderer');
18 Scheduler = require('scheduler');
19 + act = require('jest-react').act;
20 Suspense = React.Suspense;
21 useEffect = React.useEffect;
22
@@ -155,7 +157,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
157
158 // On initial mount, the suspended component is committed in an incomplete
159 // state, without a passive static effect flag.
158 - await ReactNoop.act(async () => {
160 + await act(async () => {
161 root.render(<App />);
162 });
163 expect(Scheduler).toHaveYielded(['Suspend! [Async]']);
@@ -164,7 +166,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
166 // When the promise resolves, a passive static effect flag is added. In the
167 // regression, the "missing expected static flag" would fire, because the
168 // previous fiber did not have one.
167 - await ReactNoop.act(async () => {
169 + await act(async () => {
170 resolveText('Async');
171 });
172 expect(Scheduler).toHaveYielded(['Async', 'Effect']);
packages/react-reconciler/src/__tests__/ReactSuspense-test.internal.js
+1 -1
@@ -19,7 +19,7 @@ describe('ReactSuspense', () => {
19 ReactFeatureFlags.replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
20 React = require('react');
21 ReactTestRenderer = require('react-test-renderer');
22 - act = ReactTestRenderer.unstable_concurrentAct;
22 + act = require('jest-react').act;
23 Scheduler = require('scheduler');
24 ReactCache = require('react-cache');
25
packages/react-reconciler/src/__tests__/ReactSuspenseEffectsSemantics-test.js
+95 -93
@@ -10,6 +10,7 @@
10 let React;
11 let ReactNoop;
12 let Scheduler;
13 +let act;
14 let Suspense;
15 let getCacheForType;
16 let caches;
@@ -23,6 +24,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
24 React = require('react');
25 ReactNoop = require('react-noop-renderer');
26 Scheduler = require('scheduler');
27 + act = require('jest-react').act;
28 Suspense = React.Suspense;
29
30 getCacheForType = React.unstable_getCacheForType;
@@ -253,7 +255,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
255 }
256
257 // Mount and suspend.
256 - await ReactNoop.act(async () => {
258 + await act(async () => {
259 ReactNoop.render(
260 <App>
261 <AsyncText text="Async" ms={1000} />
@@ -280,7 +282,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
282 ]);
283
284 // Resolving the suspended resource should
283 - await ReactNoop.act(async () => {
285 + await act(async () => {
286 await resolveText('Async');
287 });
288 expect(Scheduler).toHaveYielded([
@@ -302,7 +304,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
304 span('Outside'),
305 ]);
306
305 - await ReactNoop.act(async () => {
307 + await act(async () => {
308 ReactNoop.render(null);
309 });
310 expect(Scheduler).toHaveYielded([
@@ -370,7 +372,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
372 }
373
374 // Mount and suspend.
373 - ReactNoop.act(() => {
375 + act(() => {
376 ReactNoop.renderLegacySyncRoot(
377 <App>
378 <AsyncText text="Async" ms={1000} />
@@ -402,7 +404,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
404 ]);
405
406 // Resolving the suspended resource should
405 - await ReactNoop.act(async () => {
407 + await act(async () => {
408 await resolveText('Async');
409 });
410 expect(Scheduler).toHaveYielded([
@@ -419,7 +421,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
421 span('Outside'),
422 ]);
423
422 - await ReactNoop.act(async () => {
424 + await act(async () => {
425 ReactNoop.renderLegacySyncRoot(null);
426 });
427 expect(Scheduler).toHaveYielded([
@@ -467,7 +469,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
469 }
470
471 // Mount
470 - ReactNoop.act(() => {
472 + act(() => {
473 ReactNoop.renderLegacySyncRoot(<App />);
474 });
475 expect(Scheduler).toHaveYielded([
@@ -491,7 +493,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
493 ]);
494
495 // Schedule an update that causes React to suspend.
494 - ReactNoop.act(() => {
496 + act(() => {
497 ReactNoop.renderLegacySyncRoot(
498 <App>
499 <AsyncText text="Async" ms={1000} />
@@ -527,7 +529,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
529 ]);
530
531 // Resolving the suspended resource should re-create inner layout effects.
530 - await ReactNoop.act(async () => {
532 + await act(async () => {
533 await resolveText('Async');
534 });
535 expect(Scheduler).toHaveYielded([
@@ -544,7 +546,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
546 span('Outside'),
547 ]);
548
547 - await ReactNoop.act(async () => {
549 + await act(async () => {
550 ReactNoop.renderLegacySyncRoot(null);
551 });
552 expect(Scheduler).toHaveYielded([
@@ -590,7 +592,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
592 );
593 }
594
593 - await ReactNoop.act(async () => {
595 + await act(async () => {
596 ReactNoop.render(<App />);
597 });
598 expect(Scheduler).toHaveYielded([
@@ -614,7 +616,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
616 ]);
617
618 // Schedule an update that causes React to suspend.
617 - ReactNoop.act(() => {
619 + act(() => {
620 ReactNoop.render(
621 <App>
622 <AsyncText text="Async" ms={1000} />
@@ -652,7 +654,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
654 ]);
655
656 // Resolving the suspended resource should re-create inner layout effects.
655 - await ReactNoop.act(async () => {
657 + await act(async () => {
658 await resolveText('Async');
659 });
660 expect(Scheduler).toHaveYielded([
@@ -673,7 +675,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
675 span('Outside'),
676 ]);
677
676 - await ReactNoop.act(async () => {
678 + await act(async () => {
679 ReactNoop.render(null);
680 });
681 expect(Scheduler).toHaveYielded([
@@ -742,7 +744,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
744 }
745
746 // Mount
745 - await ReactNoop.act(async () => {
747 + await act(async () => {
748 ReactNoop.render(<App />);
749 });
750 expect(Scheduler).toHaveYielded([
@@ -763,7 +765,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
765 ]);
766
767 // Schedule an update that causes React to suspend.
766 - ReactNoop.act(() => {
768 + act(() => {
769 ReactNoop.render(
770 <App>
771 <AsyncText text="Async" ms={1000} />
@@ -801,7 +803,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
803 ]);
804
805 // Resolving the suspended resource should re-create inner layout effects.
804 - await ReactNoop.act(async () => {
806 + await act(async () => {
807 await resolveText('Async');
808 });
809 expect(Scheduler).toHaveYielded([
@@ -821,7 +823,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
823 span('Outside'),
824 ]);
825
824 - await ReactNoop.act(async () => {
826 + await act(async () => {
827 ReactNoop.render(null);
828 });
829 expect(Scheduler).toHaveYielded([
@@ -863,7 +865,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
865 }
866
867 // Mount
866 - await ReactNoop.act(async () => {
868 + await act(async () => {
869 ReactNoop.render(<App />);
870 });
871 expect(Scheduler).toHaveYielded([
@@ -880,7 +882,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
882 expect(ReactNoop.getChildren()).toEqual([span('Outer', [span('Inner')])]);
883
884 // Schedule an update that causes React to suspend.
883 - ReactNoop.act(() => {
885 + act(() => {
886 ReactNoop.render(
887 <App>
888 <AsyncText text="Async" ms={1000} />
@@ -911,7 +913,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
913 ]);
914
915 // Resolving the suspended resource should re-create inner layout effects.
914 - await ReactNoop.act(async () => {
916 + await act(async () => {
917 await resolveText('Async');
918 });
919 expect(Scheduler).toHaveYielded([
@@ -930,7 +932,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
932 span('Outer', [span('Inner')]),
933 ]);
934
933 - await ReactNoop.act(async () => {
935 + await act(async () => {
936 ReactNoop.render(null);
937 });
938 expect(Scheduler).toHaveYielded([
@@ -975,7 +977,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
977 }
978
979 // Mount
978 - await ReactNoop.act(async () => {
980 + await act(async () => {
981 ReactNoop.render(<App />);
982 });
983 expect(Scheduler).toHaveYielded([
@@ -994,7 +996,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
996 ]);
997
998 // Schedule an update that causes React to suspend.
997 - ReactNoop.act(() => {
999 + act(() => {
1000 ReactNoop.render(
1001 <App>
1002 <AsyncText text="Async" ms={1000} />
@@ -1028,7 +1030,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1030 ]);
1031
1032 // Resolving the suspended resource should re-create inner layout effects.
1031 - await ReactNoop.act(async () => {
1033 + await act(async () => {
1034 await resolveText('Async');
1035 });
1036 expect(Scheduler).toHaveYielded([
@@ -1046,7 +1048,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1048 span('Outer', [span('MemoizedInner')]),
1049 ]);
1050
1049 - await ReactNoop.act(async () => {
1051 + await act(async () => {
1052 ReactNoop.render(null);
1053 });
1054 expect(Scheduler).toHaveYielded([
@@ -1078,7 +1080,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1080 }
1081
1082 // Mount
1081 - await ReactNoop.act(async () => {
1083 + await act(async () => {
1084 ReactNoop.render(<App />);
1085 });
1086 expect(Scheduler).toHaveYielded([
@@ -1092,7 +1094,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1094 expect(ReactNoop.getChildren()).toEqual([span('Outer'), span('Inner')]);
1095
1096 // Suspend the inner Suspense subtree (only inner effects should be destroyed)
1095 - ReactNoop.act(() => {
1097 + act(() => {
1098 ReactNoop.render(
1099 <App innerChildren={<AsyncText text="InnerAsync_1" ms={1000} />} />,
1100 );
@@ -1115,7 +1117,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1117
1118 // Suspend the outer Suspense subtree (outer effects and inner fallback effects should be destroyed)
1119 // (This check also ensures we don't destroy effects for mounted inner fallback.)
1118 - ReactNoop.act(() => {
1120 + act(() => {
1121 ReactNoop.render(
1122 <App
1123 outerChildren={<AsyncText text="OuterAsync_1" ms={1000} />}
@@ -1144,7 +1146,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1146 ]);
1147
1148 // Show the inner Susepnse subtree (no effects should be recreated)
1147 - await ReactNoop.act(async () => {
1149 + await act(async () => {
1150 await resolveText('InnerAsync_1');
1151 });
1152 expect(Scheduler).toHaveYielded([
@@ -1161,7 +1163,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1163 ]);
1164
1165 // Suspend the inner Suspense subtree (no effects should be destroyed)
1164 - ReactNoop.act(() => {
1166 + act(() => {
1167 ReactNoop.render(
1168 <App
1169 outerChildren={<AsyncText text="OuterAsync_1" ms={1000} />}
@@ -1186,7 +1188,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1188 ]);
1189
1190 // Show the outer Susepnse subtree (only outer effects should be recreated)
1189 - await ReactNoop.act(async () => {
1191 + await act(async () => {
1192 await resolveText('OuterAsync_1');
1193 });
1194 expect(Scheduler).toHaveYielded([
@@ -1210,7 +1212,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1212 ]);
1213
1214 // Show the inner Susepnse subtree (only inner effects should be recreated)
1213 - await ReactNoop.act(async () => {
1215 + await act(async () => {
1216 await resolveText('InnerAsync_2');
1217 });
1218 expect(Scheduler).toHaveYielded([
@@ -1230,7 +1232,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1232 ]);
1233
1234 // Suspend the outer Suspense subtree (all effects should be destroyed)
1233 - ReactNoop.act(() => {
1235 + act(() => {
1236 ReactNoop.render(
1237 <App
1238 outerChildren={<AsyncText text="OuterAsync_2" ms={1000} />}
@@ -1260,7 +1262,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1262 ]);
1263
1264 // Show the outer Suspense subtree (all effects should be recreated)
1263 - await ReactNoop.act(async () => {
1265 + await act(async () => {
1266 await resolveText('OuterAsync_2');
1267 });
1268 expect(Scheduler).toHaveYielded([
@@ -1301,7 +1303,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1303 }
1304
1305 // Mount
1304 - await ReactNoop.act(async () => {
1306 + await act(async () => {
1307 ReactNoop.render(<App />);
1308 });
1309 expect(Scheduler).toHaveYielded([
@@ -1315,7 +1317,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1317 expect(ReactNoop.getChildren()).toEqual([span('Outer'), span('Inner')]);
1318
1319 // Suspend the inner Suspense subtree (only inner effects should be destroyed)
1318 - ReactNoop.act(() => {
1320 + act(() => {
1321 ReactNoop.render(
1322 <App innerChildren={<AsyncText text="InnerAsync_1" ms={1000} />} />,
1323 );
@@ -1338,7 +1340,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1340
1341 // Suspend the outer Suspense subtree (outer effects and inner fallback effects should be destroyed)
1342 // (This check also ensures we don't destroy effects for mounted inner fallback.)
1341 - ReactNoop.act(() => {
1343 + act(() => {
1344 ReactNoop.render(
1345 <App
1346 outerChildren={<AsyncText text="OuterAsync_1" ms={1000} />}
@@ -1367,7 +1369,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1369 ]);
1370
1371 // Resolve both suspended trees.
1370 - await ReactNoop.act(async () => {
1372 + await act(async () => {
1373 await resolveText('OuterAsync_1');
1374 await resolveText('InnerAsync_1');
1375 });
@@ -1419,7 +1421,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1421 }
1422
1423 // Mount
1422 - await ReactNoop.act(async () => {
1424 + await act(async () => {
1425 ReactNoop.render(<App />);
1426 });
1427 expect(Scheduler).toHaveYielded([
@@ -1436,7 +1438,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1438 ]);
1439
1440 // Suspend the outer shell
1439 - ReactNoop.act(() => {
1441 + act(() => {
1442 ReactNoop.render(
1443 <App outerChildren={<AsyncText text="OutsideAsync" ms={1000} />} />,
1444 );
@@ -1472,7 +1474,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1474 ]);
1475
1476 // Suspend the fallback and verify that it's effects get cleaned up as well
1475 - ReactNoop.act(() => {
1477 + act(() => {
1478 ReactNoop.render(
1479 <App
1480 fallbackChildren={<AsyncText text="FallbackAsync" ms={1000} />}
@@ -1514,7 +1516,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1516 ]);
1517
1518 // Resolving both resources should cleanup fallabck effects and recreate main effects
1517 - await ReactNoop.act(async () => {
1519 + await act(async () => {
1520 await resolveText('FallbackAsync');
1521 await resolveText('OutsideAsync');
1522 });
@@ -1562,7 +1564,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1564 }
1565
1566 // Mount
1565 - await ReactNoop.act(async () => {
1567 + await act(async () => {
1568 ReactNoop.render(<App />);
1569 });
1570 expect(Scheduler).toHaveYielded([
@@ -1579,7 +1581,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1581 ]);
1582
1583 // Suspend both the outer boundary and the fallback
1582 - ReactNoop.act(() => {
1584 + act(() => {
1585 ReactNoop.render(
1586 <App
1587 outerChildren={<AsyncText text="OutsideAsync" ms={1000} />}
@@ -1612,7 +1614,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1614 ]);
1615
1616 // Resolving the inside fallback
1615 - await ReactNoop.act(async () => {
1617 + await act(async () => {
1618 await resolveText('FallbackAsync');
1619 });
1620 expect(Scheduler).toHaveYielded([
@@ -1634,7 +1636,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1636 ]);
1637
1638 // Resolving the outer fallback only
1637 - await ReactNoop.act(async () => {
1639 + await act(async () => {
1640 await resolveText('OutsideAsync');
1641 });
1642 expect(Scheduler).toHaveYielded([
@@ -1679,7 +1681,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1681 }
1682
1683 // Mount
1682 - await ReactNoop.act(async () => {
1684 + await act(async () => {
1685 ReactNoop.render(<App shouldSuspend={false} />);
1686 });
1687 expect(Scheduler).toHaveYielded([
@@ -1697,7 +1699,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1699
1700 // Suspending a component in the middle of the tree
1701 // should still properly cleanup effects deeper in the tree
1700 - ReactNoop.act(() => {
1702 + act(() => {
1703 ReactNoop.render(<App shouldSuspend={true} />);
1704 });
1705 expect(Scheduler).toHaveYielded([
@@ -1724,7 +1726,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1726 ]);
1727
1728 // Resolving should cleanup.
1727 - await ReactNoop.act(async () => {
1729 + await act(async () => {
1730 await resolveText('Suspend');
1731 });
1732 expect(Scheduler).toHaveYielded([
@@ -1783,7 +1785,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1785 );
1786 }
1787
1786 - await ReactNoop.act(async () => {
1788 + await act(async () => {
1789 ReactNoop.render(
1790 <ErrorBoundary fallback={<Text text="Error" />}>
1791 <App />
@@ -1810,7 +1812,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1812 ]);
1813
1814 // Schedule an update that causes React to suspend.
1813 - await ReactNoop.act(async () => {
1815 + await act(async () => {
1816 ReactNoop.render(
1817 <ErrorBoundary fallback={<Text text="Error" />}>
1818 <App>
@@ -1841,7 +1843,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1843
1844 // Resolve the pending suspense and throw
1845 componentDidMountShouldThrow = true;
1844 - await ReactNoop.act(async () => {
1846 + await act(async () => {
1847 await resolveText('Async');
1848 });
1849 expect(Scheduler).toHaveYielded([
@@ -1920,7 +1922,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1922 );
1923 }
1924
1923 - await ReactNoop.act(async () => {
1925 + await act(async () => {
1926 ReactNoop.render(
1927 <ErrorBoundary fallback={<Text text="Error" />}>
1928 <App />
@@ -1947,7 +1949,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1949 ]);
1950
1951 // Schedule an update that suspends and triggers our error code.
1950 - await ReactNoop.act(async () => {
1952 + await act(async () => {
1953 ReactNoop.render(
1954 <ErrorBoundary fallback={<Text text="Error" />}>
1955 <App>
@@ -2036,7 +2038,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2038 );
2039 }
2040
2039 - await ReactNoop.act(async () => {
2041 + await act(async () => {
2042 ReactNoop.render(
2043 <ErrorBoundary fallback={<Text text="Error" />}>
2044 <App />
@@ -2063,7 +2065,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2065 ]);
2066
2067 // Schedule an update that causes React to suspend.
2066 - await ReactNoop.act(async () => {
2068 + await act(async () => {
2069 ReactNoop.render(
2070 <ErrorBoundary fallback={<Text text="Error" />}>
2071 <App>
@@ -2094,7 +2096,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2096
2097 // Resolve the pending suspense and throw
2098 useLayoutEffectShouldThrow = true;
2097 - await ReactNoop.act(async () => {
2099 + await act(async () => {
2100 await resolveText('Async');
2101 });
2102 expect(Scheduler).toHaveYielded([
@@ -2172,7 +2174,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2174 );
2175 }
2176
2175 - await ReactNoop.act(async () => {
2177 + await act(async () => {
2178 ReactNoop.render(
2179 <ErrorBoundary fallback={<Text text="Error" />}>
2180 <App />
@@ -2199,7 +2201,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2201 ]);
2202
2203 // Schedule an update that suspends and triggers our error code.
2202 - await ReactNoop.act(async () => {
2204 + await act(async () => {
2205 ReactNoop.render(
2206 <ErrorBoundary fallback={<Text text="Error" />}>
2207 <App>
@@ -2279,7 +2281,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2281 );
2282 }
2283
2282 - await ReactNoop.act(async () => {
2284 + await act(async () => {
2285 ReactNoop.render(<App />);
2286 });
2287 expect(Scheduler).toHaveYielded([
@@ -2295,7 +2297,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2297 ]);
2298
2299 // Schedule an update that causes React to suspend.
2298 - ReactNoop.act(() => {
2300 + act(() => {
2301 ReactNoop.render(
2302 <App>
2303 <AsyncText text="Async_1" ms={1000} />
@@ -2330,7 +2332,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2332 ]);
2333
2334 // Resolving the suspended resource should re-create inner layout effects.
2333 - await ReactNoop.act(async () => {
2335 + await act(async () => {
2336 await resolveText('Async_1');
2337 });
2338 expect(Scheduler).toHaveYielded([
@@ -2346,7 +2348,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2348 ]);
2349
2350 // Resolving the suspended resource should re-create inner layout effects.
2349 - await ReactNoop.act(async () => {
2351 + await act(async () => {
2352 await resolveText('Async_2');
2353 });
2354 expect(Scheduler).toHaveYielded([
@@ -2369,7 +2371,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2371 span('Class'),
2372 ]);
2373
2372 - await ReactNoop.act(async () => {
2374 + await act(async () => {
2375 ReactNoop.render(null);
2376 });
2377 expect(Scheduler).toHaveYielded([
@@ -2428,7 +2430,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2430 );
2431 }
2432
2431 - await ReactNoop.act(async () => {
2433 + await act(async () => {
2434 ReactNoop.render(<App />);
2435 });
2436 expect(Scheduler).toHaveYielded([
@@ -2447,7 +2449,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2449
2450 // Schedule an update that causes React to suspend.
2451 textToRead = 'A';
2450 - ReactNoop.act(() => {
2452 + act(() => {
2453 ReactNoop.render(<App />);
2454 });
2455 expect(Scheduler).toHaveYielded([
@@ -2480,7 +2482,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2482
2483 // Resolving the suspended resource should re-create inner layout effects.
2484 textToRead = 'B';
2483 - await ReactNoop.act(async () => {
2485 + await act(async () => {
2486 await resolveText('A');
2487 });
2488 expect(Scheduler).toHaveYielded([
@@ -2497,7 +2499,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2499 ]);
2500
2501 // Resolving the suspended resource should re-create inner layout effects.
2500 - await ReactNoop.act(async () => {
2502 + await act(async () => {
2503 await resolveText('B');
2504 });
2505 expect(Scheduler).toHaveYielded([
@@ -2514,7 +2516,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2516 span('Class'),
2517 ]);
2518
2517 - await ReactNoop.act(async () => {
2519 + await act(async () => {
2520 ReactNoop.render(null);
2521 });
2522 expect(Scheduler).toHaveYielded([
@@ -2602,7 +2604,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2604 );
2605 }
2606
2605 - ReactNoop.act(() => {
2607 + act(() => {
2608 ReactNoop.renderLegacySyncRoot(<App />);
2609 });
2610 expect(Scheduler).toHaveYielded([
@@ -2620,7 +2622,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2622 expect(ReactNoop.getChildren()).toEqual([]);
2623
2624 // Suspend the inner Suspense subtree (only inner effects should be destroyed)
2623 - ReactNoop.act(() => {
2625 + act(() => {
2626 ReactNoop.renderLegacySyncRoot(
2627 <App children={<AsyncText text="Async" ms={1000} />} />,
2628 );
@@ -2641,7 +2643,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2643 expect(ReactNoop.getChildren()).toEqual([span('Fallback')]);
2644
2645 // Resolving the suspended resource should re-create inner layout effects.
2644 - await ReactNoop.act(async () => {
2646 + await act(async () => {
2647 await resolveText('Async');
2648 });
2649 expect(Scheduler).toHaveYielded([
@@ -2653,7 +2655,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2655 ]);
2656 expect(ReactNoop.getChildren()).toEqual([span('Async')]);
2657
2656 - await ReactNoop.act(async () => {
2658 + await act(async () => {
2659 ReactNoop.renderLegacySyncRoot(null);
2660 });
2661 expect(Scheduler).toHaveYielded([
@@ -2681,7 +2683,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2683 }
2684
2685 // Mount
2684 - await ReactNoop.act(async () => {
2686 + await act(async () => {
2687 ReactNoop.render(<App />);
2688 });
2689 expect(Scheduler).toHaveYielded([
@@ -2700,7 +2702,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2702 ]);
2703
2704 // Suspend the inner Suspense subtree (only inner effects should be destroyed)
2703 - ReactNoop.act(() => {
2705 + act(() => {
2706 ReactNoop.render(
2707 <App children={<AsyncText text="Async" ms={1000} />} />,
2708 );
@@ -2726,7 +2728,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2728 ]);
2729
2730 // Resolving the suspended resource should re-create inner layout effects.
2729 - await ReactNoop.act(async () => {
2731 + await act(async () => {
2732 await resolveText('Async');
2733 });
2734 expect(Scheduler).toHaveYielded([
@@ -2750,7 +2752,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2752 span('refCallback'),
2753 ]);
2754
2753 - await ReactNoop.act(async () => {
2755 + await act(async () => {
2756 ReactNoop.render(null);
2757 });
2758 expect(Scheduler).toHaveYielded([
@@ -2787,7 +2789,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2789 }
2790
2791 // Mount
2790 - await ReactNoop.act(async () => {
2792 + await act(async () => {
2793 ReactNoop.render(<App />);
2794 });
2795 expect(Scheduler).toHaveYielded([
@@ -2805,7 +2807,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2807 expect(ReactNoop.getChildren()).toEqual([]);
2808
2809 // Suspend the inner Suspense subtree (only inner effects should be destroyed)
2808 - ReactNoop.act(() => {
2810 + act(() => {
2811 ReactNoop.render(
2812 <App children={<AsyncText text="Async" ms={1000} />} />,
2813 );
@@ -2829,7 +2831,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2831 expect(ReactNoop.getChildren()).toEqual([span('Fallback')]);
2832
2833 // Resolving the suspended resource should re-create inner layout effects.
2832 - await ReactNoop.act(async () => {
2834 + await act(async () => {
2835 await resolveText('Async');
2836 });
2837 expect(Scheduler).toHaveYielded([
@@ -2851,7 +2853,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2853 ]);
2854 expect(ReactNoop.getChildren()).toEqual([span('Async')]);
2855
2854 - await ReactNoop.act(async () => {
2856 + await act(async () => {
2857 ReactNoop.render(null);
2858 });
2859 expect(Scheduler).toHaveYielded([
@@ -2892,7 +2894,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2894 }
2895
2896 // Mount
2895 - await ReactNoop.act(async () => {
2897 + await act(async () => {
2898 ReactNoop.render(<App />);
2899 });
2900 expect(Scheduler).toHaveYielded([
@@ -2910,7 +2912,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2912 expect(ReactNoop.getChildren()).toEqual([]);
2913
2914 // Suspend the inner Suspense subtree (only inner effects should be destroyed)
2913 - ReactNoop.act(() => {
2915 + act(() => {
2916 ReactNoop.render(
2917 <App children={<AsyncText text="Async" ms={1000} />} />,
2918 );
@@ -2934,7 +2936,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2936 expect(ReactNoop.getChildren()).toEqual([span('Fallback')]);
2937
2938 // Resolving the suspended resource should re-create inner layout effects.
2937 - await ReactNoop.act(async () => {
2939 + await act(async () => {
2940 await resolveText('Async');
2941 });
2942 expect(Scheduler).toHaveYielded([
@@ -2956,7 +2958,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2958 ]);
2959 expect(ReactNoop.getChildren()).toEqual([span('Async')]);
2960
2959 - await ReactNoop.act(async () => {
2961 + await act(async () => {
2962 ReactNoop.render(null);
2963 });
2964 expect(Scheduler).toHaveYielded([
@@ -3011,7 +3013,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
3013 }
3014
3015 // Mount
3014 - await ReactNoop.act(async () => {
3016 + await act(async () => {
3017 ReactNoop.render(<App />);
3018 });
3019 expect(Scheduler).toHaveYielded([
@@ -3023,7 +3025,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
3025 expect(ReactNoop.getChildren()).toEqual([]);
3026
3027 // Suspend the inner Suspense subtree (only inner effects should be destroyed)
3026 - ReactNoop.act(() => {
3028 + act(() => {
3029 ReactNoop.render(
3030 <App children={<AsyncText text="Async" ms={1000} />} />,
3031 );
@@ -3040,7 +3042,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
3042 expect(ReactNoop.getChildren()).toEqual([span('Fallback')]);
3043
3044 // Resolving the suspended resource should re-create inner layout effects.
3043 - await ReactNoop.act(async () => {
3045 + await act(async () => {
3046 await resolveText('Async');
3047 });
3048 expect(Scheduler).toHaveYielded([
@@ -3055,7 +3057,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
3057 ]);
3058 expect(ReactNoop.getChildren()).toEqual([span('Async')]);
3059
3058 - await ReactNoop.act(async () => {
3060 + await act(async () => {
3061 ReactNoop.render(null);
3062 });
3063 expect(Scheduler).toHaveYielded([
@@ -3107,7 +3109,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
3109 );
3110 }
3111
3110 - await ReactNoop.act(async () => {
3112 + await act(async () => {
3113 ReactNoop.render(
3114 <ErrorBoundary fallback={<Text text="Error" />}>
3115 <App />
@@ -3134,7 +3136,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
3136 ]);
3137
3138 // Schedule an update that causes React to suspend.
3137 - await ReactNoop.act(async () => {
3139 + await act(async () => {
3140 ReactNoop.render(
3141 <ErrorBoundary fallback={<Text text="Error" />}>
3142 <App>
@@ -3165,7 +3167,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
3167
3168 // Resolve the pending suspense and throw
3169 useRefCallbackShouldThrow = true;
3168 - await ReactNoop.act(async () => {
3170 + await act(async () => {
3171 await resolveText('Async');
3172 });
3173 expect(Scheduler).toHaveYielded([
packages/react-reconciler/src/__tests__/ReactSuspenseFuzz-test.internal.js
+7 -1
@@ -2,6 +2,7 @@ let React;
2 let Suspense;
3 let ReactNoop;
4 let Scheduler;
5 +let act;
6 let ReactFeatureFlags;
7 let Random;
8
@@ -27,6 +28,7 @@ describe('ReactSuspenseFuzz', () => {
28 Suspense = React.Suspense;
29 ReactNoop = require('react-noop-renderer');
30 Scheduler = require('scheduler');
31 + act = require('jest-react').act;
32 Random = require('random-seed');
33 });
34
@@ -143,7 +145,11 @@ describe('ReactSuspenseFuzz', () => {
145 if ((elapsedTime += 1000) > 1000000) {
146 throw new Error('Something did not resolve properly.');
147 }
146 - ReactNoop.act(() => jest.advanceTimersByTime(1000));
148 + act(() => {
149 + ReactNoop.batchedUpdates(() => {
150 + jest.advanceTimersByTime(1000);
151 + });
152 + });
153 Scheduler.unstable_flushAllWithoutAsserting();
154 }
155 }
packages/react-reconciler/src/__tests__/ReactSuspenseList-test.js
+10 -8
@@ -1,6 +1,7 @@
1 let React;
2 let ReactNoop;
3 let Scheduler;
4 +let act;
5 let Profiler;
6 let Suspense;
7 let SuspenseList;
@@ -12,6 +13,7 @@ describe('ReactSuspenseList', () => {
13 React = require('react');
14 ReactNoop = require('react-noop-renderer');
15 Scheduler = require('scheduler');
16 + act = require('jest-react').act;
17 Profiler = React.Profiler;
18 Suspense = React.Suspense;
19 SuspenseList = React.SuspenseList;
@@ -284,7 +286,7 @@ describe('ReactSuspenseList', () => {
286 </>,
287 );
288
287 - await ReactNoop.act(async () => {
289 + await act(async () => {
290 C.resolve();
291 });
292
@@ -298,7 +300,7 @@ describe('ReactSuspenseList', () => {
300 </>,
301 );
302
301 - await ReactNoop.act(async () => {
303 + await act(async () => {
304 B.resolve();
305 });
306
@@ -2203,7 +2205,7 @@ describe('ReactSuspenseList', () => {
2205 );
2206
2207 // Update the row adjacent to the list
2206 - ReactNoop.act(() => updateAdjacent('C'));
2208 + act(() => updateAdjacent('C'));
2209
2210 expect(Scheduler).toHaveYielded(['C']);
2211
@@ -2259,7 +2261,7 @@ describe('ReactSuspenseList', () => {
2261 const previousInst = setAsyncB;
2262
2263 // During an update we suspend on B.
2262 - ReactNoop.act(() => setAsyncB(true));
2264 + act(() => setAsyncB(true));
2265
2266 expect(Scheduler).toHaveYielded([
2267 'Suspend! [B]',
@@ -2277,7 +2279,7 @@ describe('ReactSuspenseList', () => {
2279
2280 // Before we resolve we'll rerender the whole list.
2281 // This should leave the tree intact.
2280 - ReactNoop.act(() => ReactNoop.render(<Foo updateList={true} />));
2282 + act(() => ReactNoop.render(<Foo updateList={true} />));
2283
2284 expect(Scheduler).toHaveYielded(['A', 'Suspend! [B]', 'Loading B']);
2285
@@ -2347,7 +2349,7 @@ describe('ReactSuspenseList', () => {
2349 const previousInst = setAsyncB;
2350
2351 // During an update we suspend on B.
2350 - ReactNoop.act(() => setAsyncB(true));
2352 + act(() => setAsyncB(true));
2353
2354 expect(Scheduler).toHaveYielded([
2355 'Suspend! [B]',
@@ -2365,7 +2367,7 @@ describe('ReactSuspenseList', () => {
2367
2368 // Before we resolve we'll rerender the whole list.
2369 // This should leave the tree intact.
2368 - ReactNoop.act(() => ReactNoop.render(<Foo updateList={true} />));
2370 + act(() => ReactNoop.render(<Foo updateList={true} />));
2371
2372 expect(Scheduler).toHaveYielded(['A', 'Suspend! [B]', 'Loading B']);
2373
@@ -2425,7 +2427,7 @@ describe('ReactSuspenseList', () => {
2427
2428 expect(ReactNoop).toMatchRenderedOutput(null);
2429
2428 - await ReactNoop.act(async () => {
2430 + await act(async () => {
2431 // Add a few items at the end.
2432 if (gate(flags => flags.enableSyncDefaultUpdates)) {
2433 React.startTransition(() => {
packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js
+85 -83
@@ -2,6 +2,7 @@ let React;
2 let Fragment;
3 let ReactNoop;
4 let Scheduler;
5 +let act;
6 let Suspense;
7 let getCacheForType;
8
@@ -16,6 +17,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
17 Fragment = React.Fragment;
18 ReactNoop = require('react-noop-renderer');
19 Scheduler = require('scheduler');
20 + act = require('jest-react').act;
21 Suspense = React.Suspense;
22
23 getCacheForType = React.unstable_getCacheForType;
@@ -671,14 +673,14 @@ describe('ReactSuspenseWithNoopRenderer', () => {
673
674 // Mount the Suspense boundary without suspending, so that the subsequent
675 // updates suspend with a delay.
674 - await ReactNoop.act(async () => {
676 + await act(async () => {
677 root.render(<App step={0} shouldSuspend={false} />);
678 });
679 await advanceTimers(1000);
680 expect(Scheduler).toHaveYielded(['Sibling', 'Step 0']);
681
682 // Schedule an update at several distinct expiration times
681 - await ReactNoop.act(async () => {
683 + await act(async () => {
684 if (gate(flags => flags.enableSyncDefaultUpdates)) {
685 React.startTransition(() => {
686 root.render(<App step={1} shouldSuspend={true} />);
@@ -1228,7 +1230,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1230 expect(Scheduler).toHaveYielded(['Suspend! [Result]', 'Loading...']);
1231 expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
1232
1231 - await ReactNoop.act(async () => {
1233 + await act(async () => {
1234 resolveText('Result');
1235 });
1236
@@ -1298,7 +1300,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1300 </>,
1301 );
1302
1301 - await ReactNoop.act(async () => {
1303 + await act(async () => {
1304 resolveText('Step: 2');
1305 });
1306 expect(Scheduler).toHaveYielded(['Step: 2']);
@@ -1371,7 +1373,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1373 </>,
1374 );
1375
1374 - await ReactNoop.act(async () => {
1376 + await act(async () => {
1377 resolveText('B');
1378 });
1379
@@ -1417,7 +1419,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1419 ]);
1420 expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
1421
1420 - await ReactNoop.act(async () => {
1422 + await act(async () => {
1423 resolveText('Hi');
1424 });
1425
@@ -1464,7 +1466,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1466 'Loading...',
1467 ]);
1468 expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
1467 - await ReactNoop.act(async () => {
1469 + await act(async () => {
1470 resolveText('Hi');
1471 });
1472 expect(Scheduler).toHaveYielded(['Hi']);
@@ -1510,7 +1512,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1512 </>,
1513 ]);
1514
1513 - await ReactNoop.act(async () => {
1515 + await act(async () => {
1516 resolveText('Hi');
1517 });
1518 expect(Scheduler).toHaveYielded(['Hi']);
@@ -1553,7 +1555,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1555 'Child is hidden: true',
1556 ]);
1557
1556 - await ReactNoop.act(async () => {
1558 + await act(async () => {
1559 resolveText('Hi');
1560 });
1561
@@ -1626,20 +1628,20 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1628 }
1629
1630 const root = ReactNoop.createLegacyRoot(null);
1629 - await ReactNoop.act(async () => {
1631 + await act(async () => {
1632 root.render(<App />);
1633 });
1634 expect(Scheduler).toHaveYielded(['Mount']);
1635 expect(root).toMatchRenderedOutput('Child');
1636
1637 // Suspend the child. This puts it into an inconsistent state.
1636 - await ReactNoop.act(async () => {
1638 + await act(async () => {
1639 setShouldSuspend(true);
1640 });
1641 expect(root).toMatchRenderedOutput('Loading...');
1642
1643 // Unmount everying
1642 - await ReactNoop.act(async () => {
1644 + await act(async () => {
1645 root.render(null);
1646 });
1647 expect(Scheduler).toHaveYielded(['Unmount']);
@@ -1801,7 +1803,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1803 </>,
1804 );
1805
1804 - await ReactNoop.act(async () => {
1806 + await act(async () => {
1807 resolveText('B');
1808 });
1809
@@ -1837,7 +1839,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1839 'Effect [Loading...]',
1840 ]);
1841
1840 - await ReactNoop.act(async () => {
1842 + await act(async () => {
1843 resolveText('B2');
1844 });
1845
@@ -2091,12 +2093,12 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2093 );
2094 }
2095
2094 - await ReactNoop.act(async () => {
2096 + await act(async () => {
2097 ReactNoop.render(<App />);
2098 });
2099
2100 // TODO: assert toErrorDev() when the warning is implemented again.
2099 - ReactNoop.act(() => {
2101 + act(() => {
2102 ReactNoop.flushSync(() => _setShow(true));
2103 });
2104 });
@@ -2118,12 +2120,12 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2120 }
2121 }
2122
2121 - await ReactNoop.act(async () => {
2123 + await act(async () => {
2124 ReactNoop.render(<App />);
2125 });
2126
2127 // TODO: assert toErrorDev() when the warning is implemented again.
2126 - ReactNoop.act(() => {
2128 + act(() => {
2129 ReactNoop.flushSync(() => show());
2130 });
2131 });
@@ -2145,14 +2147,14 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2147 }
2148 }
2149
2148 - await ReactNoop.act(async () => {
2150 + await act(async () => {
2151 ReactNoop.render(<App />);
2152 });
2153
2154 expect(Scheduler).toHaveYielded(['Suspend! [A]']);
2155 expect(ReactNoop).toMatchRenderedOutput('Loading...');
2156
2155 - ReactNoop.act(() => {
2157 + act(() => {
2158 ReactNoop.flushSync(() => showB());
2159 });
2160
@@ -2178,12 +2180,12 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2180 </Suspense>
2181 );
2182 }
2181 - await ReactNoop.act(async () => {
2183 + await act(async () => {
2184 ReactNoop.render(<App />);
2185 });
2186
2187 // TODO: assert toErrorDev() when the warning is implemented again.
2186 - ReactNoop.act(() => {
2188 + act(() => {
2189 ReactNoop.flushSync(() => _setShow(true));
2190 });
2191 },
@@ -2205,12 +2207,12 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2207 }
2208 }
2209
2208 - await ReactNoop.act(async () => {
2210 + await act(async () => {
2211 ReactNoop.render(<App />);
2212 });
2213
2214 // also make sure lowpriority is okay
2213 - await ReactNoop.act(async () => show(true));
2215 + await act(async () => show(true));
2216
2217 expect(Scheduler).toHaveYielded(['Suspend! [A]']);
2218 await resolveText('A');
@@ -2231,12 +2233,12 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2233 );
2234 }
2235
2234 - await ReactNoop.act(async () => {
2236 + await act(async () => {
2237 ReactNoop.render(<App />);
2238 });
2239
2240 // also make sure lowpriority is okay
2239 - await ReactNoop.act(async () => _setShow(true));
2241 + await act(async () => _setShow(true));
2242
2243 expect(Scheduler).toHaveYielded(['Suspend! [A]']);
2244 await resolveText('A');
@@ -2499,7 +2501,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2501 expect(Scheduler).toFlushAndYield([]);
2502
2503 // Initial render.
2502 - await ReactNoop.act(async () => {
2504 + await act(async () => {
2505 React.startTransition(() => transitionToPage('A'));
2506
2507 expect(Scheduler).toFlushAndYield(['Suspend! [A]', 'Loading...']);
@@ -2515,7 +2517,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2517 expect(ReactNoop.getChildren()).toEqual([span('A')]);
2518
2519 // Start transition.
2518 - await ReactNoop.act(async () => {
2520 + await act(async () => {
2521 React.startTransition(() => transitionToPage('B'));
2522
2523 expect(Scheduler).toFlushAndYield(['Suspend! [B]', 'Loading...']);
@@ -2554,7 +2556,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2556 expect(Scheduler).toFlushAndYield([]);
2557
2558 // Initial render.
2557 - await ReactNoop.act(async () => {
2559 + await act(async () => {
2560 React.startTransition(() => transitionToPage('A'));
2561
2562 expect(Scheduler).toFlushAndYield(['Suspend! [A]', 'Loading...']);
@@ -2570,7 +2572,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2572 expect(ReactNoop.getChildren()).toEqual([span('A')]);
2573
2574 // Start transition.
2573 - await ReactNoop.act(async () => {
2575 + await act(async () => {
2576 React.startTransition(() => transitionToPage('B'));
2577
2578 expect(Scheduler).toFlushAndYield(['Suspend! [B]', 'Loading...']);
@@ -2658,7 +2660,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2660 expect(Scheduler).toFlushAndYield([]);
2661
2662 // Initial render.
2661 - await ReactNoop.act(async () => {
2663 + await act(async () => {
2664 React.startTransition(() => transitionToPage('A'));
2665
2666 expect(Scheduler).toFlushAndYield(['Suspend! [A]', 'Loading...']);
@@ -2674,7 +2676,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2676 expect(ReactNoop.getChildren()).toEqual([span('A')]);
2677
2678 // Start transition.
2677 - await ReactNoop.act(async () => {
2679 + await act(async () => {
2680 React.startTransition(() => transitionToPage('B'));
2681
2682 expect(Scheduler).toFlushAndYield(['Suspend! [B]', 'Loading...']);
@@ -2692,7 +2694,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2694 expect(ReactNoop.getChildren()).toEqual([span('B')]);
2695
2696 // Start a long (infinite) transition.
2695 - await ReactNoop.act(async () => {
2697 + await act(async () => {
2698 React.startTransition(() => transitionToPage('C'));
2699
2700 expect(Scheduler).toFlushAndYield(['Suspend! [C]', 'Loading...']);
@@ -2728,7 +2730,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2730 expect(Scheduler).toFlushAndYield([]);
2731
2732 // Initial render.
2731 - await ReactNoop.act(async () => {
2733 + await act(async () => {
2734 React.startTransition(() => transitionToPage('A'));
2735
2736 expect(Scheduler).toFlushAndYield(['Suspend! [A]', 'Loading...']);
@@ -2744,7 +2746,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2746 expect(ReactNoop.getChildren()).toEqual([span('A')]);
2747
2748 // Start transition.
2747 - await ReactNoop.act(async () => {
2749 + await act(async () => {
2750 React.startTransition(() => transitionToPage('B'));
2751
2752 expect(Scheduler).toFlushAndYield(['Suspend! [B]', 'Loading...']);
@@ -2761,7 +2763,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2763 expect(ReactNoop.getChildren()).toEqual([span('B')]);
2764
2765 // Start a long (infinite) transition.
2764 - await ReactNoop.act(async () => {
2766 + await act(async () => {
2767 React.startTransition(() => transitionToPage('C'));
2768
2769 expect(Scheduler).toFlushAndYield(['Suspend! [C]', 'Loading...']);
@@ -2884,19 +2886,19 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2886 }
2887
2888 const root = ReactNoop.createRoot();
2887 - await ReactNoop.act(async () => {
2889 + await act(async () => {
2890 root.render(<App text="Initial" />);
2891 });
2892 expect(Scheduler).toHaveYielded(['Suspend! [Initial]']);
2893
2894 // Resolve initial render
2893 - await ReactNoop.act(async () => {
2895 + await act(async () => {
2896 await resolveText('Initial');
2897 });
2898 expect(Scheduler).toHaveYielded(['Initial']);
2899 expect(root).toMatchRenderedOutput(<span prop="Initial" />);
2900
2899 - await ReactNoop.act(async () => {
2901 + await act(async () => {
2902 // Update. Since showing a fallback would hide content that's already
2903 // visible, it should suspend for a JND without committing.
2904 if (gate(flags => flags.enableSyncDefaultUpdates)) {
@@ -2953,13 +2955,13 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2955 }
2956
2957 const root = ReactNoop.createRoot();
2956 - await ReactNoop.act(async () => {
2958 + await act(async () => {
2959 root.render(<App />);
2960 });
2961
2962 expect(Scheduler).toHaveYielded(['Foo']);
2963
2962 - await ReactNoop.act(async () => {
2964 + await act(async () => {
2965 foo.setState({suspend: true});
2966
2967 // In the regression that this covers, we would neglect to reset the
@@ -3110,13 +3112,13 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3112 }
3113
3114 await seedNextTextCache('A');
3113 - await ReactNoop.act(async () => {
3115 + await act(async () => {
3116 root.render(<Parent />);
3117 });
3118 expect(Scheduler).toHaveYielded(['A']);
3119 expect(root).toMatchRenderedOutput(<span prop="A" />);
3120
3119 - await ReactNoop.act(async () => {
3121 + await act(async () => {
3122 // Schedule two updates that originate inside the Suspense boundary.
3123 // The first one causes the boundary to suspend. The second one is at
3124 // lower priority and unsuspends the tree.
@@ -3164,13 +3166,13 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3166 }
3167
3168 await seedNextTextCache('A');
3167 - await ReactNoop.act(async () => {
3169 + await act(async () => {
3170 root.render(<Parent />);
3171 });
3172 expect(Scheduler).toHaveYielded(['A']);
3173 expect(root).toMatchRenderedOutput(<span prop="A" />);
3174
3173 - await ReactNoop.act(async () => {
3175 + await act(async () => {
3176 // Schedule two updates that originate inside the Suspense boundary.
3177 // The first one causes the boundary to suspend. The second one is at
3178 // lower priority and unsuspends it by hiding the async component.
@@ -3233,13 +3235,13 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3235
3236 // Resolve the initial tree
3237 await seedNextTextCache('A');
3236 - await ReactNoop.act(async () => {
3238 + await act(async () => {
3239 root.render(<App />);
3240 });
3241 expect(Scheduler).toHaveYielded(['A']);
3242 expect(root).toMatchRenderedOutput(<span prop="A" />);
3243
3242 - await ReactNoop.act(async () => {
3244 + await act(async () => {
3245 // Schedule an update inside the Suspense boundary that suspends.
3246 setAppText('B');
3247 expect(Scheduler).toFlushAndYield(['Suspend! [B]', 'Loading...']);
@@ -3255,7 +3257,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3257 // Schedule a default pri update on the boundary, and a lower pri update
3258 // on the fallback. We're testing to make sure the fallback can still
3259 // update even though the primary tree is suspended.
3258 - await ReactNoop.act(async () => {
3260 + await act(async () => {
3261 setAppText('C');
3262 React.startTransition(() => {
3263 setFallbackText('Still loading...');
@@ -3318,7 +3320,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3320
3321 // Mount an initial tree. Resolve A so that it doesn't suspend.
3322 await seedNextTextCache('A');
3321 - await ReactNoop.act(async () => {
3323 + await act(async () => {
3324 root.render(<Parent />);
3325 });
3326 expect(Scheduler).toHaveYielded(['A']);
@@ -3327,7 +3329,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3329
3330 // Schedule another update. This will "flip" the alternate pairs.
3331 await resolveText('B');
3330 - await ReactNoop.act(async () => {
3332 + await act(async () => {
3333 setText('B');
3334 });
3335 expect(Scheduler).toHaveYielded(['B']);
@@ -3335,14 +3337,14 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3337 expect(root).toMatchRenderedOutput(<span prop="B" />);
3338
3339 // Schedule another update. This time, we'll suspend.
3338 - await ReactNoop.act(async () => {
3340 + await act(async () => {
3341 setText('C');
3342 });
3343 expect(Scheduler).toHaveYielded(['Suspend! [C]', 'Loading...']);
3344
3345 // Commit. This will insert a fragment fiber to wrap around the component
3346 // that triggered the update.
3345 - await ReactNoop.act(async () => {
3347 + await act(async () => {
3348 await advanceTimers(250);
3349 });
3350 // The fragment fiber is part of the current tree, but the setState return
@@ -3357,7 +3359,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3359
3360 // Update again. This should unsuspend the tree.
3361 await resolveText('D');
3360 - await ReactNoop.act(async () => {
3362 + await act(async () => {
3363 setText('D');
3364 });
3365 // Even though the fragment fiber is not part of the return path, we should
@@ -3395,7 +3397,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3397
3398 // Mount an initial tree. Resolve A so that it doesn't suspend.
3399 await seedNextTextCache('A');
3398 - await ReactNoop.act(async () => {
3400 + await act(async () => {
3401 root.render(<Parent />);
3402 });
3403 expect(Scheduler).toHaveYielded(['A']);
@@ -3404,7 +3406,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3406
3407 // Schedule another update. This will "flip" the alternate pairs.
3408 await resolveText('B');
3407 - await ReactNoop.act(async () => {
3409 + await act(async () => {
3410 setText('B');
3411 });
3412 expect(Scheduler).toHaveYielded(['B']);
@@ -3412,14 +3414,14 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3414 expect(root).toMatchRenderedOutput(<span prop="B" />);
3415
3416 // Schedule another update. This time, we'll suspend.
3415 - await ReactNoop.act(async () => {
3417 + await act(async () => {
3418 setText('C');
3419 });
3420 expect(Scheduler).toHaveYielded(['Suspend! [C]', 'Loading...']);
3421
3422 // Commit. This will insert a fragment fiber to wrap around the component
3423 // that triggered the update.
3422 - await ReactNoop.act(async () => {
3424 + await act(async () => {
3425 await advanceTimers(250);
3426 });
3427 // The fragment fiber is part of the current tree, but the setState return
@@ -3432,7 +3434,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3434 </>,
3435 );
3436
3435 - await ReactNoop.act(async () => {
3437 + await act(async () => {
3438 // Schedule a normal pri update. This will suspend again.
3439 setText('D');
3440
@@ -3504,7 +3506,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3506
3507 // Mount an initial tree. Resolve A so that it doesn't suspend.
3508 await seedNextTextCache('Inner text: A');
3507 - await ReactNoop.act(async () => {
3509 + await act(async () => {
3510 root.render(<Parent step={0} />);
3511 });
3512 expect(Scheduler).toHaveYielded([
@@ -3524,7 +3526,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3526 );
3527
3528 // Update. This causes the inner component to suspend.
3527 - await ReactNoop.act(async () => {
3529 + await act(async () => {
3530 setText('B');
3531 });
3532 expect(Scheduler).toHaveYielded([
@@ -3547,7 +3549,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3549 );
3550
3551 // Schedule a high pri update on the parent.
3550 - await ReactNoop.act(async () => {
3552 + await act(async () => {
3553 ReactNoop.discreteUpdates(() => {
3554 root.render(<Parent step={1} />);
3555 });
@@ -3574,7 +3576,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3576 );
3577
3578 // Now finish resolving the inner text
3577 - await ReactNoop.act(async () => {
3579 + await act(async () => {
3580 await resolveText('Inner text: B');
3581 });
3582 expect(Scheduler).toHaveYielded([
@@ -3643,7 +3645,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3645
3646 // Mount an initial tree. Resolve A so that it doesn't suspend.
3647 await seedNextTextCache('Inner: A0');
3646 - await ReactNoop.act(async () => {
3648 + await act(async () => {
3649 root.render(<Parent step={0} />);
3650 });
3651 expect(Scheduler).toHaveYielded(['Outer: A0', 'Inner: A0', 'Commit Child']);
@@ -3655,7 +3657,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3657 );
3658
3659 // Update. This causes the inner component to suspend.
3658 - await ReactNoop.act(async () => {
3660 + await act(async () => {
3661 setText('B');
3662 });
3663 expect(Scheduler).toHaveYielded([
@@ -3675,7 +3677,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3677
3678 // Schedule a high pri update on the parent. This will unblock the content.
3679 await resolveText('Inner: B1');
3678 - await ReactNoop.act(async () => {
3680 + await act(async () => {
3681 ReactNoop.discreteUpdates(() => {
3682 root.render(<Parent step={1} />);
3683 });
@@ -3731,7 +3733,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3733 }
3734
3735 const root = ReactNoop.createRoot();
3734 - await ReactNoop.act(async () => {
3736 + await act(async () => {
3737 await seedNextTextCache('A');
3738 await seedNextTextCache('B');
3739 root.render(<App />);
@@ -3744,7 +3746,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3746 </>,
3747 );
3748
3747 - await ReactNoop.act(async () => {
3749 + await act(async () => {
3750 // Triggers suspense at normal pri
3751 setTextA('A1');
3752 // Triggers in an unrelated tree at a different pri
@@ -3847,14 +3849,14 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3849 }
3850
3851 const root = ReactNoop.createRoot();
3850 - await ReactNoop.act(async () => {
3852 + await act(async () => {
3853 root.render(<Root />);
3854 });
3855 expect(Scheduler).toHaveYielded(['']);
3856 expect(root).toMatchRenderedOutput(<span prop="" />);
3857
3858 // Update to "a". That will suspend.
3857 - await ReactNoop.act(async () => {
3859 + await act(async () => {
3860 setTextWithShortTransition('a');
3861 expect(Scheduler).toFlushAndYield([
3862 'Pending...',
@@ -3872,7 +3874,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3874 );
3875
3876 // Update to "b". That will suspend, too.
3875 - await ReactNoop.act(async () => {
3877 + await act(async () => {
3878 setTextWithLongTransition('b');
3879 expect(Scheduler).toFlushAndYield([
3880 // Neither is resolved yet.
@@ -3891,7 +3893,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3893 );
3894
3895 // Resolve "a". But "b" is still pending.
3894 - await ReactNoop.act(async () => {
3896 + await act(async () => {
3897 await resolveText('a');
3898
3899 expect(Scheduler).toFlushAndYield(['Suspend! [b]', 'Loading...']);
@@ -3903,7 +3905,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3905 );
3906
3907 // Resolve "b". This should remove the pending state.
3906 - await ReactNoop.act(async () => {
3908 + await act(async () => {
3909 await resolveText('b');
3910 });
3911 expect(Scheduler).toHaveYielded(['b']);
@@ -3924,7 +3926,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3926 }
3927
3928 const root = ReactNoop.createRoot();
3927 - await ReactNoop.act(async () => {
3929 + await act(async () => {
3930 await seedNextTextCache('A');
3931 root.render(
3932 <Suspense fallback={<Text text="Loading..." />}>
@@ -3935,7 +3937,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3937 expect(Scheduler).toHaveYielded(['A']);
3938 expect(root).toMatchRenderedOutput(<span prop="A" />);
3939
3938 - await ReactNoop.act(async () => {
3940 + await act(async () => {
3941 setText('B');
3942 ReactNoop.idleUpdates(() => {
3943 setText('B');
@@ -3951,7 +3953,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3953 expect(Scheduler).toFlushAndYield(['Suspend! [B]']);
3954 });
3955
3954 - await ReactNoop.act(async () => {
3956 + await act(async () => {
3957 setText('B');
3958 await resolveText('B');
3959 });
@@ -3971,7 +3973,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3973 }
3974
3975 const root = ReactNoop.createRoot();
3974 - await ReactNoop.act(async () => {
3976 + await act(async () => {
3977 root.render(
3978 <>
3979 <UpdatingText />
@@ -3989,7 +3991,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3991 </>,
3992 );
3993
3992 - await ReactNoop.act(async () => {
3994 + await act(async () => {
3995 // Resolve the promise. This will trigger a retry.
3996 await resolveText('Async');
3997 // Before the retry happens, schedule a new update.
@@ -4039,13 +4041,13 @@ describe('ReactSuspenseWithNoopRenderer', () => {
4041
4042 const root = ReactNoop.createRoot();
4043
4042 - await ReactNoop.act(async () => {
4044 + await act(async () => {
4045 root.render(<App show={false} />);
4046 });
4047 expect(Scheduler).toHaveYielded(['Mount Child']);
4048 expect(root).toMatchRenderedOutput(<span prop="Child" />);
4049
4048 - await ReactNoop.act(async () => {
4050 + await act(async () => {
4051 root.render(<App show={true} />);
4052 });
4053 expect(Scheduler).toHaveYielded(['Suspend! [Async]', 'Loading...']);
@@ -4056,7 +4058,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
4058 </>,
4059 );
4060
4059 - await ReactNoop.act(async () => {
4061 + await act(async () => {
4062 root.render(null);
4063 });
4064 expect(Scheduler).toHaveYielded(['Unmount Child']);
@@ -4087,13 +4089,13 @@ describe('ReactSuspenseWithNoopRenderer', () => {
4089
4090 const root = ReactNoop.createLegacyRoot();
4091
4090 - await ReactNoop.act(async () => {
4092 + await act(async () => {
4093 root.render(<App show={false} />);
4094 });
4095 expect(Scheduler).toHaveYielded(['Mount Child']);
4096 expect(root).toMatchRenderedOutput(<span prop="Child" />);
4097
4096 - await ReactNoop.act(async () => {
4098 + await act(async () => {
4099 root.render(<App show={true} />);
4100 });
4101 expect(Scheduler).toHaveYielded(['Suspend! [Async]', 'Loading...']);
@@ -4104,7 +4106,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
4106 </>,
4107 );
4108
4107 - await ReactNoop.act(async () => {
4109 + await act(async () => {
4110 root.render(null);
4111 });
4112 expect(Scheduler).toHaveYielded(['Unmount Child']);
packages/react-reconciler/src/__tests__/ReactTransition-test.js
+7 -7
@@ -36,7 +36,7 @@ describe('ReactTransition', () => {
36 Suspense = React.Suspense;
37 startTransition = React.startTransition;
38 getCacheForType = React.unstable_getCacheForType;
39 - act = ReactNoop.act;
39 + act = require('jest-react').act;
40
41 caches = [];
42 seededCache = null;
@@ -551,7 +551,7 @@ describe('ReactTransition', () => {
551 test('interrupt a refresh transition if a new transition is scheduled', async () => {
552 const root = ReactNoop.createRoot();
553
554 - await ReactNoop.act(async () => {
554 + await act(async () => {
555 root.render(
556 <>
557 <Suspense fallback={<Text text="Loading..." />} />
@@ -562,7 +562,7 @@ describe('ReactTransition', () => {
562 expect(Scheduler).toHaveYielded(['Initial']);
563 expect(root).toMatchRenderedOutput('Initial');
564
565 - await ReactNoop.act(async () => {
565 + await act(async () => {
566 // Start a refresh transition
567 startTransition(() => {
568 root.render(
@@ -729,13 +729,13 @@ describe('ReactTransition', () => {
729
730 const root = ReactNoop.createRoot();
731
732 - await ReactNoop.act(async () => {
732 + await act(async () => {
733 root.render(<App shouldSuspend={false} step={0} />);
734 });
735 expect(Scheduler).toHaveYielded(['A0', 'B0', 'C0']);
736 expect(root).toMatchRenderedOutput('A0B0C0');
737
738 - await ReactNoop.act(async () => {
738 + await act(async () => {
739 // This update will suspend.
740 startTransition(() => {
741 root.render(<App shouldSuspend={true} step={1} />);
@@ -911,7 +911,7 @@ describe('ReactTransition', () => {
911 }
912
913 const root = ReactNoop.createRoot();
914 - await ReactNoop.act(async () => {
914 + await act(async () => {
915 root.render(<App />);
916 });
917 expect(Scheduler).toHaveYielded([
@@ -921,7 +921,7 @@ describe('ReactTransition', () => {
921 ]);
922 expect(root).toMatchRenderedOutput('Transition pri: 0, Normal pri: 0');
923
924 - await ReactNoop.act(async () => {
924 + await act(async () => {
925 updateTransitionPri();
926
927 expect(Scheduler).toFlushAndYieldThrough([
packages/react-reconciler/src/__tests__/ReactUpdatePriority-test.js
+6 -4
@@ -5,6 +5,7 @@ let ContinuousEventPriority;
5 let startTransition;
6 let useState;
7 let useEffect;
8 +let act;
9
10 describe('ReactUpdatePriority', () => {
11 beforeEach(() => {
@@ -13,6 +14,7 @@ describe('ReactUpdatePriority', () => {
14 React = require('react');
15 ReactNoop = require('react-noop-renderer');
16 Scheduler = require('scheduler');
17 + act = require('jest-react').act;
18 ContinuousEventPriority = require('react-reconciler/constants')
19 .ContinuousEventPriority;
20 startTransition = React.startTransition;
@@ -36,7 +38,7 @@ describe('ReactUpdatePriority', () => {
38 return <Text text={state} />;
39 }
40
39 - await ReactNoop.act(async () => {
41 + await act(async () => {
42 ReactNoop.flushSync(() => {
43 root.render(<App />);
44 });
@@ -61,7 +63,7 @@ describe('ReactUpdatePriority', () => {
63 return <Text text={`Idle: ${idleState}, Default: ${defaultState}`} />;
64 }
65
64 - await ReactNoop.act(async () => {
66 + await act(async () => {
67 ReactNoop.idleUpdates(() => {
68 root.render(<App />);
69 });
@@ -106,13 +108,13 @@ describe('ReactUpdatePriority', () => {
108 );
109 }
110
109 - await ReactNoop.act(async () => {
111 + await act(async () => {
112 root.render(<App />);
113 });
114 expect(Scheduler).toHaveYielded(['A1', 'B1', 'C1']);
115 expect(root).toMatchRenderedOutput('A1B1C1');
116
115 - await ReactNoop.act(async () => {
117 + await act(async () => {
118 startTransition(() => {
119 setCounter(2);
120 });
packages/react-reconciler/src/__tests__/ReactUpdaters-test.internal.js
+1 -3
@@ -12,7 +12,6 @@
12 let React;
13 let ReactFeatureFlags;
14 let ReactDOM;
15 -let ReactTestUtils;
15 let Scheduler;
16 let mockDevToolsHook;
17 let allSchedulerTags;
@@ -65,10 +64,9 @@ describe('updaters', () => {
64
65 React = require('react');
66 ReactDOM = require('react-dom');
68 - ReactTestUtils = require('react-dom/test-utils');
67 Scheduler = require('scheduler');
68
71 - act = ReactTestUtils.unstable_concurrentAct;
69 + act = require('jest-react').act;
70 });
71
72 it('should report the (host) root as the scheduler for root-level render', async () => {
packages/react-reconciler/src/__tests__/SchedulingProfiler-test.internal.js
+4 -2
@@ -26,6 +26,7 @@ describe('SchedulingProfiler', () => {
26 let ReactTestRenderer;
27 let ReactNoop;
28 let Scheduler;
29 + let act;
30
31 let clearedMarks;
32 let featureDetectionMarkName = null;
@@ -86,6 +87,7 @@ describe('SchedulingProfiler', () => {
87 ReactNoop = require('react-noop-renderer');
88
89 Scheduler = require('scheduler');
90 + act = require('jest-react').act;
91
92 const SchedulingProfiler = require('react-reconciler/src/SchedulingProfiler');
93 formatLanes = SchedulingProfiler.formatLanes;
@@ -518,7 +520,7 @@ describe('SchedulingProfiler', () => {
520 return didMount;
521 }
522
521 - ReactTestRenderer.unstable_concurrentAct(() => {
523 + act(() => {
524 ReactTestRenderer.create(<Example />, {unstable_isConcurrent: true});
525 });
526
@@ -553,7 +555,7 @@ describe('SchedulingProfiler', () => {
555 return didRender;
556 }
557
556 - ReactTestRenderer.unstable_concurrentAct(() => {
558 + act(() => {
559 ReactTestRenderer.create(<Example />, {unstable_isConcurrent: true});
560 });
561
packages/react-reconciler/src/__tests__/StrictEffectsMode-test.js
+1 -1
@@ -20,7 +20,7 @@ describe('StrictEffectsMode', () => {
20 React = require('react');
21 ReactTestRenderer = require('react-test-renderer');
22 Scheduler = require('scheduler');
23 - act = ReactTestRenderer.unstable_concurrentAct;
23 + act = require('jest-react').act;
24 });
25
26 function supportsDoubleInvokeEffects() {
packages/react-reconciler/src/__tests__/StrictEffectsModeDefaults-test.internal.js
+30 -28
@@ -12,6 +12,7 @@
12 let React;
13 let ReactNoop;
14 let Scheduler;
15 +let act;
16
17 describe('StrictEffectsMode defaults', () => {
18 beforeEach(() => {
@@ -20,6 +21,7 @@ describe('StrictEffectsMode defaults', () => {
21 React = require('react');
22 ReactNoop = require('react-noop-renderer');
23 Scheduler = require('scheduler');
24 + act = require('jest-react').act;
25
26 const ReactFeatureFlags = require('shared/ReactFeatureFlags');
27 ReactFeatureFlags.enableStrictEffects = __DEV__;
@@ -41,7 +43,7 @@ describe('StrictEffectsMode defaults', () => {
43 return text;
44 }
45
44 - ReactNoop.act(() => {
46 + act(() => {
47 ReactNoop.renderLegacySyncRoot(<App text={'mount'} />);
48 });
49
@@ -70,7 +72,7 @@ describe('StrictEffectsMode defaults', () => {
72 }
73 }
74
73 - ReactNoop.act(() => {
75 + act(() => {
76 ReactNoop.renderLegacySyncRoot(<App text={'mount'} />);
77 });
78
@@ -89,7 +91,7 @@ describe('StrictEffectsMode defaults', () => {
91 return label;
92 }
93
92 - ReactNoop.act(() => {
94 + act(() => {
95 ReactNoop.render(
96 <>
97 <ComponentWithEffects label={'one'} />
@@ -103,7 +105,7 @@ describe('StrictEffectsMode defaults', () => {
105 ]);
106 });
107
106 - ReactNoop.act(() => {
108 + act(() => {
109 ReactNoop.render(
110 <>
111 <ComponentWithEffects label={'one'} />
@@ -143,7 +145,7 @@ describe('StrictEffectsMode defaults', () => {
145 return label;
146 }
147
146 - ReactNoop.act(() => {
148 + act(() => {
149 ReactNoop.render(
150 <>
151 <ComponentWithEffects label={'one'} />
@@ -162,7 +164,7 @@ describe('StrictEffectsMode defaults', () => {
164 ]);
165 });
166
165 - ReactNoop.act(() => {
167 + act(() => {
168 ReactNoop.render(
169 <>
170 <ComponentWithEffects label={'one'} />
@@ -204,7 +206,7 @@ describe('StrictEffectsMode defaults', () => {
206
207 return text;
208 }
207 - ReactNoop.act(() => {
209 + act(() => {
210 ReactNoop.render(<App text={'mount'} />);
211 });
212
@@ -217,7 +219,7 @@ describe('StrictEffectsMode defaults', () => {
219 'useEffect mount',
220 ]);
221
220 - ReactNoop.act(() => {
222 + act(() => {
223 ReactNoop.render(<App text={'update'} />);
224 });
225
@@ -228,7 +230,7 @@ describe('StrictEffectsMode defaults', () => {
230 'useEffect mount',
231 ]);
232
231 - ReactNoop.act(() => {
233 + act(() => {
234 ReactNoop.render(null);
235 });
236
@@ -253,7 +255,7 @@ describe('StrictEffectsMode defaults', () => {
255 return text;
256 }
257
256 - ReactNoop.act(() => {
258 + act(() => {
259 ReactNoop.render(<App text={'mount'} />);
260 });
261
@@ -266,7 +268,7 @@ describe('StrictEffectsMode defaults', () => {
268 'useEffect Two mount',
269 ]);
270
269 - ReactNoop.act(() => {
271 + act(() => {
272 ReactNoop.render(<App text={'update'} />);
273 });
274
@@ -277,7 +279,7 @@ describe('StrictEffectsMode defaults', () => {
279 'useEffect Two mount',
280 ]);
281
280 - ReactNoop.act(() => {
282 + act(() => {
283 ReactNoop.render(null);
284 });
285
@@ -304,7 +306,7 @@ describe('StrictEffectsMode defaults', () => {
306 return text;
307 }
308
307 - ReactNoop.act(() => {
309 + act(() => {
310 ReactNoop.render(<App text={'mount'} />);
311 });
312
@@ -317,7 +319,7 @@ describe('StrictEffectsMode defaults', () => {
319 'useLayoutEffect Two mount',
320 ]);
321
320 - ReactNoop.act(() => {
322 + act(() => {
323 ReactNoop.render(<App text={'update'} />);
324 });
325
@@ -328,7 +330,7 @@ describe('StrictEffectsMode defaults', () => {
330 'useLayoutEffect Two mount',
331 ]);
332
331 - ReactNoop.act(() => {
333 + act(() => {
334 ReactNoop.render(null);
335 });
336
@@ -351,7 +353,7 @@ describe('StrictEffectsMode defaults', () => {
353 return text;
354 }
355
354 - ReactNoop.act(() => {
356 + act(() => {
357 ReactNoop.render(<App text={'mount'} />);
358 });
359
@@ -362,7 +364,7 @@ describe('StrictEffectsMode defaults', () => {
364 'useEffect mount',
365 ]);
366
365 - ReactNoop.act(() => {
367 + act(() => {
368 ReactNoop.render(<App text={'update'} />);
369 });
370
@@ -371,7 +373,7 @@ describe('StrictEffectsMode defaults', () => {
373 'useEffect mount',
374 ]);
375
374 - ReactNoop.act(() => {
376 + act(() => {
377 ReactNoop.render(null);
378 });
379
@@ -402,7 +404,7 @@ describe('StrictEffectsMode defaults', () => {
404 }
405 }
406
405 - ReactNoop.act(() => {
407 + act(() => {
408 ReactNoop.render(<App />);
409 });
410
@@ -432,7 +434,7 @@ describe('StrictEffectsMode defaults', () => {
434 }
435 }
436
435 - ReactNoop.act(() => {
437 + act(() => {
438 ReactNoop.render(<App text={'mount'} />);
439 });
440
@@ -442,13 +444,13 @@ describe('StrictEffectsMode defaults', () => {
444 'componentDidMount',
445 ]);
446
445 - ReactNoop.act(() => {
447 + act(() => {
448 ReactNoop.render(<App text={'update'} />);
449 });
450
451 expect(Scheduler).toHaveYielded(['componentDidUpdate']);
452
451 - ReactNoop.act(() => {
453 + act(() => {
454 ReactNoop.render(null);
455 });
456
@@ -475,7 +477,7 @@ describe('StrictEffectsMode defaults', () => {
477 return text;
478 }
479
478 - ReactNoop.act(() => {
480 + act(() => {
481 ReactNoop.render(<App text={'mount'} />);
482 });
483
@@ -527,7 +529,7 @@ describe('StrictEffectsMode defaults', () => {
529 return showChild && <Child />;
530 }
531
530 - ReactNoop.act(() => {
532 + act(() => {
533 ReactNoop.render(<App />);
534 });
535
@@ -540,7 +542,7 @@ describe('StrictEffectsMode defaults', () => {
542 'App useEffect mount',
543 ]);
544
543 - ReactNoop.act(() => {
545 + act(() => {
546 _setShowChild(true);
547 });
548
@@ -594,7 +596,7 @@ describe('StrictEffectsMode defaults', () => {
596 );
597 }
598
597 - ReactNoop.act(() => {
599 + act(() => {
600 ReactNoop.render(<App text={'mount'} />);
601 });
602
@@ -610,7 +612,7 @@ describe('StrictEffectsMode defaults', () => {
612 'useEffect mount',
613 ]);
614
613 - ReactNoop.act(() => {
615 + act(() => {
616 ReactNoop.render(<App text={'mount'} />);
617 });
618
@@ -621,7 +623,7 @@ describe('StrictEffectsMode defaults', () => {
623 'useEffect mount',
624 ]);
625
624 - ReactNoop.act(() => {
626 + act(() => {
627 ReactNoop.render(null);
628 });
629
packages/react-reconciler/src/__tests__/useMutableSource-test.internal.js
+2 -2
@@ -30,7 +30,7 @@ function loadModules() {
30 React = require('react');
31 ReactNoop = require('react-noop-renderer');
32 Scheduler = require('scheduler');
33 - act = ReactNoop.act;
33 + act = require('jest-react').act;
34
35 // Stable entrypoints export with "unstable_" prefix.
36 createMutableSource =
@@ -1443,7 +1443,7 @@ describe('useMutableSource', () => {
1443 // Now mutate A. Both hooks should update.
1444 // This is at high priority so that it doesn't get batched with default
1445 // priority updates that might fire during the passive effect
1446 - await ReactNoop.act(async () => {
1446 + await act(async () => {
1447 ReactNoop.discreteUpdates(() => {
1448 mutateA('a1');
1449 });
packages/react-reconciler/src/__tests__/useMutableSourceHydration-test.js
+1 -1
@@ -26,7 +26,7 @@ describe('useMutableSourceHydration', () => {
26 ReactDOMServer = require('react-dom/server');
27 Scheduler = require('scheduler');
28
29 - act = require('react-dom/test-utils').unstable_concurrentAct;
29 + act = require('jest-react').act;
30
31 // Stable entrypoints export with "unstable_" prefix.
32 createMutableSource =
packages/react-reconciler/src/__tests__/useRef-test.internal.js
+1 -1
@@ -31,7 +31,7 @@ describe('useRef', () => {
31 const ReactFeatureFlags = require('shared/ReactFeatureFlags');
32 ReactFeatureFlags.debugRenderPhaseSideEffectsForStrictMode = false;
33
34 - act = ReactNoop.act;
34 + act = require('jest-react').act;
35 useCallback = React.useCallback;
36 useEffect = React.useEffect;
37 useLayoutEffect = React.useLayoutEffect;
packages/react-refresh/src/__tests__/ReactFresh-test.js
+2 -2
@@ -29,7 +29,7 @@ describe('ReactFresh', () => {
29 ReactFreshRuntime.injectIntoGlobalHook(global);
30 ReactDOM = require('react-dom');
31 Scheduler = require('scheduler');
32 - act = require('react-dom/test-utils').unstable_concurrentAct;
32 + act = require('jest-react').act;
33 createReactClass = require('create-react-class/factory')(
34 React.Component,
35 React.isValidElement,
@@ -3782,7 +3782,7 @@ describe('ReactFresh', () => {
3782 React = require('react');
3783 ReactDOM = require('react-dom');
3784 Scheduler = require('scheduler');
3785 - act = require('react-dom/test-utils').unstable_concurrentAct;
3785 + act = require('jest-react').act;
3786
3787 // Important! Inject into the global hook *after* ReactDOM runs:
3788 ReactFreshRuntime = require('react-refresh/runtime');
packages/react-refresh/src/__tests__/ReactFreshIntegration-test.js
+1 -1
@@ -30,7 +30,7 @@ describe('ReactFreshIntegration', () => {
30 ReactFreshRuntime = require('react-refresh/runtime');
31 ReactFreshRuntime.injectIntoGlobalHook(global);
32 ReactDOM = require('react-dom');
33 - act = require('react-dom/test-utils').unstable_concurrentAct;
33 + act = require('jest-react').act;
34 container = document.createElement('div');
35 document.body.appendChild(container);
36 exportsObj = undefined;
packages/react-server-dom-relay/src/__tests__/ReactFlightDOMRelay-test.internal.js
+1 -1
@@ -18,7 +18,7 @@ describe('ReactFlightDOMRelay', () => {
18 beforeEach(() => {
19 jest.resetModules();
20
21 - act = require('react-dom/test-utils').unstable_concurrentAct;
21 + act = require('jest-react').act;
22 React = require('react');
23 ReactDOM = require('react-dom');
24 ReactDOMFlightRelayServer = require('react-server-dom-relay/server');
packages/react-server-dom-webpack/src/__tests__/ReactFlightDOM-test.js
+1 -1
@@ -36,7 +36,7 @@ describe('ReactFlightDOM', () => {
36 jest.resetModules();
37 webpackModules = {};
38 webpackMap = {};
39 - act = require('react-dom/test-utils').unstable_concurrentAct;
39 + act = require('jest-react').act;
40 Stream = require('stream');
41 React = require('react');
42 ReactDOM = require('react-dom');
packages/react-test-renderer/src/ReactTestRenderer.js
+2 -128
@@ -21,7 +21,6 @@ import {
21 flushSync,
22 injectIntoDevTools,
23 batchedUpdates,
24 - IsThisRendererActing,
24 } from 'react-reconciler/src/ReactFiberReconciler';
25 import {findCurrentFiberUsingSlowPath} from 'react-reconciler/src/ReactFiberTreeReflection';
26 import {
@@ -46,15 +45,11 @@ import invariant from 'shared/invariant';
45 import isArray from 'shared/isArray';
46 import getComponentNameFromType from 'shared/getComponentNameFromType';
47 import ReactVersion from 'shared/ReactVersion';
49 -import ReactSharedInternals from 'shared/ReactSharedInternals';
50 -import enqueueTask from 'shared/enqueueTask';
48
49 import {getPublicInstance} from './ReactTestHostConfig';
50 import {ConcurrentRoot, LegacyRoot} from 'react-reconciler/src/ReactRootTags';
51 import {allowConcurrentByDefault} from 'shared/ReactFeatureFlags';
52
56 -const {IsSomeRendererActing, ReactCurrentActQueue} = ReactSharedInternals;
57 -
53 const act_notBatchedInLegacyMode = React.unstable_act;
54 function act(callback: () => Thenable<mixed>): Thenable<void> {
55 return act_notBatchedInLegacyMode(() => {
@@ -62,6 +57,8 @@ function act(callback: () => Thenable<mixed>): Thenable<void> {
57 });
58 }
59
60 +// TODO: Remove from public bundle
61 +
62 type TestRendererOptions = {
63 createNodeMock: (element: React$Element<any>) => any,
64 unstable_isConcurrent: boolean,
@@ -601,133 +598,10 @@ injectIntoDevTools({
598 rendererPackageName: 'react-test-renderer',
599 });
600
604 -let actingUpdatesScopeDepth = 0;
605 -
606 -// This version of `act` is only used by our tests. Unlike the public version
607 -// of `act`, it's designed to work identically in both production and
608 -// development. It may have slightly different behavior from the public
609 -// version, too, since our constraints in our test suite are not the same as
610 -// those of developers using React — we're testing React itself, as opposed to
611 -// building an app with React.
612 -// TODO: Migrate our tests to use ReactNoop. Although we would need to figure
613 -// out a solution for Relay, which has some Concurrent Mode tests.
614 -// TODO: Replace the internal "concurrent" implementations of `act` with a
615 -// single shared module.
616 -function unstable_concurrentAct(scope: () => Thenable<mixed> | void) {
617 - if (Scheduler.unstable_flushAllWithoutAsserting === undefined) {
618 - throw Error(
619 - 'This version of `act` requires a special mock build of Scheduler.',
620 - );
621 - }
622 - if (setTimeout._isMockFunction !== true) {
623 - throw Error(
624 - "This version of `act` requires Jest's timer mocks " +
625 - '(i.e. jest.useFakeTimers).',
626 - );
627 - }
628 -
629 - const previousActingUpdatesScopeDepth = actingUpdatesScopeDepth;
630 - const previousIsSomeRendererActing = IsSomeRendererActing.current;
631 - const previousIsThisRendererActing = IsThisRendererActing.current;
632 - IsSomeRendererActing.current = true;
633 - IsThisRendererActing.current = true;
634 - actingUpdatesScopeDepth++;
635 - if (__DEV__ && actingUpdatesScopeDepth === 1) {
636 - ReactCurrentActQueue.disableActWarning = true;
637 - }
638 -
639 - const unwind = () => {
640 - if (__DEV__ && actingUpdatesScopeDepth === 1) {
641 - ReactCurrentActQueue.disableActWarning = false;
642 - }
643 - actingUpdatesScopeDepth--;
644 - IsSomeRendererActing.current = previousIsSomeRendererActing;
645 - IsThisRendererActing.current = previousIsThisRendererActing;
646 - if (__DEV__) {
647 - if (actingUpdatesScopeDepth > previousActingUpdatesScopeDepth) {
648 - // if it's _less than_ previousActingUpdatesScopeDepth, then we can
649 - // assume the 'other' one has warned
650 - console.error(
651 - 'You seem to have overlapping act() calls, this is not supported. ' +
652 - 'Be sure to await previous act() calls before making a new one. ',
653 - );
654 - }
655 - }
656 - };
657 -
658 - // TODO: This would be way simpler if 1) we required a promise to be
659 - // returned and 2) we could use async/await. Since it's only our used in
660 - // our test suite, we should be able to.
661 - try {
662 - const thenable = batchedUpdates(scope);
663 - if (
664 - typeof thenable === 'object' &&
665 - thenable !== null &&
666 - typeof thenable.then === 'function'
667 - ) {
668 - return {
669 - then(resolve: () => void, reject: (error: mixed) => void) {
670 - thenable.then(
671 - () => {
672 - flushActWork(
673 - () => {
674 - unwind();
675 - resolve();
676 - },
677 - error => {
678 - unwind();
679 - reject(error);
680 - },
681 - );
682 - },
683 - error => {
684 - unwind();
685 - reject(error);
686 - },
687 - );
688 - },
689 - };
690 - } else {
691 - try {
692 - // TODO: Let's not support non-async scopes at all in our tests. Need to
693 - // migrate existing tests.
694 - let didFlushWork;
695 - do {
696 - didFlushWork = Scheduler.unstable_flushAllWithoutAsserting();
697 - } while (didFlushWork);
698 - } finally {
699 - unwind();
700 - }
701 - }
702 - } catch (error) {
703 - unwind();
704 - throw error;
705 - }
706 -}
707 -
708 -function flushActWork(resolve, reject) {
709 - // Flush suspended fallbacks
710 - // $FlowFixMe: Flow doesn't know about global Jest object
711 - jest.runOnlyPendingTimers();
712 - enqueueTask(() => {
713 - try {
714 - const didFlushWork = Scheduler.unstable_flushAllWithoutAsserting();
715 - if (didFlushWork) {
716 - flushActWork(resolve, reject);
717 - } else {
718 - resolve();
719 - }
720 - } catch (error) {
721 - reject(error);
722 - }
723 - });
724 -}
725 -
601 export {
602 Scheduler as _Scheduler,
603 create,
604 /* eslint-disable-next-line camelcase */
605 batchedUpdates as unstable_batchedUpdates,
606 act,
732 - unstable_concurrentAct,
607 };
packages/react/src/IsSomeRendererActing.js deleted
-17
@@ -1,17 +0,0 @@
1 -/**
2 - * Copyright (c) Facebook, Inc. and its affiliates.
3 - *
4 - * This source code is licensed under the MIT license found in the
5 - * LICENSE file in the root directory of this source tree.
6 - *
7 - * @flow
8 - */
9 -
10 -/**
11 - * Used by act() to track whether you're inside an act() scope.
12 - */
13 -
14 -const IsSomeRendererActing = {
15 - current: (false: boolean),
16 -};
17 -export default IsSomeRendererActing;
packages/react/src/ReactSharedInternals.js
-2
@@ -11,13 +11,11 @@ import ReactCurrentBatchConfig from './ReactCurrentBatchConfig';
11 import ReactCurrentActQueue from './ReactCurrentActQueue';
12 import ReactCurrentOwner from './ReactCurrentOwner';
13 import ReactDebugCurrentFrame from './ReactDebugCurrentFrame';
14 -import IsSomeRendererActing from './IsSomeRendererActing';
14
15 const ReactSharedInternals = {
16 ReactCurrentDispatcher,
17 ReactCurrentBatchConfig,
18 ReactCurrentOwner,
20 - IsSomeRendererActing,
19 // Used by renderers to avoid bundling object-assign twice in UMD bundles:
20 assign,
21 };
packages/react/src/__tests__/ReactCoffeeScriptClass-test.coffee
+1 -1
@@ -20,7 +20,7 @@ describe 'ReactCoffeeScriptClass', ->
20 beforeEach ->
21 React = require 'react'
22 ReactDOM = require 'react-dom'
23 - act = require('react-dom/test-utils').unstable_concurrentAct
23 + act = require('jest-react').act
24 PropTypes = require 'prop-types'
25 container = document.createElement 'div'
26 root = ReactDOM.createRoot container
packages/react/src/__tests__/ReactES6Class-test.js
+1 -1
@@ -29,7 +29,7 @@ describe('ReactES6Class', () => {
29 PropTypes = require('prop-types');
30 React = require('react');
31 ReactDOM = require('react-dom');
32 - act = require('react-dom/test-utils').unstable_concurrentAct;
32 + act = require('jest-react').act;
33 container = document.createElement('div');
34 root = ReactDOM.createRoot(container);
35 attachedListener = null;
packages/react/src/__tests__/ReactProfiler-test.internal.js
+34 -35
@@ -15,7 +15,7 @@ let ReactFeatureFlags;
15 let ReactNoop;
16 let Scheduler;
17 let ReactTestRenderer;
18 -let ReactTestRendererAct;
18 +let act;
19 let AdvanceTime;
20
21 function loadModules({
@@ -36,15 +36,14 @@ function loadModules({
36
37 React = require('react');
38 Scheduler = require('scheduler');
39 + act = require('jest-react').act;
40
41 if (useNoopRenderer) {
42 ReactNoop = require('react-noop-renderer');
43 ReactTestRenderer = null;
43 - ReactTestRendererAct = null;
44 } else {
45 ReactNoop = null;
46 ReactTestRenderer = require('react-test-renderer');
47 - ReactTestRendererAct = ReactTestRenderer.unstable_concurrentAct;
47 }
48
49 AdvanceTime = class extends React.Component {
@@ -346,7 +345,7 @@ describe(`onRender`, () => {
345 Scheduler.unstable_advanceTime(20); // 30 -> 50
346
347 // Updating a sibling should not report a re-render.
349 - ReactTestRendererAct(updateProfilerSibling);
348 + act(updateProfilerSibling);
349
350 expect(callback).not.toHaveBeenCalled();
351 });
@@ -672,7 +671,7 @@ describe(`onRender`, () => {
671
672 const onRender = jest.fn();
673
675 - ReactNoop.act(() => {
674 + act(() => {
675 ReactNoop.render(
676 <React.Profiler id="root" onRender={onRender}>
677 <Component />
@@ -1641,7 +1640,7 @@ describe(`onCommit`, () => {
1640 const setCountRef = React.createRef(null);
1641
1642 let renderer = null;
1644 - ReactTestRendererAct(() => {
1643 + act(() => {
1644 renderer = ReactTestRenderer.create(
1645 <React.Profiler id="root-mount" onCommit={callback}>
1646 <React.Profiler id="a">
@@ -1668,7 +1667,7 @@ describe(`onCommit`, () => {
1667 expect(call[2]).toBe(1010); // durations
1668 expect(call[3]).toBe(2); // commit start time (before mutations or effects)
1669
1671 - ReactTestRendererAct(() => setCountRef.current(count => count + 1));
1670 + act(() => setCountRef.current(count => count + 1));
1671
1672 expect(callback).toHaveBeenCalledTimes(2);
1673
@@ -1680,7 +1679,7 @@ describe(`onCommit`, () => {
1679 expect(call[2]).toBe(110); // durations
1680 expect(call[3]).toBe(1013); // commit start time (before mutations or effects)
1681
1683 - ReactTestRendererAct(() => {
1682 + act(() => {
1683 renderer.update(
1684 <React.Profiler id="root-update" onCommit={callback}>
1685 <React.Profiler id="b">
@@ -1739,7 +1738,7 @@ describe(`onCommit`, () => {
1738
1739 // Test an error that happens during an effect
1740
1742 - ReactTestRendererAct(() => {
1741 + act(() => {
1742 ReactTestRenderer.create(
1743 <React.Profiler id="root" onCommit={callback}>
1744 <ErrorBoundary
@@ -1825,7 +1824,7 @@ describe(`onCommit`, () => {
1824
1825 let renderer = null;
1826
1828 - ReactTestRendererAct(() => {
1827 + act(() => {
1828 renderer = ReactTestRenderer.create(
1829 <React.Profiler id="root" onCommit={callback}>
1830 <ErrorBoundary
@@ -1867,7 +1866,7 @@ describe(`onCommit`, () => {
1866
1867 // Test an error that happens during an cleanup function
1868
1870 - ReactTestRendererAct(() => {
1869 + act(() => {
1870 renderer.update(
1871 <React.Profiler id="root" onCommit={callback}>
1872 <ErrorBoundary
@@ -1952,7 +1951,7 @@ describe(`onPostCommit`, () => {
1951 Scheduler.unstable_advanceTime(1);
1952
1953 let renderer;
1955 - ReactTestRendererAct(() => {
1954 + act(() => {
1955 renderer = ReactTestRenderer.create(
1956 <React.Profiler id="mount-test" onPostCommit={callback}>
1957 <ComponentWithEffects />
@@ -1973,7 +1972,7 @@ describe(`onPostCommit`, () => {
1972
1973 Scheduler.unstable_advanceTime(1);
1974
1976 - ReactTestRendererAct(() => {
1975 + act(() => {
1976 renderer.update(
1977 <React.Profiler id="update-test" onPostCommit={callback}>
1978 <ComponentWithEffects />
@@ -1994,7 +1993,7 @@ describe(`onPostCommit`, () => {
1993
1994 Scheduler.unstable_advanceTime(1);
1995
1997 - ReactTestRendererAct(() => {
1996 + act(() => {
1997 renderer.update(
1998 <React.Profiler id="unmount-test" onPostCommit={callback} />,
1999 );
@@ -2036,7 +2035,7 @@ describe(`onPostCommit`, () => {
2035
2036 Scheduler.unstable_advanceTime(1);
2037
2039 - ReactTestRendererAct(() => {
2038 + act(() => {
2039 ReactTestRenderer.create(
2040 <React.Profiler id="mount-test" onPostCommit={callback}>
2041 <ComponentWithEffects />
@@ -2084,7 +2083,7 @@ describe(`onPostCommit`, () => {
2083 const setCountRef = React.createRef(null);
2084
2085 let renderer = null;
2087 - ReactTestRendererAct(() => {
2086 + act(() => {
2087 renderer = ReactTestRenderer.create(
2088 <React.Profiler id="root-mount" onPostCommit={callback}>
2089 <React.Profiler id="a">
@@ -2111,7 +2110,7 @@ describe(`onPostCommit`, () => {
2110 expect(call[2]).toBe(1010); // durations
2111 expect(call[3]).toBe(2); // commit start time (before mutations or effects)
2112
2114 - ReactTestRendererAct(() => setCountRef.current(count => count + 1));
2113 + act(() => setCountRef.current(count => count + 1));
2114
2115 expect(callback).toHaveBeenCalledTimes(2);
2116
@@ -2123,7 +2122,7 @@ describe(`onPostCommit`, () => {
2122 expect(call[2]).toBe(110); // durations
2123 expect(call[3]).toBe(1013); // commit start time (before mutations or effects)
2124
2126 - ReactTestRendererAct(() => {
2125 + act(() => {
2126 renderer.update(
2127 <React.Profiler id="root-update" onPostCommit={callback}>
2128 <React.Profiler id="b">
@@ -2182,7 +2181,7 @@ describe(`onPostCommit`, () => {
2181
2182 // Test an error that happens during an effect
2183
2185 - ReactTestRendererAct(() => {
2184 + act(() => {
2185 ReactTestRenderer.create(
2186 <React.Profiler id="root" onPostCommit={callback}>
2187 <ErrorBoundary
@@ -2269,7 +2268,7 @@ describe(`onPostCommit`, () => {
2268
2269 let renderer = null;
2270
2272 - ReactTestRendererAct(() => {
2271 + act(() => {
2272 renderer = ReactTestRenderer.create(
2273 <React.Profiler id="root" onPostCommit={callback}>
2274 <ErrorBoundary
@@ -2311,7 +2310,7 @@ describe(`onPostCommit`, () => {
2310
2311 // Test an error that happens during an cleanup function
2312
2314 - ReactTestRendererAct(() => {
2313 + act(() => {
2314 renderer.update(
2315 <React.Profiler id="root" onPostCommit={callback}>
2316 <ErrorBoundary
@@ -2428,7 +2427,7 @@ describe(`onNestedUpdateScheduled`, () => {
2427
2428 const onNestedUpdateScheduled = jest.fn();
2429
2431 - ReactNoop.act(() => {
2430 + act(() => {
2431 ReactNoop.render(
2432 <React.Profiler
2433 id="test"
@@ -2489,7 +2488,7 @@ describe(`onNestedUpdateScheduled`, () => {
2488 const onNestedUpdateScheduledTwo = jest.fn();
2489 const onNestedUpdateScheduledThree = jest.fn();
2490
2492 - ReactNoop.act(() => {
2491 + act(() => {
2492 ReactNoop.render(
2493 <React.Profiler
2494 id="one"
@@ -2537,7 +2536,7 @@ describe(`onNestedUpdateScheduled`, () => {
2536
2537 const onNestedUpdateScheduled = jest.fn();
2538
2540 - ReactNoop.act(() => {
2539 + act(() => {
2540 ReactNoop.renderToRootWithID(
2541 <React.Profiler
2542 id="test"
@@ -2577,7 +2576,7 @@ describe(`onNestedUpdateScheduled`, () => {
2576
2577 const onNestedUpdateScheduled = jest.fn();
2578
2580 - ReactNoop.act(() => {
2579 + act(() => {
2580 ReactNoop.render(
2581 <React.Profiler
2582 id="test"
@@ -2603,7 +2602,7 @@ describe(`onNestedUpdateScheduled`, () => {
2602
2603 const onNestedUpdateScheduled = jest.fn();
2604
2606 - ReactNoop.act(() => {
2605 + act(() => {
2606 ReactNoop.render(
2607 <React.Profiler
2608 id="test"
@@ -2614,7 +2613,7 @@ describe(`onNestedUpdateScheduled`, () => {
2613 });
2614 expect(Scheduler).toHaveYielded(['Component:false']);
2615
2617 - ReactNoop.act(() => {
2616 + act(() => {
2617 updateFnRef.current();
2618 });
2619 expect(Scheduler).toHaveYielded(['Component:true']);
@@ -2633,7 +2632,7 @@ describe(`onNestedUpdateScheduled`, () => {
2632
2633 const onNestedUpdateScheduled = jest.fn();
2634
2636 - ReactNoop.act(() => {
2635 + act(() => {
2636 ReactNoop.render(
2637 <React.Profiler
2638 id="test"
@@ -2664,7 +2663,7 @@ describe(`onNestedUpdateScheduled`, () => {
2663
2664 const onNestedUpdateScheduled = jest.fn();
2665
2667 - ReactNoop.act(() => {
2666 + act(() => {
2667 ReactNoop.render(
2668 <React.Profiler
2669 id="test"
@@ -2681,7 +2680,7 @@ describe(`onNestedUpdateScheduled`, () => {
2680 expect(onNestedUpdateScheduled).toHaveBeenCalledTimes(1);
2681 expect(onNestedUpdateScheduled.mock.calls[0][0]).toBe('test');
2682
2684 - ReactNoop.act(() => {
2683 + act(() => {
2684 ReactNoop.render(
2685 <React.Profiler
2686 id="test"
@@ -2716,7 +2715,7 @@ describe(`onNestedUpdateScheduled`, () => {
2715
2716 const onNestedUpdateScheduled = jest.fn();
2717
2719 - ReactNoop.act(() => {
2718 + act(() => {
2719 ReactNoop.render(
2720 <React.Profiler
2721 id="test"
@@ -2756,7 +2755,7 @@ describe(`onNestedUpdateScheduled`, () => {
2755
2756 const onNestedUpdateScheduled = jest.fn();
2757
2759 - ReactNoop.act(() => {
2758 + act(() => {
2759 ReactNoop.render(
2760 <React.Profiler
2761 id="test"
@@ -2768,7 +2767,7 @@ describe(`onNestedUpdateScheduled`, () => {
2767 expect(Scheduler).toHaveYielded(['Component:false:false']);
2768 expect(onNestedUpdateScheduled).not.toHaveBeenCalled();
2769
2771 - ReactNoop.act(() => {
2770 + act(() => {
2771 ReactNoop.render(
2772 <React.Profiler
2773 id="test"
@@ -2803,7 +2802,7 @@ describe(`onNestedUpdateScheduled`, () => {
2802
2803 const onNestedUpdateScheduled = jest.fn();
2804
2806 - ReactNoop.act(() => {
2805 + act(() => {
2806 ReactNoop.render(
2807 <React.Profiler
2808 id="test"
@@ -2814,7 +2813,7 @@ describe(`onNestedUpdateScheduled`, () => {
2813 });
2814 expect(Scheduler).toHaveYielded(['Component:false']);
2815
2817 - ReactNoop.act(() => {
2816 + act(() => {
2817 updateFnRef.current();
2818 });
2819 expect(Scheduler).toHaveYielded(['Component:true']);
packages/react/src/__tests__/ReactStrictMode-test.internal.js
+1 -2
@@ -19,8 +19,7 @@ describe('ReactStrictMode', () => {
19 React = require('react');
20 ReactDOM = require('react-dom');
21
22 - const TestUtils = require('react-dom/test-utils');
23 - act = TestUtils.unstable_concurrentAct;
22 + act = require('jest-react').act;
23
24 const ReactFeatureFlags = require('shared/ReactFeatureFlags');
25 ReactFeatureFlags.enableStrictEffects = __DEV__;
packages/react/src/__tests__/ReactTypeScriptClass-test.ts
+3 -2
@@ -1,7 +1,7 @@
1 /// <reference path="./testDefinitions/PropTypes.d.ts" />
2 /// <reference path="./testDefinitions/React.d.ts" />
3 /// <reference path="./testDefinitions/ReactDOM.d.ts" />
4 -/// <reference path="./testDefinitions/ReactDOMTestUtils.d.ts" />
4 +/// <reference path="./testDefinitions/ReactInternalAct.d.ts" />
5
6 /*!
7 * Copyright (c) Facebook, Inc. and its affiliates.
@@ -14,6 +14,7 @@ import React = require('react');
14 import ReactDOM = require('react-dom');
15 import ReactDOMTestUtils = require('react-dom/test-utils');
16 import PropTypes = require('prop-types');
17 +import internalAct = require('jest-react');
18
19 // Before Each
20
@@ -21,7 +22,7 @@ let container;
22 let root;
23 let attachedListener = null;
24 let renderedName = null;
24 -let act = ReactDOMTestUtils.unstable_concurrentAct;
25 +let act = internalAct.act;
26
27 class Inner extends React.Component {
28 getName() {
packages/react/src/__tests__/testDefinitions/ReactInternalAct.d.ts renamed
+2 -2
@@ -12,6 +12,6 @@
12 * just helpers for the unit test.
13 */
14
15 -declare module 'react-dom/test-utils' {
16 - export function unstable_concurrentAct(cb : () => any) : any
15 +declare module 'jest-react' {
16 + export function act(cb : () => any) : any
17 }
packages/react/src/forks/ReactSharedInternals.umd.js
-2
@@ -10,13 +10,11 @@ import * as Scheduler from 'scheduler';
10 import ReactCurrentDispatcher from '../ReactCurrentDispatcher';
11 import ReactCurrentOwner from '../ReactCurrentOwner';
12 import ReactDebugCurrentFrame from '../ReactDebugCurrentFrame';
13 -import IsSomeRendererActing from '../IsSomeRendererActing';
13 import ReactCurrentBatchConfig from '../ReactCurrentBatchConfig';
14
15 const ReactSharedInternals = {
16 ReactCurrentDispatcher,
17 ReactCurrentOwner,
19 - IsSomeRendererActing,
18 ReactCurrentBatchConfig,
19 // Used by renderers to avoid bundling object-assign twice in UMD bundles:
20 assign,
packages/use-subscription/src/__tests__/useSubscription-test.js
+1 -1
@@ -27,7 +27,7 @@ describe('useSubscription', () => {
27 ReactTestRenderer = require('react-test-renderer');
28 Scheduler = require('scheduler');
29
30 - act = ReactTestRenderer.unstable_concurrentAct;
30 + act = require('jest-react').act;
31
32 BehaviorSubject = require('rxjs').BehaviorSubject;
33 ReplaySubject = require('rxjs').ReplaySubject;
scripts/jest/typescript/preprocessor.js
+1 -1
@@ -42,7 +42,7 @@ function compile(content, contentFilename) {
42 let source;
43 const libRegex = /lib\.(.+\.)?d\.ts$/;
44 const jestRegex = /jest\.d\.ts/;
45 - const reactRegex = /(?:React|ReactDOM|ReactDOMTestUtils|PropTypes)(?:\.d)?\.ts$/;
45 + const reactRegex = /(?:React|ReactDOM|ReactInternalAct|PropTypes)(?:\.d)?\.ts$/;
46
47 // `path.normalize` is used to turn forward slashes in
48 // the file path into backslashes on Windows.
scripts/rollup/bundles.js
+1 -1
@@ -734,7 +734,7 @@ const bundles = [
734 moduleType: ISOMORPHIC,
735 entry: 'jest-react',
736 global: 'JestReact',
737 - externals: [],
737 + externals: ['react', 'scheduler', 'scheduler/unstable_mock'],
738 },
739
740 /******* ESLint Plugin for Hooks *******/