|
9 | 9 |
|
10 | 10 | 'use strict';
|
11 | 11 |
|
| 12 | +function normalizeCodeLocInfo(str) { |
| 13 | + return ( |
| 14 | + typeof str === 'string' && |
| 15 | + str.replace(/\n +(?:at|in) ([\S]+)[^\n]*/g, function(m, name) { |
| 16 | + return '\n in ' + name + ' (at **)'; |
| 17 | + }) |
| 18 | + ); |
| 19 | +} |
| 20 | + |
12 | 21 | describe('Timeline profiler', () => {
|
13 | 22 | let React;
|
14 | 23 | let ReactDOMClient;
|
@@ -1175,6 +1184,18 @@ describe('Timeline profiler', () => {
|
1175 | 1184 | if (timelineData) {
|
1176 | 1185 | expect(timelineData).toHaveLength(1);
|
1177 | 1186 |
|
| 1187 | + // normalize the location for component stack source |
| 1188 | + // for snapshot testing |
| 1189 | + timelineData.forEach(data => { |
| 1190 | + data.schedulingEvents.forEach(event => { |
| 1191 | + if (event.componentStack) { |
| 1192 | + event.componentStack = normalizeCodeLocInfo( |
| 1193 | + event.componentStack, |
| 1194 | + ); |
| 1195 | + } |
| 1196 | + }); |
| 1197 | + }); |
| 1198 | + |
1178 | 1199 | return timelineData[0];
|
1179 | 1200 | } else {
|
1180 | 1201 | return null;
|
@@ -1256,27 +1277,35 @@ describe('Timeline profiler', () => {
|
1256 | 1277 | Array [
|
1257 | 1278 | Object {
|
1258 | 1279 | "componentName": "Example",
|
| 1280 | + "componentStack": " |
| 1281 | + in Example (at **)", |
1259 | 1282 | "lanes": "0b0000000000000000000000000000100",
|
1260 | 1283 | "timestamp": 10,
|
1261 | 1284 | "type": "schedule-state-update",
|
1262 | 1285 | "warning": null,
|
1263 | 1286 | },
|
1264 | 1287 | Object {
|
1265 | 1288 | "componentName": "Example",
|
| 1289 | + "componentStack": " |
| 1290 | + in Example (at **)", |
1266 | 1291 | "lanes": "0b0000000000000000000000001000000",
|
1267 | 1292 | "timestamp": 10,
|
1268 | 1293 | "type": "schedule-state-update",
|
1269 | 1294 | "warning": null,
|
1270 | 1295 | },
|
1271 | 1296 | Object {
|
1272 | 1297 | "componentName": "Example",
|
| 1298 | + "componentStack": " |
| 1299 | + in Example (at **)", |
1273 | 1300 | "lanes": "0b0000000000000000000000001000000",
|
1274 | 1301 | "timestamp": 10,
|
1275 | 1302 | "type": "schedule-state-update",
|
1276 | 1303 | "warning": null,
|
1277 | 1304 | },
|
1278 | 1305 | Object {
|
1279 | 1306 | "componentName": "Example",
|
| 1307 | + "componentStack": " |
| 1308 | + in Example (at **)", |
1280 | 1309 | "lanes": "0b0000000000000000000000000010000",
|
1281 | 1310 | "timestamp": 10,
|
1282 | 1311 | "type": "schedule-state-update",
|
@@ -1614,6 +1643,8 @@ describe('Timeline profiler', () => {
|
1614 | 1643 | },
|
1615 | 1644 | Object {
|
1616 | 1645 | "componentName": "Example",
|
| 1646 | + "componentStack": " |
| 1647 | + in Example (at **)", |
1617 | 1648 | "lanes": "0b0000000000000000000000000000001",
|
1618 | 1649 | "timestamp": 20,
|
1619 | 1650 | "type": "schedule-state-update",
|
@@ -1741,6 +1772,8 @@ describe('Timeline profiler', () => {
|
1741 | 1772 | },
|
1742 | 1773 | Object {
|
1743 | 1774 | "componentName": "Example",
|
| 1775 | + "componentStack": " |
| 1776 | + in Example (at **)", |
1744 | 1777 | "lanes": "0b0000000000000000000000000010000",
|
1745 | 1778 | "timestamp": 10,
|
1746 | 1779 | "type": "schedule-state-update",
|
@@ -1872,6 +1905,8 @@ describe('Timeline profiler', () => {
|
1872 | 1905 | },
|
1873 | 1906 | Object {
|
1874 | 1907 | "componentName": "Example",
|
| 1908 | + "componentStack": " |
| 1909 | + in Example (at **)", |
1875 | 1910 | "lanes": "0b0000000000000000000000000000001",
|
1876 | 1911 | "timestamp": 21,
|
1877 | 1912 | "type": "schedule-state-update",
|
@@ -1934,6 +1969,8 @@ describe('Timeline profiler', () => {
|
1934 | 1969 | },
|
1935 | 1970 | Object {
|
1936 | 1971 | "componentName": "Example",
|
| 1972 | + "componentStack": " |
| 1973 | + in Example (at **)", |
1937 | 1974 | "lanes": "0b0000000000000000000000000010000",
|
1938 | 1975 | "timestamp": 21,
|
1939 | 1976 | "type": "schedule-state-update",
|
@@ -1982,6 +2019,8 @@ describe('Timeline profiler', () => {
|
1982 | 2019 | },
|
1983 | 2020 | Object {
|
1984 | 2021 | "componentName": "Example",
|
| 2022 | + "componentStack": " |
| 2023 | + in Example (at **)", |
1985 | 2024 | "lanes": "0b0000000000000000000000000010000",
|
1986 | 2025 | "timestamp": 20,
|
1987 | 2026 | "type": "schedule-state-update",
|
@@ -2065,6 +2104,8 @@ describe('Timeline profiler', () => {
|
2065 | 2104 | },
|
2066 | 2105 | Object {
|
2067 | 2106 | "componentName": "ErrorBoundary",
|
| 2107 | + "componentStack": " |
| 2108 | + in ErrorBoundary (at **)", |
2068 | 2109 | "lanes": "0b0000000000000000000000000000001",
|
2069 | 2110 | "timestamp": 20,
|
2070 | 2111 | "type": "schedule-state-update",
|
@@ -2177,6 +2218,8 @@ describe('Timeline profiler', () => {
|
2177 | 2218 | },
|
2178 | 2219 | Object {
|
2179 | 2220 | "componentName": "ErrorBoundary",
|
| 2221 | + "componentStack": " |
| 2222 | + in ErrorBoundary (at **)", |
2180 | 2223 | "lanes": "0b0000000000000000000000000000001",
|
2181 | 2224 | "timestamp": 30,
|
2182 | 2225 | "type": "schedule-state-update",
|
@@ -2441,6 +2484,52 @@ describe('Timeline profiler', () => {
|
2441 | 2484 | }
|
2442 | 2485 | `);
|
2443 | 2486 | });
|
| 2487 | + |
| 2488 | + it('should generate component stacks for state update', async () => { |
| 2489 | + function CommponentWithChildren({initialRender}) { |
| 2490 | + Scheduler.unstable_yieldValue('Render ComponentWithChildren'); |
| 2491 | + return <Child initialRender={initialRender} />; |
| 2492 | + } |
| 2493 | + |
| 2494 | + function Child({initialRender}) { |
| 2495 | + const [didRender, setDidRender] = React.useState(initialRender); |
| 2496 | + if (!didRender) { |
| 2497 | + setDidRender(true); |
| 2498 | + } |
| 2499 | + Scheduler.unstable_yieldValue('Render Child'); |
| 2500 | + return null; |
| 2501 | + } |
| 2502 | + |
| 2503 | + renderRootHelper(<CommponentWithChildren initialRender={false} />); |
| 2504 | + |
| 2505 | + expect(Scheduler).toFlushAndYield([ |
| 2506 | + 'Render ComponentWithChildren', |
| 2507 | + 'Render Child', |
| 2508 | + 'Render Child', |
| 2509 | + ]); |
| 2510 | + |
| 2511 | + const timelineData = stopProfilingAndGetTimelineData(); |
| 2512 | + expect(timelineData.schedulingEvents).toMatchInlineSnapshot(` |
| 2513 | + Array [ |
| 2514 | + Object { |
| 2515 | + "lanes": "0b0000000000000000000000000010000", |
| 2516 | + "timestamp": 10, |
| 2517 | + "type": "schedule-render", |
| 2518 | + "warning": null, |
| 2519 | + }, |
| 2520 | + Object { |
| 2521 | + "componentName": "Child", |
| 2522 | + "componentStack": " |
| 2523 | + in Child (at **) |
| 2524 | + in CommponentWithChildren (at **)", |
| 2525 | + "lanes": "0b0000000000000000000000000010000", |
| 2526 | + "timestamp": 10, |
| 2527 | + "type": "schedule-state-update", |
| 2528 | + "warning": null, |
| 2529 | + }, |
| 2530 | + ] |
| 2531 | + `); |
| 2532 | + }); |
2444 | 2533 | });
|
2445 | 2534 |
|
2446 | 2535 | describe('when not profiling', () => {
|
|
0 commit comments