@samitouri / QOS-React-2 / commits / 1c49a7ef59

Added remaining profiling tests. One currently fails because of a bug with act() and interaction tracing

Brian Vaughn committed May 4, 2019 at 14:22 UTC 1c49a7ef59f5e35b11d7418fee163a6d93a0856a
2 files changed +218 -107
src/__tests__/__snapshots__/profiling-test.js.snap
+87 -50
@@ -1,33 +1,6 @@
1 // Jest Snapshot v1, https://goo.gl/fbAQLP
2
3 -exports[`profiling commitDetails should be collected for each commit: 1: mount 1`] = `
4 -[root]
5 - ▾ <Parent key="A">
6 - <Child key="0">
7 - <Child key="1">
8 -`;
9 -
10 -exports[`profiling commitDetails should be collected for each commit: 2: add child 1`] = `
11 -[root]
12 - ▾ <Parent key="A">
13 - <Child key="0">
14 - <Child key="1">
15 - <Child key="2">
16 -`;
17 -
18 -exports[`profiling commitDetails should be collected for each commit: 3: remove children 1`] = `
19 -[root]
20 - ▾ <Parent key="A">
21 - <Child key="0">
22 -`;
23 -
24 -exports[`profiling commitDetails should be collected for each commit: 4: profiling stopped 1`] = `
25 -[root]
26 - ▾ <Parent key="A">
27 - <Child key="0">
28 -`;
29 -
30 -exports[`profiling commitDetails should be collected for each commit: 5: CommitDetails: mount 1`] = `
3 +exports[`profiling CommitDetails should be collected for each commit: CommitDetails commitIndex: 0 1`] = `
4 Object {
5 "actualDurations": Map {
6 1 => 14,
@@ -41,7 +14,7 @@ Object {
14 }
15 `;
16
44 -exports[`profiling commitDetails should be collected for each commit: 6: CommitDetails: add child 1`] = `
17 +exports[`profiling CommitDetails should be collected for each commit: CommitDetails commitIndex: 1 1`] = `
18 Object {
19 "actualDurations": Map {
20 3 => 2,
@@ -56,7 +29,7 @@ Object {
29 }
30 `;
31
59 -exports[`profiling commitDetails should be collected for each commit: 7: CommitDetails: remove children 1`] = `
32 +exports[`profiling CommitDetails should be collected for each commit: CommitDetails commitIndex: 2 1`] = `
33 Object {
34 "actualDurations": Map {
35 3 => 2,
@@ -69,42 +42,106 @@ Object {
42 }
43 `;
44
72 -exports[`profiling profilingSummary should be collected for each commit: 1: mount 1`] = `
73 -[root]
74 - ▾ <Parent key="A">
75 - <Child key="0">
76 - <Child key="1">
45 +exports[`profiling CommitDetails should be collected for each commit: CommitDetails commitIndex: 3 1`] = `
46 +Object {
47 + "actualDurations": Map {
48 + 2 => 10,
49 + 1 => 10,
50 + },
51 + "commitIndex": 3,
52 + "interactions": Array [],
53 + "rootID": 1,
54 +}
55 +`;
56 +
57 +exports[`profiling FiberCommits should be collected for each rendered fiber: FiberCommits: element 2 1`] = `
58 +Object {
59 + "commitDurations": Array [
60 + 0,
61 + 12,
62 + 1,
63 + 14,
64 + 2,
65 + 16,
66 + ],
67 + "fiberID": 2,
68 + "rootID": 1,
69 +}
70 +`;
71 +
72 +exports[`profiling FiberCommits should be collected for each rendered fiber: FiberCommits: element 3 1`] = `
73 +Object {
74 + "commitDurations": Array [
75 + 0,
76 + 2,
77 + 1,
78 + 2,
79 + 2,
80 + 2,
81 + ],
82 + "fiberID": 3,
83 + "rootID": 1,
84 +}
85 `;
86
79 -exports[`profiling profilingSummary should be collected for each commit: 2: add child 1`] = `
80 -[root]
81 - ▾ <Parent key="A">
82 - <Child key="0">
83 - <Child key="1">
84 - <Child key="2">
87 +exports[`profiling FiberCommits should be collected for each rendered fiber: FiberCommits: element 4 1`] = `
88 +Object {
89 + "commitDurations": Array [
90 + 1,
91 + 2,
92 + 2,
93 + 2,
94 + ],
95 + "fiberID": 4,
96 + "rootID": 1,
97 +}
98 `;
99
87 -exports[`profiling profilingSummary should be collected for each commit: 3: remove children 1`] = `
88 -[root]
89 - ▾ <Parent key="A">
90 - <Child key="0">
100 +exports[`profiling FiberCommits should be collected for each rendered fiber: FiberCommits: element 5 1`] = `
101 +Object {
102 + "commitDurations": Array [
103 + 2,
104 + 2,
105 + ],
106 + "fiberID": 5,
107 + "rootID": 1,
108 +}
109 `;
110
93 -exports[`profiling profilingSummary should be collected for each commit: 4: profiling stopped 1`] = `
94 -[root]
95 - ▾ <Parent key="A">
96 - <Child key="0">
111 +exports[`profiling Interactions should be collected for every traced interaction: Interactions 1`] = `
112 +Array [
113 + Object {
114 + "__count": 0,
115 + "commits": Array [
116 + 1,
117 + ],
118 + "id": 0,
119 + "name": "one child",
120 + "timestamp": 10,
121 + },
122 + Object {
123 + "__count": 0,
124 + "commits": Array [
125 + 2,
126 + ],
127 + "id": 1,
128 + "name": "two children",
129 + "timestamp": 22,
130 + },
131 +]
132 `;
133
99 -exports[`profiling profilingSummary should be collected for each commit: ProfilingSummary 1`] = `
134 +exports[`profiling ProfilingSummary should be collected for each commit: ProfilingSummary 1`] = `
135 Object {
136 "commitDurations": Array [
137 16,
138 12,
139 + 10,
140 ],
141 "commitTimes": Array [
142 16,
143 28,
144 + 38,
145 ],
146 "initialTreeBaseDurations": Map {
147 1 => 14,
src/__tests__/profiling-test.js
+131 -57
@@ -4,6 +4,7 @@ describe('profiling', () => {
4 let React;
5 let ReactDOM;
6 let Scheduler;
7 + let SchedulerTracing;
8 let TestRenderer;
9 let store;
10 let utils;
@@ -18,10 +19,11 @@ describe('profiling', () => {
19 React = require('react');
20 ReactDOM = require('react-dom');
21 Scheduler = require('scheduler');
22 + SchedulerTracing = require('scheduler/tracing');
23 TestRenderer = utils.requireTestRenderer();
24 });
25
24 - describe('profilingSummary', () => {
26 + describe('ProfilingSummary', () => {
27 it('should be collected for each commit', async done => {
28 const Parent = ({ count }) => {
29 Scheduler.advanceTime(10);
@@ -36,26 +38,19 @@ describe('profiling', () => {
38
39 const container = document.createElement('div');
40
39 - utils.act(() => ReactDOM.render(<Parent key="A" count={2} />, container));
40 - expect(store).toMatchSnapshot('1: mount');
41 -
41 + utils.act(() => ReactDOM.render(<Parent count={2} />, container));
42 utils.act(() => store.startProfiling());
43 -
44 - utils.act(() => ReactDOM.render(<Parent key="A" count={3} />, container));
45 - expect(store).toMatchSnapshot('2: add child');
46 -
47 - utils.act(() => ReactDOM.render(<Parent key="A" count={1} />, container));
48 - expect(store).toMatchSnapshot('3: remove children');
49 -
43 + utils.act(() => ReactDOM.render(<Parent count={3} />, container));
44 + utils.act(() => ReactDOM.render(<Parent count={1} />, container));
45 + utils.act(() => ReactDOM.render(<Parent count={0} />, container));
46 utils.act(() => store.stopProfiling());
51 - expect(store).toMatchSnapshot('4: profiling stopped');
47
53 - let profilingSummary;
48 function Suspender({ rendererID, rootID }) {
55 - profilingSummary = store.profilingCache.ProfilingSummary.read({
49 + const profilingSummary = store.profilingCache.ProfilingSummary.read({
50 rendererID,
51 rootID,
52 });
53 + expect(profilingSummary).toMatchSnapshot('ProfilingSummary');
54 return null;
55 }
56
@@ -70,13 +65,11 @@ describe('profiling', () => {
65 )
66 );
67
73 - expect(profilingSummary).toMatchSnapshot('ProfilingSummary');
74 -
68 done();
69 });
70 });
71
79 - describe('commitDetails', () => {
72 + describe('CommitDetails', () => {
73 it('should be collected for each commit', async done => {
74 const Parent = ({ count }) => {
75 Scheduler.advanceTime(10);
@@ -92,72 +85,153 @@ describe('profiling', () => {
85 const container = document.createElement('div');
86
87 utils.act(() => store.startProfiling());
88 + utils.act(() => ReactDOM.render(<Parent count={2} />, container));
89 + utils.act(() => ReactDOM.render(<Parent count={3} />, container));
90 + utils.act(() => ReactDOM.render(<Parent count={1} />, container));
91 + utils.act(() => ReactDOM.render(<Parent count={0} />, container));
92 + utils.act(() => store.stopProfiling());
93 +
94 + function Suspender({ commitIndex, rendererID, rootID }) {
95 + const commitDetails = store.profilingCache.CommitDetails.read({
96 + commitIndex,
97 + rendererID,
98 + rootID,
99 + });
100 + expect(commitDetails).toMatchSnapshot(
101 + `CommitDetails commitIndex: ${commitIndex}`
102 + );
103 + return null;
104 + }
105
96 - utils.act(() => ReactDOM.render(<Parent key="A" count={2} />, container));
97 - expect(store).toMatchSnapshot('1: mount');
106 + const rendererID = utils.getRendererID();
107 + const rootID = store.roots[0];
108
99 - utils.act(() => ReactDOM.render(<Parent key="A" count={3} />, container));
100 - expect(store).toMatchSnapshot('2: add child');
109 + for (let commitIndex = 0; commitIndex <= 3; commitIndex++) {
110 + await utils.actSuspense(() =>
111 + TestRenderer.create(
112 + <React.Suspense fallback={null}>
113 + <Suspender
114 + commitIndex={commitIndex}
115 + rendererID={rendererID}
116 + rootID={rootID}
117 + />
118 + </React.Suspense>
119 + )
120 + );
121 + }
122
102 - utils.act(() => ReactDOM.render(<Parent key="A" count={1} />, container));
103 - expect(store).toMatchSnapshot('3: remove children');
123 + done();
124 + });
125 + });
126
127 + describe('FiberCommits', () => {
128 + it('should be collected for each rendered fiber', async done => {
129 + const Parent = ({ count }) => {
130 + Scheduler.advanceTime(10);
131 + return new Array(count)
132 + .fill(true)
133 + .map((_, index) => <Child key={index} />);
134 + };
135 + const Child = () => {
136 + Scheduler.advanceTime(2);
137 + return null;
138 + };
139 +
140 + const container = document.createElement('div');
141 +
142 + utils.act(() => store.startProfiling());
143 + utils.act(() => ReactDOM.render(<Parent count={1} />, container));
144 + utils.act(() => ReactDOM.render(<Parent count={2} />, container));
145 + utils.act(() => ReactDOM.render(<Parent count={3} />, container));
146 utils.act(() => store.stopProfiling());
106 - expect(store).toMatchSnapshot('4: profiling stopped');
147
108 - let commitDetails;
109 - function Suspender({ commitIndex, rendererID, rootID }) {
110 - commitDetails = store.profilingCache.CommitDetails.read({
111 - commitIndex,
148 + function Suspender({ fiberID, rendererID, rootID }) {
149 + const fiberCommits = store.profilingCache.FiberCommits.read({
150 + fiberID,
151 rendererID,
152 rootID,
153 });
154 + expect(fiberCommits).toMatchSnapshot(
155 + `FiberCommits: element ${fiberID}`
156 + );
157 return null;
158 }
159
160 const rendererID = utils.getRendererID();
161 const rootID = store.roots[0];
162
121 - await utils.actSuspense(() =>
122 - TestRenderer.create(
123 - <React.Suspense fallback={null}>
124 - <Suspender
125 - commitIndex={0}
126 - rendererID={rendererID}
127 - rootID={rootID}
128 - />
129 - </React.Suspense>
163 + for (let index = 0; index < store.numElements; index++) {
164 + await utils.actSuspense(() =>
165 + TestRenderer.create(
166 + <React.Suspense fallback={null}>
167 + <Suspender
168 + fiberID={store.getElementIDAtIndex(index)}
169 + rendererID={rendererID}
170 + rootID={rootID}
171 + />
172 + </React.Suspense>
173 + )
174 + );
175 + }
176 +
177 + done();
178 + });
179 + });
180 +
181 + describe('Interactions', () => {
182 + it('should be collected for every traced interaction', async done => {
183 + const Parent = ({ count }) => {
184 + Scheduler.advanceTime(10);
185 + return new Array(count)
186 + .fill(true)
187 + .map((_, index) => <Child key={index} />);
188 + };
189 + const Child = () => {
190 + Scheduler.advanceTime(2);
191 + return null;
192 + };
193 +
194 + const container = document.createElement('div');
195 +
196 + utils.act(() => store.startProfiling());
197 + console.log('[test] render one');
198 + utils.act(() =>
199 + SchedulerTracing.unstable_trace(
200 + 'one child',
201 + Scheduler.unstable_now(),
202 + () => ReactDOM.render(<Parent count={1} />, container)
203 )
204 );
132 - expect(commitDetails).toMatchSnapshot('5: CommitDetails: mount');
133 -
134 - await utils.actSuspense(() =>
135 - TestRenderer.create(
136 - <React.Suspense fallback={null}>
137 - <Suspender
138 - commitIndex={1}
139 - rendererID={rendererID}
140 - rootID={rootID}
141 - />
142 - </React.Suspense>
205 + console.log('[test] render two');
206 + utils.act(() =>
207 + SchedulerTracing.unstable_trace(
208 + 'two children',
209 + Scheduler.unstable_now(),
210 + () => ReactDOM.render(<Parent count={2} />, container)
211 )
212 );
145 - expect(commitDetails).toMatchSnapshot('6: CommitDetails: add child');
213 + console.log('[test] done');
214 + utils.act(() => store.stopProfiling());
215 +
216 + function Suspender({ rendererID, rootID }) {
217 + const interactions = store.profilingCache.Interactions.read({
218 + rendererID,
219 + rootID,
220 + });
221 + expect(interactions).toMatchSnapshot('Interactions');
222 + return null;
223 + }
224 +
225 + const rendererID = utils.getRendererID();
226 + const rootID = store.roots[0];
227
228 await utils.actSuspense(() =>
229 TestRenderer.create(
230 <React.Suspense fallback={null}>
150 - <Suspender
151 - commitIndex={2}
152 - rendererID={rendererID}
153 - rootID={rootID}
154 - />
231 + <Suspender rendererID={rendererID} rootID={rootID} />
232 </React.Suspense>
233 )
234 );
158 - expect(commitDetails).toMatchSnapshot(
159 - '7: CommitDetails: remove children'
160 - );
235
236 done();
237 });