Skip to content

Commit

Permalink
chore: use versioned render in profilingCache test
Browse files Browse the repository at this point in the history
  • Loading branch information
hoxyq committed Feb 5, 2024
1 parent e51cda5 commit 6ac2c98
Showing 1 changed file with 140 additions and 50 deletions.
190 changes: 140 additions & 50 deletions packages/react-devtools-shared/src/__tests__/profilingCache-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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) => <Child key={index} duration={index} />);
return (
<React.Fragment>
{children}
<MemoizedChild duration={1} />
</React.Fragment>
);
};
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(
<RootA>
<Parent count={2} />
</RootA>,
),
);
utils.act(() =>
rootB.render(
<RootB>
<Parent count={1} />
</RootB>,
),
);
utils.act(() => store.profilerStore.startProfiling());
utils.act(() =>
rootA.render(
<RootA>
<Parent count={3} />
</RootA>,
),
);
utils.act(() =>
rootC.render(
<RootC>
<Parent count={1} />
</RootC>,
),
);
utils.act(() =>
rootA.render(
<RootA>
<Parent count={1} />
</RootA>,
),
);
utils.act(() => rootB.unmount());
utils.act(() =>
rootA.render(
<RootA>
<Parent count={0} />
</RootA>,
),
);
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}) => {
Expand All @@ -171,13 +286,11 @@ describe('ProfilingCache', () => {
};
const MemoizedChild = React.memo(Child);

const container = document.createElement('div');

utils.act(() => store.profilerStore.startProfiling());
utils.act(() => legacyRender(<Parent count={2} />, container));
utils.act(() => legacyRender(<Parent count={3} />, container));
utils.act(() => legacyRender(<Parent count={1} />, container));
utils.act(() => legacyRender(<Parent count={0} />, container));
utils.act(() => render(<Parent count={2} />));
utils.act(() => render(<Parent count={3} />));
utils.act(() => render(<Parent count={1} />));
utils.act(() => render(<Parent count={0} />));
utils.act(() => store.profilerStore.stopProfiling());

const rootID = store.roots[0];
Expand Down Expand Up @@ -244,19 +357,13 @@ describe('ProfilingCache', () => {
}
}

const container = document.createElement('div');

utils.act(() => store.profilerStore.startProfiling());
utils.act(() => legacyRender(<LegacyContextProvider />, container));
utils.act(() => render(<LegacyContextProvider />));
expect(instance).not.toBeNull();
utils.act(() => (instance: any).setState({count: 1}));
utils.act(() =>
legacyRender(<LegacyContextProvider foo={123} />, container),
);
utils.act(() =>
legacyRender(<LegacyContextProvider bar="abc" />, container),
);
utils.act(() => legacyRender(<LegacyContextProvider />, container));
utils.act(() => render(<LegacyContextProvider foo={123} />));
utils.act(() => render(<LegacyContextProvider bar="abc" />));
utils.act(() => render(<LegacyContextProvider />));
utils.act(() => store.profilerStore.stopProfiling());

const rootID = store.roots[0];
Expand Down Expand Up @@ -574,25 +681,21 @@ describe('ProfilingCache', () => {
return null;
};

const container = document.createElement('div');

utils.act(() => store.profilerStore.startProfiling());
utils.act(() =>
legacyRender(
render(
<Context.Provider value={true}>
<Component count={1} />
</Context.Provider>,
container,
),
);

// Second render has no changed hooks, only changed props.
utils.act(() =>
legacyRender(
render(
<Context.Provider value={true}>
<Component count={2} />
</Context.Provider>,
container,
),
);

Expand All @@ -604,11 +707,10 @@ describe('ProfilingCache', () => {

// Fifth render has a changed context value, but no changed hook.
utils.act(() =>
legacyRender(
render(
<Context.Provider value={false}>
<Component count={2} />
</Context.Provider>,
container,
),
);

Expand Down Expand Up @@ -754,9 +856,7 @@ describe('ProfilingCache', () => {
};

utils.act(() => store.profilerStore.startProfiling());
utils.act(() =>
legacyRender(<Grandparent />, document.createElement('div')),
);
utils.act(() => render(<Grandparent />));
utils.act(() => store.profilerStore.stopProfiling());

expect(store).toMatchInlineSnapshot(`
Expand Down Expand Up @@ -822,9 +922,7 @@ describe('ProfilingCache', () => {
};

utils.act(() => store.profilerStore.startProfiling());
await utils.actAsync(() =>
legacyRender(<Parent />, document.createElement('div')),
);
await utils.actAsync(() => render(<Parent />));
utils.act(() => store.profilerStore.stopProfiling());

const rootID = store.roots[0];
Expand Down Expand Up @@ -880,12 +978,10 @@ describe('ProfilingCache', () => {
};
const MemoizedChild = React.memo(Child);

const container = document.createElement('div');

utils.act(() => store.profilerStore.startProfiling());
utils.act(() => legacyRender(<Parent count={1} />, container));
utils.act(() => legacyRender(<Parent count={2} />, container));
utils.act(() => legacyRender(<Parent count={3} />, container));
utils.act(() => render(<Parent count={1} />));
utils.act(() => render(<Parent count={2} />));
utils.act(() => render(<Parent count={3} />));
utils.act(() => store.profilerStore.stopProfiling());

const rootID = store.roots[0];
Expand Down Expand Up @@ -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(<React.Suspense />, container));
utils.act(() => render(<React.Suspense />));
utils.act(() => store.profilerStore.stopProfiling());

const rootID = store.roots[0];
Expand All @@ -969,7 +1063,7 @@ describe('ProfilingCache', () => {
"updaters": [
{
"compiledWithForget": false,
"displayName": "render()",
"displayName": "createRoot()",
"hocDisplayNames": null,
"id": 1,
"key": null,
Expand All @@ -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(<React.Suspense />, container));
utils.act(() => render(<React.Suspense />));
utils.act(() => store.profilerStore.stopProfiling());

const rootID = store.roots[0];
Expand All @@ -1012,7 +1103,7 @@ describe('ProfilingCache', () => {
"updaters": [
{
"compiledWithForget": false,
"displayName": "render()",
"displayName": "createRoot()",
"hocDisplayNames": null,
"id": 1,
"key": null,
Expand Down Expand Up @@ -1105,13 +1196,12 @@ describe('ProfilingCache', () => {

const {Simulate} = require('react-dom/test-utils');

const container = document.createElement('div');
utils.act(() => legacyRender(<App />, container));
expect(container.textContent).toBe('Home');
utils.act(() => render(<App />));
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
Expand Down

0 comments on commit 6ac2c98

Please sign in to comment.