From f69b028c7b6d954644643736388a0b01b46312cc Mon Sep 17 00:00:00 2001 From: jackwolfskin0302 Date: Sat, 26 Jun 2021 17:33:55 -0700 Subject: [PATCH] React sync for revisions 568dc35...27c9c95 Summary: Includes a re-implementation of the `act` testing API to decouple it from the mock Scheduler module. Because our Jest configuration mocks the Scheduler for all tests in www, some tests had become accidentally coupled to it. I had to update ~60 test files. The most common pattern I found was people calling `act()` with a no-op function, which had the effect of flushing all pending work. This no longer works in the new implementation. (We will eventually provide a way to opt into Scheduler mocking for advanced cases, but it probably won't be the default.) The fix was usually to wrap an earlier update in `act` to ensure that all its work is fully flushed. --- This sync includes the following changes: - **[27c9c95e2](https://github.com/facebook/react/commit/27c9c95e2)**: act: Bypass microtask for "default sync" updates ([#21740](https://github.com/facebook/react/pull/21740)) //// - **[e577bfb1c](https://github.com/facebook/react/commit/e577bfb1c)**: Add tests for invokeGuardedCallback ([#21734](https://github.com/facebook/react/pull/21734)) //// - **[355591add](https://github.com/facebook/react/commit/355591add)**: Next/experimental release versions include commit date ([#21700](https://github.com/facebook/react/pull/21700)) //// - **[d7dce572c](https://github.com/facebook/react/commit/d7dce572c)**: Remove internal `act` builds from public modules ([#21721](https://github.com/facebook/react/pull/21721)) //// - **[06f7b4f43](https://github.com/facebook/react/commit/06f7b4f43)**: `act` should work without mock Scheduler ([#21714](https://github.com/facebook/react/pull/21714)) //// - **[422e0bb36](https://github.com/facebook/react/commit/422e0bb36)**: Delete test-utils implementation of `act` ([#21703](https://github.com/facebook/react/pull/21703)) //// Reviewed By: rickhanlonii Differential Revision: D29314763 fbshipit-source-id: 6c53a053e00defee0ab89f30e2f6bd2a1ff29bce --- .../__tests__/Recoil_Link-test.js | 12 ++- ...il_useRecoilBridgeAcrossReactRoots-test.js | 73 ++++++++++--------- 2 files changed, 46 insertions(+), 39 deletions(-) diff --git a/src/contrib/uri_persistence/__tests__/Recoil_Link-test.js b/src/contrib/uri_persistence/__tests__/Recoil_Link-test.js index 768646f..b6b4618 100644 --- a/src/contrib/uri_persistence/__tests__/Recoil_Link-test.js +++ b/src/contrib/uri_persistence/__tests__/Recoil_Link-test.js @@ -71,7 +71,9 @@ test('Link - snapshot', async () => { 'https://test.com/test?atom=%22MAP', ); - Simulate.click(c.children[0], {button: 0}); + act(() => { + Simulate.click(c.children[0], {button: 0}); + }); await flushPromisesAndTimers(); expect(c.textContent).toEqual('"MAP"LINK-MAP'); }); @@ -95,7 +97,9 @@ test('Link - stateChange', async () => { 'https://test.com/test?atom=%22MAP', ); - Simulate.click(c.children[0], {button: 0}); + act(() => { + Simulate.click(c.children[0], {button: 0}); + }); await flushPromisesAndTimers(); expect(c.textContent).toEqual('"MAP"LINK'); }); @@ -120,7 +124,9 @@ test('Link - state update', async () => { 'https://test.com/test?atom=%22MAP%20SET', ); - Simulate.click(c.children[0], {button: 0}); + act(() => { + Simulate.click(c.children[0], {button: 0}); + }); await flushPromisesAndTimers(); expect(c.textContent).toEqual('"MAP SET"LINK'); }); diff --git a/src/hooks/__tests__/Recoil_useRecoilBridgeAcrossReactRoots-test.js b/src/hooks/__tests__/Recoil_useRecoilBridgeAcrossReactRoots-test.js index 7ba1312..b1f6f07 100644 --- a/src/hooks/__tests__/Recoil_useRecoilBridgeAcrossReactRoots-test.js +++ b/src/hooks/__tests__/Recoil_useRecoilBridgeAcrossReactRoots-test.js @@ -36,52 +36,53 @@ const testRecoil = getRecoilTestFn(() => { useRecoilBridgeAcrossReactRoots = require('../Recoil_useRecoilBridgeAcrossReactRoots'); }); -testRecoil('useRecoilBridgeAcrossReactRoots - create a context bridge', () => { - const myAtom = atom({ - key: 'useRecoilBridgeAcrossReactRoots - context bridge', - default: 'DEFAULT', - }); +testRecoil( + 'useRecoilBridgeAcrossReactRoots - create a context bridge', + async () => { + const myAtom = atom({ + key: 'useRecoilBridgeAcrossReactRoots - context bridge', + default: 'DEFAULT', + }); - function initializeState({set, getLoadable}) { - expect(getLoadable(myAtom).contents).toEqual('DEFAULT'); - set(myAtom, 'INITIALIZE'); - expect(getLoadable(myAtom).contents).toEqual('INITIALIZE'); - } + function initializeState({set, getLoadable}) { + expect(getLoadable(myAtom).contents).toEqual('DEFAULT'); + set(myAtom, 'INITIALIZE'); + expect(getLoadable(myAtom).contents).toEqual('INITIALIZE'); + } - const [ReadWriteAtom, setAtom] = componentThatReadsAndWritesAtom(myAtom); + const [ReadWriteAtom, setAtom] = componentThatReadsAndWritesAtom(myAtom); - function NestedReactRoot({children}) { - const ref = useRef(); - const RecoilBridge = useRecoilBridgeAcrossReactRoots(); + function NestedReactRoot({children}) { + const ref = useRef(); + const RecoilBridge = useRecoilBridgeAcrossReactRoots(); - useEffect(() => { - act(() => { + useEffect(() => { ReactDOM.render( {children}, ref.current ?? document.createElement('div'), ); - }); - }, [children]); + }, [children]); - return
; - } + return
; + } - const container = document.createElement('div'); - act(() => { - ReactDOM.render( - - - - + const container = document.createElement('div'); + await act(() => { + ReactDOM.render( + - - , - container, - ); - }); - expect(container.textContent).toEqual('"INITIALIZE""INITIALIZE"'); + + + + , + container, + ); + }); - act(() => setAtom('SET')); - expect(container.textContent).toEqual('"SET""SET"'); -}); + expect(container.textContent).toEqual('"INITIALIZE""INITIALIZE"'); + + act(() => setAtom('SET')); + expect(container.textContent).toEqual('"SET""SET"'); + }, +);