diff --git a/packages/react-devtools-shared/src/__tests__/storeStressSync-test.js b/packages/react-devtools-shared/src/__tests__/storeStressSync-test.js index e7bb03b34f7db..bf444f169249a 100644 --- a/packages/react-devtools-shared/src/__tests__/storeStressSync-test.js +++ b/packages/react-devtools-shared/src/__tests__/storeStressSync-test.js @@ -7,14 +7,14 @@ * @flow */ +import {getLegacyRenderImplementation} from './utils'; + describe('StoreStress (Legacy Mode)', () => { let React; - let ReactDOM; let act; let bridge; let store; let print; - let legacyRender; beforeEach(() => { bridge = global.bridge; @@ -22,18 +22,20 @@ describe('StoreStress (Legacy Mode)', () => { store.collapseNodesByDefault = false; React = require('react'); - ReactDOM = require('react-dom'); const utils = require('./utils'); act = utils.act; - legacyRender = utils.legacyRender; print = require('./__serializers__/storeSerializer').print; }); + const {render, unmount, createContainer, getContainer} = + getLegacyRenderImplementation(); + // This is a stress test for the tree mount/update/unmount traversal. // It renders different trees that should produce the same output. // @reactVersion >= 16.9 + // @reactVersion < 19 it('should handle a stress test with different tree operations (Legacy Mode)', () => { let setShowX; const A = () => 'a'; @@ -60,8 +62,7 @@ describe('StoreStress (Legacy Mode)', () => { } // 1. Render a normal version of [a, b, c, d, e]. - let container = document.createElement('div'); - act(() => legacyRender({[a, b, c, d, e]}, container)); + act(() => render({[a, b, c, d, e]})); expect(store).toMatchInlineSnapshot(` [root] ▾ @@ -71,7 +72,7 @@ describe('StoreStress (Legacy Mode)', () => { `); - expect(container.textContent).toMatch('abcde'); + expect(getContainer().textContent).toMatch('abcde'); const snapshotForABCDE = print(store); // 2. Render a version where renders an child instead of 'c'. @@ -89,18 +90,18 @@ describe('StoreStress (Legacy Mode)', () => { `); - expect(container.textContent).toMatch('abxde'); + expect(getContainer().textContent).toMatch('abxde'); const snapshotForABXDE = print(store); // 3. Verify flipping it back produces the original result. act(() => { setShowX(false); }); - expect(container.textContent).toMatch('abcde'); + expect(getContainer().textContent).toMatch('abcde'); expect(print(store)).toBe(snapshotForABCDE); // 4. Clean up. - act(() => ReactDOM.unmountComponentAtNode(container)); + act(() => unmount()); expect(print(store)).toBe(''); // Now comes the interesting part. @@ -138,61 +139,62 @@ describe('StoreStress (Legacy Mode)', () => { // 5. Test fresh mount for each case. for (let i = 0; i < cases.length; i++) { // Ensure fresh mount. - container = document.createElement('div'); + createContainer(); // Verify mounting 'abcde'. - act(() => legacyRender({cases[i]}, container)); - expect(container.textContent).toMatch('abcde'); + act(() => render({cases[i]})); + expect(getContainer().textContent).toMatch('abcde'); expect(print(store)).toEqual(snapshotForABCDE); // Verify switching to 'abxde'. act(() => { setShowX(true); }); - expect(container.textContent).toMatch('abxde'); + expect(getContainer().textContent).toMatch('abxde'); expect(print(store)).toBe(snapshotForABXDE); // Verify switching back to 'abcde'. act(() => { setShowX(false); }); - expect(container.textContent).toMatch('abcde'); + expect(getContainer().textContent).toMatch('abcde'); expect(print(store)).toBe(snapshotForABCDE); // Clean up. - act(() => ReactDOM.unmountComponentAtNode(container)); + act(() => unmount()); expect(print(store)).toBe(''); } // 6. Verify *updates* by reusing the container between iterations. // There'll be no unmounting until the very end. - container = document.createElement('div'); + createContainer(); for (let i = 0; i < cases.length; i++) { // Verify mounting 'abcde'. - act(() => legacyRender({cases[i]}, container)); - expect(container.textContent).toMatch('abcde'); + act(() => render({cases[i]})); + expect(getContainer().textContent).toMatch('abcde'); expect(print(store)).toEqual(snapshotForABCDE); // Verify switching to 'abxde'. act(() => { setShowX(true); }); - expect(container.textContent).toMatch('abxde'); + expect(getContainer().textContent).toMatch('abxde'); expect(print(store)).toBe(snapshotForABXDE); // Verify switching back to 'abcde'. act(() => { setShowX(false); }); - expect(container.textContent).toMatch('abcde'); + expect(getContainer().textContent).toMatch('abcde'); expect(print(store)).toBe(snapshotForABCDE); // Don't unmount. Reuse the container between iterations. } - act(() => ReactDOM.unmountComponentAtNode(container)); + act(() => unmount()); expect(print(store)).toBe(''); }); // @reactVersion >= 16.9 + // @reactVersion <= 18.2 it('should handle stress test with reordering (Legacy Mode)', () => { const A = () => 'a'; const B = () => 'b'; @@ -320,27 +322,29 @@ describe('StoreStress (Legacy Mode)', () => { // 1. Capture the expected render result. const snapshots = []; - let container = document.createElement('div'); for (let i = 0; i < steps.length; i++) { - act(() => legacyRender({steps[i]}, container)); + createContainer(); + + act(() => render({steps[i]})); // We snapshot each step once so it doesn't regress. expect(store).toMatchInlineSnapshot(stepsSnapshot[i]); snapshots.push(print(store)); - act(() => ReactDOM.unmountComponentAtNode(container)); + act(() => unmount()); expect(print(store)).toBe(''); } // 2. Verify that we can update from every step to every other step and back. for (let i = 0; i < steps.length; i++) { for (let j = 0; j < steps.length; j++) { - container = document.createElement('div'); - act(() => legacyRender({steps[i]}, container)); + createContainer(); + + act(() => render({steps[i]})); expect(print(store)).toMatch(snapshots[i]); - act(() => legacyRender({steps[j]}, container)); + act(() => render({steps[j]})); expect(print(store)).toMatch(snapshots[j]); - act(() => legacyRender({steps[i]}, container)); + act(() => render({steps[i]})); expect(print(store)).toMatch(snapshots[i]); - act(() => ReactDOM.unmountComponentAtNode(container)); + act(() => unmount()); expect(print(store)).toBe(''); } } @@ -348,41 +352,40 @@ describe('StoreStress (Legacy Mode)', () => { // 3. Same test as above, but this time we wrap children in a host component. for (let i = 0; i < steps.length; i++) { for (let j = 0; j < steps.length; j++) { - container = document.createElement('div'); + createContainer(); + act(() => - legacyRender( + render(
{steps[i]}
, - container, ), ); expect(print(store)).toMatch(snapshots[i]); act(() => - legacyRender( + render(
{steps[j]}
, - container, ), ); expect(print(store)).toMatch(snapshots[j]); act(() => - legacyRender( + render(
{steps[i]}
, - container, ), ); expect(print(store)).toMatch(snapshots[i]); - act(() => ReactDOM.unmountComponentAtNode(container)); + act(() => unmount()); expect(print(store)).toBe(''); } } }); // @reactVersion >= 18.0 + // @reactVersion <= 18.2 it('should handle a stress test for Suspense (Legacy Mode)', async () => { const A = () => 'a'; const B = () => 'b'; @@ -528,29 +531,31 @@ describe('StoreStress (Legacy Mode)', () => { // 1. For each step, check Suspense can render them as initial primary content. // This is the only step where we use Jest snapshots. const snapshots = []; - let container = document.createElement('div'); for (let i = 0; i < steps.length; i++) { + createContainer(); + act(() => - legacyRender( + render( {steps[i]} , - container, ), ); // We snapshot each step once so it doesn't regress. expect(store).toMatchInlineSnapshot(stepsSnapshot[i]); snapshots.push(print(store)); - act(() => ReactDOM.unmountComponentAtNode(container)); + act(() => unmount()); expect(print(store)).toBe(''); } // 2. Verify check Suspense can render same steps as initial fallback content. for (let i = 0; i < steps.length; i++) { + createContainer(); + act(() => - legacyRender( + render( @@ -560,11 +565,10 @@ describe('StoreStress (Legacy Mode)', () => { , - container, ), ); expect(print(store)).toEqual(snapshots[i]); - act(() => ReactDOM.unmountComponentAtNode(container)); + act(() => unmount()); expect(print(store)).toBe(''); } @@ -572,45 +576,43 @@ describe('StoreStress (Legacy Mode)', () => { for (let i = 0; i < steps.length; i++) { for (let j = 0; j < steps.length; j++) { // Always start with a fresh container and steps[i]. - container = document.createElement('div'); + createContainer(); + act(() => - legacyRender( + render( {steps[i]} , - container, ), ); expect(print(store)).toEqual(snapshots[i]); // Re-render with steps[j]. act(() => - legacyRender( + render( {steps[j]} , - container, ), ); // Verify the successful transition to steps[j]. expect(print(store)).toEqual(snapshots[j]); // Check that we can transition back again. act(() => - legacyRender( + render( {steps[i]} , - container, ), ); expect(print(store)).toEqual(snapshots[i]); // Clean up after every iteration. - act(() => ReactDOM.unmountComponentAtNode(container)); + act(() => unmount()); expect(print(store)).toBe(''); } } @@ -619,9 +621,10 @@ describe('StoreStress (Legacy Mode)', () => { for (let i = 0; i < steps.length; i++) { for (let j = 0; j < steps.length; j++) { // Always start with a fresh container and steps[i]. - container = document.createElement('div'); + createContainer(); + act(() => - legacyRender( + render( @@ -631,13 +634,12 @@ describe('StoreStress (Legacy Mode)', () => { , - container, ), ); expect(print(store)).toEqual(snapshots[i]); // Re-render with steps[j]. act(() => - legacyRender( + render( @@ -647,14 +649,13 @@ describe('StoreStress (Legacy Mode)', () => { , - container, ), ); // Verify the successful transition to steps[j]. expect(print(store)).toEqual(snapshots[j]); // Check that we can transition back again. act(() => - legacyRender( + render( @@ -664,12 +665,11 @@ describe('StoreStress (Legacy Mode)', () => { , - container, ), ); expect(print(store)).toEqual(snapshots[i]); // Clean up after every iteration. - act(() => ReactDOM.unmountComponentAtNode(container)); + act(() => unmount()); expect(print(store)).toBe(''); } } @@ -678,21 +678,21 @@ describe('StoreStress (Legacy Mode)', () => { for (let i = 0; i < steps.length; i++) { for (let j = 0; j < steps.length; j++) { // Always start with a fresh container and steps[i]. - container = document.createElement('div'); + createContainer(); + act(() => - legacyRender( + render( {steps[i]} , - container, ), ); expect(print(store)).toEqual(snapshots[i]); // Re-render with steps[j]. act(() => - legacyRender( + render( @@ -702,25 +702,23 @@ describe('StoreStress (Legacy Mode)', () => { , - container, ), ); // Verify the successful transition to steps[j]. expect(print(store)).toEqual(snapshots[j]); // Check that we can transition back again. act(() => - legacyRender( + render( {steps[i]} , - container, ), ); expect(print(store)).toEqual(snapshots[i]); // Clean up after every iteration. - act(() => ReactDOM.unmountComponentAtNode(container)); + act(() => unmount()); expect(print(store)).toBe(''); } } @@ -729,9 +727,10 @@ describe('StoreStress (Legacy Mode)', () => { for (let i = 0; i < steps.length; i++) { for (let j = 0; j < steps.length; j++) { // Always start with a fresh container and steps[i]. - container = document.createElement('div'); + createContainer(); + act(() => - legacyRender( + render( @@ -741,26 +740,24 @@ describe('StoreStress (Legacy Mode)', () => { , - container, ), ); expect(print(store)).toEqual(snapshots[i]); // Re-render with steps[j]. act(() => - legacyRender( + render( {steps[j]} , - container, ), ); // Verify the successful transition to steps[j]. expect(print(store)).toEqual(snapshots[j]); // Check that we can transition back again. act(() => - legacyRender( + render( @@ -770,12 +767,11 @@ describe('StoreStress (Legacy Mode)', () => { , - container, ), ); expect(print(store)).toEqual(snapshots[i]); // Clean up after every iteration. - act(() => ReactDOM.unmountComponentAtNode(container)); + act(() => unmount()); expect(print(store)).toBe(''); } } @@ -784,15 +780,15 @@ describe('StoreStress (Legacy Mode)', () => { for (let i = 0; i < steps.length; i++) { for (let j = 0; j < steps.length; j++) { // Always start with a fresh container and steps[i]. - container = document.createElement('div'); + createContainer(); + act(() => - legacyRender( + render( {steps[i]} , - container, ), ); @@ -824,7 +820,7 @@ describe('StoreStress (Legacy Mode)', () => { // Trigger actual fallback. act(() => - legacyRender( + render( @@ -834,7 +830,6 @@ describe('StoreStress (Legacy Mode)', () => { , - container, ), ); expect(print(store)).toEqual(snapshots[j]); @@ -852,13 +847,12 @@ describe('StoreStress (Legacy Mode)', () => { // Switch to primary mode. act(() => - legacyRender( + render( {steps[i]} , - container, ), ); // Fallback is still forced though. @@ -876,13 +870,14 @@ describe('StoreStress (Legacy Mode)', () => { expect(print(store)).toEqual(snapshots[i]); // Clean up after every iteration. - act(() => ReactDOM.unmountComponentAtNode(container)); + act(() => unmount()); expect(print(store)).toBe(''); } } }); // @reactVersion >= 18.0 + // @reactVersion <= 18.2 it('should handle a stress test for Suspense without type change (Legacy Mode)', () => { const A = () => 'a'; const B = () => 'b'; @@ -1176,10 +1171,12 @@ describe('StoreStress (Legacy Mode)', () => { // 1. For each step, check Suspense can render them as initial primary content. // This is the only step where we use Jest snapshots. const snapshots = []; - let container = document.createElement('div'); + for (let i = 0; i < steps.length; i++) { + createContainer(); + act(() => - legacyRender( + render( @@ -1187,13 +1184,12 @@ describe('StoreStress (Legacy Mode)', () => { , - container, ), ); // We snapshot each step once so it doesn't regress. expect(store).toMatchInlineSnapshot(stepsSnapshot[i]); snapshots.push(print(store)); - act(() => ReactDOM.unmountComponentAtNode(container)); + act(() => unmount()); expect(print(store)).toBe(''); } @@ -1202,8 +1198,10 @@ describe('StoreStress (Legacy Mode)', () => { // which is different from the snapshots above. So we take more snapshots. const fallbackSnapshots = []; for (let i = 0; i < steps.length; i++) { + createContainer(); + act(() => - legacyRender( + render( @@ -1213,13 +1211,12 @@ describe('StoreStress (Legacy Mode)', () => { , - container, ), ); // We snapshot each step once so it doesn't regress. expect(store).toMatchInlineSnapshot(stepsSnapshotTwo[i]); fallbackSnapshots.push(print(store)); - act(() => ReactDOM.unmountComponentAtNode(container)); + act(() => unmount()); expect(print(store)).toBe(''); } @@ -1227,9 +1224,10 @@ describe('StoreStress (Legacy Mode)', () => { for (let i = 0; i < steps.length; i++) { for (let j = 0; j < steps.length; j++) { // Always start with a fresh container and steps[i]. - container = document.createElement('div'); + createContainer(); + act(() => - legacyRender( + render( @@ -1237,13 +1235,12 @@ describe('StoreStress (Legacy Mode)', () => { , - container, ), ); expect(print(store)).toEqual(snapshots[i]); // Re-render with steps[j]. act(() => - legacyRender( + render( @@ -1251,14 +1248,13 @@ describe('StoreStress (Legacy Mode)', () => { , - container, ), ); // Verify the successful transition to steps[j]. expect(print(store)).toEqual(snapshots[j]); // Check that we can transition back again. act(() => - legacyRender( + render( @@ -1266,12 +1262,11 @@ describe('StoreStress (Legacy Mode)', () => { , - container, ), ); expect(print(store)).toEqual(snapshots[i]); // Clean up after every iteration. - act(() => ReactDOM.unmountComponentAtNode(container)); + act(() => unmount()); expect(print(store)).toBe(''); } } @@ -1280,9 +1275,10 @@ describe('StoreStress (Legacy Mode)', () => { for (let i = 0; i < steps.length; i++) { for (let j = 0; j < steps.length; j++) { // Always start with a fresh container and steps[i]. - container = document.createElement('div'); + createContainer(); + act(() => - legacyRender( + render( @@ -1295,13 +1291,12 @@ describe('StoreStress (Legacy Mode)', () => { , - container, ), ); expect(print(store)).toEqual(fallbackSnapshots[i]); // Re-render with steps[j]. act(() => - legacyRender( + render( @@ -1314,14 +1309,13 @@ describe('StoreStress (Legacy Mode)', () => { , - container, ), ); // Verify the successful transition to steps[j]. expect(print(store)).toEqual(fallbackSnapshots[j]); // Check that we can transition back again. act(() => - legacyRender( + render( @@ -1334,12 +1328,11 @@ describe('StoreStress (Legacy Mode)', () => { , - container, ), ); expect(print(store)).toEqual(fallbackSnapshots[i]); // Clean up after every iteration. - act(() => ReactDOM.unmountComponentAtNode(container)); + act(() => unmount()); expect(print(store)).toBe(''); } } @@ -1348,9 +1341,10 @@ describe('StoreStress (Legacy Mode)', () => { for (let i = 0; i < steps.length; i++) { for (let j = 0; j < steps.length; j++) { // Always start with a fresh container and steps[i]. - container = document.createElement('div'); + createContainer(); + act(() => - legacyRender( + render( @@ -1358,13 +1352,12 @@ describe('StoreStress (Legacy Mode)', () => { , - container, ), ); expect(print(store)).toEqual(snapshots[i]); // Re-render with steps[j]. act(() => - legacyRender( + render( @@ -1372,14 +1365,13 @@ describe('StoreStress (Legacy Mode)', () => { , - container, ), ); // Verify the successful transition to steps[j]. expect(print(store)).toEqual(fallbackSnapshots[j]); // Check that we can transition back again. act(() => - legacyRender( + render( @@ -1387,12 +1379,11 @@ describe('StoreStress (Legacy Mode)', () => { , - container, ), ); expect(print(store)).toEqual(snapshots[i]); // Clean up after every iteration. - act(() => ReactDOM.unmountComponentAtNode(container)); + act(() => unmount()); expect(print(store)).toBe(''); } } @@ -1401,9 +1392,10 @@ describe('StoreStress (Legacy Mode)', () => { for (let i = 0; i < steps.length; i++) { for (let j = 0; j < steps.length; j++) { // Always start with a fresh container and steps[i]. - container = document.createElement('div'); + createContainer(); + act(() => - legacyRender( + render( @@ -1411,13 +1403,12 @@ describe('StoreStress (Legacy Mode)', () => { , - container, ), ); expect(print(store)).toEqual(fallbackSnapshots[i]); // Re-render with steps[j]. act(() => - legacyRender( + render( @@ -1425,14 +1416,13 @@ describe('StoreStress (Legacy Mode)', () => { , - container, ), ); // Verify the successful transition to steps[j]. expect(print(store)).toEqual(snapshots[j]); // Check that we can transition back again. act(() => - legacyRender( + render( @@ -1440,12 +1430,11 @@ describe('StoreStress (Legacy Mode)', () => { , - container, ), ); expect(print(store)).toEqual(fallbackSnapshots[i]); // Clean up after every iteration. - act(() => ReactDOM.unmountComponentAtNode(container)); + act(() => unmount()); expect(print(store)).toBe(''); } } @@ -1454,9 +1443,10 @@ describe('StoreStress (Legacy Mode)', () => { for (let i = 0; i < steps.length; i++) { for (let j = 0; j < steps.length; j++) { // Always start with a fresh container and steps[i]. - container = document.createElement('div'); + createContainer(); + act(() => - legacyRender( + render( @@ -1464,7 +1454,6 @@ describe('StoreStress (Legacy Mode)', () => { , - container, ), ); @@ -1496,7 +1485,7 @@ describe('StoreStress (Legacy Mode)', () => { // Trigger actual fallback. act(() => - legacyRender( + render( @@ -1504,7 +1493,6 @@ describe('StoreStress (Legacy Mode)', () => { , - container, ), ); expect(print(store)).toEqual(fallbackSnapshots[j]); @@ -1522,7 +1510,7 @@ describe('StoreStress (Legacy Mode)', () => { // Switch to primary mode. act(() => - legacyRender( + render( @@ -1530,7 +1518,6 @@ describe('StoreStress (Legacy Mode)', () => { , - container, ), ); // Fallback is still forced though. @@ -1548,7 +1535,7 @@ describe('StoreStress (Legacy Mode)', () => { expect(print(store)).toEqual(snapshots[i]); // Clean up after every iteration. - act(() => ReactDOM.unmountComponentAtNode(container)); + act(() => unmount()); expect(print(store)).toBe(''); } }