Delete test-utils implementation of `act` (#21703)
* Delete test-utils implementation of `act` Since it's dev-only now, we can use the one provided by the reconciler. * Move act related stuff out of EventInternals
Andrew Clark committed
Jun 22, 2021 at 17:21 UTC
422e0bb3604dd7d3f6158df87b05932a43c89017
4 files changed
+14
-236
packages/react-dom/src/client/ReactDOM.js
+5
-5
@@ -28,8 +28,8 @@ import {
28
flushSync,
29
flushControlled,
30
injectIntoDevTools,
31
- flushPassiveEffects,
31
IsThisRendererActing,
32
+ act,
33
attemptSynchronousHydration,
34
attemptDiscreteHydration,
35
attemptContinuousHydration,
@@ -155,7 +155,7 @@ function renderSubtreeIntoContainer(
155
}
156
157
const Internals = {
158
- // Keep in sync with ReactTestUtils.js, and ReactTestUtilsAct.js.
158
+ // Keep in sync with ReactTestUtils.js.
159
// This is an array for better minification.
160
Events: [
161
getInstanceFromNode,
@@ -163,10 +163,10 @@ const Internals = {
163
getFiberCurrentPropsFromNode,
164
enqueueStateRestore,
165
restoreStateIfNeeded,
166
- flushPassiveEffects,
167
- // TODO: This is related to `act`, not events. Move to separate key?
168
- IsThisRendererActing,
166
],
167
+ act,
168
+ // TODO: Temporary. Only used by our internal version of `act. Will remove.
169
+ IsThisRendererActing,
170
};
171
172
export {
packages/react-dom/src/test-utils/ReactTestUtils.js
+6
-7
@@ -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 {act} from './ReactTestUtilsPublicAct';
21
import {unstable_concurrentAct} from './ReactTestUtilsInternalAct';
22
import {
23
rethrowCaughtError,
@@ -26,17 +25,17 @@ import {
25
} from 'shared/ReactErrorUtils';
26
import isArray from 'shared/isArray';
27
29
-// Keep in sync with ReactDOM.js, and ReactTestUtilsAct.js:
30
-const EventInternals =
31
- ReactDOM.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Events;
28
+// Keep in sync with ReactDOM.js:
29
+const SecretInternals =
30
+ ReactDOM.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
31
+const EventInternals = SecretInternals.Events;
32
const getInstanceFromNode = EventInternals[0];
33
const getNodeFromInstance = EventInternals[1];
34
const getFiberCurrentPropsFromNode = EventInternals[2];
35
const enqueueStateRestore = EventInternals[3];
36
const restoreStateIfNeeded = EventInternals[4];
37
-// const flushPassiveEffects = EventInternals[5];
38
-// TODO: This is related to `act`, not events. Move to separate key?
39
-// const IsThisRendererActing = EventInternals[6];
37
+
38
+const act = SecretInternals.act;
39
40
function Event(suffix) {}
41
packages/react-dom/src/test-utils/ReactTestUtilsInternalAct.js
+3
-10
@@ -14,16 +14,9 @@ import ReactSharedInternals from 'shared/ReactSharedInternals';
14
import enqueueTask from 'shared/enqueueTask';
15
import * as Scheduler from 'scheduler';
16
17
-// Keep in sync with ReactDOM.js, and ReactTestUtils.js:
18
-const EventInternals =
19
- ReactDOM.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Events;
20
-// const getInstanceFromNode = EventInternals[0];
21
-// const getNodeFromInstance = EventInternals[1];
22
-// const getFiberCurrentPropsFromNode = EventInternals[2];
23
-// const enqueueStateRestore = EventInternals[3];
24
-// const restoreStateIfNeeded = EventInternals[4];
25
-// const flushPassiveEffects = EventInternals[5];
26
-const IsThisRendererActing = EventInternals[6];
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
packages/react-dom/src/test-utils/ReactTestUtilsPublicAct.js
deleted
-214
@@ -1,214 +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
-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
-import invariant from 'shared/invariant';
17
-
18
-// Keep in sync with ReactDOM.js, and ReactTestUtils.js:
19
-const EventInternals =
20
- ReactDOM.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Events;
21
-// const getInstanceFromNode = EventInternals[0];
22
-// const getNodeFromInstance = EventInternals[1];
23
-// const getFiberCurrentPropsFromNode = EventInternals[2];
24
-// const enqueueStateRestore = EventInternals[3];
25
-// const restoreStateIfNeeded = EventInternals[4];
26
-const flushPassiveEffects = EventInternals[5];
27
-const IsThisRendererActing = EventInternals[6];
28
-
29
-const batchedUpdates = ReactDOM.unstable_batchedUpdates;
30
-
31
-const {IsSomeRendererActing} = ReactSharedInternals;
32
-
33
-// This is the public version of `ReactTestUtils.act`. It is implemented in
34
-// "userspace" (i.e. not the reconciler), so that it doesn't add to the
35
-// production bundle size.
36
-// TODO: Remove this implementation of `act` in favor of the one exported by
37
-// the reconciler. To do this, we must first drop support for `act` in
38
-// production mode.
39
-
40
-// TODO: Remove support for the mock scheduler build, which was only added for
41
-// the purposes of internal testing. Internal tests should use
42
-// `unstable_concurrentAct` instead.
43
-const isSchedulerMocked =
44
- typeof Scheduler.unstable_flushAllWithoutAsserting === 'function';
45
-const flushWork =
46
- Scheduler.unstable_flushAllWithoutAsserting ||
47
- function() {
48
- let didFlushWork = false;
49
- while (flushPassiveEffects()) {
50
- didFlushWork = true;
51
- }
52
-
53
- return didFlushWork;
54
- };
55
-
56
-function flushWorkAndMicroTasks(onDone: (err: ?Error) => void) {
57
- try {
58
- flushWork();
59
- enqueueTask(() => {
60
- if (flushWork()) {
61
- flushWorkAndMicroTasks(onDone);
62
- } else {
63
- onDone();
64
- }
65
- });
66
- } catch (err) {
67
- onDone(err);
68
- }
69
-}
70
-
71
-// we track the 'depth' of the act() calls with this counter,
72
-// so we can tell if any async act() calls try to run in parallel.
73
-
74
-let actingUpdatesScopeDepth = 0;
75
-
76
-export function act(callback: () => Thenable<mixed>): Thenable<void> {
77
- if (!__DEV__) {
78
- invariant(
79
- false,
80
- 'act(...) is not supported in production builds of React.',
81
- );
82
- }
83
- const previousActingUpdatesScopeDepth = actingUpdatesScopeDepth;
84
- actingUpdatesScopeDepth++;
85
-
86
- const previousIsSomeRendererActing = IsSomeRendererActing.current;
87
- const previousIsThisRendererActing = IsThisRendererActing.current;
88
- IsSomeRendererActing.current = true;
89
- IsThisRendererActing.current = true;
90
-
91
- function onDone() {
92
- actingUpdatesScopeDepth--;
93
- IsSomeRendererActing.current = previousIsSomeRendererActing;
94
- IsThisRendererActing.current = previousIsThisRendererActing;
95
- if (__DEV__) {
96
- if (actingUpdatesScopeDepth > previousActingUpdatesScopeDepth) {
97
- // if it's _less than_ previousActingUpdatesScopeDepth, then we can assume the 'other' one has warned
98
- console.error(
99
- 'You seem to have overlapping act() calls, this is not supported. ' +
100
- 'Be sure to await previous act() calls before making a new one. ',
101
- );
102
- }
103
- }
104
- }
105
-
106
- let result;
107
- try {
108
- result = batchedUpdates(callback);
109
- } catch (error) {
110
- // on sync errors, we still want to 'cleanup' and decrement actingUpdatesScopeDepth
111
- onDone();
112
- throw error;
113
- }
114
-
115
- if (
116
- result !== null &&
117
- typeof result === 'object' &&
118
- typeof result.then === 'function'
119
- ) {
120
- // setup a boolean that gets set to true only
121
- // once this act() call is await-ed
122
- let called = false;
123
- if (__DEV__) {
124
- if (typeof Promise !== 'undefined') {
125
- //eslint-disable-next-line no-undef
126
- Promise.resolve()
127
- .then(() => {})
128
- .then(() => {
129
- if (called === false) {
130
- console.error(
131
- 'You called act(async () => ...) without await. ' +
132
- 'This could lead to unexpected testing behaviour, interleaving multiple act ' +
133
- 'calls and mixing their scopes. You should - await act(async () => ...);',
134
- );
135
- }
136
- });
137
- }
138
- }
139
-
140
- // in the async case, the returned thenable runs the callback, flushes
141
- // effects and microtasks in a loop until flushPassiveEffects() === false,
142
- // and cleans up
143
- return {
144
- then(resolve, reject) {
145
- called = true;
146
- result.then(
147
- () => {
148
- if (
149
- actingUpdatesScopeDepth > 1 ||
150
- (isSchedulerMocked === true &&
151
- previousIsSomeRendererActing === true)
152
- ) {
153
- onDone();
154
- resolve();
155
- return;
156
- }
157
- // we're about to exit the act() scope,
158
- // now's the time to flush tasks/effects
159
- flushWorkAndMicroTasks((err: ?Error) => {
160
- onDone();
161
- if (err) {
162
- reject(err);
163
- } else {
164
- resolve();
165
- }
166
- });
167
- },
168
- err => {
169
- onDone();
170
- reject(err);
171
- },
172
- );
173
- },
174
- };
175
- } else {
176
- if (__DEV__) {
177
- if (result !== undefined) {
178
- console.error(
179
- 'The callback passed to act(...) function ' +
180
- 'must return undefined, or a Promise. You returned %s',
181
- result,
182
- );
183
- }
184
- }
185
-
186
- // flush effects until none remain, and cleanup
187
- try {
188
- if (
189
- actingUpdatesScopeDepth === 1 &&
190
- (isSchedulerMocked === false || previousIsSomeRendererActing === false)
191
- ) {
192
- // we're about to exit the act() scope,
193
- // now's the time to flush effects
194
- flushWork();
195
- }
196
- onDone();
197
- } catch (err) {
198
- onDone();
199
- throw err;
200
- }
201
-
202
- // in the sync case, the returned thenable only warns *if* await-ed
203
- return {
204
- then(resolve) {
205
- if (__DEV__) {
206
- console.error(
207
- 'Do not await the result of calling act(...) with sync logic, it is not a Promise.',
208
- );
209
- }
210
- resolve();
211
- },
212
- };
213
- }
214
-}