chore: use versioned render in profilingCommitTreeBuilder test and gate some for legacy rendering (#28236)
Ruslan Lesiutin committed
Feb 6, 2024 at 12:26 UTC
103cddbb9d433b08622c43336b170ffc63acdee3
2 files changed
+88
-32
packages/react-devtools-shared/src/__tests__/profilingCommitTreeBuilder-test.js
+84
-31
@@ -9,11 +9,14 @@
9
10
import type Store from 'react-devtools-shared/src/devtools/store';
11
12
+import {
13
+ getLegacyRenderImplementation,
14
+ getModernRenderImplementation,
15
+} from './utils';
16
+
17
describe('commit tree', () => {
18
let React;
14
- let ReactDOMClient;
19
let Scheduler;
16
- let legacyRender;
20
let store: Store;
21
let utils;
22
@@ -21,19 +24,20 @@ describe('commit tree', () => {
24
utils = require('./utils');
25
utils.beforeEachProfiling();
26
24
- legacyRender = utils.legacyRender;
25
-
27
store = global.store;
28
store.collapseNodesByDefault = false;
29
store.recordChangeDescriptions = true;
30
31
React = require('react');
31
- ReactDOMClient = require('react-dom/client');
32
Scheduler = require('scheduler');
33
});
34
35
+ const {render: legacyRender} = getLegacyRenderImplementation();
36
+ const {render: modernRender} = getModernRenderImplementation();
37
+
38
// @reactVersion >= 16.9
36
- it('should be able to rebuild the store tree for each commit', () => {
39
+ // @reactVersion <= 18.2
40
+ it('should be able to rebuild the store tree for each commit (legacy render)', () => {
41
const Parent = ({count}) => {
42
Scheduler.unstable_advanceTime(10);
43
return new Array(count)
@@ -45,16 +49,73 @@ describe('commit tree', () => {
49
return null;
50
});
51
48
- const container = document.createElement('div');
52
+ utils.act(() => store.profilerStore.startProfiling());
53
+ utils.act(() => legacyRender(<Parent count={1} />));
54
+ expect(store).toMatchInlineSnapshot(`
55
+ [root]
56
+ ▾ <Parent>
57
+ <Child key="0"> [Memo]
58
+ `);
59
+ utils.act(() => legacyRender(<Parent count={3} />));
60
+ expect(store).toMatchInlineSnapshot(`
61
+ [root]
62
+ ▾ <Parent>
63
+ <Child key="0"> [Memo]
64
+ <Child key="1"> [Memo]
65
+ <Child key="2"> [Memo]
66
+ `);
67
+ utils.act(() => legacyRender(<Parent count={2} />));
68
+ expect(store).toMatchInlineSnapshot(`
69
+ [root]
70
+ ▾ <Parent>
71
+ <Child key="0"> [Memo]
72
+ <Child key="1"> [Memo]
73
+ `);
74
+ utils.act(() => legacyRender(<Parent count={0} />));
75
+ expect(store).toMatchInlineSnapshot(`
76
+ [root]
77
+ <Parent>
78
+ `);
79
+ utils.act(() => store.profilerStore.stopProfiling());
80
+
81
+ const rootID = store.roots[0];
82
+ const commitTrees = [];
83
+ for (let commitIndex = 0; commitIndex < 4; commitIndex++) {
84
+ commitTrees.push(
85
+ store.profilerStore.profilingCache.getCommitTree({
86
+ commitIndex,
87
+ rootID,
88
+ }),
89
+ );
90
+ }
91
+
92
+ expect(commitTrees[0].nodes.size).toBe(3); // <Root> + <Parent> + <Child>
93
+ expect(commitTrees[1].nodes.size).toBe(5); // <Root> + <Parent> + <Child> x 3
94
+ expect(commitTrees[2].nodes.size).toBe(4); // <Root> + <Parent> + <Child> x 2
95
+ expect(commitTrees[3].nodes.size).toBe(2); // <Root> + <Parent>
96
+ });
97
+
98
+ // @reactVersion >= 18
99
+ it('should be able to rebuild the store tree for each commit (createRoot)', () => {
100
+ const Parent = ({count}) => {
101
+ Scheduler.unstable_advanceTime(10);
102
+ return new Array(count)
103
+ .fill(true)
104
+ .map((_, index) => <Child key={index} />);
105
+ };
106
+ const Child = React.memo(function Child() {
107
+ Scheduler.unstable_advanceTime(2);
108
+ return null;
109
+ });
110
111
utils.act(() => store.profilerStore.startProfiling());
51
- utils.act(() => legacyRender(<Parent count={1} />, container));
112
+ utils.act(() => modernRender(<Parent count={1} />));
113
expect(store).toMatchInlineSnapshot(`
114
[root]
115
▾ <Parent>
116
<Child key="0"> [Memo]
117
`);
57
- utils.act(() => legacyRender(<Parent count={3} />, container));
118
+ utils.act(() => modernRender(<Parent count={3} />));
119
expect(store).toMatchInlineSnapshot(`
120
[root]
121
▾ <Parent>
@@ -62,14 +123,14 @@ describe('commit tree', () => {
123
<Child key="1"> [Memo]
124
<Child key="2"> [Memo]
125
`);
65
- utils.act(() => legacyRender(<Parent count={2} />, container));
126
+ utils.act(() => modernRender(<Parent count={2} />));
127
expect(store).toMatchInlineSnapshot(`
128
[root]
129
▾ <Parent>
130
<Child key="0"> [Memo]
131
<Child key="1"> [Memo]
132
`);
72
- utils.act(() => legacyRender(<Parent count={0} />, container));
133
+ utils.act(() => modernRender(<Parent count={0} />));
134
expect(store).toMatchInlineSnapshot(`
135
[root]
136
<Parent>
@@ -118,25 +179,24 @@ describe('commit tree', () => {
179
});
180
181
// @reactVersion >= 16.9
182
+ // @reactVersion <= 18.2
183
it('should support Lazy components (legacy render)', async () => {
122
- const container = document.createElement('div');
123
-
184
utils.act(() => store.profilerStore.startProfiling());
125
- utils.act(() => legacyRender(<App renderChildren={true} />, container));
185
+ utils.act(() => legacyRender(<App renderChildren={true} />));
186
await Promise.resolve();
187
expect(store).toMatchInlineSnapshot(`
188
[root]
189
▾ <App>
190
<Suspense>
191
`);
132
- utils.act(() => legacyRender(<App renderChildren={true} />, container));
192
+ utils.act(() => legacyRender(<App renderChildren={true} />));
193
expect(store).toMatchInlineSnapshot(`
194
[root]
195
▾ <App>
196
▾ <Suspense>
197
<LazyInnerComponent>
198
`);
139
- utils.act(() => legacyRender(<App renderChildren={false} />, container));
199
+ utils.act(() => legacyRender(<App renderChildren={false} />));
200
expect(store).toMatchInlineSnapshot(`
201
[root]
202
<App>
@@ -161,25 +221,22 @@ describe('commit tree', () => {
221
222
// @reactVersion >= 18.0
223
it('should support Lazy components (createRoot)', async () => {
164
- const container = document.createElement('div');
165
- const root = ReactDOMClient.createRoot(container);
166
-
224
utils.act(() => store.profilerStore.startProfiling());
168
- utils.act(() => root.render(<App renderChildren={true} />));
225
+ utils.act(() => modernRender(<App renderChildren={true} />));
226
await Promise.resolve();
227
expect(store).toMatchInlineSnapshot(`
228
[root]
229
▾ <App>
230
<Suspense>
231
`);
175
- utils.act(() => root.render(<App renderChildren={true} />));
232
+ utils.act(() => modernRender(<App renderChildren={true} />));
233
expect(store).toMatchInlineSnapshot(`
234
[root]
235
▾ <App>
236
▾ <Suspense>
237
<LazyInnerComponent>
238
`);
182
- utils.act(() => root.render(<App renderChildren={false} />));
239
+ utils.act(() => modernRender(<App renderChildren={false} />));
240
expect(store).toMatchInlineSnapshot(`
241
[root]
242
<App>
@@ -203,17 +260,16 @@ describe('commit tree', () => {
260
});
261
262
// @reactVersion >= 16.9
263
+ // @reactVersion <= 18.2
264
it('should support Lazy components that are unmounted before resolving (legacy render)', async () => {
207
- const container = document.createElement('div');
208
-
265
utils.act(() => store.profilerStore.startProfiling());
210
- utils.act(() => legacyRender(<App renderChildren={true} />, container));
266
+ utils.act(() => legacyRender(<App renderChildren={true} />));
267
expect(store).toMatchInlineSnapshot(`
268
[root]
269
▾ <App>
270
<Suspense>
271
`);
216
- utils.act(() => legacyRender(<App renderChildren={false} />, container));
272
+ utils.act(() => legacyRender(<App renderChildren={false} />));
273
expect(store).toMatchInlineSnapshot(`
274
[root]
275
<App>
@@ -237,17 +293,14 @@ describe('commit tree', () => {
293
294
// @reactVersion >= 18.0
295
it('should support Lazy components that are unmounted before resolving (createRoot)', async () => {
240
- const container = document.createElement('div');
241
- const root = ReactDOMClient.createRoot(container);
242
-
296
utils.act(() => store.profilerStore.startProfiling());
244
- utils.act(() => root.render(<App renderChildren={true} />));
297
+ utils.act(() => modernRender(<App renderChildren={true} />));
298
expect(store).toMatchInlineSnapshot(`
299
[root]
300
▾ <App>
301
<Suspense>
302
`);
250
- utils.act(() => root.render(<App renderChildren={false} />));
303
+ utils.act(() => modernRender(<App renderChildren={false} />));
304
expect(store).toMatchInlineSnapshot(`
305
[root]
306
<App>
packages/react-devtools-shared/src/__tests__/utils.js
+4
-1
@@ -182,6 +182,9 @@ export function getModernRenderImplementation(): RenderImplementation {
182
});
183
184
function render(elements) {
185
+ if (root == null) {
186
+ root = ReactDOMClient.createRoot(container);
187
+ }
188
root.render(elements);
189
190
return unmount;
@@ -195,7 +198,7 @@ export function getModernRenderImplementation(): RenderImplementation {
198
container = document.createElement('div');
199
document.body.appendChild(container);
200
198
- root = ReactDOMClient.createRoot(container);
201
+ root = null;
202
203
containersToRemove.push(container);
204
}