From a1682c79f0902a4d0e85cdd506c0dcfd90d26899 Mon Sep 17 00:00:00 2001 From: Sunil Pai Date: Thu, 6 Feb 2020 01:05:17 +0000 Subject: [PATCH] Use testing builds for our own tests Following up from #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 --- fixtures/dom/src/__tests__/nested-act-test.js | 5 +- fixtures/dom/src/__tests__/wrong-act-test.js | 5 +- packages/react-dom/package.json | 1 + .../ReactDOMSuspensePlaceholder-test.js | 4 +- .../forks/ReactFeatureFlags.readonly.js | 2 +- .../shared/forks/ReactFeatureFlags.testing.js | 80 +++++++++---------- .../forks/ReactFeatureFlags.testing.www.js | 64 +++++++++++++++ scripts/jest/config.base.js | 3 + scripts/jest/setupHostConfigs.js | 2 + scripts/jest/setupTests.build.js | 2 + scripts/rollup/forks.js | 10 ++- 11 files changed, 123 insertions(+), 55 deletions(-) create mode 100644 packages/shared/forks/ReactFeatureFlags.testing.www.js diff --git a/fixtures/dom/src/__tests__/nested-act-test.js b/fixtures/dom/src/__tests__/nested-act-test.js index c7a191943abdfc..ae7e7d838b9b2b 100644 --- a/fixtures/dom/src/__tests__/nested-act-test.js +++ b/fixtures/dom/src/__tests__/nested-act-test.js @@ -13,10 +13,7 @@ let TestRenderer; global.__DEV__ = process.env.NODE_ENV !== 'production'; -jest.mock('react-dom', () => - require.requireActual('react-dom/cjs/react-dom-testing.development.js') -); -// we'll replace the above with react/testing and react-dom/testing right before the next minor +jest.mock('react-dom', () => require.requireActual('react-dom/testing.js')); expect.extend(require('../toWarnDev')); diff --git a/fixtures/dom/src/__tests__/wrong-act-test.js b/fixtures/dom/src/__tests__/wrong-act-test.js index 10df65ce6df601..4244c18b84f7c1 100644 --- a/fixtures/dom/src/__tests__/wrong-act-test.js +++ b/fixtures/dom/src/__tests__/wrong-act-test.js @@ -18,10 +18,7 @@ let ARTTest; global.__DEV__ = process.env.NODE_ENV !== 'production'; global.__EXPERIMENTAL__ = process.env.RELEASE_CHANNEL === 'experimental'; -jest.mock('react-dom', () => - require.requireActual('react-dom/cjs/react-dom-testing.development.js') -); -// we'll replace the above with react/testing and react-dom/testing right before the next minor +jest.mock('react-dom', () => require.requireActual('react-dom/testing.js')); expect.extend(require('../toWarnDev')); diff --git a/packages/react-dom/package.json b/packages/react-dom/package.json index 7e6cf5e5c0ee8d..4388616e430a6b 100644 --- a/packages/react-dom/package.json +++ b/packages/react-dom/package.json @@ -30,6 +30,7 @@ "README.md", "build-info.json", "index.js", + "testing.js", "profiling.js", "server.js", "server.browser.js", diff --git a/packages/react-dom/src/__tests__/ReactDOMSuspensePlaceholder-test.js b/packages/react-dom/src/__tests__/ReactDOMSuspensePlaceholder-test.js index 94bd63ff026cd1..661134f388422c 100644 --- a/packages/react-dom/src/__tests__/ReactDOMSuspensePlaceholder-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMSuspensePlaceholder-test.js @@ -13,7 +13,6 @@ let React; let ReactDOM; let Suspense; let ReactCache; -let ReactTestUtils; let Scheduler; let TextResource; let act; @@ -26,9 +25,8 @@ describe('ReactDOMSuspensePlaceholder', () => { React = require('react'); ReactDOM = require('react-dom'); ReactCache = require('react-cache'); - ReactTestUtils = require('react-dom/test-utils'); Scheduler = require('scheduler'); - act = ReactTestUtils.act; + act = ReactDOM.act; Suspense = React.Suspense; container = document.createElement('div'); document.body.appendChild(container); diff --git a/packages/shared/forks/ReactFeatureFlags.readonly.js b/packages/shared/forks/ReactFeatureFlags.readonly.js index 0ef29a2b4e8d3e..5a35e8fb72981b 100644 --- a/packages/shared/forks/ReactFeatureFlags.readonly.js +++ b/packages/shared/forks/ReactFeatureFlags.readonly.js @@ -9,4 +9,4 @@ // It lets us determine whether we're running in Fire mode without making tests internal. const ReactFeatureFlags = require('../ReactFeatureFlags'); // Forbid writes because this wouldn't work with bundle tests. -module.exports = Object.freeze({...ReactFeatureFlags}); +module.exports = Object.freeze({...ReactFeatureFlags, isTestEnvironment: true}); diff --git a/packages/shared/forks/ReactFeatureFlags.testing.js b/packages/shared/forks/ReactFeatureFlags.testing.js index 7fb99f782d83f8..c9a695b057a345 100644 --- a/packages/shared/forks/ReactFeatureFlags.testing.js +++ b/packages/shared/forks/ReactFeatureFlags.testing.js @@ -7,51 +7,51 @@ * @flow */ -import invariant from 'shared/invariant'; +// keep in sync with ReactFeatureFlags.js +// only isTestEnvironment is different, and true import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags'; import typeof * as PersistentFeatureFlagsType from './ReactFeatureFlags.persistent'; -export const debugRenderPhaseSideEffectsForStrictMode = false; -export const enableUserTimingAPI = __DEV__; -export const warnAboutDeprecatedLifecycles = true; -export const replayFailedUnitOfWorkWithInvokeGuardedCallback = false; -export const enableProfilerTimer = __PROFILE__; -export const enableSchedulerTracing = __PROFILE__; -export const enableSuspenseServerRenderer = false; -export const enableSelectiveHydration = false; -export const enableChunksAPI = false; -export const disableJavaScriptURLs = false; -export const disableInputAttributeSyncing = false; -export const exposeConcurrentModeAPIs = __EXPERIMENTAL__; -export const warnAboutShorthandPropertyCollision = false; -export const enableSchedulerDebugging = false; -export const enableDeprecatedFlareAPI = false; -export const enableFundamentalAPI = false; -export const enableScopeAPI = false; -export const enableJSXTransformAPI = false; -export const warnAboutUnmockedScheduler = false; -export const flushSuspenseFallbacksInTests = true; -export const enableSuspenseCallback = false; -export const warnAboutDefaultPropsOnFunctionComponents = false; -export const warnAboutStringRefs = false; -export const disableLegacyContext = false; -export const disableSchedulerTimeoutBasedOnReactExpirationTime = false; -export const enableTrainModelFix = true; -export const enableTrustedTypesIntegration = false; -export const enableNativeTargetAsInstance = false; -export const disableCreateFactory = false; -export const disableTextareaChildren = false; -export const disableUnstableRenderSubtreeIntoContainer = false; -export const warnUnstableRenderSubtreeIntoContainer = false; -export const disableUnstableCreatePortal = false; -export const deferPassiveEffectCleanupDuringUnmount = false; -export const isTestEnvironment = true; +export { + enableUserTimingAPI, + debugRenderPhaseSideEffectsForStrictMode, + replayFailedUnitOfWorkWithInvokeGuardedCallback, + warnAboutDeprecatedLifecycles, + enableProfilerTimer, + enableSchedulerTracing, + enableSuspenseServerRenderer, + enableSelectiveHydration, + enableChunksAPI, + enableSchedulerDebugging, + disableJavaScriptURLs, + exposeConcurrentModeAPIs, + warnAboutShorthandPropertyCollision, + enableDeprecatedFlareAPI, + enableFundamentalAPI, + enableScopeAPI, + enableJSXTransformAPI, + warnAboutUnmockedScheduler, + flushSuspenseFallbacksInTests, + enableSuspenseCallback, + warnAboutDefaultPropsOnFunctionComponents, + disableSchedulerTimeoutBasedOnReactExpirationTime, + enableTrainModelFix, + enableTrustedTypesIntegration, + enableNativeTargetAsInstance, + deferPassiveEffectCleanupDuringUnmount, + disableInputAttributeSyncing, + warnAboutStringRefs, + disableLegacyContext, + disableCreateFactory, + disableTextareaChildren, + disableUnstableRenderSubtreeIntoContainer, + warnUnstableRenderSubtreeIntoContainer, + disableUnstableCreatePortal, + addUserTimingListener, +} from 'shared/ReactFeatureFlags'; -// Only used in www builds. -export function addUserTimingListener() { - invariant(false, 'Not implemented.'); -} +export const isTestEnvironment = true; // Flow magic to verify the exports of this file match the original version. // eslint-disable-next-line no-unused-vars diff --git a/packages/shared/forks/ReactFeatureFlags.testing.www.js b/packages/shared/forks/ReactFeatureFlags.testing.www.js new file mode 100644 index 00000000000000..bd18a9aeb0e675 --- /dev/null +++ b/packages/shared/forks/ReactFeatureFlags.testing.www.js @@ -0,0 +1,64 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +// keep in sync with forks/ReactFeatureFlags.testing.js +// only isTestEnvironment is different, and true + +import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags'; +import typeof * as FeatureFlagsShimType from './ReactFeatureFlags.www'; + +// Re-export dynamic flags from the www version. +export const { + debugRenderPhaseSideEffectsForStrictMode, + disableInputAttributeSyncing, + enableTrustedTypesIntegration, + deferPassiveEffectCleanupDuringUnmount, +} = require('ReactFeatureFlags'); + +export { + enableUserTimingAPI, + replayFailedUnitOfWorkWithInvokeGuardedCallback, + warnAboutDeprecatedLifecycles, + enableProfilerTimer, + enableSchedulerTracing, + enableSuspenseServerRenderer, + enableSelectiveHydration, + enableChunksAPI, + enableSchedulerDebugging, + disableJavaScriptURLs, + exposeConcurrentModeAPIs, + warnAboutShorthandPropertyCollision, + enableDeprecatedFlareAPI, + enableFundamentalAPI, + enableScopeAPI, + enableJSXTransformAPI, + warnAboutUnmockedScheduler, + flushSuspenseFallbacksInTests, + enableSuspenseCallback, + warnAboutDefaultPropsOnFunctionComponents, + disableSchedulerTimeoutBasedOnReactExpirationTime, + enableTrainModelFix, + enableNativeTargetAsInstance, + warnAboutStringRefs, + disableLegacyContext, + disableCreateFactory, + disableTextareaChildren, + disableUnstableRenderSubtreeIntoContainer, + warnUnstableRenderSubtreeIntoContainer, + disableUnstableCreatePortal, + addUserTimingListener, +} from 'shared/ReactFeatureFlags'; + +export const isTestEnvironment = true; + +// Flow magic to verify the exports of this file match the original version. +// eslint-disable-next-line no-unused-vars +type Check<_X, Y: _X, X: Y = _X> = null; +// eslint-disable-next-line no-unused-expressions +(null: Check); diff --git a/scripts/jest/config.base.js b/scripts/jest/config.base.js index f696dfd2ced4e9..90a8c81b791569 100644 --- a/scripts/jest/config.base.js +++ b/scripts/jest/config.base.js @@ -4,6 +4,9 @@ module.exports = { haste: { hasteImplModulePath: require.resolve('./noHaste.js'), }, + moduleNameMapper: { + '^shared/ReactFeatureFlags': `/packages/shared/forks/ReactFeatureFlags.testing`, + }, modulePathIgnorePatterns: [ '/scripts/rollup/shims/', '/scripts/bench/', diff --git a/scripts/jest/setupHostConfigs.js b/scripts/jest/setupHostConfigs.js index 93078a03cdee0a..a3afc4f273eddc 100644 --- a/scripts/jest/setupHostConfigs.js +++ b/scripts/jest/setupHostConfigs.js @@ -177,6 +177,8 @@ inlinedHostConfigs.forEach(rendererInfo => { } }); +jest.mock('react-dom', () => require.requireActual('react-dom/testing')); + // Make it possible to import this module inside // the React package itself. jest.mock('shared/ReactSharedInternals', () => diff --git a/scripts/jest/setupTests.build.js b/scripts/jest/setupTests.build.js index 62db0fc007f95f..7dcd12811f2793 100644 --- a/scripts/jest/setupTests.build.js +++ b/scripts/jest/setupTests.build.js @@ -1,5 +1,7 @@ 'use strict'; +jest.mock('react-dom', () => require.requireActual(`react-dom/testing`)); + jest.mock('scheduler', () => require.requireActual('scheduler/unstable_mock')); jest.mock('scheduler/src/SchedulerHostConfig', () => require.requireActual('scheduler/src/forks/SchedulerHostConfig.mock.js') diff --git a/scripts/rollup/forks.js b/scripts/rollup/forks.js index 9f1f3c41bdd627..aa0938b7d539d5 100644 --- a/scripts/rollup/forks.js +++ b/scripts/rollup/forks.js @@ -46,7 +46,7 @@ const forks = Object.freeze({ // Without this fork, importing `shared/ReactSharedInternals` inside // the `react` package itself would not work due to a cyclical dependency. 'shared/ReactSharedInternals': (bundleType, entry, dependencies) => { - if (entry === 'react' || entry === 'react/testing') { + if (entry === 'react') { return 'react/src/ReactSharedInternals'; } if (dependencies.indexOf('react') === -1) { @@ -107,8 +107,12 @@ const forks = Object.freeze({ } return 'shared/forks/ReactFeatureFlags.test-renderer.js'; case 'react-dom/testing': - return 'shared/forks/ReactFeatureFlags.testing.js'; - case 'react/testing': + switch (bundleType) { + case FB_WWW_DEV: + case FB_WWW_PROD: + case FB_WWW_PROFILING: + return 'shared/forks/ReactFeatureFlags.testing.www.js'; + } return 'shared/forks/ReactFeatureFlags.testing.js'; default: switch (bundleType) {