From f0102aab41c7a2e242a1d17fcfc072db3701c463 Mon Sep 17 00:00:00 2001 From: Sunil Pai Date: Mon, 2 Mar 2020 15:57:24 +0000 Subject: [PATCH] Bring back OSS testing builds We removed this in https://github.com/facebook/react/pull/18138 to unblock 16.13. This PR brings it back, with some changes - - testing builds are prefixed with `unstable-`, i.e - `react-dom/unstable-testing` - added back to `bundles.js` - reintroduces the `isTestEnvironment`feature flag. Not used to generate the actual builds, but is used for test specific logic - flushes suspense fallbacks in prod for testing builds - changes tests in TestUtilsAct to reflect this - misc test config changes --- fixtures/dom/src/__tests__/nested-act-test.js | 5 +- fixtures/dom/src/__tests__/wrong-act-test.js | 19 +-- packages/react-dom/npm/testing.js | 38 ----- packages/react-dom/npm/unstable-testing.js | 7 + packages/react-dom/package.json | 1 + .../src/__tests__/ReactTestUtilsAct-test.js | 10 +- ...c.fb.js => unstable-testing.classic.fb.js} | 0 ...al.js => unstable-testing.experimental.js} | 0 .../{testing.js => unstable-testing.js} | 0 ...rn.fb.js => unstable-testing.modern.fb.js} | 0 ...g.stable.js => unstable-testing.stable.js} | 0 .../src/ReactFiberWorkLoop.js | 7 +- packages/shared/ReactFeatureFlags.js | 122 +--------------- .../shared/forks/ReactFeatureFlags.default.js | 133 ++++++++++++++++++ .../forks/ReactFeatureFlags.default.www.js | 109 ++++++++++++++ .../forks/ReactFeatureFlags.native-fb.js | 3 +- .../forks/ReactFeatureFlags.native-oss.js | 3 +- .../forks/ReactFeatureFlags.persistent.js | 3 +- .../forks/ReactFeatureFlags.readonly.js | 4 +- .../forks/ReactFeatureFlags.test-renderer.js | 3 +- .../ReactFeatureFlags.test-renderer.www.js | 3 +- .../shared/forks/ReactFeatureFlags.testing.js | 89 ++++++------ .../forks/ReactFeatureFlags.testing.www.js | 85 ++++++----- .../shared/forks/ReactFeatureFlags.www.js | 101 +------------ scripts/jest/config.source-persistent.js | 5 +- scripts/jest/config.source.js | 5 +- scripts/jest/setupTests.build.js | 3 + scripts/rollup/bundles.js | 19 ++- scripts/rollup/forks.js | 2 +- scripts/shared/inlinedHostConfigs.js | 2 +- 30 files changed, 412 insertions(+), 369 deletions(-) delete mode 100644 packages/react-dom/npm/testing.js create mode 100644 packages/react-dom/npm/unstable-testing.js rename packages/react-dom/{testing.classic.fb.js => unstable-testing.classic.fb.js} (100%) rename packages/react-dom/{testing.experimental.js => unstable-testing.experimental.js} (100%) rename packages/react-dom/{testing.js => unstable-testing.js} (100%) rename packages/react-dom/{testing.modern.fb.js => unstable-testing.modern.fb.js} (100%) rename packages/react-dom/{testing.stable.js => unstable-testing.stable.js} (100%) create mode 100644 packages/shared/forks/ReactFeatureFlags.default.js create mode 100644 packages/shared/forks/ReactFeatureFlags.default.www.js diff --git a/fixtures/dom/src/__tests__/nested-act-test.js b/fixtures/dom/src/__tests__/nested-act-test.js index 4a39a0ea98f7f..c07eb5d53358a 100644 --- a/fixtures/dom/src/__tests__/nested-act-test.js +++ b/fixtures/dom/src/__tests__/nested-act-test.js @@ -15,12 +15,15 @@ let TestAct; global.__DEV__ = process.env.NODE_ENV !== 'production'; expect.extend(require('../toWarnDev')); +jest.mock('react-dom', () => + require.requireActual('react-dom/unstable-testing') +); describe('unmocked scheduler', () => { beforeEach(() => { jest.resetModules(); React = require('react'); - DOMAct = require('react-dom/test-utils').act; + DOMAct = require('react-dom').act; TestRenderer = require('react-test-renderer'); TestAct = TestRenderer.act; }); diff --git a/fixtures/dom/src/__tests__/wrong-act-test.js b/fixtures/dom/src/__tests__/wrong-act-test.js index 38029be9b9cae..8df6ec7b7c9cb 100644 --- a/fixtures/dom/src/__tests__/wrong-act-test.js +++ b/fixtures/dom/src/__tests__/wrong-act-test.js @@ -10,7 +10,6 @@ let React; let ReactDOM; let ReactART; -let TestUtils; let ARTSVGMode; let ARTCurrentMode; let TestRenderer; @@ -20,6 +19,9 @@ global.__DEV__ = process.env.NODE_ENV !== 'production'; global.__EXPERIMENTAL__ = process.env.RELEASE_CHANNEL === 'experimental'; expect.extend(require('../toWarnDev')); +jest.mock('react-dom', () => + require.requireActual('react-dom/unstable-testing') +); function App(props) { return 'hello world'; @@ -29,7 +31,6 @@ beforeEach(() => { jest.resetModules(); React = require('react'); ReactDOM = require('react-dom'); - TestUtils = require('react-dom/test-utils'); ReactART = require('react-art'); ARTSVGMode = require('art/modes/svg'); ARTCurrentMode = require('art/modes/current'); @@ -70,7 +71,7 @@ beforeEach(() => { }); it("doesn't warn when you use the right act + renderer: dom", () => { - TestUtils.act(() => { + ReactDOM.act(() => { ReactDOM.render(, document.createElement('div')); }); }); @@ -86,7 +87,7 @@ it('resets correctly across renderers', () => { React.useEffect(() => {}, []); return null; } - TestUtils.act(() => { + ReactDOM.act(() => { TestRenderer.act(() => {}); expect(() => { TestRenderer.create(); @@ -123,7 +124,7 @@ it('warns when using the wrong act version - test + dom: updates', () => { it('warns when using the wrong act version - dom + test: .create()', () => { expect(() => { - TestUtils.act(() => { + ReactDOM.act(() => { TestRenderer.create(); }); }).toWarnDev(["It looks like you're using the wrong act()"], { @@ -134,7 +135,7 @@ it('warns when using the wrong act version - dom + test: .create()', () => { it('warns when using the wrong act version - dom + test: .update()', () => { const root = TestRenderer.create(); expect(() => { - TestUtils.act(() => { + ReactDOM.act(() => { root.update(); }); }).toWarnDev(["It looks like you're using the wrong act()"], { @@ -151,14 +152,14 @@ it('warns when using the wrong act version - dom + test: updates', () => { } TestRenderer.create(); expect(() => { - TestUtils.act(() => { + ReactDOM.act(() => { setCtr(1); }); }).toWarnDev(["It looks like you're using the wrong act()"]); }); it('does not warn when nesting react-act inside react-dom', () => { - TestUtils.act(() => { + ReactDOM.act(() => { ReactDOM.render(, document.createElement('div')); }); }); @@ -171,7 +172,7 @@ it('does not warn when nesting react-act inside react-test-renderer', () => { it("doesn't warn if you use nested acts from different renderers", () => { TestRenderer.act(() => { - TestUtils.act(() => { + ReactDOM.act(() => { TestRenderer.create(); }); }); diff --git a/packages/react-dom/npm/testing.js b/packages/react-dom/npm/testing.js deleted file mode 100644 index 0cb587bf9a9dc..0000000000000 --- a/packages/react-dom/npm/testing.js +++ /dev/null @@ -1,38 +0,0 @@ -'use strict'; - -function checkDCE() { - /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */ - if ( - typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined' || - typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE !== 'function' - ) { - return; - } - if (process.env.NODE_ENV !== 'production') { - // This branch is unreachable because this function is only called - // in production, but the condition is true only in development. - // Therefore if the branch is still here, dead code elimination wasn't - // properly applied. - // Don't change the message. React DevTools relies on it. Also make sure - // this message doesn't occur elsewhere in this function, or it will cause - // a false positive. - throw new Error('^_^'); - } - try { - // Verify that the code above has been dead code eliminated (DCE'd). - __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(checkDCE); - } catch (err) { - // DevTools shouldn't crash React, no matter what. - // We should still report in case we break this code. - console.error(err); - } -} - -if (process.env.NODE_ENV === 'production') { - // DCE check should happen before ReactDOM bundle executes so that - // DevTools can report bad minification during injection. - checkDCE(); - module.exports = require('./cjs/react-dom-testing.production.min.js'); -} else { - module.exports = require('./cjs/react-dom-testing.development.js'); -} diff --git a/packages/react-dom/npm/unstable-testing.js b/packages/react-dom/npm/unstable-testing.js new file mode 100644 index 0000000000000..7185d893ba502 --- /dev/null +++ b/packages/react-dom/npm/unstable-testing.js @@ -0,0 +1,7 @@ +'use strict'; + +if (process.env.NODE_ENV === 'production') { + module.exports = require('./cjs/react-dom-unstable-testing.production.min.js'); +} else { + module.exports = require('./cjs/react-dom-unstable-testing.development.js'); +} diff --git a/packages/react-dom/package.json b/packages/react-dom/package.json index fb5f49740caf4..4acf66e9c945b 100644 --- a/packages/react-dom/package.json +++ b/packages/react-dom/package.json @@ -39,6 +39,7 @@ "unstable-fizz.browser.js", "unstable-fizz.node.js", "unstable-native-dependencies.js", + "unstable-testing.js", "cjs/", "umd/" ], diff --git a/packages/react-dom/src/__tests__/ReactTestUtilsAct-test.js b/packages/react-dom/src/__tests__/ReactTestUtilsAct-test.js index 2f14259735000..20fef14166311 100644 --- a/packages/react-dom/src/__tests__/ReactTestUtilsAct-test.js +++ b/packages/react-dom/src/__tests__/ReactTestUtilsAct-test.js @@ -9,7 +9,6 @@ let React; let ReactDOM; -let ReactTestUtils; let SchedulerTracing; let Scheduler; let act; @@ -25,7 +24,7 @@ function sleep(period) { }); } -describe('ReactTestUtils.act()', () => { +describe('act()', () => { // first we run all the tests with concurrent mode if (__EXPERIMENTAL__) { let concurrentRoot = null; @@ -155,10 +154,9 @@ function runActTests(label, render, unmount, rerender) { jest.resetModules(); React = require('react'); ReactDOM = require('react-dom'); - ReactTestUtils = require('react-dom/test-utils'); SchedulerTracing = require('scheduler/tracing'); Scheduler = require('scheduler'); - act = ReactTestUtils.act; + act = ReactDOM.act; container = document.createElement('div'); document.body.appendChild(container); }); @@ -721,7 +719,7 @@ function runActTests(label, render, unmount, rerender) { }); describe('suspense', () => { - if (__DEV__ && __EXPERIMENTAL__) { + if (__EXPERIMENTAL__) { // todo - remove __DEV__ check once we start using testing builds it('triggers fallbacks if available', async () => { let resolved = false; @@ -792,7 +790,7 @@ function runActTests(label, render, unmount, rerender) { } }); describe('warn in prod mode', () => { - it('warns if you try to use act() in prod mode', () => { + xit('warns if you try to use act() in prod mode', () => { const spy = spyOnDevAndProd(console, 'error'); act(() => {}); diff --git a/packages/react-dom/testing.classic.fb.js b/packages/react-dom/unstable-testing.classic.fb.js similarity index 100% rename from packages/react-dom/testing.classic.fb.js rename to packages/react-dom/unstable-testing.classic.fb.js diff --git a/packages/react-dom/testing.experimental.js b/packages/react-dom/unstable-testing.experimental.js similarity index 100% rename from packages/react-dom/testing.experimental.js rename to packages/react-dom/unstable-testing.experimental.js diff --git a/packages/react-dom/testing.js b/packages/react-dom/unstable-testing.js similarity index 100% rename from packages/react-dom/testing.js rename to packages/react-dom/unstable-testing.js diff --git a/packages/react-dom/testing.modern.fb.js b/packages/react-dom/unstable-testing.modern.fb.js similarity index 100% rename from packages/react-dom/testing.modern.fb.js rename to packages/react-dom/unstable-testing.modern.fb.js diff --git a/packages/react-dom/testing.stable.js b/packages/react-dom/unstable-testing.stable.js similarity index 100% rename from packages/react-dom/testing.stable.js rename to packages/react-dom/unstable-testing.stable.js diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.js b/packages/react-reconciler/src/ReactFiberWorkLoop.js index 8850e8532f901..011ed04687704 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.js @@ -28,6 +28,7 @@ import { warnAboutUnmockedScheduler, flushSuspenseFallbacksInTests, disableSchedulerTimeoutBasedOnReactExpirationTime, + isTestEnvironment, } from 'shared/ReactFeatureFlags'; import ReactSharedInternals from 'shared/ReactSharedInternals'; import invariant from 'shared/invariant'; @@ -789,7 +790,7 @@ function finishConcurrentRender( hasNotProcessedNewUpdates && // do not delay if we're inside an act() scope !( - __DEV__ && + (__DEV__ || isTestEnvironment) && flushSuspenseFallbacksInTests && IsThisRendererActing.current ) @@ -855,7 +856,7 @@ function finishConcurrentRender( if ( // do not delay if we're inside an act() scope !( - __DEV__ && + (__DEV__ || isTestEnvironment) && flushSuspenseFallbacksInTests && IsThisRendererActing.current ) @@ -946,7 +947,7 @@ function finishConcurrentRender( if ( // do not delay if we're inside an act() scope !( - __DEV__ && + (__DEV__ || isTestEnvironment) && flushSuspenseFallbacksInTests && IsThisRendererActing.current ) && diff --git a/packages/shared/ReactFeatureFlags.js b/packages/shared/ReactFeatureFlags.js index 412ec5f9eef73..53b0a9c3bdb0d 100644 --- a/packages/shared/ReactFeatureFlags.js +++ b/packages/shared/ReactFeatureFlags.js @@ -7,124 +7,4 @@ * @flow strict */ -export const enableUserTimingAPI = __DEV__; - -// Helps identify side effects in render-phase lifecycle hooks and setState -// reducers by double invoking them in Strict Mode. -export const debugRenderPhaseSideEffectsForStrictMode = __DEV__; - -// To preserve the "Pause on caught exceptions" behavior of the debugger, we -// replay the begin phase of a failed component inside invokeGuardedCallback. -export const replayFailedUnitOfWorkWithInvokeGuardedCallback = __DEV__; - -// Warn about deprecated, async-unsafe lifecycles; relates to RFC #6: -export const warnAboutDeprecatedLifecycles = true; - -// Gather advanced timing metrics for Profiler subtrees. -export const enableProfilerTimer = __PROFILE__; - -// Trace which interactions trigger each commit. -export const enableSchedulerTracing = __PROFILE__; - -// SSR experiments -export const enableSuspenseServerRenderer = __EXPERIMENTAL__; -export const enableSelectiveHydration = __EXPERIMENTAL__; - -// Flight experiments -export const enableBlocksAPI = __EXPERIMENTAL__; - -// Only used in www builds. -export const enableSchedulerDebugging = false; - -// Only used in www builds. -export function addUserTimingListener() { - throw new Error('Not implemented.'); -} - -// Disable javascript: URL strings in href for XSS protection. -export const disableJavaScriptURLs = false; - -// Warns when a combination of updates on a dom can cause a style declaration -// that clashes with a previous one https://github.com/facebook/react/pull/14181 -export const warnAboutShorthandPropertyCollision = true; - -// Experimental React Flare event system and event components support. -export const enableDeprecatedFlareAPI = false; - -// Experimental Host Component support. -export const enableFundamentalAPI = false; - -// Experimental Scope support. -export const enableScopeAPI = false; - -// New API for JSX transforms to target - https://github.com/reactjs/rfcs/pull/107 - -// We will enforce mocking scheduler with scheduler/unstable_mock at some point. (v17?) -// Till then, we warn about the missing mock, but still fallback to a legacy mode compatible version -export const warnAboutUnmockedScheduler = false; - -// For tests, we flush suspense fallbacks in an act scope; -// *except* in some of our own tests, where we test incremental loading states. -export const flushSuspenseFallbacksInTests = true; - -// Add a callback property to suspense to notify which promises are currently -// in the update queue. This allows reporting and tracing of what is causing -// the user to see a loading state. -// Also allows hydration callbacks to fire when a dehydrated boundary gets -// hydrated or deleted. -export const enableSuspenseCallback = false; - -// Part of the simplification of React.createElement so we can eventually move -// from React.createElement to React.jsx -// https://github.com/reactjs/rfcs/blob/createlement-rfc/text/0000-create-element-changes.md -export const warnAboutDefaultPropsOnFunctionComponents = false; - -export const disableSchedulerTimeoutBasedOnReactExpirationTime = false; - -export const enableTrustedTypesIntegration = false; - -// Controls sequence of passive effect destroy and create functions. -// If this flag is off, destroy and create functions may be interleaved. -// When the flag is on, all destroy functions will be run (for all fibers) -// before any create functions are run, similar to how layout effects work. -// This flag provides a killswitch if that proves to break existing code somehow. -export const runAllPassiveEffectDestroysBeforeCreates = false; - -// Controls behavior of deferred effect destroy functions during unmount. -// Previously these functions were run during commit (along with layout effects). -// Ideally we should delay these until after commit for performance reasons. -// This flag provides a killswitch if that proves to break existing code somehow. -// -// WARNING This flag only has an affect if used with runAllPassiveEffectDestroysBeforeCreates. -export const deferPassiveEffectCleanupDuringUnmount = false; - -// Enables a warning when trying to spread a 'key' to an element; -// a deprecated pattern we want to get rid of in the future -export const warnAboutSpreadingKeyToJSX = false; - -// Internal-only attempt to debug a React Native issue. See D20130868. -export const throwEarlyForMysteriousError = false; - -// -------------------------- -// Future APIs to be deprecated -// -------------------------- - -// Prevent the value and checked attributes from syncing -// with their related DOM properties -export const disableInputAttributeSyncing = false; - -export const warnAboutStringRefs = false; - -export const disableLegacyContext = false; - -// Disables children for