From 6ac2c98c19b8fc3661087285127d99f982aa348d Mon Sep 17 00:00:00 2001 From: Ruslan Lesiutin Date: Mon, 5 Feb 2024 11:37:18 +0000 Subject: [PATCH] chore: use versioned render in profilingCache test --- .../src/__tests__/profilingCache-test.js | 190 +++++++++++++----- 1 file changed, 140 insertions(+), 50 deletions(-) diff --git a/packages/react-devtools-shared/src/__tests__/profilingCache-test.js b/packages/react-devtools-shared/src/__tests__/profilingCache-test.js index aefc8d5e078bc..ebf1bdd33108f 100644 --- a/packages/react-devtools-shared/src/__tests__/profilingCache-test.js +++ b/packages/react-devtools-shared/src/__tests__/profilingCache-test.js @@ -10,6 +10,8 @@ import type {FrontendBridge} from 'react-devtools-shared/src/bridge'; import type Store from 'react-devtools-shared/src/devtools/store'; +import {getVersionedRenderImplementation} from './utils'; + describe('ProfilingCache', () => { let PropTypes; let React; @@ -39,8 +41,11 @@ describe('ProfilingCache', () => { Scheduler = require('scheduler'); }); + const {render, getContainer} = getVersionedRenderImplementation(); + // @reactVersion >= 16.9 - it('should collect data for each root (including ones added or mounted after profiling started)', () => { + // @reactVersion < 19 + it('should collect data for each root (including ones added or mounted after profiling started) (Legacy Render)', () => { const Parent = ({count}) => { Scheduler.unstable_advanceTime(10); const children = new Array(count) @@ -151,6 +156,116 @@ describe('ProfilingCache', () => { }); }); + // @reactVersion >= 18 + it('should collect data for each root (including ones added or mounted after profiling started) (Concurrent Render)', () => { + const Parent = ({count}) => { + Scheduler.unstable_advanceTime(10); + const children = new Array(count) + .fill(true) + .map((_, index) => ); + return ( + + {children} + + + ); + }; + const Child = ({duration}) => { + Scheduler.unstable_advanceTime(duration); + return null; + }; + const MemoizedChild = React.memo(Child); + + const RootA = ({children}) => children; + const RootB = ({children}) => children; + const RootC = ({children}) => children; + + const containerA = document.createElement('div'); + const containerB = document.createElement('div'); + const containerC = document.createElement('div'); + + const rootA = ReactDOMClient.createRoot(containerA); + const rootB = ReactDOMClient.createRoot(containerB); + const rootC = ReactDOMClient.createRoot(containerC); + + utils.act(() => + rootA.render( + + + , + ), + ); + utils.act(() => + rootB.render( + + + , + ), + ); + utils.act(() => store.profilerStore.startProfiling()); + utils.act(() => + rootA.render( + + + , + ), + ); + utils.act(() => + rootC.render( + + + , + ), + ); + utils.act(() => + rootA.render( + + + , + ), + ); + utils.act(() => rootB.unmount()); + utils.act(() => + rootA.render( + + + , + ), + ); + utils.act(() => store.profilerStore.stopProfiling()); + utils.act(() => rootA.unmount()); + + const rootIDs = Array.from( + store.profilerStore.profilingData.dataForRoots.values(), + ).map(({rootID}) => rootID); + expect(rootIDs).toHaveLength(3); + + const originalProfilingDataForRoot = []; + + let data = store.profilerStore.getDataForRoot(rootIDs[0]); + expect(data.displayName).toMatchInlineSnapshot(`"RootA"`); + expect(data.commitData).toHaveLength(3); + originalProfilingDataForRoot.push(data); + + data = store.profilerStore.getDataForRoot(rootIDs[1]); + expect(data.displayName).toMatchInlineSnapshot(`"RootC"`); + expect(data.commitData).toHaveLength(1); + originalProfilingDataForRoot.push(data); + + data = store.profilerStore.getDataForRoot(rootIDs[2]); + expect(data.displayName).toMatchInlineSnapshot(`"RootB"`); + expect(data.commitData).toHaveLength(1); + originalProfilingDataForRoot.push(data); + + utils.exportImportHelper(bridge, store); + + rootIDs.forEach((rootID, index) => { + const current = store.profilerStore.getDataForRoot(rootID); + const prev = originalProfilingDataForRoot[index]; + expect(current).toEqual(prev); + }); + }); + // @reactVersion >= 16.9 it('should collect data for each commit', () => { const Parent = ({count}) => { @@ -171,13 +286,11 @@ describe('ProfilingCache', () => { }; const MemoizedChild = React.memo(Child); - const container = document.createElement('div'); - utils.act(() => store.profilerStore.startProfiling()); - utils.act(() => legacyRender(, container)); - utils.act(() => legacyRender(, container)); - utils.act(() => legacyRender(, container)); - utils.act(() => legacyRender(, container)); + utils.act(() => render()); + utils.act(() => render()); + utils.act(() => render()); + utils.act(() => render()); utils.act(() => store.profilerStore.stopProfiling()); const rootID = store.roots[0]; @@ -244,19 +357,13 @@ describe('ProfilingCache', () => { } } - const container = document.createElement('div'); - utils.act(() => store.profilerStore.startProfiling()); - utils.act(() => legacyRender(, container)); + utils.act(() => render()); expect(instance).not.toBeNull(); utils.act(() => (instance: any).setState({count: 1})); - utils.act(() => - legacyRender(, container), - ); - utils.act(() => - legacyRender(, container), - ); - utils.act(() => legacyRender(, container)); + utils.act(() => render()); + utils.act(() => render()); + utils.act(() => render()); utils.act(() => store.profilerStore.stopProfiling()); const rootID = store.roots[0]; @@ -574,25 +681,21 @@ describe('ProfilingCache', () => { return null; }; - const container = document.createElement('div'); - utils.act(() => store.profilerStore.startProfiling()); utils.act(() => - legacyRender( + render( , - container, ), ); // Second render has no changed hooks, only changed props. utils.act(() => - legacyRender( + render( , - container, ), ); @@ -604,11 +707,10 @@ describe('ProfilingCache', () => { // Fifth render has a changed context value, but no changed hook. utils.act(() => - legacyRender( + render( , - container, ), ); @@ -754,9 +856,7 @@ describe('ProfilingCache', () => { }; utils.act(() => store.profilerStore.startProfiling()); - utils.act(() => - legacyRender(, document.createElement('div')), - ); + utils.act(() => render()); utils.act(() => store.profilerStore.stopProfiling()); expect(store).toMatchInlineSnapshot(` @@ -822,9 +922,7 @@ describe('ProfilingCache', () => { }; utils.act(() => store.profilerStore.startProfiling()); - await utils.actAsync(() => - legacyRender(, document.createElement('div')), - ); + await utils.actAsync(() => render()); utils.act(() => store.profilerStore.stopProfiling()); const rootID = store.roots[0]; @@ -880,12 +978,10 @@ describe('ProfilingCache', () => { }; const MemoizedChild = React.memo(Child); - const container = document.createElement('div'); - utils.act(() => store.profilerStore.startProfiling()); - utils.act(() => legacyRender(, container)); - utils.act(() => legacyRender(, container)); - utils.act(() => legacyRender(, container)); + utils.act(() => render()); + utils.act(() => render()); + utils.act(() => render()); utils.act(() => store.profilerStore.stopProfiling()); const rootID = store.roots[0]; @@ -941,10 +1037,8 @@ describe('ProfilingCache', () => { // @reactVersion >= 18.0.0 // @reactVersion <= 18.2.0 it('should handle unexpectedly shallow suspense trees for react v[18.0.0 - 18.2.0]', () => { - const container = document.createElement('div'); - utils.act(() => store.profilerStore.startProfiling()); - utils.act(() => legacyRender(, container)); + utils.act(() => render()); utils.act(() => store.profilerStore.stopProfiling()); const rootID = store.roots[0]; @@ -969,7 +1063,7 @@ describe('ProfilingCache', () => { "updaters": [ { "compiledWithForget": false, - "displayName": "render()", + "displayName": "createRoot()", "hocDisplayNames": null, "id": 1, "key": null, @@ -981,13 +1075,10 @@ describe('ProfilingCache', () => { `); }); - // This test is not gated. - // For this test we use the current version of react, built from source. + // @reactVersion > 18.2.0 it('should handle unexpectedly shallow suspense trees', () => { - const container = document.createElement('div'); - utils.act(() => store.profilerStore.startProfiling()); - utils.act(() => legacyRender(, container)); + utils.act(() => render()); utils.act(() => store.profilerStore.stopProfiling()); const rootID = store.roots[0]; @@ -1012,7 +1103,7 @@ describe('ProfilingCache', () => { "updaters": [ { "compiledWithForget": false, - "displayName": "render()", + "displayName": "createRoot()", "hocDisplayNames": null, "id": 1, "key": null, @@ -1105,13 +1196,12 @@ describe('ProfilingCache', () => { const {Simulate} = require('react-dom/test-utils'); - const container = document.createElement('div'); - utils.act(() => legacyRender(, container)); - expect(container.textContent).toBe('Home'); + utils.act(() => render()); + expect(getContainer().textContent).toBe('Home'); utils.act(() => store.profilerStore.startProfiling()); utils.act(() => Simulate.click(linkRef.current)); utils.act(() => store.profilerStore.stopProfiling()); - expect(container.textContent).toBe('About'); + expect(getContainer().textContent).toBe('About'); }); // @reactVersion >= 18.0