@samitouri / QOS-React-1 / commits / 103cddbb9d

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 }