Skip to content

Commit fe0c945

Browse files
committed
Use testing builds for our own tests
Following up from facebook#17915 where we generated testing builds for `react-dom`, this PR uses those builds for our own tests. - fixes `ReactFeatureFlags.testing` to use all the default flags - changes `ReactFeatureFlags.readonly` to return `isTestEnvironment: true` (this might not strictly be needed) - with jest, mocks `react-dom` with the testing version, both for source and builds - uses `ReactDOM.act` in one of these tests to verify it actually works
1 parent 256d78d commit fe0c945

15 files changed

+263
-44
lines changed

fixtures/dom/src/__tests__/nested-act-test.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,7 @@ let TestRenderer;
1313

1414
global.__DEV__ = process.env.NODE_ENV !== 'production';
1515

16-
jest.mock('react-dom', () =>
17-
require.requireActual('react-dom/cjs/react-dom-testing.development.js')
18-
);
19-
// we'll replace the above with react/testing and react-dom/testing right before the next minor
16+
jest.mock('react-dom', () => require.requireActual('react-dom/testing'));
2017

2118
expect.extend(require('../toWarnDev'));
2219

fixtures/dom/src/__tests__/wrong-act-test.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,7 @@ let ARTTest;
1818
global.__DEV__ = process.env.NODE_ENV !== 'production';
1919
global.__EXPERIMENTAL__ = process.env.RELEASE_CHANNEL === 'experimental';
2020

21-
jest.mock('react-dom', () =>
22-
require.requireActual('react-dom/cjs/react-dom-testing.development.js')
23-
);
24-
// we'll replace the above with react/testing and react-dom/testing right before the next minor
21+
jest.mock('react-dom', () => require.requireActual('react-dom/testing'));
2522

2623
expect.extend(require('../toWarnDev'));
2724

packages/react-dom/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"README.md",
3131
"build-info.json",
3232
"index.js",
33+
"testing.js",
3334
"profiling.js",
3435
"server.js",
3536
"server.browser.js",

packages/react-dom/src/__tests__/ReactDOMSuspensePlaceholder-test.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ let React;
1313
let ReactDOM;
1414
let Suspense;
1515
let ReactCache;
16-
let ReactTestUtils;
1716
let Scheduler;
1817
let TextResource;
1918
let act;
@@ -26,9 +25,8 @@ describe('ReactDOMSuspensePlaceholder', () => {
2625
React = require('react');
2726
ReactDOM = require('react-dom');
2827
ReactCache = require('react-cache');
29-
ReactTestUtils = require('react-dom/test-utils');
3028
Scheduler = require('scheduler');
31-
act = ReactTestUtils.act;
29+
act = ReactDOM.act;
3230
Suspense = React.Suspense;
3331
container = document.createElement('div');
3432
document.body.appendChild(container);

packages/react-dom/testing.fb.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
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+
8+
'use strict';
9+
10+
const ReactDOMFB = require('./src/client/ReactDOMFB');
11+
12+
// TODO: decide on the top-level export form.
13+
// This is hacky but makes it work with both Rollup and Jest.
14+
module.exports = ReactDOMFB.default || ReactDOMFB;

packages/shared/ReactFeatureFlags.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
* @flow strict
88
*/
99

10+
/*
11+
SYNC WITH forks/ReactFeatureFlags.testing.js
12+
except isTestEnvironment = true
13+
*/
14+
1015
export const enableUserTimingAPI = __DEV__;
1116

1217
// Helps identify side effects in render-phase lifecycle hooks and setState

packages/shared/forks/ReactFeatureFlags.readonly.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@
99
// It lets us determine whether we're running in Fire mode without making tests internal.
1010
const ReactFeatureFlags = require('../ReactFeatureFlags');
1111
// Forbid writes because this wouldn't work with bundle tests.
12-
module.exports = Object.freeze({...ReactFeatureFlags});
12+
module.exports = Object.freeze({...ReactFeatureFlags, isTestEnvironment: true});

packages/shared/forks/ReactFeatureFlags.test-renderer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export const disableUnstableRenderSubtreeIntoContainer = false;
4747
export const warnUnstableRenderSubtreeIntoContainer = false;
4848
export const disableUnstableCreatePortal = false;
4949
export const deferPassiveEffectCleanupDuringUnmount = false;
50-
export const isTestEnvironment = true; // this should probably *never* change
50+
export const isTestEnvironment = true;
5151

5252
// Only used in www builds.
5353
export function addUserTimingListener() {

packages/shared/forks/ReactFeatureFlags.test-renderer.www.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export const disableUnstableRenderSubtreeIntoContainer = false;
4545
export const warnUnstableRenderSubtreeIntoContainer = false;
4646
export const disableUnstableCreatePortal = false;
4747
export const deferPassiveEffectCleanupDuringUnmount = false;
48-
export const isTestEnvironment = true; // this should probably *never* change
48+
export const isTestEnvironment = true;
4949

5050
// Only used in www builds.
5151
export function addUserTimingListener() {

packages/shared/forks/ReactFeatureFlags.testing.js

Lines changed: 100 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,58 +4,131 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @flow
7+
* @flow strict
88
*/
99

10-
import invariant from 'shared/invariant';
10+
/*
11+
SYNC WITH ReactFeatureFlags.js
12+
except isTestEnvironment = true
13+
*/
1114

12-
import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags';
13-
import typeof * as PersistentFeatureFlagsType from './ReactFeatureFlags.persistent';
14-
15-
export const debugRenderPhaseSideEffectsForStrictMode = false;
1615
export const enableUserTimingAPI = __DEV__;
16+
17+
// Helps identify side effects in render-phase lifecycle hooks and setState
18+
// reducers by double invoking them in Strict Mode.
19+
export const debugRenderPhaseSideEffectsForStrictMode = __DEV__;
20+
21+
// To preserve the "Pause on caught exceptions" behavior of the debugger, we
22+
// replay the begin phase of a failed component inside invokeGuardedCallback.
23+
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = __DEV__;
24+
25+
// Warn about deprecated, async-unsafe lifecycles; relates to RFC #6:
1726
export const warnAboutDeprecatedLifecycles = true;
18-
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
27+
28+
// Gather advanced timing metrics for Profiler subtrees.
1929
export const enableProfilerTimer = __PROFILE__;
30+
31+
// Trace which interactions trigger each commit.
2032
export const enableSchedulerTracing = __PROFILE__;
21-
export const enableSuspenseServerRenderer = false;
22-
export const enableSelectiveHydration = false;
23-
export const enableChunksAPI = false;
33+
34+
// SSR experiments
35+
export const enableSuspenseServerRenderer = __EXPERIMENTAL__;
36+
export const enableSelectiveHydration = __EXPERIMENTAL__;
37+
38+
// Flight experiments
39+
export const enableChunksAPI = __EXPERIMENTAL__;
40+
41+
// Only used in www builds.
42+
export const enableSchedulerDebugging = false;
43+
44+
// Only used in www builds.
45+
export function addUserTimingListener() {
46+
throw new Error('Not implemented.');
47+
}
48+
49+
// Disable javascript: URL strings in href for XSS protection.
2450
export const disableJavaScriptURLs = false;
25-
export const disableInputAttributeSyncing = false;
51+
52+
// These APIs will no longer be "unstable" in the upcoming 16.7 release,
53+
// Control this behavior with a flag to support 16.6 minor releases in the meanwhile.
2654
export const exposeConcurrentModeAPIs = __EXPERIMENTAL__;
55+
2756
export const warnAboutShorthandPropertyCollision = false;
28-
export const enableSchedulerDebugging = false;
57+
58+
// Experimental React Flare event system and event components support.
2959
export const enableDeprecatedFlareAPI = false;
60+
61+
// Experimental Host Component support.
3062
export const enableFundamentalAPI = false;
63+
64+
// Experimental Scope support.
3165
export const enableScopeAPI = false;
66+
67+
// New API for JSX transforms to target - https://github.com/reactjs/rfcs/pull/107
3268
export const enableJSXTransformAPI = false;
69+
70+
// We will enforce mocking scheduler with scheduler/unstable_mock at some point. (v17?)
71+
// Till then, we warn about the missing mock, but still fallback to a legacy mode compatible version
3372
export const warnAboutUnmockedScheduler = false;
73+
74+
// For tests, we flush suspense fallbacks in an act scope;
75+
// *except* in some of our own tests, where we test incremental loading states.
3476
export const flushSuspenseFallbacksInTests = true;
77+
78+
// Add a callback property to suspense to notify which promises are currently
79+
// in the update queue. This allows reporting and tracing of what is causing
80+
// the user to see a loading state.
81+
// Also allows hydration callbacks to fire when a dehydrated boundary gets
82+
// hydrated or deleted.
3583
export const enableSuspenseCallback = false;
84+
85+
// Part of the simplification of React.createElement so we can eventually move
86+
// from React.createElement to React.jsx
87+
// https://github.com/reactjs/rfcs/blob/createlement-rfc/text/0000-create-element-changes.md
3688
export const warnAboutDefaultPropsOnFunctionComponents = false;
37-
export const warnAboutStringRefs = false;
38-
export const disableLegacyContext = false;
89+
3990
export const disableSchedulerTimeoutBasedOnReactExpirationTime = false;
91+
4092
export const enableTrainModelFix = true;
93+
4194
export const enableTrustedTypesIntegration = false;
95+
96+
// Flag to turn event.target and event.currentTarget in ReactNative from a reactTag to a component instance
4297
export const enableNativeTargetAsInstance = false;
98+
99+
// Controls behavior of deferred effect destroy functions during unmount.
100+
// Previously these functions were run during commit (along with layout effects).
101+
// Ideally we should delay these until after commit for performance reasons.
102+
// This flag provides a killswitch if that proves to break existing code somehow.
103+
export const deferPassiveEffectCleanupDuringUnmount = false;
104+
105+
export const isTestEnvironment = true;
106+
107+
// --------------------------
108+
// Future APIs to be deprecated
109+
// --------------------------
110+
111+
// Prevent the value and checked attributes from syncing
112+
// with their related DOM properties
113+
export const disableInputAttributeSyncing = false;
114+
115+
export const warnAboutStringRefs = false;
116+
117+
export const disableLegacyContext = false;
118+
119+
// Disables React.createFactory
43120
export const disableCreateFactory = false;
121+
122+
// Disables children for <textarea> elements
44123
export const disableTextareaChildren = false;
124+
125+
// Disables Maps as ReactElement children
45126
export const disableMapsAsChildren = false;
127+
128+
// Disables ReactDOM.unstable_renderSubtreeIntoContainer
46129
export const disableUnstableRenderSubtreeIntoContainer = false;
130+
// We should remove this flag once the above flag becomes enabled
47131
export const warnUnstableRenderSubtreeIntoContainer = false;
48-
export const disableUnstableCreatePortal = false;
49-
export const deferPassiveEffectCleanupDuringUnmount = false;
50-
export const isTestEnvironment = true;
51132

52-
// Only used in www builds.
53-
export function addUserTimingListener() {
54-
invariant(false, 'Not implemented.');
55-
}
56-
57-
// Flow magic to verify the exports of this file match the original version.
58-
// eslint-disable-next-line no-unused-vars
59-
type Check<_X, Y: _X, X: Y = _X> = null;
60-
// eslint-disable-next-line no-unused-expressions
61-
(null: Check<PersistentFeatureFlagsType, FeatureFlagsType>);
133+
// Disables ReactDOM.unstable_createPortal
134+
export const disableUnstableCreatePortal = false;
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
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+
SYNC WITH forks/ReactFeatureFlags.www.js
12+
except isTestEnvironment = true
13+
*/
14+
15+
import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags';
16+
import typeof * as FeatureFlagsShimType from './ReactFeatureFlags.www';
17+
18+
// Re-export dynamic flags from the www version.
19+
export const {
20+
debugRenderPhaseSideEffectsForStrictMode,
21+
disableInputAttributeSyncing,
22+
enableTrustedTypesIntegration,
23+
deferPassiveEffectCleanupDuringUnmount,
24+
} = require('ReactFeatureFlags');
25+
26+
// In www, we have experimental support for gathering data
27+
// from User Timing API calls in production. By default, we
28+
// only emit performance.mark/measure calls in __DEV__. But if
29+
// somebody calls addUserTimingListener() which is exposed as an
30+
// experimental FB-only export, we call performance.mark/measure
31+
// as long as there is more than a single listener.
32+
export let enableUserTimingAPI = __DEV__;
33+
34+
export const enableProfilerTimer = __PROFILE__;
35+
export const enableSchedulerTracing = __PROFILE__;
36+
export const enableSchedulerDebugging = true;
37+
38+
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
39+
export const warnAboutDeprecatedLifecycles = true;
40+
export const warnAboutShorthandPropertyCollision = false;
41+
export const disableLegacyContext = false;
42+
export const warnAboutStringRefs = false;
43+
export const warnAboutDefaultPropsOnFunctionComponents = false;
44+
export const disableSchedulerTimeoutBasedOnReactExpirationTime = false;
45+
46+
export const enableTrainModelFix = true;
47+
48+
export const exposeConcurrentModeAPIs = __EXPERIMENTAL__;
49+
50+
export const enableSuspenseServerRenderer = true;
51+
export const enableSelectiveHydration = true;
52+
53+
export const enableChunksAPI = __EXPERIMENTAL__;
54+
55+
export const disableJavaScriptURLs = true;
56+
57+
let refCount = 0;
58+
export function addUserTimingListener() {
59+
if (__DEV__) {
60+
// Noop.
61+
return () => {};
62+
}
63+
refCount++;
64+
updateFlagOutsideOfReactCallStack();
65+
return () => {
66+
refCount--;
67+
updateFlagOutsideOfReactCallStack();
68+
};
69+
}
70+
71+
// The flag is intentionally updated in a timeout.
72+
// We don't support toggling it during reconciliation or
73+
// commit since that would cause mismatching user timing API calls.
74+
let timeout = null;
75+
function updateFlagOutsideOfReactCallStack() {
76+
if (!timeout) {
77+
timeout = setTimeout(() => {
78+
timeout = null;
79+
enableUserTimingAPI = refCount > 0;
80+
});
81+
}
82+
}
83+
84+
export const enableDeprecatedFlareAPI = true;
85+
86+
export const enableFundamentalAPI = false;
87+
88+
export const enableScopeAPI = true;
89+
90+
export const enableJSXTransformAPI = true;
91+
92+
export const warnAboutUnmockedScheduler = true;
93+
94+
export const enableSuspenseCallback = true;
95+
96+
export const flushSuspenseFallbacksInTests = true;
97+
98+
export const enableNativeTargetAsInstance = false;
99+
100+
export const disableCreateFactory = false;
101+
102+
export const disableTextareaChildren = false;
103+
104+
export const disableMapsAsChildren = false;
105+
106+
export const disableUnstableRenderSubtreeIntoContainer = false;
107+
108+
export const warnUnstableRenderSubtreeIntoContainer = false;
109+
110+
export const disableUnstableCreatePortal = false;
111+
112+
export const isTestEnvironment = true;
113+
114+
// Flow magic to verify the exports of this file match the original version.
115+
// eslint-disable-next-line no-unused-vars
116+
type Check<_X, Y: _X, X: Y = _X> = null;
117+
// eslint-disable-next-line no-unused-expressions
118+
(null: Check<FeatureFlagsShimType, FeatureFlagsType>);

packages/shared/forks/ReactFeatureFlags.www.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
* @flow
88
*/
99

10+
/*
11+
SYNC WITH forks/ReactFeatureFlags.testing.www.js
12+
except isTestEnvironment = false
13+
*/
14+
1015
import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags';
1116
import typeof * as FeatureFlagsShimType from './ReactFeatureFlags.www';
1217

0 commit comments

Comments
 (0)