Skip to content

Commit

Permalink
React sync for revisions 568dc35...27c9c95
Browse files Browse the repository at this point in the history
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](facebook/react@27c9c95e2)**: act: Bypass microtask for "default sync" updates ([#21740](facebook/react#21740)) //<Andrew Clark>//
- **[e577bfb1c](facebook/react@e577bfb1c)**: Add tests for invokeGuardedCallback ([#21734](facebook/react#21734)) //<Dan Abramov>//
- **[355591add](facebook/react@355591add)**: Next/experimental release versions include commit date ([#21700](facebook/react#21700)) //<Brian Vaughn>//
- **[d7dce572c](facebook/react@d7dce572c)**: Remove internal `act` builds from public modules ([#21721](facebook/react#21721)) //<Andrew Clark>//
- **[06f7b4f43](facebook/react@06f7b4f43)**: `act` should work without mock Scheduler ([#21714](facebook/react#21714)) //<Andrew Clark>//
- **[422e0bb36](facebook/react@422e0bb36)**: Delete test-utils implementation of `act` ([#21703](facebook/react#21703)) //<Andrew Clark>//

Reviewed By: rickhanlonii

Differential Revision: D29314763

fbshipit-source-id: 6c53a053e00defee0ab89f30e2f6bd2a1ff29bce
  • Loading branch information
acdlite authored and facebook-github-bot committed Jun 27, 2021
1 parent df577ed commit abff581
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 39 deletions.
12 changes: 9 additions & 3 deletions src/contrib/uri_persistence/__tests__/Recoil_Link-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
});
Expand All @@ -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');
});
Expand All @@ -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');
});
73 changes: 37 additions & 36 deletions src/hooks/__tests__/Recoil_useRecoilBridgeAcrossReactRoots-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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(
<RecoilBridge>{children}</RecoilBridge>,
ref.current ?? document.createElement('div'),
);
});
}, [children]);
}, [children]);

return <div ref={ref} />;
}
return <div ref={ref} />;
}

const container = document.createElement('div');
act(() => {
ReactDOM.render(
<RecoilRoot initializeState={initializeState}>
<ReadWriteAtom />

<NestedReactRoot>
const container = document.createElement('div');
await act(() => {
ReactDOM.render(
<RecoilRoot initializeState={initializeState}>
<ReadWriteAtom />
</NestedReactRoot>
</RecoilRoot>,
container,
);
});

expect(container.textContent).toEqual('"INITIALIZE""INITIALIZE"');
<NestedReactRoot>
<ReadWriteAtom />
</NestedReactRoot>
</RecoilRoot>,
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"');
},
);

0 comments on commit abff581

Please sign in to comment.