chore: use versioned render in profilingCache test (#28242)
Ruslan Lesiutin committed
Feb 6, 2024 at 11:24 UTC
cb78d2f1f3a09dcacf730273a584c769f69c47b3
1 file changed
+183
-50
packages/react-devtools-shared/src/__tests__/profilingCache-test.js
+183
-50
@@ -10,6 +10,8 @@
10
import type {FrontendBridge} from 'react-devtools-shared/src/bridge';
11
import type Store from 'react-devtools-shared/src/devtools/store';
12
13
+import {getVersionedRenderImplementation} from './utils';
14
+
15
describe('ProfilingCache', () => {
16
let PropTypes;
17
let React;
@@ -39,8 +41,11 @@ describe('ProfilingCache', () => {
41
Scheduler = require('scheduler');
42
});
43
44
+ const {render, getContainer} = getVersionedRenderImplementation();
45
+
46
// @reactVersion >= 16.9
43
- it('should collect data for each root (including ones added or mounted after profiling started)', () => {
47
+ // @reactVersion <= 18.2
48
+ it('should collect data for each root (including ones added or mounted after profiling started) (legacy render)', () => {
49
const Parent = ({count}) => {
50
Scheduler.unstable_advanceTime(10);
51
const children = new Array(count)
@@ -151,6 +156,116 @@ describe('ProfilingCache', () => {
156
});
157
});
158
159
+ // @reactVersion >= 18
160
+ it('should collect data for each root (including ones added or mounted after profiling started) (createRoot)', () => {
161
+ const Parent = ({count}) => {
162
+ Scheduler.unstable_advanceTime(10);
163
+ const children = new Array(count)
164
+ .fill(true)
165
+ .map((_, index) => <Child key={index} duration={index} />);
166
+ return (
167
+ <React.Fragment>
168
+ {children}
169
+ <MemoizedChild duration={1} />
170
+ </React.Fragment>
171
+ );
172
+ };
173
+ const Child = ({duration}) => {
174
+ Scheduler.unstable_advanceTime(duration);
175
+ return null;
176
+ };
177
+ const MemoizedChild = React.memo(Child);
178
+
179
+ const RootA = ({children}) => children;
180
+ const RootB = ({children}) => children;
181
+ const RootC = ({children}) => children;
182
+
183
+ const containerA = document.createElement('div');
184
+ const containerB = document.createElement('div');
185
+ const containerC = document.createElement('div');
186
+
187
+ const rootA = ReactDOMClient.createRoot(containerA);
188
+ const rootB = ReactDOMClient.createRoot(containerB);
189
+ const rootC = ReactDOMClient.createRoot(containerC);
190
+
191
+ utils.act(() =>
192
+ rootA.render(
193
+ <RootA>
194
+ <Parent count={2} />
195
+ </RootA>,
196
+ ),
197
+ );
198
+ utils.act(() =>
199
+ rootB.render(
200
+ <RootB>
201
+ <Parent count={1} />
202
+ </RootB>,
203
+ ),
204
+ );
205
+ utils.act(() => store.profilerStore.startProfiling());
206
+ utils.act(() =>
207
+ rootA.render(
208
+ <RootA>
209
+ <Parent count={3} />
210
+ </RootA>,
211
+ ),
212
+ );
213
+ utils.act(() =>
214
+ rootC.render(
215
+ <RootC>
216
+ <Parent count={1} />
217
+ </RootC>,
218
+ ),
219
+ );
220
+ utils.act(() =>
221
+ rootA.render(
222
+ <RootA>
223
+ <Parent count={1} />
224
+ </RootA>,
225
+ ),
226
+ );
227
+ utils.act(() => rootB.unmount());
228
+ utils.act(() =>
229
+ rootA.render(
230
+ <RootA>
231
+ <Parent count={0} />
232
+ </RootA>,
233
+ ),
234
+ );
235
+ utils.act(() => store.profilerStore.stopProfiling());
236
+ utils.act(() => rootA.unmount());
237
+
238
+ const rootIDs = Array.from(
239
+ store.profilerStore.profilingData.dataForRoots.values(),
240
+ ).map(({rootID}) => rootID);
241
+ expect(rootIDs).toHaveLength(3);
242
+
243
+ const originalProfilingDataForRoot = [];
244
+
245
+ let data = store.profilerStore.getDataForRoot(rootIDs[0]);
246
+ expect(data.displayName).toMatchInlineSnapshot(`"RootA"`);
247
+ expect(data.commitData).toHaveLength(3);
248
+ originalProfilingDataForRoot.push(data);
249
+
250
+ data = store.profilerStore.getDataForRoot(rootIDs[1]);
251
+ expect(data.displayName).toMatchInlineSnapshot(`"RootC"`);
252
+ expect(data.commitData).toHaveLength(1);
253
+ originalProfilingDataForRoot.push(data);
254
+
255
+ data = store.profilerStore.getDataForRoot(rootIDs[2]);
256
+ expect(data.displayName).toMatchInlineSnapshot(`"RootB"`);
257
+ expect(data.commitData).toHaveLength(1);
258
+ originalProfilingDataForRoot.push(data);
259
+
260
+ utils.exportImportHelper(bridge, store);
261
+
262
+ rootIDs.forEach((rootID, index) => {
263
+ const current = store.profilerStore.getDataForRoot(rootID);
264
+ const prev = originalProfilingDataForRoot[index];
265
+ expect(current).toEqual(prev);
266
+ });
267
+ });
268
+
269
// @reactVersion >= 16.9
270
it('should collect data for each commit', () => {
271
const Parent = ({count}) => {
@@ -171,13 +286,11 @@ describe('ProfilingCache', () => {
286
};
287
const MemoizedChild = React.memo(Child);
288
174
- const container = document.createElement('div');
175
-
289
utils.act(() => store.profilerStore.startProfiling());
177
- utils.act(() => legacyRender(<Parent count={2} />, container));
178
- utils.act(() => legacyRender(<Parent count={3} />, container));
179
- utils.act(() => legacyRender(<Parent count={1} />, container));
180
- utils.act(() => legacyRender(<Parent count={0} />, container));
290
+ utils.act(() => render(<Parent count={2} />));
291
+ utils.act(() => render(<Parent count={3} />));
292
+ utils.act(() => render(<Parent count={1} />));
293
+ utils.act(() => render(<Parent count={0} />));
294
utils.act(() => store.profilerStore.stopProfiling());
295
296
const rootID = store.roots[0];
@@ -244,19 +357,13 @@ describe('ProfilingCache', () => {
357
}
358
}
359
247
- const container = document.createElement('div');
248
-
360
utils.act(() => store.profilerStore.startProfiling());
250
- utils.act(() => legacyRender(<LegacyContextProvider />, container));
361
+ utils.act(() => render(<LegacyContextProvider />));
362
expect(instance).not.toBeNull();
363
utils.act(() => (instance: any).setState({count: 1}));
253
- utils.act(() =>
254
- legacyRender(<LegacyContextProvider foo={123} />, container),
255
- );
256
- utils.act(() =>
257
- legacyRender(<LegacyContextProvider bar="abc" />, container),
258
- );
259
- utils.act(() => legacyRender(<LegacyContextProvider />, container));
364
+ utils.act(() => render(<LegacyContextProvider foo={123} />));
365
+ utils.act(() => render(<LegacyContextProvider bar="abc" />));
366
+ utils.act(() => render(<LegacyContextProvider />));
367
utils.act(() => store.profilerStore.stopProfiling());
368
369
const rootID = store.roots[0];
@@ -574,25 +681,21 @@ describe('ProfilingCache', () => {
681
return null;
682
};
683
577
- const container = document.createElement('div');
578
-
684
utils.act(() => store.profilerStore.startProfiling());
685
utils.act(() =>
581
- legacyRender(
686
+ render(
687
<Context.Provider value={true}>
688
<Component count={1} />
689
</Context.Provider>,
585
- container,
690
),
691
);
692
693
// Second render has no changed hooks, only changed props.
694
utils.act(() =>
591
- legacyRender(
695
+ render(
696
<Context.Provider value={true}>
697
<Component count={2} />
698
</Context.Provider>,
595
- container,
699
),
700
);
701
@@ -604,11 +707,10 @@ describe('ProfilingCache', () => {
707
708
// Fifth render has a changed context value, but no changed hook.
709
utils.act(() =>
607
- legacyRender(
710
+ render(
711
<Context.Provider value={false}>
712
<Component count={2} />
713
</Context.Provider>,
611
- container,
714
),
715
);
716
@@ -754,9 +856,7 @@ describe('ProfilingCache', () => {
856
};
857
858
utils.act(() => store.profilerStore.startProfiling());
757
- utils.act(() =>
758
- legacyRender(<Grandparent />, document.createElement('div')),
759
- );
859
+ utils.act(() => render(<Grandparent />));
860
utils.act(() => store.profilerStore.stopProfiling());
861
862
expect(store).toMatchInlineSnapshot(`
@@ -822,9 +922,7 @@ describe('ProfilingCache', () => {
922
};
923
924
utils.act(() => store.profilerStore.startProfiling());
825
- await utils.actAsync(() =>
826
- legacyRender(<Parent />, document.createElement('div')),
827
- );
925
+ await utils.actAsync(() => render(<Parent />));
926
utils.act(() => store.profilerStore.stopProfiling());
927
928
const rootID = store.roots[0];
@@ -880,12 +978,10 @@ describe('ProfilingCache', () => {
978
};
979
const MemoizedChild = React.memo(Child);
980
883
- const container = document.createElement('div');
884
-
981
utils.act(() => store.profilerStore.startProfiling());
886
- utils.act(() => legacyRender(<Parent count={1} />, container));
887
- utils.act(() => legacyRender(<Parent count={2} />, container));
888
- utils.act(() => legacyRender(<Parent count={3} />, container));
982
+ utils.act(() => render(<Parent count={1} />));
983
+ utils.act(() => render(<Parent count={2} />));
984
+ utils.act(() => render(<Parent count={3} />));
985
utils.act(() => store.profilerStore.stopProfiling());
986
987
const rootID = store.roots[0];
@@ -940,11 +1036,11 @@ describe('ProfilingCache', () => {
1036
1037
// @reactVersion >= 18.0.0
1038
// @reactVersion <= 18.2.0
943
- it('should handle unexpectedly shallow suspense trees for react v[18.0.0 - 18.2.0]', () => {
944
- const container = document.createElement('div');
945
-
1039
+ it('should handle unexpectedly shallow suspense trees for react v[18.0.0 - 18.2.0] (legacy render)', () => {
1040
utils.act(() => store.profilerStore.startProfiling());
947
- utils.act(() => legacyRender(<React.Suspense />, container));
1041
+ utils.act(() =>
1042
+ legacyRender(<React.Suspense />, document.createElement('div')),
1043
+ );
1044
utils.act(() => store.profilerStore.stopProfiling());
1045
1046
const rootID = store.roots[0];
@@ -981,13 +1077,51 @@ describe('ProfilingCache', () => {
1077
`);
1078
});
1079
984
- // This test is not gated.
985
- // For this test we use the current version of react, built from source.
986
- it('should handle unexpectedly shallow suspense trees', () => {
987
- const container = document.createElement('div');
1080
+ // @reactVersion >= 18.0.0
1081
+ // @reactVersion <= 18.2.0
1082
+ it('should handle unexpectedly shallow suspense trees for react v[18.0.0 - 18.2.0] (createRoot)', () => {
1083
+ utils.act(() => store.profilerStore.startProfiling());
1084
+ utils.act(() => render(<React.Suspense />));
1085
+ utils.act(() => store.profilerStore.stopProfiling());
1086
1087
+ const rootID = store.roots[0];
1088
+ const commitData = store.profilerStore.getDataForRoot(rootID).commitData;
1089
+ expect(commitData).toMatchInlineSnapshot(`
1090
+ [
1091
+ {
1092
+ "changeDescriptions": Map {},
1093
+ "duration": 0,
1094
+ "effectDuration": null,
1095
+ "fiberActualDurations": Map {
1096
+ 1 => 0,
1097
+ 2 => 0,
1098
+ },
1099
+ "fiberSelfDurations": Map {
1100
+ 1 => 0,
1101
+ 2 => 0,
1102
+ },
1103
+ "passiveEffectDuration": null,
1104
+ "priorityLevel": "Normal",
1105
+ "timestamp": 0,
1106
+ "updaters": [
1107
+ {
1108
+ "compiledWithForget": false,
1109
+ "displayName": "createRoot()",
1110
+ "hocDisplayNames": null,
1111
+ "id": 1,
1112
+ "key": null,
1113
+ "type": 11,
1114
+ },
1115
+ ],
1116
+ },
1117
+ ]
1118
+ `);
1119
+ });
1120
+
1121
+ // @reactVersion > 18.2.0
1122
+ it('should handle unexpectedly shallow suspense trees', () => {
1123
utils.act(() => store.profilerStore.startProfiling());
990
- utils.act(() => legacyRender(<React.Suspense />, container));
1124
+ utils.act(() => render(<React.Suspense />));
1125
utils.act(() => store.profilerStore.stopProfiling());
1126
1127
const rootID = store.roots[0];
@@ -1012,7 +1146,7 @@ describe('ProfilingCache', () => {
1146
"updaters": [
1147
{
1148
"compiledWithForget": false,
1015
- "displayName": "render()",
1149
+ "displayName": "createRoot()",
1150
"hocDisplayNames": null,
1151
"id": 1,
1152
"key": null,
@@ -1105,13 +1239,12 @@ describe('ProfilingCache', () => {
1239
1240
const {Simulate} = require('react-dom/test-utils');
1241
1108
- const container = document.createElement('div');
1109
- utils.act(() => legacyRender(<App />, container));
1110
- expect(container.textContent).toBe('Home');
1242
+ utils.act(() => render(<App />));
1243
+ expect(getContainer().textContent).toBe('Home');
1244
utils.act(() => store.profilerStore.startProfiling());
1245
utils.act(() => Simulate.click(linkRef.current));
1246
utils.act(() => store.profilerStore.stopProfiling());
1114
- expect(container.textContent).toBe('About');
1247
+ expect(getContainer().textContent).toBe('About');
1248
});
1249
1250
// @reactVersion >= 18.0