@samitouri / QOS-React / commits / f0e808e5bc

[Debug Tools] Always use includeHooksSource option (#28309)

This option was added defensively but it's not needed. There's no cost to including it always. I suspect this optional was added mainly to avoid needing to update tests. That's not a reason to have an unnecessary public API though. We have a praxis for dealing with source location in tests to avoid them failing tests. I also ported them to inline snapshots so that additions to the protocol isn't such a pain.

Sebastian Markbåge committed Feb 14, 2024 at 11:07 UTC f0e808e5bcbfdaa24a8a0893cd718f4d189f2369
5 files changed +2096 -979
packages/react-debug-tools/src/ReactDebugHooks.js
+22 -31
@@ -569,7 +569,7 @@ export type HooksNode = {
569 value: mixed,
570 subHooks: Array<HooksNode>,
571 debugInfo: null | ReactDebugInfo,
572 - hookSource?: HookSource,
572 + hookSource: null | HookSource,
573 };
574 export type HooksTree = Array<HooksNode>;
575
@@ -716,7 +716,6 @@ function parseCustomHookName(functionName: void | string): string {
716 function buildTree(
717 rootStack: any,
718 readHookLog: Array<HookLogEntry>,
719 - includeHooksSource: boolean,
719 ): HooksTree {
720 const rootChildren: Array<HooksNode> = [];
721 let prevStack = null;
@@ -760,16 +759,13 @@ function buildTree(
759 value: undefined,
760 subHooks: children,
761 debugInfo: null,
763 - };
764 -
765 - if (includeHooksSource) {
766 - levelChild.hookSource = {
762 + hookSource: {
763 lineNumber: stackFrame.lineNumber,
764 columnNumber: stackFrame.columnNumber,
765 functionName: stackFrame.functionName,
766 fileName: stackFrame.fileName,
771 - };
772 - }
767 + },
768 + };
769
770 levelChildren.push(levelChild);
771 stackOfChildren.push(levelChildren);
@@ -800,26 +796,25 @@ function buildTree(
796 value: hook.value,
797 subHooks: [],
798 debugInfo: debugInfo,
799 + hookSource: null,
800 };
801
805 - if (includeHooksSource) {
806 - const hookSource: HookSource = {
807 - lineNumber: null,
808 - functionName: null,
809 - fileName: null,
810 - columnNumber: null,
811 - };
812 - if (stack && stack.length >= 1) {
813 - const stackFrame = stack[0];
814 - hookSource.lineNumber = stackFrame.lineNumber;
815 - hookSource.functionName = stackFrame.functionName;
816 - hookSource.fileName = stackFrame.fileName;
817 - hookSource.columnNumber = stackFrame.columnNumber;
818 - }
819 -
820 - levelChild.hookSource = hookSource;
802 + const hookSource: HookSource = {
803 + lineNumber: null,
804 + functionName: null,
805 + fileName: null,
806 + columnNumber: null,
807 + };
808 + if (stack && stack.length >= 1) {
809 + const stackFrame = stack[0];
810 + hookSource.lineNumber = stackFrame.lineNumber;
811 + hookSource.functionName = stackFrame.functionName;
812 + hookSource.fileName = stackFrame.fileName;
813 + hookSource.columnNumber = stackFrame.columnNumber;
814 }
815
816 + levelChild.hookSource = hookSource;
817 +
818 levelChildren.push(levelChild);
819 }
820
@@ -897,7 +892,6 @@ export function inspectHooks<Props>(
892 renderFunction: Props => React$Node,
893 props: Props,
894 currentDispatcher: ?CurrentDispatcherRef,
900 - includeHooksSource: boolean = false,
895 ): HooksTree {
896 // DevTools will pass the current renderer's injected dispatcher.
897 // Other apps might compile debug hooks as part of their app though.
@@ -923,7 +917,7 @@ export function inspectHooks<Props>(
917 currentDispatcher.current = previousDispatcher;
918 }
919 const rootStack = ErrorStackParser.parse(ancestorStackError);
926 - return buildTree(rootStack, readHookLog, includeHooksSource);
920 + return buildTree(rootStack, readHookLog);
921 }
922
923 function setupContexts(contextMap: Map<ReactContext<any>, any>, fiber: Fiber) {
@@ -955,7 +949,6 @@ function inspectHooksOfForwardRef<Props, Ref>(
949 props: Props,
950 ref: Ref,
951 currentDispatcher: CurrentDispatcherRef,
958 - includeHooksSource: boolean,
952 ): HooksTree {
953 const previousDispatcher = currentDispatcher.current;
954 let readHookLog;
@@ -972,7 +965,7 @@ function inspectHooksOfForwardRef<Props, Ref>(
965 currentDispatcher.current = previousDispatcher;
966 }
967 const rootStack = ErrorStackParser.parse(ancestorStackError);
975 - return buildTree(rootStack, readHookLog, includeHooksSource);
968 + return buildTree(rootStack, readHookLog);
969 }
970
971 function resolveDefaultProps(Component: any, baseProps: any) {
@@ -993,7 +986,6 @@ function resolveDefaultProps(Component: any, baseProps: any) {
986 export function inspectHooksOfFiber(
987 fiber: Fiber,
988 currentDispatcher: ?CurrentDispatcherRef,
996 - includeHooksSource: boolean = false,
989 ): HooksTree {
990 // DevTools will pass the current renderer's injected dispatcher.
991 // Other apps might compile debug hooks as part of their app though.
@@ -1035,11 +1027,10 @@ export function inspectHooksOfFiber(
1027 props,
1028 fiber.ref,
1029 currentDispatcher,
1038 - includeHooksSource,
1030 );
1031 }
1032
1042 - return inspectHooks(type, props, currentDispatcher, includeHooksSource);
1033 + return inspectHooks(type, props, currentDispatcher);
1034 } finally {
1035 currentFiber = null;
1036 currentHook = null;
packages/react-debug-tools/src/__tests__/ReactHooksInspection-test.js
+494 -228
@@ -13,6 +13,18 @@
13 let React;
14 let ReactDebugTools;
15
16 +function normalizeSourceLoc(tree) {
17 + tree.forEach(node => {
18 + if (node.hookSource) {
19 + node.hookSource.fileName = '**';
20 + node.hookSource.lineNumber = 0;
21 + node.hookSource.columnNumber = 0;
22 + }
23 + normalizeSourceLoc(node.subHooks);
24 + });
25 + return tree;
26 +}
27 +
28 describe('ReactHooksInspection', () => {
29 beforeEach(() => {
30 jest.resetModules();
@@ -26,16 +38,24 @@ describe('ReactHooksInspection', () => {
38 return <div>{state}</div>;
39 }
40 const tree = ReactDebugTools.inspectHooks(Foo, {});
29 - expect(tree).toEqual([
30 - {
31 - isStateEditable: true,
32 - id: 0,
33 - name: 'State',
34 - value: 'hello world',
35 - debugInfo: null,
36 - subHooks: [],
37 - },
38 - ]);
41 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
42 + [
43 + {
44 + "debugInfo": null,
45 + "hookSource": {
46 + "columnNumber": 0,
47 + "fileName": "**",
48 + "functionName": "Foo",
49 + "lineNumber": 0,
50 + },
51 + "id": 0,
52 + "isStateEditable": true,
53 + "name": "State",
54 + "subHooks": [],
55 + "value": "hello world",
56 + },
57 + ]
58 + `);
59 });
60
61 it('should inspect a simple custom hook', () => {
@@ -49,25 +69,75 @@ describe('ReactHooksInspection', () => {
69 return <div>{value}</div>;
70 }
71 const tree = ReactDebugTools.inspectHooks(Foo, {});
52 - expect(tree).toEqual([
53 - {
54 - isStateEditable: false,
55 - id: null,
56 - name: 'Custom',
57 - value: __DEV__ ? 'custom hook label' : undefined,
58 - debugInfo: null,
59 - subHooks: [
72 + if (__DEV__) {
73 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
74 + [
75 + {
76 + "debugInfo": null,
77 + "hookSource": {
78 + "columnNumber": 0,
79 + "fileName": "**",
80 + "functionName": "Foo",
81 + "lineNumber": 0,
82 + },
83 + "id": null,
84 + "isStateEditable": false,
85 + "name": "Custom",
86 + "subHooks": [
87 + {
88 + "debugInfo": null,
89 + "hookSource": {
90 + "columnNumber": 0,
91 + "fileName": "**",
92 + "functionName": "useCustom",
93 + "lineNumber": 0,
94 + },
95 + "id": 0,
96 + "isStateEditable": true,
97 + "name": "State",
98 + "subHooks": [],
99 + "value": "hello world",
100 + },
101 + ],
102 + "value": "custom hook label",
103 + },
104 + ]
105 + `);
106 + } else {
107 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
108 + [
109 {
61 - isStateEditable: true,
62 - id: 0,
63 - name: 'State',
64 - value: 'hello world',
65 - debugInfo: null,
66 - subHooks: [],
110 + "debugInfo": null,
111 + "hookSource": {
112 + "columnNumber": 0,
113 + "fileName": "**",
114 + "functionName": "Foo",
115 + "lineNumber": 0,
116 + },
117 + "id": null,
118 + "isStateEditable": false,
119 + "name": "Custom",
120 + "subHooks": [
121 + {
122 + "debugInfo": null,
123 + "hookSource": {
124 + "columnNumber": 0,
125 + "fileName": "**",
126 + "functionName": "useCustom",
127 + "lineNumber": 0,
128 + },
129 + "id": 0,
130 + "isStateEditable": true,
131 + "name": "State",
132 + "subHooks": [],
133 + "value": "hello world",
134 + },
135 + ],
136 + "value": undefined,
137 },
68 - ],
69 - },
70 - ]);
138 + ]
139 + `);
140 + }
141 });
142
143 it('should inspect a tree of multiple hooks', () => {
@@ -87,58 +157,96 @@ describe('ReactHooksInspection', () => {
157 );
158 }
159 const tree = ReactDebugTools.inspectHooks(Foo, {});
90 - expect(tree).toEqual([
91 - {
92 - isStateEditable: false,
93 - id: null,
94 - name: 'Custom',
95 - value: undefined,
96 - debugInfo: null,
97 - subHooks: [
98 - {
99 - isStateEditable: true,
100 - id: 0,
101 - name: 'State',
102 - debugInfo: null,
103 - subHooks: [],
104 - value: 'hello',
105 - },
106 - {
107 - isStateEditable: false,
108 - id: 1,
109 - name: 'Effect',
110 - debugInfo: null,
111 - subHooks: [],
112 - value: effect,
113 - },
114 - ],
115 - },
116 - {
117 - isStateEditable: false,
118 - id: null,
119 - name: 'Custom',
120 - value: undefined,
121 - debugInfo: null,
122 - subHooks: [
123 - {
124 - isStateEditable: true,
125 - id: 2,
126 - name: 'State',
127 - value: 'world',
128 - debugInfo: null,
129 - subHooks: [],
160 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
161 + [
162 + {
163 + "debugInfo": null,
164 + "hookSource": {
165 + "columnNumber": 0,
166 + "fileName": "**",
167 + "functionName": "Foo",
168 + "lineNumber": 0,
169 },
131 - {
132 - isStateEditable: false,
133 - id: 3,
134 - name: 'Effect',
135 - value: effect,
136 - debugInfo: null,
137 - subHooks: [],
170 + "id": null,
171 + "isStateEditable": false,
172 + "name": "Custom",
173 + "subHooks": [
174 + {
175 + "debugInfo": null,
176 + "hookSource": {
177 + "columnNumber": 0,
178 + "fileName": "**",
179 + "functionName": "useCustom",
180 + "lineNumber": 0,
181 + },
182 + "id": 0,
183 + "isStateEditable": true,
184 + "name": "State",
185 + "subHooks": [],
186 + "value": "hello",
187 + },
188 + {
189 + "debugInfo": null,
190 + "hookSource": {
191 + "columnNumber": 0,
192 + "fileName": "**",
193 + "functionName": "useCustom",
194 + "lineNumber": 0,
195 + },
196 + "id": 1,
197 + "isStateEditable": false,
198 + "name": "Effect",
199 + "subHooks": [],
200 + "value": [Function],
201 + },
202 + ],
203 + "value": undefined,
204 + },
205 + {
206 + "debugInfo": null,
207 + "hookSource": {
208 + "columnNumber": 0,
209 + "fileName": "**",
210 + "functionName": "Foo",
211 + "lineNumber": 0,
212 },
139 - ],
140 - },
141 - ]);
213 + "id": null,
214 + "isStateEditable": false,
215 + "name": "Custom",
216 + "subHooks": [
217 + {
218 + "debugInfo": null,
219 + "hookSource": {
220 + "columnNumber": 0,
221 + "fileName": "**",
222 + "functionName": "useCustom",
223 + "lineNumber": 0,
224 + },
225 + "id": 2,
226 + "isStateEditable": true,
227 + "name": "State",
228 + "subHooks": [],
229 + "value": "world",
230 + },
231 + {
232 + "debugInfo": null,
233 + "hookSource": {
234 + "columnNumber": 0,
235 + "fileName": "**",
236 + "functionName": "useCustom",
237 + "lineNumber": 0,
238 + },
239 + "id": 3,
240 + "isStateEditable": false,
241 + "name": "Effect",
242 + "subHooks": [],
243 + "value": [Function],
244 + },
245 + ],
246 + "value": undefined,
247 + },
248 + ]
249 + `);
250 });
251
252 it('should inspect a tree of multiple levels of hooks', () => {
@@ -168,92 +276,154 @@ describe('ReactHooksInspection', () => {
276 );
277 }
278 const tree = ReactDebugTools.inspectHooks(Foo, {});
171 - expect(tree).toEqual([
172 - {
173 - isStateEditable: false,
174 - id: null,
175 - name: 'Bar',
176 - value: undefined,
177 - debugInfo: null,
178 - subHooks: [
179 - {
180 - isStateEditable: false,
181 - id: null,
182 - name: 'Custom',
183 - value: undefined,
184 - debugInfo: null,
185 - subHooks: [
186 - {
187 - isStateEditable: true,
188 - id: 0,
189 - name: 'Reducer',
190 - value: 'hello',
191 - debugInfo: null,
192 - subHooks: [],
279 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
280 + [
281 + {
282 + "debugInfo": null,
283 + "hookSource": {
284 + "columnNumber": 0,
285 + "fileName": "**",
286 + "functionName": "Foo",
287 + "lineNumber": 0,
288 + },
289 + "id": null,
290 + "isStateEditable": false,
291 + "name": "Bar",
292 + "subHooks": [
293 + {
294 + "debugInfo": null,
295 + "hookSource": {
296 + "columnNumber": 0,
297 + "fileName": "**",
298 + "functionName": "useBar",
299 + "lineNumber": 0,
300 },
194 - {
195 - isStateEditable: false,
196 - id: 1,
197 - name: 'Effect',
198 - value: effect,
199 - debugInfo: null,
200 - subHooks: [],
301 + "id": null,
302 + "isStateEditable": false,
303 + "name": "Custom",
304 + "subHooks": [
305 + {
306 + "debugInfo": null,
307 + "hookSource": {
308 + "columnNumber": 0,
309 + "fileName": "**",
310 + "functionName": "useCustom",
311 + "lineNumber": 0,
312 + },
313 + "id": 0,
314 + "isStateEditable": true,
315 + "name": "Reducer",
316 + "subHooks": [],
317 + "value": "hello",
318 + },
319 + {
320 + "debugInfo": null,
321 + "hookSource": {
322 + "columnNumber": 0,
323 + "fileName": "**",
324 + "functionName": "useCustom",
325 + "lineNumber": 0,
326 + },
327 + "id": 1,
328 + "isStateEditable": false,
329 + "name": "Effect",
330 + "subHooks": [],
331 + "value": [Function],
332 + },
333 + ],
334 + "value": undefined,
335 + },
336 + {
337 + "debugInfo": null,
338 + "hookSource": {
339 + "columnNumber": 0,
340 + "fileName": "**",
341 + "functionName": "useBar",
342 + "lineNumber": 0,
343 },
202 - ],
203 - },
204 - {
205 - isStateEditable: false,
206 - id: 2,
207 - name: 'LayoutEffect',
208 - value: effect,
209 - debugInfo: null,
210 - subHooks: [],
211 - },
212 - ],
213 - },
214 - {
215 - isStateEditable: false,
216 - id: null,
217 - name: 'Baz',
218 - value: undefined,
219 - debugInfo: null,
220 - subHooks: [
221 - {
222 - isStateEditable: false,
223 - id: 3,
224 - name: 'LayoutEffect',
225 - value: effect,
226 - debugInfo: null,
227 - subHooks: [],
344 + "id": 2,
345 + "isStateEditable": false,
346 + "name": "LayoutEffect",
347 + "subHooks": [],
348 + "value": [Function],
349 + },
350 + ],
351 + "value": undefined,
352 + },
353 + {
354 + "debugInfo": null,
355 + "hookSource": {
356 + "columnNumber": 0,
357 + "fileName": "**",
358 + "functionName": "Foo",
359 + "lineNumber": 0,
360 },
229 - {
230 - isStateEditable: false,
231 - id: null,
232 - name: 'Custom',
233 - debugInfo: null,
234 - subHooks: [
235 - {
236 - isStateEditable: true,
237 - id: 4,
238 - name: 'Reducer',
239 - debugInfo: null,
240 - subHooks: [],
241 - value: 'world',
361 + "id": null,
362 + "isStateEditable": false,
363 + "name": "Baz",
364 + "subHooks": [
365 + {
366 + "debugInfo": null,
367 + "hookSource": {
368 + "columnNumber": 0,
369 + "fileName": "**",
370 + "functionName": "useBaz",
371 + "lineNumber": 0,
372 },
243 - {
244 - isStateEditable: false,
245 - id: 5,
246 - name: 'Effect',
247 - debugInfo: null,
248 - subHooks: [],
249 - value: effect,
373 + "id": 3,
374 + "isStateEditable": false,
375 + "name": "LayoutEffect",
376 + "subHooks": [],
377 + "value": [Function],
378 + },
379 + {
380 + "debugInfo": null,
381 + "hookSource": {
382 + "columnNumber": 0,
383 + "fileName": "**",
384 + "functionName": "useBaz",
385 + "lineNumber": 0,
386 },
251 - ],
252 - value: undefined,
253 - },
254 - ],
255 - },
256 - ]);
387 + "id": null,
388 + "isStateEditable": false,
389 + "name": "Custom",
390 + "subHooks": [
391 + {
392 + "debugInfo": null,
393 + "hookSource": {
394 + "columnNumber": 0,
395 + "fileName": "**",
396 + "functionName": "useCustom",
397 + "lineNumber": 0,
398 + },
399 + "id": 4,
400 + "isStateEditable": true,
401 + "name": "Reducer",
402 + "subHooks": [],
403 + "value": "world",
404 + },
405 + {
406 + "debugInfo": null,
407 + "hookSource": {
408 + "columnNumber": 0,
409 + "fileName": "**",
410 + "functionName": "useCustom",
411 + "lineNumber": 0,
412 + },
413 + "id": 5,
414 + "isStateEditable": false,
415 + "name": "Effect",
416 + "subHooks": [],
417 + "value": [Function],
418 + },
419 + ],
420 + "value": undefined,
421 + },
422 + ],
423 + "value": undefined,
424 + },
425 + ]
426 + `);
427 });
428
429 it('should inspect the default value using the useContext hook', () => {
@@ -263,16 +433,24 @@ describe('ReactHooksInspection', () => {
433 return <div>{value}</div>;
434 }
435 const tree = ReactDebugTools.inspectHooks(Foo, {});
266 - expect(tree).toEqual([
267 - {
268 - isStateEditable: false,
269 - id: null,
270 - name: 'Context',
271 - value: 'default',
272 - debugInfo: null,
273 - subHooks: [],
274 - },
275 - ]);
436 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
437 + [
438 + {
439 + "debugInfo": null,
440 + "hookSource": {
441 + "columnNumber": 0,
442 + "fileName": "**",
443 + "functionName": "Foo",
444 + "lineNumber": 0,
445 + },
446 + "id": null,
447 + "isStateEditable": false,
448 + "name": "Context",
449 + "subHooks": [],
450 + "value": "default",
451 + },
452 + ]
453 + `);
454 });
455
456 it('should support an injected dispatcher', () => {
@@ -331,41 +509,71 @@ describe('ReactHooksInspection', () => {
509 );
510 }
511 const tree = ReactDebugTools.inspectHooks(Foo, {});
334 - expect(tree).toEqual([
335 - {
336 - isStateEditable: false,
337 - id: null,
338 - name: 'Context',
339 - value: 'hi',
340 - debugInfo: null,
341 - subHooks: [],
342 - },
343 - {
344 - isStateEditable: false,
345 - id: null,
346 - name: 'Custom',
347 - value: undefined,
348 - debugInfo: null,
349 - subHooks: [
350 - {
351 - isStateEditable: false,
352 - id: null,
353 - name: 'Promise',
354 - value: 'world',
355 - debugInfo: [{name: 'Hello'}],
356 - subHooks: [],
512 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
513 + [
514 + {
515 + "debugInfo": null,
516 + "hookSource": {
517 + "columnNumber": 0,
518 + "fileName": "**",
519 + "functionName": "Foo",
520 + "lineNumber": 0,
521 },
358 - {
359 - isStateEditable: true,
360 - id: 0,
361 - name: 'State',
362 - value: 'world',
363 - debugInfo: null,
364 - subHooks: [],
522 + "id": null,
523 + "isStateEditable": false,
524 + "name": "Context",
525 + "subHooks": [],
526 + "value": "hi",
527 + },
528 + {
529 + "debugInfo": null,
530 + "hookSource": {
531 + "columnNumber": 0,
532 + "fileName": "**",
533 + "functionName": "Foo",
534 + "lineNumber": 0,
535 },
366 - ],
367 - },
368 - ]);
536 + "id": null,
537 + "isStateEditable": false,
538 + "name": "Custom",
539 + "subHooks": [
540 + {
541 + "debugInfo": [
542 + {
543 + "name": "Hello",
544 + },
545 + ],
546 + "hookSource": {
547 + "columnNumber": 0,
548 + "fileName": "**",
549 + "functionName": "useCustom",
550 + "lineNumber": 0,
551 + },
552 + "id": null,
553 + "isStateEditable": false,
554 + "name": "Promise",
555 + "subHooks": [],
556 + "value": "world",
557 + },
558 + {
559 + "debugInfo": null,
560 + "hookSource": {
561 + "columnNumber": 0,
562 + "fileName": "**",
563 + "functionName": "useCustom",
564 + "lineNumber": 0,
565 + },
566 + "id": 0,
567 + "isStateEditable": true,
568 + "name": "State",
569 + "subHooks": [],
570 + "value": "world",
571 + },
572 + ],
573 + "value": undefined,
574 + },
575 + ]
576 + `);
577 });
578
579 it('should inspect use() calls for unresolved Promise', () => {
@@ -376,16 +584,24 @@ describe('ReactHooksInspection', () => {
584 return <div>{value}</div>;
585 }
586 const tree = ReactDebugTools.inspectHooks(Foo, {});
379 - expect(tree).toEqual([
380 - {
381 - isStateEditable: false,
382 - id: null,
383 - name: 'Unresolved',
384 - value: promise,
385 - debugInfo: null,
386 - subHooks: [],
387 - },
388 - ]);
587 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
588 + [
589 + {
590 + "debugInfo": null,
591 + "hookSource": {
592 + "columnNumber": 0,
593 + "fileName": "**",
594 + "functionName": "Foo",
595 + "lineNumber": 0,
596 + },
597 + "id": null,
598 + "isStateEditable": false,
599 + "name": "Unresolved",
600 + "subHooks": [],
601 + "value": Promise {},
602 + },
603 + ]
604 + `);
605 });
606
607 describe('useDebugValue', () => {
@@ -408,25 +624,75 @@ describe('ReactHooksInspection', () => {
624 return null;
625 }
626 const tree = ReactDebugTools.inspectHooks(Foo, {});
411 - expect(tree).toEqual([
412 - {
413 - isStateEditable: false,
414 - id: null,
415 - name: 'Custom',
416 - value: __DEV__ ? 'bar:123' : undefined,
417 - debugInfo: null,
418 - subHooks: [
627 + if (__DEV__) {
628 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
629 + [
630 + {
631 + "debugInfo": null,
632 + "hookSource": {
633 + "columnNumber": 0,
634 + "fileName": "**",
635 + "functionName": "Foo",
636 + "lineNumber": 0,
637 + },
638 + "id": null,
639 + "isStateEditable": false,
640 + "name": "Custom",
641 + "subHooks": [
642 + {
643 + "debugInfo": null,
644 + "hookSource": {
645 + "columnNumber": 0,
646 + "fileName": "**",
647 + "functionName": "useCustom",
648 + "lineNumber": 0,
649 + },
650 + "id": 0,
651 + "isStateEditable": true,
652 + "name": "State",
653 + "subHooks": [],
654 + "value": 0,
655 + },
656 + ],
657 + "value": "bar:123",
658 + },
659 + ]
660 + `);
661 + } else {
662 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
663 + [
664 {
420 - isStateEditable: true,
421 - id: 0,
422 - name: 'State',
423 - debugInfo: null,
424 - subHooks: [],
425 - value: 0,
665 + "debugInfo": null,
666 + "hookSource": {
667 + "columnNumber": 0,
668 + "fileName": "**",
669 + "functionName": "Foo",
670 + "lineNumber": 0,
671 + },
672 + "id": null,
673 + "isStateEditable": false,
674 + "name": "Custom",
675 + "subHooks": [
676 + {
677 + "debugInfo": null,
678 + "hookSource": {
679 + "columnNumber": 0,
680 + "fileName": "**",
681 + "functionName": "useCustom",
682 + "lineNumber": 0,
683 + },
684 + "id": 0,
685 + "isStateEditable": true,
686 + "name": "State",
687 + "subHooks": [],
688 + "value": 0,
689 + },
690 + ],
691 + "value": undefined,
692 },
427 - ],
428 - },
429 - ]);
693 + ]
694 + `);
695 + }
696 });
697 });
698 });
packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js
+1578 -717
@@ -17,6 +17,18 @@ let ReactDebugTools;
17 let act;
18 let useMemoCache;
19
20 +function normalizeSourceLoc(tree) {
21 + tree.forEach(node => {
22 + if (node.hookSource) {
23 + node.hookSource.fileName = '**';
24 + node.hookSource.lineNumber = 0;
25 + node.hookSource.columnNumber = 0;
26 + }
27 + normalizeSourceLoc(node.subHooks);
28 + });
29 + return tree;
30 +}
31 +
32 describe('ReactHooksInspectionIntegration', () => {
33 beforeEach(() => {
34 jest.resetModules();
@@ -43,24 +55,38 @@ describe('ReactHooksInspectionIntegration', () => {
55
56 let childFiber = renderer.root.findByType(Foo)._currentFiber();
57 let tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
46 - expect(tree).toEqual([
47 - {
48 - isStateEditable: true,
49 - id: 0,
50 - name: 'State',
51 - value: 'hello',
52 - debugInfo: null,
53 - subHooks: [],
54 - },
55 - {
56 - isStateEditable: true,
57 - id: 1,
58 - name: 'State',
59 - value: 'world',
60 - debugInfo: null,
61 - subHooks: [],
62 - },
63 - ]);
58 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
59 + [
60 + {
61 + "debugInfo": null,
62 + "hookSource": {
63 + "columnNumber": 0,
64 + "fileName": "**",
65 + "functionName": "Foo",
66 + "lineNumber": 0,
67 + },
68 + "id": 0,
69 + "isStateEditable": true,
70 + "name": "State",
71 + "subHooks": [],
72 + "value": "hello",
73 + },
74 + {
75 + "debugInfo": null,
76 + "hookSource": {
77 + "columnNumber": 0,
78 + "fileName": "**",
79 + "functionName": "Foo",
80 + "lineNumber": 0,
81 + },
82 + "id": 1,
83 + "isStateEditable": true,
84 + "name": "State",
85 + "subHooks": [],
86 + "value": "world",
87 + },
88 + ]
89 + `);
90
91 const {onMouseDown: setStateA, onMouseUp: setStateB} =
92 renderer.root.findByType('div').props;
@@ -70,48 +96,76 @@ describe('ReactHooksInspectionIntegration', () => {
96 childFiber = renderer.root.findByType(Foo)._currentFiber();
97 tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
98
73 - expect(tree).toEqual([
74 - {
75 - isStateEditable: true,
76 - id: 0,
77 - name: 'State',
78 - value: 'Hi',
79 - debugInfo: null,
80 - subHooks: [],
81 - },
82 - {
83 - isStateEditable: true,
84 - id: 1,
85 - name: 'State',
86 - value: 'world',
87 - debugInfo: null,
88 - subHooks: [],
89 - },
90 - ]);
99 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
100 + [
101 + {
102 + "debugInfo": null,
103 + "hookSource": {
104 + "columnNumber": 0,
105 + "fileName": "**",
106 + "functionName": "Foo",
107 + "lineNumber": 0,
108 + },
109 + "id": 0,
110 + "isStateEditable": true,
111 + "name": "State",
112 + "subHooks": [],
113 + "value": "Hi",
114 + },
115 + {
116 + "debugInfo": null,
117 + "hookSource": {
118 + "columnNumber": 0,
119 + "fileName": "**",
120 + "functionName": "Foo",
121 + "lineNumber": 0,
122 + },
123 + "id": 1,
124 + "isStateEditable": true,
125 + "name": "State",
126 + "subHooks": [],
127 + "value": "world",
128 + },
129 + ]
130 + `);
131
132 await act(() => setStateB('world!'));
133
134 childFiber = renderer.root.findByType(Foo)._currentFiber();
135 tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
136
97 - expect(tree).toEqual([
98 - {
99 - isStateEditable: true,
100 - id: 0,
101 - name: 'State',
102 - value: 'Hi',
103 - debugInfo: null,
104 - subHooks: [],
105 - },
106 - {
107 - isStateEditable: true,
108 - id: 1,
109 - name: 'State',
110 - value: 'world!',
111 - debugInfo: null,
112 - subHooks: [],
113 - },
114 - ]);
137 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
138 + [
139 + {
140 + "debugInfo": null,
141 + "hookSource": {
142 + "columnNumber": 0,
143 + "fileName": "**",
144 + "functionName": "Foo",
145 + "lineNumber": 0,
146 + },
147 + "id": 0,
148 + "isStateEditable": true,
149 + "name": "State",
150 + "subHooks": [],
151 + "value": "Hi",
152 + },
153 + {
154 + "debugInfo": null,
155 + "hookSource": {
156 + "columnNumber": 0,
157 + "fileName": "**",
158 + "functionName": "Foo",
159 + "lineNumber": 0,
160 + },
161 + "id": 1,
162 + "isStateEditable": true,
163 + "name": "State",
164 + "subHooks": [],
165 + "value": "world!",
166 + },
167 + ]
168 + `);
169 });
170
171 it('should inspect the current state of all stateful hooks', async () => {
@@ -158,72 +212,122 @@ describe('ReactHooksInspectionIntegration', () => {
212 const {onClick: updateStates} = renderer.root.findByType('div').props;
213
214 let tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
161 - expect(tree).toEqual([
162 - {
163 - isStateEditable: true,
164 - id: 0,
165 - name: 'State',
166 - value: 'a',
167 - debugInfo: null,
168 - subHooks: [],
169 - },
170 - {
171 - isStateEditable: true,
172 - id: 1,
173 - name: 'Reducer',
174 - value: 'b',
175 - debugInfo: null,
176 - subHooks: [],
177 - },
178 - {
179 - isStateEditable: false,
180 - id: 2,
181 - name: 'Ref',
182 - value: 'c',
183 - debugInfo: null,
184 - subHooks: [],
185 - },
186 - {
187 - isStateEditable: false,
188 - id: 3,
189 - name: 'LayoutEffect',
190 - value: effect,
191 - debugInfo: null,
192 - subHooks: [],
193 - },
194 - {
195 - isStateEditable: false,
196 - id: 4,
197 - name: 'Effect',
198 - value: effect,
199 - debugInfo: null,
200 - subHooks: [],
201 - },
202 - {
203 - isStateEditable: false,
204 - id: 5,
205 - name: 'ImperativeHandle',
206 - value: outsideRef.current,
207 - debugInfo: null,
208 - subHooks: [],
209 - },
210 - {
211 - isStateEditable: false,
212 - id: 6,
213 - name: 'Memo',
214 - value: 'ab',
215 - debugInfo: null,
216 - subHooks: [],
217 - },
218 - {
219 - isStateEditable: false,
220 - id: 7,
221 - name: 'Callback',
222 - value: updateStates,
223 - debugInfo: null,
224 - subHooks: [],
225 - },
226 - ]);
215 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
216 + [
217 + {
218 + "debugInfo": null,
219 + "hookSource": {
220 + "columnNumber": 0,
221 + "fileName": "**",
222 + "functionName": "Foo",
223 + "lineNumber": 0,
224 + },
225 + "id": 0,
226 + "isStateEditable": true,
227 + "name": "State",
228 + "subHooks": [],
229 + "value": "a",
230 + },
231 + {
232 + "debugInfo": null,
233 + "hookSource": {
234 + "columnNumber": 0,
235 + "fileName": "**",
236 + "functionName": "Foo",
237 + "lineNumber": 0,
238 + },
239 + "id": 1,
240 + "isStateEditable": true,
241 + "name": "Reducer",
242 + "subHooks": [],
243 + "value": "b",
244 + },
245 + {
246 + "debugInfo": null,
247 + "hookSource": {
248 + "columnNumber": 0,
249 + "fileName": "**",
250 + "functionName": "Foo",
251 + "lineNumber": 0,
252 + },
253 + "id": 2,
254 + "isStateEditable": false,
255 + "name": "Ref",
256 + "subHooks": [],
257 + "value": "c",
258 + },
259 + {
260 + "debugInfo": null,
261 + "hookSource": {
262 + "columnNumber": 0,
263 + "fileName": "**",
264 + "functionName": "Foo",
265 + "lineNumber": 0,
266 + },
267 + "id": 3,
268 + "isStateEditable": false,
269 + "name": "LayoutEffect",
270 + "subHooks": [],
271 + "value": [Function],
272 + },
273 + {
274 + "debugInfo": null,
275 + "hookSource": {
276 + "columnNumber": 0,
277 + "fileName": "**",
278 + "functionName": "Foo",
279 + "lineNumber": 0,
280 + },
281 + "id": 4,
282 + "isStateEditable": false,
283 + "name": "Effect",
284 + "subHooks": [],
285 + "value": [Function],
286 + },
287 + {
288 + "debugInfo": null,
289 + "hookSource": {
290 + "columnNumber": 0,
291 + "fileName": "**",
292 + "functionName": "Foo",
293 + "lineNumber": 0,
294 + },
295 + "id": 5,
296 + "isStateEditable": false,
297 + "name": "ImperativeHandle",
298 + "subHooks": [],
299 + "value": [Function],
300 + },
301 + {
302 + "debugInfo": null,
303 + "hookSource": {
304 + "columnNumber": 0,
305 + "fileName": "**",
306 + "functionName": "Foo",
307 + "lineNumber": 0,
308 + },
309 + "id": 6,
310 + "isStateEditable": false,
311 + "name": "Memo",
312 + "subHooks": [],
313 + "value": "ab",
314 + },
315 + {
316 + "debugInfo": null,
317 + "hookSource": {
318 + "columnNumber": 0,
319 + "fileName": "**",
320 + "functionName": "Foo",
321 + "lineNumber": 0,
322 + },
323 + "id": 7,
324 + "isStateEditable": false,
325 + "name": "Callback",
326 + "subHooks": [],
327 + "value": [Function],
328 + },
329 + ]
330 + `);
331
332 await act(() => {
333 updateStates();
@@ -232,72 +336,122 @@ describe('ReactHooksInspectionIntegration', () => {
336 childFiber = renderer.root.findByType(Foo)._currentFiber();
337 tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
338
235 - expect(tree).toEqual([
236 - {
237 - isStateEditable: true,
238 - id: 0,
239 - name: 'State',
240 - value: 'A',
241 - debugInfo: null,
242 - subHooks: [],
243 - },
244 - {
245 - isStateEditable: true,
246 - id: 1,
247 - name: 'Reducer',
248 - value: 'B',
249 - debugInfo: null,
250 - subHooks: [],
251 - },
252 - {
253 - isStateEditable: false,
254 - id: 2,
255 - name: 'Ref',
256 - value: 'C',
257 - debugInfo: null,
258 - subHooks: [],
259 - },
260 - {
261 - isStateEditable: false,
262 - id: 3,
263 - name: 'LayoutEffect',
264 - value: effect,
265 - debugInfo: null,
266 - subHooks: [],
267 - },
268 - {
269 - isStateEditable: false,
270 - id: 4,
271 - name: 'Effect',
272 - value: effect,
273 - debugInfo: null,
274 - subHooks: [],
275 - },
276 - {
277 - isStateEditable: false,
278 - id: 5,
279 - name: 'ImperativeHandle',
280 - value: outsideRef.current,
281 - debugInfo: null,
282 - subHooks: [],
283 - },
284 - {
285 - isStateEditable: false,
286 - id: 6,
287 - name: 'Memo',
288 - value: 'Ab',
289 - debugInfo: null,
290 - subHooks: [],
291 - },
292 - {
293 - isStateEditable: false,
294 - id: 7,
295 - name: 'Callback',
296 - value: updateStates,
297 - debugInfo: null,
298 - subHooks: [],
299 - },
300 - ]);
339 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
340 + [
341 + {
342 + "debugInfo": null,
343 + "hookSource": {
344 + "columnNumber": 0,
345 + "fileName": "**",
346 + "functionName": "Foo",
347 + "lineNumber": 0,
348 + },
349 + "id": 0,
350 + "isStateEditable": true,
351 + "name": "State",
352 + "subHooks": [],
353 + "value": "A",
354 + },
355 + {
356 + "debugInfo": null,
357 + "hookSource": {
358 + "columnNumber": 0,
359 + "fileName": "**",
360 + "functionName": "Foo",
361 + "lineNumber": 0,
362 + },
363 + "id": 1,
364 + "isStateEditable": true,
365 + "name": "Reducer",
366 + "subHooks": [],
367 + "value": "B",
368 + },
369 + {
370 + "debugInfo": null,
371 + "hookSource": {
372 + "columnNumber": 0,
373 + "fileName": "**",
374 + "functionName": "Foo",
375 + "lineNumber": 0,
376 + },
377 + "id": 2,
378 + "isStateEditable": false,
379 + "name": "Ref",
380 + "subHooks": [],
381 + "value": "C",
382 + },
383 + {
384 + "debugInfo": null,
385 + "hookSource": {
386 + "columnNumber": 0,
387 + "fileName": "**",
388 + "functionName": "Foo",
389 + "lineNumber": 0,
390 + },
391 + "id": 3,
392 + "isStateEditable": false,
393 + "name": "LayoutEffect",
394 + "subHooks": [],
395 + "value": [Function],
396 + },
397 + {
398 + "debugInfo": null,
399 + "hookSource": {
400 + "columnNumber": 0,
401 + "fileName": "**",
402 + "functionName": "Foo",
403 + "lineNumber": 0,
404 + },
405 + "id": 4,
406 + "isStateEditable": false,
407 + "name": "Effect",
408 + "subHooks": [],
409 + "value": [Function],
410 + },
411 + {
412 + "debugInfo": null,
413 + "hookSource": {
414 + "columnNumber": 0,
415 + "fileName": "**",
416 + "functionName": "Foo",
417 + "lineNumber": 0,
418 + },
419 + "id": 5,
420 + "isStateEditable": false,
421 + "name": "ImperativeHandle",
422 + "subHooks": [],
423 + "value": [Function],
424 + },
425 + {
426 + "debugInfo": null,
427 + "hookSource": {
428 + "columnNumber": 0,
429 + "fileName": "**",
430 + "functionName": "Foo",
431 + "lineNumber": 0,
432 + },
433 + "id": 6,
434 + "isStateEditable": false,
435 + "name": "Memo",
436 + "subHooks": [],
437 + "value": "Ab",
438 + },
439 + {
440 + "debugInfo": null,
441 + "hookSource": {
442 + "columnNumber": 0,
443 + "fileName": "**",
444 + "functionName": "Foo",
445 + "lineNumber": 0,
446 + },
447 + "id": 7,
448 + "isStateEditable": false,
449 + "name": "Callback",
450 + "subHooks": [],
451 + "value": [Function],
452 + },
453 + ]
454 + `);
455 });
456
457 it('should inspect the current state of all stateful hooks, including useInsertionEffect', async () => {
@@ -346,80 +500,136 @@ describe('ReactHooksInspectionIntegration', () => {
500 const {onClick: updateStates} = renderer.root.findByType('div').props;
501
502 let tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
349 - expect(tree).toEqual([
350 - {
351 - isStateEditable: true,
352 - id: 0,
353 - name: 'State',
354 - value: 'a',
355 - debugInfo: null,
356 - subHooks: [],
357 - },
358 - {
359 - isStateEditable: true,
360 - id: 1,
361 - name: 'Reducer',
362 - value: 'b',
363 - debugInfo: null,
364 - subHooks: [],
365 - },
366 - {
367 - isStateEditable: false,
368 - id: 2,
369 - name: 'Ref',
370 - value: 'c',
371 - debugInfo: null,
372 - subHooks: [],
373 - },
374 - {
375 - isStateEditable: false,
376 - id: 3,
377 - name: 'InsertionEffect',
378 - value: effect,
379 - debugInfo: null,
380 - subHooks: [],
381 - },
382 - {
383 - isStateEditable: false,
384 - id: 4,
385 - name: 'LayoutEffect',
386 - value: effect,
387 - debugInfo: null,
388 - subHooks: [],
389 - },
390 - {
391 - isStateEditable: false,
392 - id: 5,
393 - name: 'Effect',
394 - value: effect,
395 - debugInfo: null,
396 - subHooks: [],
397 - },
398 - {
399 - isStateEditable: false,
400 - id: 6,
401 - name: 'ImperativeHandle',
402 - value: outsideRef.current,
403 - debugInfo: null,
404 - subHooks: [],
405 - },
406 - {
407 - isStateEditable: false,
408 - id: 7,
409 - name: 'Memo',
410 - value: 'ab',
411 - debugInfo: null,
412 - subHooks: [],
413 - },
414 - {
415 - isStateEditable: false,
416 - id: 8,
417 - name: 'Callback',
418 - value: updateStates,
419 - debugInfo: null,
420 - subHooks: [],
421 - },
422 - ]);
503 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
504 + [
505 + {
506 + "debugInfo": null,
507 + "hookSource": {
508 + "columnNumber": 0,
509 + "fileName": "**",
510 + "functionName": "Foo",
511 + "lineNumber": 0,
512 + },
513 + "id": 0,
514 + "isStateEditable": true,
515 + "name": "State",
516 + "subHooks": [],
517 + "value": "a",
518 + },
519 + {
520 + "debugInfo": null,
521 + "hookSource": {
522 + "columnNumber": 0,
523 + "fileName": "**",
524 + "functionName": "Foo",
525 + "lineNumber": 0,
526 + },
527 + "id": 1,
528 + "isStateEditable": true,
529 + "name": "Reducer",
530 + "subHooks": [],
531 + "value": "b",
532 + },
533 + {
534 + "debugInfo": null,
535 + "hookSource": {
536 + "columnNumber": 0,
537 + "fileName": "**",
538 + "functionName": "Foo",
539 + "lineNumber": 0,
540 + },
541 + "id": 2,
542 + "isStateEditable": false,
543 + "name": "Ref",
544 + "subHooks": [],
545 + "value": "c",
546 + },
547 + {
548 + "debugInfo": null,
549 + "hookSource": {
550 + "columnNumber": 0,
551 + "fileName": "**",
552 + "functionName": "Foo",
553 + "lineNumber": 0,
554 + },
555 + "id": 3,
556 + "isStateEditable": false,
557 + "name": "InsertionEffect",
558 + "subHooks": [],
559 + "value": [Function],
560 + },
561 + {
562 + "debugInfo": null,
563 + "hookSource": {
564 + "columnNumber": 0,
565 + "fileName": "**",
566 + "functionName": "Foo",
567 + "lineNumber": 0,
568 + },
569 + "id": 4,
570 + "isStateEditable": false,
571 + "name": "LayoutEffect",
572 + "subHooks": [],
573 + "value": [Function],
574 + },
575 + {
576 + "debugInfo": null,
577 + "hookSource": {
578 + "columnNumber": 0,
579 + "fileName": "**",
580 + "functionName": "Foo",
581 + "lineNumber": 0,
582 + },
583 + "id": 5,
584 + "isStateEditable": false,
585 + "name": "Effect",
586 + "subHooks": [],
587 + "value": [Function],
588 + },
589 + {
590 + "debugInfo": null,
591 + "hookSource": {
592 + "columnNumber": 0,
593 + "fileName": "**",
594 + "functionName": "Foo",
595 + "lineNumber": 0,
596 + },
597 + "id": 6,
598 + "isStateEditable": false,
599 + "name": "ImperativeHandle",
600 + "subHooks": [],
601 + "value": [Function],
602 + },
603 + {
604 + "debugInfo": null,
605 + "hookSource": {
606 + "columnNumber": 0,
607 + "fileName": "**",
608 + "functionName": "Foo",
609 + "lineNumber": 0,
610 + },
611 + "id": 7,
612 + "isStateEditable": false,
613 + "name": "Memo",
614 + "subHooks": [],
615 + "value": "ab",
616 + },
617 + {
618 + "debugInfo": null,
619 + "hookSource": {
620 + "columnNumber": 0,
621 + "fileName": "**",
622 + "functionName": "Foo",
623 + "lineNumber": 0,
624 + },
625 + "id": 8,
626 + "isStateEditable": false,
627 + "name": "Callback",
628 + "subHooks": [],
629 + "value": [Function],
630 + },
631 + ]
632 + `);
633
634 await act(() => {
635 updateStates();
@@ -428,80 +638,136 @@ describe('ReactHooksInspectionIntegration', () => {
638 childFiber = renderer.root.findByType(Foo)._currentFiber();
639 tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
640
431 - expect(tree).toEqual([
432 - {
433 - isStateEditable: true,
434 - id: 0,
435 - name: 'State',
436 - value: 'A',
437 - debugInfo: null,
438 - subHooks: [],
439 - },
440 - {
441 - isStateEditable: true,
442 - id: 1,
443 - name: 'Reducer',
444 - value: 'B',
445 - debugInfo: null,
446 - subHooks: [],
447 - },
448 - {
449 - isStateEditable: false,
450 - id: 2,
451 - name: 'Ref',
452 - value: 'C',
453 - debugInfo: null,
454 - subHooks: [],
455 - },
456 - {
457 - isStateEditable: false,
458 - id: 3,
459 - name: 'InsertionEffect',
460 - value: effect,
461 - debugInfo: null,
462 - subHooks: [],
463 - },
464 - {
465 - isStateEditable: false,
466 - id: 4,
467 - name: 'LayoutEffect',
468 - value: effect,
469 - debugInfo: null,
470 - subHooks: [],
471 - },
472 - {
473 - isStateEditable: false,
474 - id: 5,
475 - name: 'Effect',
476 - value: effect,
477 - debugInfo: null,
478 - subHooks: [],
479 - },
480 - {
481 - isStateEditable: false,
482 - id: 6,
483 - name: 'ImperativeHandle',
484 - value: outsideRef.current,
485 - debugInfo: null,
486 - subHooks: [],
487 - },
488 - {
489 - isStateEditable: false,
490 - id: 7,
491 - name: 'Memo',
492 - value: 'Ab',
493 - debugInfo: null,
494 - subHooks: [],
495 - },
496 - {
497 - isStateEditable: false,
498 - id: 8,
499 - name: 'Callback',
500 - value: updateStates,
501 - debugInfo: null,
502 - subHooks: [],
503 - },
504 - ]);
641 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
642 + [
643 + {
644 + "debugInfo": null,
645 + "hookSource": {
646 + "columnNumber": 0,
647 + "fileName": "**",
648 + "functionName": "Foo",
649 + "lineNumber": 0,
650 + },
651 + "id": 0,
652 + "isStateEditable": true,
653 + "name": "State",
654 + "subHooks": [],
655 + "value": "A",
656 + },
657 + {
658 + "debugInfo": null,
659 + "hookSource": {
660 + "columnNumber": 0,
661 + "fileName": "**",
662 + "functionName": "Foo",
663 + "lineNumber": 0,
664 + },
665 + "id": 1,
666 + "isStateEditable": true,
667 + "name": "Reducer",
668 + "subHooks": [],
669 + "value": "B",
670 + },
671 + {
672 + "debugInfo": null,
673 + "hookSource": {
674 + "columnNumber": 0,
675 + "fileName": "**",
676 + "functionName": "Foo",
677 + "lineNumber": 0,
678 + },
679 + "id": 2,
680 + "isStateEditable": false,
681 + "name": "Ref",
682 + "subHooks": [],
683 + "value": "C",
684 + },
685 + {
686 + "debugInfo": null,
687 + "hookSource": {
688 + "columnNumber": 0,
689 + "fileName": "**",
690 + "functionName": "Foo",
691 + "lineNumber": 0,
692 + },
693 + "id": 3,
694 + "isStateEditable": false,
695 + "name": "InsertionEffect",
696 + "subHooks": [],
697 + "value": [Function],
698 + },
699 + {
700 + "debugInfo": null,
701 + "hookSource": {
702 + "columnNumber": 0,
703 + "fileName": "**",
704 + "functionName": "Foo",
705 + "lineNumber": 0,
706 + },
707 + "id": 4,
708 + "isStateEditable": false,
709 + "name": "LayoutEffect",
710 + "subHooks": [],
711 + "value": [Function],
712 + },
713 + {
714 + "debugInfo": null,
715 + "hookSource": {
716 + "columnNumber": 0,
717 + "fileName": "**",
718 + "functionName": "Foo",
719 + "lineNumber": 0,
720 + },
721 + "id": 5,
722 + "isStateEditable": false,
723 + "name": "Effect",
724 + "subHooks": [],
725 + "value": [Function],
726 + },
727 + {
728 + "debugInfo": null,
729 + "hookSource": {
730 + "columnNumber": 0,
731 + "fileName": "**",
732 + "functionName": "Foo",
733 + "lineNumber": 0,
734 + },
735 + "id": 6,
736 + "isStateEditable": false,
737 + "name": "ImperativeHandle",
738 + "subHooks": [],
739 + "value": [Function],
740 + },
741 + {
742 + "debugInfo": null,
743 + "hookSource": {
744 + "columnNumber": 0,
745 + "fileName": "**",
746 + "functionName": "Foo",
747 + "lineNumber": 0,
748 + },
749 + "id": 7,
750 + "isStateEditable": false,
751 + "name": "Memo",
752 + "subHooks": [],
753 + "value": "Ab",
754 + },
755 + {
756 + "debugInfo": null,
757 + "hookSource": {
758 + "columnNumber": 0,
759 + "fileName": "**",
760 + "functionName": "Foo",
761 + "lineNumber": 0,
762 + },
763 + "id": 8,
764 + "isStateEditable": false,
765 + "name": "Callback",
766 + "subHooks": [],
767 + "value": [Function],
768 + },
769 + ]
770 + `);
771 });
772
773 it('should inspect the value of the current provider in useContext', () => {
@@ -517,16 +783,24 @@ describe('ReactHooksInspectionIntegration', () => {
783 );
784 const childFiber = renderer.root.findByType(Foo)._currentFiber();
785 const tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
520 - expect(tree).toEqual([
521 - {
522 - isStateEditable: false,
523 - id: null,
524 - name: 'Context',
525 - value: 'contextual',
526 - debugInfo: null,
527 - subHooks: [],
528 - },
529 - ]);
786 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
787 + [
788 + {
789 + "debugInfo": null,
790 + "hookSource": {
791 + "columnNumber": 0,
792 + "fileName": "**",
793 + "functionName": "Foo",
794 + "lineNumber": 0,
795 + },
796 + "id": null,
797 + "isStateEditable": false,
798 + "name": "Context",
799 + "subHooks": [],
800 + "value": "contextual",
801 + },
802 + ]
803 + `);
804 });
805
806 it('should inspect forwardRef', () => {
@@ -540,16 +814,24 @@ describe('ReactHooksInspectionIntegration', () => {
814
815 const childFiber = renderer.root.findByType(Foo)._currentFiber();
816 const tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
543 - expect(tree).toEqual([
544 - {
545 - isStateEditable: false,
546 - id: 0,
547 - name: 'ImperativeHandle',
548 - value: obj,
549 - debugInfo: null,
550 - subHooks: [],
551 - },
552 - ]);
817 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
818 + [
819 + {
820 + "debugInfo": null,
821 + "hookSource": {
822 + "columnNumber": 0,
823 + "fileName": "**",
824 + "functionName": undefined,
825 + "lineNumber": 0,
826 + },
827 + "id": 0,
828 + "isStateEditable": false,
829 + "name": "ImperativeHandle",
830 + "subHooks": [],
831 + "value": [Function],
832 + },
833 + ]
834 + `);
835 });
836
837 it('should inspect memo', () => {
@@ -562,16 +844,24 @@ describe('ReactHooksInspectionIntegration', () => {
844 // TODO: Test renderer findByType is broken for memo. Have to search for the inner.
845 const childFiber = renderer.root.findByType(InnerFoo)._currentFiber();
846 const tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
565 - expect(tree).toEqual([
566 - {
567 - isStateEditable: true,
568 - id: 0,
569 - name: 'State',
570 - value: 'hello',
571 - debugInfo: null,
572 - subHooks: [],
573 - },
574 - ]);
847 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
848 + [
849 + {
850 + "debugInfo": null,
851 + "hookSource": {
852 + "columnNumber": 0,
853 + "fileName": "**",
854 + "functionName": "InnerFoo",
855 + "lineNumber": 0,
856 + },
857 + "id": 0,
858 + "isStateEditable": true,
859 + "name": "State",
860 + "subHooks": [],
861 + "value": "hello",
862 + },
863 + ]
864 + `);
865 });
866
867 it('should inspect custom hooks', () => {
@@ -586,25 +876,39 @@ describe('ReactHooksInspectionIntegration', () => {
876 const renderer = ReactTestRenderer.create(<Foo />);
877 const childFiber = renderer.root.findByType(Foo)._currentFiber();
878 const tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
589 - expect(tree).toEqual([
590 - {
591 - isStateEditable: false,
592 - id: null,
593 - name: 'Custom',
594 - value: undefined,
595 - debugInfo: null,
596 - subHooks: [
597 - {
598 - isStateEditable: true,
599 - id: 0,
600 - name: 'State',
601 - value: 'hello',
602 - debugInfo: null,
603 - subHooks: [],
604 - },
605 - ],
606 - },
607 - ]);
879 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
880 + [
881 + {
882 + "debugInfo": null,
883 + "hookSource": {
884 + "columnNumber": 0,
885 + "fileName": "**",
886 + "functionName": "Foo",
887 + "lineNumber": 0,
888 + },
889 + "id": null,
890 + "isStateEditable": false,
891 + "name": "Custom",
892 + "subHooks": [
893 + {
894 + "debugInfo": null,
895 + "hookSource": {
896 + "columnNumber": 0,
897 + "fileName": "**",
898 + "functionName": "useCustom",
899 + "lineNumber": 0,
900 + },
901 + "id": 0,
902 + "isStateEditable": true,
903 + "name": "State",
904 + "subHooks": [],
905 + "value": "hello",
906 + },
907 + ],
908 + "value": undefined,
909 + },
910 + ]
911 + `);
912 });
913
914 it('should support composite useTransition hook', () => {
@@ -617,32 +921,52 @@ describe('ReactHooksInspectionIntegration', () => {
921 const renderer = ReactTestRenderer.create(<Foo />);
922 const childFiber = renderer.root.findByType(Foo)._currentFiber();
923 const tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
620 - expect(tree).toEqual([
621 - {
622 - id: 0,
623 - isStateEditable: false,
624 - name: 'Transition',
625 - value: undefined,
626 - debugInfo: null,
627 - subHooks: [],
628 - },
629 - {
630 - id: 1,
631 - isStateEditable: false,
632 - name: 'Memo',
633 - value: 'hello',
634 - debugInfo: null,
635 - subHooks: [],
636 - },
637 - {
638 - id: 2,
639 - isStateEditable: false,
640 - name: 'Memo',
641 - value: 'not used',
642 - debugInfo: null,
643 - subHooks: [],
644 - },
645 - ]);
924 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
925 + [
926 + {
927 + "debugInfo": null,
928 + "hookSource": {
929 + "columnNumber": 0,
930 + "fileName": "**",
931 + "functionName": null,
932 + "lineNumber": 0,
933 + },
934 + "id": 0,
935 + "isStateEditable": false,
936 + "name": "Transition",
937 + "subHooks": [],
938 + "value": undefined,
939 + },
940 + {
941 + "debugInfo": null,
942 + "hookSource": {
943 + "columnNumber": 0,
944 + "fileName": "**",
945 + "functionName": "Foo",
946 + "lineNumber": 0,
947 + },
948 + "id": 1,
949 + "isStateEditable": false,
950 + "name": "Memo",
951 + "subHooks": [],
952 + "value": "hello",
953 + },
954 + {
955 + "debugInfo": null,
956 + "hookSource": {
957 + "columnNumber": 0,
958 + "fileName": "**",
959 + "functionName": "Foo",
960 + "lineNumber": 0,
961 + },
962 + "id": 2,
963 + "isStateEditable": false,
964 + "name": "Memo",
965 + "subHooks": [],
966 + "value": "not used",
967 + },
968 + ]
969 + `);
970 });
971
972 it('should support useDeferredValue hook', () => {
@@ -655,32 +979,52 @@ describe('ReactHooksInspectionIntegration', () => {
979 const renderer = ReactTestRenderer.create(<Foo />);
980 const childFiber = renderer.root.findByType(Foo)._currentFiber();
981 const tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
658 - expect(tree).toEqual([
659 - {
660 - id: 0,
661 - isStateEditable: false,
662 - name: 'DeferredValue',
663 - value: 'abc',
664 - debugInfo: null,
665 - subHooks: [],
666 - },
667 - {
668 - id: 1,
669 - isStateEditable: false,
670 - name: 'Memo',
671 - value: 1,
672 - debugInfo: null,
673 - subHooks: [],
674 - },
675 - {
676 - id: 2,
677 - isStateEditable: false,
678 - name: 'Memo',
679 - value: 2,
680 - debugInfo: null,
681 - subHooks: [],
682 - },
683 - ]);
982 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
983 + [
984 + {
985 + "debugInfo": null,
986 + "hookSource": {
987 + "columnNumber": 0,
988 + "fileName": "**",
989 + "functionName": null,
990 + "lineNumber": 0,
991 + },
992 + "id": 0,
993 + "isStateEditable": false,
994 + "name": "DeferredValue",
995 + "subHooks": [],
996 + "value": "abc",
997 + },
998 + {
999 + "debugInfo": null,
1000 + "hookSource": {
1001 + "columnNumber": 0,
1002 + "fileName": "**",
1003 + "functionName": "Foo",
1004 + "lineNumber": 0,
1005 + },
1006 + "id": 1,
1007 + "isStateEditable": false,
1008 + "name": "Memo",
1009 + "subHooks": [],
1010 + "value": 1,
1011 + },
1012 + {
1013 + "debugInfo": null,
1014 + "hookSource": {
1015 + "columnNumber": 0,
1016 + "fileName": "**",
1017 + "functionName": "Foo",
1018 + "lineNumber": 0,
1019 + },
1020 + "id": 2,
1021 + "isStateEditable": false,
1022 + "name": "Memo",
1023 + "subHooks": [],
1024 + "value": 2,
1025 + },
1026 + ]
1027 + `);
1028 });
1029
1030 it('should support useId hook', () => {
@@ -701,14 +1045,22 @@ describe('ReactHooksInspectionIntegration', () => {
1045 expect(tree[0].name).toEqual('Id');
1046 expect(String(tree[0].value).startsWith(':r')).toBe(true);
1047
704 - expect(tree[1]).toEqual({
705 - id: 1,
706 - isStateEditable: true,
707 - name: 'State',
708 - value: 'hello',
709 - debugInfo: null,
710 - subHooks: [],
711 - });
1048 + expect(normalizeSourceLoc(tree)[1]).toMatchInlineSnapshot(`
1049 + {
1050 + "debugInfo": null,
1051 + "hookSource": {
1052 + "columnNumber": 0,
1053 + "fileName": "**",
1054 + "functionName": "Foo",
1055 + "lineNumber": 0,
1056 + },
1057 + "id": 1,
1058 + "isStateEditable": true,
1059 + "name": "State",
1060 + "subHooks": [],
1061 + "value": "hello",
1062 + }
1063 + `);
1064 });
1065
1066 describe('useMemoCache', () => {
@@ -792,67 +1144,218 @@ describe('ReactHooksInspectionIntegration', () => {
1144 const renderer = ReactTestRenderer.create(<Example />);
1145 const childFiber = renderer.root.findByType(Example)._currentFiber();
1146 const tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
795 - expect(tree).toEqual([
796 - {
797 - isStateEditable: false,
798 - id: null,
799 - name: 'LabeledValue',
800 - value: __DEV__ ? 'custom label a' : undefined,
801 - debugInfo: null,
802 - subHooks: [
1147 + if (__DEV__) {
1148 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
1149 + [
1150 {
804 - isStateEditable: true,
805 - id: 0,
806 - name: 'State',
807 - value: 'a',
808 - debugInfo: null,
809 - subHooks: [],
1151 + "debugInfo": null,
1152 + "hookSource": {
1153 + "columnNumber": 0,
1154 + "fileName": "**",
1155 + "functionName": "Example",
1156 + "lineNumber": 0,
1157 + },
1158 + "id": null,
1159 + "isStateEditable": false,
1160 + "name": "LabeledValue",
1161 + "subHooks": [
1162 + {
1163 + "debugInfo": null,
1164 + "hookSource": {
1165 + "columnNumber": 0,
1166 + "fileName": "**",
1167 + "functionName": "useLabeledValue",
1168 + "lineNumber": 0,
1169 + },
1170 + "id": 0,
1171 + "isStateEditable": true,
1172 + "name": "State",
1173 + "subHooks": [],
1174 + "value": "a",
1175 + },
1176 + ],
1177 + "value": "custom label a",
1178 },
811 - ],
812 - },
813 - {
814 - isStateEditable: true,
815 - id: 1,
816 - name: 'State',
817 - value: 'b',
818 - debugInfo: null,
819 - subHooks: [],
820 - },
821 - {
822 - isStateEditable: false,
823 - id: null,
824 - name: 'Anonymous',
825 - value: undefined,
826 - debugInfo: null,
827 - subHooks: [
1179 {
829 - isStateEditable: true,
830 - id: 2,
831 - name: 'State',
832 - value: 'c',
833 - debugInfo: null,
834 - subHooks: [],
1180 + "debugInfo": null,
1181 + "hookSource": {
1182 + "columnNumber": 0,
1183 + "fileName": "**",
1184 + "functionName": "Example",
1185 + "lineNumber": 0,
1186 + },
1187 + "id": 1,
1188 + "isStateEditable": true,
1189 + "name": "State",
1190 + "subHooks": [],
1191 + "value": "b",
1192 },
836 - ],
837 - },
838 - {
839 - isStateEditable: false,
840 - id: null,
841 - name: 'LabeledValue',
842 - value: __DEV__ ? 'custom label d' : undefined,
843 - debugInfo: null,
844 - subHooks: [
1193 {
846 - isStateEditable: true,
847 - id: 3,
848 - name: 'State',
849 - value: 'd',
850 - debugInfo: null,
851 - subHooks: [],
1194 + "debugInfo": null,
1195 + "hookSource": {
1196 + "columnNumber": 0,
1197 + "fileName": "**",
1198 + "functionName": "Example",
1199 + "lineNumber": 0,
1200 + },
1201 + "id": null,
1202 + "isStateEditable": false,
1203 + "name": "Anonymous",
1204 + "subHooks": [
1205 + {
1206 + "debugInfo": null,
1207 + "hookSource": {
1208 + "columnNumber": 0,
1209 + "fileName": "**",
1210 + "functionName": "useAnonymous",
1211 + "lineNumber": 0,
1212 + },
1213 + "id": 2,
1214 + "isStateEditable": true,
1215 + "name": "State",
1216 + "subHooks": [],
1217 + "value": "c",
1218 + },
1219 + ],
1220 + "value": undefined,
1221 },
853 - ],
854 - },
855 - ]);
1222 + {
1223 + "debugInfo": null,
1224 + "hookSource": {
1225 + "columnNumber": 0,
1226 + "fileName": "**",
1227 + "functionName": "Example",
1228 + "lineNumber": 0,
1229 + },
1230 + "id": null,
1231 + "isStateEditable": false,
1232 + "name": "LabeledValue",
1233 + "subHooks": [
1234 + {
1235 + "debugInfo": null,
1236 + "hookSource": {
1237 + "columnNumber": 0,
1238 + "fileName": "**",
1239 + "functionName": "useLabeledValue",
1240 + "lineNumber": 0,
1241 + },
1242 + "id": 3,
1243 + "isStateEditable": true,
1244 + "name": "State",
1245 + "subHooks": [],
1246 + "value": "d",
1247 + },
1248 + ],
1249 + "value": "custom label d",
1250 + },
1251 + ]
1252 + `);
1253 + } else
1254 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
1255 + [
1256 + {
1257 + "debugInfo": null,
1258 + "hookSource": {
1259 + "columnNumber": 0,
1260 + "fileName": "**",
1261 + "functionName": "Example",
1262 + "lineNumber": 0,
1263 + },
1264 + "id": null,
1265 + "isStateEditable": false,
1266 + "name": "LabeledValue",
1267 + "subHooks": [
1268 + {
1269 + "debugInfo": null,
1270 + "hookSource": {
1271 + "columnNumber": 0,
1272 + "fileName": "**",
1273 + "functionName": "useLabeledValue",
1274 + "lineNumber": 0,
1275 + },
1276 + "id": 0,
1277 + "isStateEditable": true,
1278 + "name": "State",
1279 + "subHooks": [],
1280 + "value": "a",
1281 + },
1282 + ],
1283 + "value": undefined,
1284 + },
1285 + {
1286 + "debugInfo": null,
1287 + "hookSource": {
1288 + "columnNumber": 0,
1289 + "fileName": "**",
1290 + "functionName": "Example",
1291 + "lineNumber": 0,
1292 + },
1293 + "id": 1,
1294 + "isStateEditable": true,
1295 + "name": "State",
1296 + "subHooks": [],
1297 + "value": "b",
1298 + },
1299 + {
1300 + "debugInfo": null,
1301 + "hookSource": {
1302 + "columnNumber": 0,
1303 + "fileName": "**",
1304 + "functionName": "Example",
1305 + "lineNumber": 0,
1306 + },
1307 + "id": null,
1308 + "isStateEditable": false,
1309 + "name": "Anonymous",
1310 + "subHooks": [
1311 + {
1312 + "debugInfo": null,
1313 + "hookSource": {
1314 + "columnNumber": 0,
1315 + "fileName": "**",
1316 + "functionName": "useAnonymous",
1317 + "lineNumber": 0,
1318 + },
1319 + "id": 2,
1320 + "isStateEditable": true,
1321 + "name": "State",
1322 + "subHooks": [],
1323 + "value": "c",
1324 + },
1325 + ],
1326 + "value": undefined,
1327 + },
1328 + {
1329 + "debugInfo": null,
1330 + "hookSource": {
1331 + "columnNumber": 0,
1332 + "fileName": "**",
1333 + "functionName": "Example",
1334 + "lineNumber": 0,
1335 + },
1336 + "id": null,
1337 + "isStateEditable": false,
1338 + "name": "LabeledValue",
1339 + "subHooks": [
1340 + {
1341 + "debugInfo": null,
1342 + "hookSource": {
1343 + "columnNumber": 0,
1344 + "fileName": "**",
1345 + "functionName": "useLabeledValue",
1346 + "lineNumber": 0,
1347 + },
1348 + "id": 3,
1349 + "isStateEditable": true,
1350 + "name": "State",
1351 + "subHooks": [],
1352 + "value": "d",
1353 + },
1354 + ],
1355 + "value": undefined,
1356 + },
1357 + ]
1358 + `);
1359 });
1360
1361 it('should support inspectable values for nested custom hooks', () => {
@@ -871,34 +1374,104 @@ describe('ReactHooksInspectionIntegration', () => {
1374 const renderer = ReactTestRenderer.create(<Example />);
1375 const childFiber = renderer.root.findByType(Example)._currentFiber();
1376 const tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
874 - expect(tree).toEqual([
875 - {
876 - isStateEditable: false,
877 - id: null,
878 - name: 'Outer',
879 - value: __DEV__ ? 'outer' : undefined,
880 - debugInfo: null,
881 - subHooks: [
1377 + if (__DEV__) {
1378 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
1379 + [
1380 {
883 - isStateEditable: false,
884 - id: null,
885 - name: 'Inner',
886 - value: __DEV__ ? 'inner' : undefined,
887 - debugInfo: null,
888 - subHooks: [
1381 + "debugInfo": null,
1382 + "hookSource": {
1383 + "columnNumber": 0,
1384 + "fileName": "**",
1385 + "functionName": "Example",
1386 + "lineNumber": 0,
1387 + },
1388 + "id": null,
1389 + "isStateEditable": false,
1390 + "name": "Outer",
1391 + "subHooks": [
1392 {
890 - isStateEditable: true,
891 - id: 0,
892 - name: 'State',
893 - value: 0,
894 - debugInfo: null,
895 - subHooks: [],
1393 + "debugInfo": null,
1394 + "hookSource": {
1395 + "columnNumber": 0,
1396 + "fileName": "**",
1397 + "functionName": "useOuter",
1398 + "lineNumber": 0,
1399 + },
1400 + "id": null,
1401 + "isStateEditable": false,
1402 + "name": "Inner",
1403 + "subHooks": [
1404 + {
1405 + "debugInfo": null,
1406 + "hookSource": {
1407 + "columnNumber": 0,
1408 + "fileName": "**",
1409 + "functionName": "useInner",
1410 + "lineNumber": 0,
1411 + },
1412 + "id": 0,
1413 + "isStateEditable": true,
1414 + "name": "State",
1415 + "subHooks": [],
1416 + "value": 0,
1417 + },
1418 + ],
1419 + "value": "inner",
1420 },
1421 ],
1422 + "value": "outer",
1423 },
899 - ],
900 - },
901 - ]);
1424 + ]
1425 + `);
1426 + } else
1427 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
1428 + [
1429 + {
1430 + "debugInfo": null,
1431 + "hookSource": {
1432 + "columnNumber": 0,
1433 + "fileName": "**",
1434 + "functionName": "Example",
1435 + "lineNumber": 0,
1436 + },
1437 + "id": null,
1438 + "isStateEditable": false,
1439 + "name": "Outer",
1440 + "subHooks": [
1441 + {
1442 + "debugInfo": null,
1443 + "hookSource": {
1444 + "columnNumber": 0,
1445 + "fileName": "**",
1446 + "functionName": "useOuter",
1447 + "lineNumber": 0,
1448 + },
1449 + "id": null,
1450 + "isStateEditable": false,
1451 + "name": "Inner",
1452 + "subHooks": [
1453 + {
1454 + "debugInfo": null,
1455 + "hookSource": {
1456 + "columnNumber": 0,
1457 + "fileName": "**",
1458 + "functionName": "useInner",
1459 + "lineNumber": 0,
1460 + },
1461 + "id": 0,
1462 + "isStateEditable": true,
1463 + "name": "State",
1464 + "subHooks": [],
1465 + "value": 0,
1466 + },
1467 + ],
1468 + "value": undefined,
1469 + },
1470 + ],
1471 + "value": undefined,
1472 + },
1473 + ]
1474 + `);
1475 });
1476
1477 it('should support multiple inspectable values per custom hooks', () => {
@@ -921,59 +1494,194 @@ describe('ReactHooksInspectionIntegration', () => {
1494 const renderer = ReactTestRenderer.create(<Example />);
1495 const childFiber = renderer.root.findByType(Example)._currentFiber();
1496 const tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
924 - expect(tree).toEqual([
925 - {
926 - isStateEditable: false,
927 - id: null,
928 - name: 'SingleLabelCustom',
929 - value: __DEV__ ? 'single one' : undefined,
930 - debugInfo: null,
931 - subHooks: [
1497 + if (__DEV__) {
1498 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
1499 + [
1500 {
933 - isStateEditable: true,
934 - id: 0,
935 - name: 'State',
936 - value: 0,
937 - debugInfo: null,
938 - subHooks: [],
1501 + "debugInfo": null,
1502 + "hookSource": {
1503 + "columnNumber": 0,
1504 + "fileName": "**",
1505 + "functionName": "Example",
1506 + "lineNumber": 0,
1507 + },
1508 + "id": null,
1509 + "isStateEditable": false,
1510 + "name": "SingleLabelCustom",
1511 + "subHooks": [
1512 + {
1513 + "debugInfo": null,
1514 + "hookSource": {
1515 + "columnNumber": 0,
1516 + "fileName": "**",
1517 + "functionName": "useSingleLabelCustom",
1518 + "lineNumber": 0,
1519 + },
1520 + "id": 0,
1521 + "isStateEditable": true,
1522 + "name": "State",
1523 + "subHooks": [],
1524 + "value": 0,
1525 + },
1526 + ],
1527 + "value": "single one",
1528 },
940 - ],
941 - },
942 - {
943 - isStateEditable: false,
944 - id: null,
945 - name: 'MultiLabelCustom',
946 - value: __DEV__ ? ['one', 'two', 'three'] : undefined,
947 - debugInfo: null,
948 - subHooks: [
1529 {
950 - isStateEditable: true,
951 - id: 1,
952 - name: 'State',
953 - value: 0,
954 - debugInfo: null,
955 - subHooks: [],
1530 + "debugInfo": null,
1531 + "hookSource": {
1532 + "columnNumber": 0,
1533 + "fileName": "**",
1534 + "functionName": "Example",
1535 + "lineNumber": 0,
1536 + },
1537 + "id": null,
1538 + "isStateEditable": false,
1539 + "name": "MultiLabelCustom",
1540 + "subHooks": [
1541 + {
1542 + "debugInfo": null,
1543 + "hookSource": {
1544 + "columnNumber": 0,
1545 + "fileName": "**",
1546 + "functionName": "useMultiLabelCustom",
1547 + "lineNumber": 0,
1548 + },
1549 + "id": 1,
1550 + "isStateEditable": true,
1551 + "name": "State",
1552 + "subHooks": [],
1553 + "value": 0,
1554 + },
1555 + ],
1556 + "value": [
1557 + "one",
1558 + "two",
1559 + "three",
1560 + ],
1561 },
957 - ],
958 - },
959 - {
960 - isStateEditable: false,
961 - id: null,
962 - name: 'SingleLabelCustom',
963 - value: __DEV__ ? 'single two' : undefined,
964 - debugInfo: null,
965 - subHooks: [
1562 {
967 - isStateEditable: true,
968 - id: 2,
969 - name: 'State',
970 - value: 0,
971 - debugInfo: null,
972 - subHooks: [],
1563 + "debugInfo": null,
1564 + "hookSource": {
1565 + "columnNumber": 0,
1566 + "fileName": "**",
1567 + "functionName": "Example",
1568 + "lineNumber": 0,
1569 + },
1570 + "id": null,
1571 + "isStateEditable": false,
1572 + "name": "SingleLabelCustom",
1573 + "subHooks": [
1574 + {
1575 + "debugInfo": null,
1576 + "hookSource": {
1577 + "columnNumber": 0,
1578 + "fileName": "**",
1579 + "functionName": "useSingleLabelCustom",
1580 + "lineNumber": 0,
1581 + },
1582 + "id": 2,
1583 + "isStateEditable": true,
1584 + "name": "State",
1585 + "subHooks": [],
1586 + "value": 0,
1587 + },
1588 + ],
1589 + "value": "single two",
1590 },
974 - ],
975 - },
976 - ]);
1591 + ]
1592 + `);
1593 + } else
1594 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
1595 + [
1596 + {
1597 + "debugInfo": null,
1598 + "hookSource": {
1599 + "columnNumber": 0,
1600 + "fileName": "**",
1601 + "functionName": "Example",
1602 + "lineNumber": 0,
1603 + },
1604 + "id": null,
1605 + "isStateEditable": false,
1606 + "name": "SingleLabelCustom",
1607 + "subHooks": [
1608 + {
1609 + "debugInfo": null,
1610 + "hookSource": {
1611 + "columnNumber": 0,
1612 + "fileName": "**",
1613 + "functionName": "useSingleLabelCustom",
1614 + "lineNumber": 0,
1615 + },
1616 + "id": 0,
1617 + "isStateEditable": true,
1618 + "name": "State",
1619 + "subHooks": [],
1620 + "value": 0,
1621 + },
1622 + ],
1623 + "value": undefined,
1624 + },
1625 + {
1626 + "debugInfo": null,
1627 + "hookSource": {
1628 + "columnNumber": 0,
1629 + "fileName": "**",
1630 + "functionName": "Example",
1631 + "lineNumber": 0,
1632 + },
1633 + "id": null,
1634 + "isStateEditable": false,
1635 + "name": "MultiLabelCustom",
1636 + "subHooks": [
1637 + {
1638 + "debugInfo": null,
1639 + "hookSource": {
1640 + "columnNumber": 0,
1641 + "fileName": "**",
1642 + "functionName": "useMultiLabelCustom",
1643 + "lineNumber": 0,
1644 + },
1645 + "id": 1,
1646 + "isStateEditable": true,
1647 + "name": "State",
1648 + "subHooks": [],
1649 + "value": 0,
1650 + },
1651 + ],
1652 + "value": undefined,
1653 + },
1654 + {
1655 + "debugInfo": null,
1656 + "hookSource": {
1657 + "columnNumber": 0,
1658 + "fileName": "**",
1659 + "functionName": "Example",
1660 + "lineNumber": 0,
1661 + },
1662 + "id": null,
1663 + "isStateEditable": false,
1664 + "name": "SingleLabelCustom",
1665 + "subHooks": [
1666 + {
1667 + "debugInfo": null,
1668 + "hookSource": {
1669 + "columnNumber": 0,
1670 + "fileName": "**",
1671 + "functionName": "useSingleLabelCustom",
1672 + "lineNumber": 0,
1673 + },
1674 + "id": 2,
1675 + "isStateEditable": true,
1676 + "name": "State",
1677 + "subHooks": [],
1678 + "value": 0,
1679 + },
1680 + ],
1681 + "value": undefined,
1682 + },
1683 + ]
1684 + `);
1685 });
1686
1687 it('should ignore useDebugValue() made outside of a custom hook', () => {
@@ -999,25 +1707,74 @@ describe('ReactHooksInspectionIntegration', () => {
1707 const renderer = ReactTestRenderer.create(<Example />);
1708 const childFiber = renderer.root.findByType(Example)._currentFiber();
1709 const tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
1002 - expect(tree).toEqual([
1003 - {
1004 - isStateEditable: false,
1005 - id: null,
1006 - name: 'Custom',
1007 - value: __DEV__ ? 'bar:123' : undefined,
1008 - debugInfo: null,
1009 - subHooks: [
1710 + if (__DEV__) {
1711 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
1712 + [
1713 + {
1714 + "debugInfo": null,
1715 + "hookSource": {
1716 + "columnNumber": 0,
1717 + "fileName": "**",
1718 + "functionName": "Example",
1719 + "lineNumber": 0,
1720 + },
1721 + "id": null,
1722 + "isStateEditable": false,
1723 + "name": "Custom",
1724 + "subHooks": [
1725 + {
1726 + "debugInfo": null,
1727 + "hookSource": {
1728 + "columnNumber": 0,
1729 + "fileName": "**",
1730 + "functionName": "useCustom",
1731 + "lineNumber": 0,
1732 + },
1733 + "id": 0,
1734 + "isStateEditable": true,
1735 + "name": "State",
1736 + "subHooks": [],
1737 + "value": 0,
1738 + },
1739 + ],
1740 + "value": "bar:123",
1741 + },
1742 + ]
1743 + `);
1744 + } else
1745 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
1746 + [
1747 {
1011 - isStateEditable: true,
1012 - id: 0,
1013 - name: 'State',
1014 - debugInfo: null,
1015 - subHooks: [],
1016 - value: 0,
1748 + "debugInfo": null,
1749 + "hookSource": {
1750 + "columnNumber": 0,
1751 + "fileName": "**",
1752 + "functionName": "Example",
1753 + "lineNumber": 0,
1754 + },
1755 + "id": null,
1756 + "isStateEditable": false,
1757 + "name": "Custom",
1758 + "subHooks": [
1759 + {
1760 + "debugInfo": null,
1761 + "hookSource": {
1762 + "columnNumber": 0,
1763 + "fileName": "**",
1764 + "functionName": "useCustom",
1765 + "lineNumber": 0,
1766 + },
1767 + "id": 0,
1768 + "isStateEditable": true,
1769 + "name": "State",
1770 + "subHooks": [],
1771 + "value": 0,
1772 + },
1773 + ],
1774 + "value": undefined,
1775 },
1018 - ],
1019 - },
1020 - ]);
1776 + ]
1777 + `);
1778 });
1779 });
1780
@@ -1052,16 +1809,24 @@ describe('ReactHooksInspectionIntegration', () => {
1809
1810 const childFiber = renderer.root._currentFiber();
1811 const tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
1055 - expect(tree).toEqual([
1056 - {
1057 - isStateEditable: true,
1058 - id: 0,
1059 - name: 'State',
1060 - value: 'def',
1061 - debugInfo: null,
1062 - subHooks: [],
1063 - },
1064 - ]);
1812 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
1813 + [
1814 + {
1815 + "debugInfo": null,
1816 + "hookSource": {
1817 + "columnNumber": 0,
1818 + "fileName": "**",
1819 + "functionName": "Foo",
1820 + "lineNumber": 0,
1821 + },
1822 + "id": 0,
1823 + "isStateEditable": true,
1824 + "name": "State",
1825 + "subHooks": [],
1826 + "value": "def",
1827 + },
1828 + ]
1829 + `);
1830 });
1831
1832 it('should support an injected dispatcher', () => {
@@ -1146,24 +1911,40 @@ describe('ReactHooksInspectionIntegration', () => {
1911
1912 const childFiber = renderer.root._currentFiber();
1913 const tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
1149 - expect(tree).toEqual([
1150 - {
1151 - isStateEditable: false,
1152 - id: null,
1153 - name: 'Context',
1154 - value: 1,
1155 - debugInfo: null,
1156 - subHooks: [],
1157 - },
1158 - {
1159 - isStateEditable: true,
1160 - id: 0,
1161 - name: 'State',
1162 - value: {count: 2},
1163 - debugInfo: null,
1164 - subHooks: [],
1165 - },
1166 - ]);
1914 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
1915 + [
1916 + {
1917 + "debugInfo": null,
1918 + "hookSource": {
1919 + "columnNumber": 0,
1920 + "fileName": "**",
1921 + "functionName": "Foo",
1922 + "lineNumber": 0,
1923 + },
1924 + "id": null,
1925 + "isStateEditable": false,
1926 + "name": "Context",
1927 + "subHooks": [],
1928 + "value": 1,
1929 + },
1930 + {
1931 + "debugInfo": null,
1932 + "hookSource": {
1933 + "columnNumber": 0,
1934 + "fileName": "**",
1935 + "functionName": "Foo",
1936 + "lineNumber": 0,
1937 + },
1938 + "id": 0,
1939 + "isStateEditable": true,
1940 + "name": "State",
1941 + "subHooks": [],
1942 + "value": {
1943 + "count": 2,
1944 + },
1945 + },
1946 + ]
1947 + `);
1948 });
1949
1950 it('should support composite useSyncExternalStore hook', () => {
@@ -1181,32 +1962,52 @@ describe('ReactHooksInspectionIntegration', () => {
1962 const renderer = ReactTestRenderer.create(<Foo />);
1963 const childFiber = renderer.root.findByType(Foo)._currentFiber();
1964 const tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
1184 - expect(tree).toEqual([
1185 - {
1186 - id: 0,
1187 - isStateEditable: false,
1188 - name: 'SyncExternalStore',
1189 - value: 'snapshot',
1190 - debugInfo: null,
1191 - subHooks: [],
1192 - },
1193 - {
1194 - id: 1,
1195 - isStateEditable: false,
1196 - name: 'Memo',
1197 - value: 'memo',
1198 - debugInfo: null,
1199 - subHooks: [],
1200 - },
1201 - {
1202 - id: 2,
1203 - isStateEditable: false,
1204 - name: 'Memo',
1205 - value: 'not used',
1206 - debugInfo: null,
1207 - subHooks: [],
1208 - },
1209 - ]);
1965 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
1966 + [
1967 + {
1968 + "debugInfo": null,
1969 + "hookSource": {
1970 + "columnNumber": 0,
1971 + "fileName": "**",
1972 + "functionName": null,
1973 + "lineNumber": 0,
1974 + },
1975 + "id": 0,
1976 + "isStateEditable": false,
1977 + "name": "SyncExternalStore",
1978 + "subHooks": [],
1979 + "value": "snapshot",
1980 + },
1981 + {
1982 + "debugInfo": null,
1983 + "hookSource": {
1984 + "columnNumber": 0,
1985 + "fileName": "**",
1986 + "functionName": "Foo",
1987 + "lineNumber": 0,
1988 + },
1989 + "id": 1,
1990 + "isStateEditable": false,
1991 + "name": "Memo",
1992 + "subHooks": [],
1993 + "value": "memo",
1994 + },
1995 + {
1996 + "debugInfo": null,
1997 + "hookSource": {
1998 + "columnNumber": 0,
1999 + "fileName": "**",
2000 + "functionName": "Foo",
2001 + "lineNumber": 0,
2002 + },
2003 + "id": 2,
2004 + "isStateEditable": false,
2005 + "name": "Memo",
2006 + "subHooks": [],
2007 + "value": "not used",
2008 + },
2009 + ]
2010 + `);
2011 });
2012
2013 it('should support use(Context) hook', () => {
@@ -1222,32 +2023,52 @@ describe('ReactHooksInspectionIntegration', () => {
2023 const renderer = ReactTestRenderer.create(<Foo />);
2024 const childFiber = renderer.root.findByType(Foo)._currentFiber();
2025 const tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
1225 - expect(tree).toEqual([
1226 - {
1227 - id: null,
1228 - isStateEditable: false,
1229 - name: 'Context',
1230 - value: 'default',
1231 - debugInfo: null,
1232 - subHooks: [],
1233 - },
1234 - {
1235 - id: 0,
1236 - isStateEditable: false,
1237 - name: 'Memo',
1238 - value: 'memo',
1239 - debugInfo: null,
1240 - subHooks: [],
1241 - },
1242 - {
1243 - id: 1,
1244 - isStateEditable: false,
1245 - name: 'Memo',
1246 - value: 'not used',
1247 - debugInfo: null,
1248 - subHooks: [],
1249 - },
1250 - ]);
2026 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
2027 + [
2028 + {
2029 + "debugInfo": null,
2030 + "hookSource": {
2031 + "columnNumber": 0,
2032 + "fileName": "**",
2033 + "functionName": "Foo",
2034 + "lineNumber": 0,
2035 + },
2036 + "id": null,
2037 + "isStateEditable": false,
2038 + "name": "Context",
2039 + "subHooks": [],
2040 + "value": "default",
2041 + },
2042 + {
2043 + "debugInfo": null,
2044 + "hookSource": {
2045 + "columnNumber": 0,
2046 + "fileName": "**",
2047 + "functionName": "Foo",
2048 + "lineNumber": 0,
2049 + },
2050 + "id": 0,
2051 + "isStateEditable": false,
2052 + "name": "Memo",
2053 + "subHooks": [],
2054 + "value": "memo",
2055 + },
2056 + {
2057 + "debugInfo": null,
2058 + "hookSource": {
2059 + "columnNumber": 0,
2060 + "fileName": "**",
2061 + "functionName": "Foo",
2062 + "lineNumber": 0,
2063 + },
2064 + "id": 1,
2065 + "isStateEditable": false,
2066 + "name": "Memo",
2067 + "subHooks": [],
2068 + "value": "not used",
2069 + },
2070 + ]
2071 + `);
2072 });
2073
2074 // @gate enableAsyncActions
@@ -1263,32 +2084,52 @@ describe('ReactHooksInspectionIntegration', () => {
2084 const renderer = ReactTestRenderer.create(<Foo />);
2085 const childFiber = renderer.root.findByType(Foo)._currentFiber();
2086 const tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
1266 - expect(tree).toEqual([
1267 - {
1268 - id: 0,
1269 - isStateEditable: false,
1270 - name: 'Optimistic',
1271 - value: 'abc',
1272 - debugInfo: null,
1273 - subHooks: [],
1274 - },
1275 - {
1276 - id: 1,
1277 - isStateEditable: false,
1278 - name: 'Memo',
1279 - value: 'memo',
1280 - debugInfo: null,
1281 - subHooks: [],
1282 - },
1283 - {
1284 - id: 2,
1285 - isStateEditable: false,
1286 - name: 'Memo',
1287 - value: 'not used',
1288 - debugInfo: null,
1289 - subHooks: [],
1290 - },
1291 - ]);
2087 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
2088 + [
2089 + {
2090 + "debugInfo": null,
2091 + "hookSource": {
2092 + "columnNumber": 0,
2093 + "fileName": "**",
2094 + "functionName": "Foo",
2095 + "lineNumber": 0,
2096 + },
2097 + "id": 0,
2098 + "isStateEditable": false,
2099 + "name": "Optimistic",
2100 + "subHooks": [],
2101 + "value": "abc",
2102 + },
2103 + {
2104 + "debugInfo": null,
2105 + "hookSource": {
2106 + "columnNumber": 0,
2107 + "fileName": "**",
2108 + "functionName": "Foo",
2109 + "lineNumber": 0,
2110 + },
2111 + "id": 1,
2112 + "isStateEditable": false,
2113 + "name": "Memo",
2114 + "subHooks": [],
2115 + "value": "memo",
2116 + },
2117 + {
2118 + "debugInfo": null,
2119 + "hookSource": {
2120 + "columnNumber": 0,
2121 + "fileName": "**",
2122 + "functionName": "Foo",
2123 + "lineNumber": 0,
2124 + },
2125 + "id": 2,
2126 + "isStateEditable": false,
2127 + "name": "Memo",
2128 + "subHooks": [],
2129 + "value": "not used",
2130 + },
2131 + ]
2132 + `);
2133 });
2134
2135 // @gate enableFormActions && enableAsyncActions
@@ -1306,31 +2147,51 @@ describe('ReactHooksInspectionIntegration', () => {
2147 const renderer = ReactTestRenderer.create(<Foo />);
2148 const childFiber = renderer.root.findByType(Foo)._currentFiber();
2149 const tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
1309 - expect(tree).toEqual([
1310 - {
1311 - id: 0,
1312 - isStateEditable: false,
1313 - name: 'FormState',
1314 - value: 0,
1315 - debugInfo: null,
1316 - subHooks: [],
1317 - },
1318 - {
1319 - id: 1,
1320 - isStateEditable: false,
1321 - name: 'Memo',
1322 - value: 'memo',
1323 - debugInfo: null,
1324 - subHooks: [],
1325 - },
1326 - {
1327 - id: 2,
1328 - isStateEditable: false,
1329 - name: 'Memo',
1330 - value: 'not used',
1331 - debugInfo: null,
1332 - subHooks: [],
1333 - },
1334 - ]);
2150 + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
2151 + [
2152 + {
2153 + "debugInfo": null,
2154 + "hookSource": {
2155 + "columnNumber": 0,
2156 + "fileName": "**",
2157 + "functionName": "Foo",
2158 + "lineNumber": 0,
2159 + },
2160 + "id": 0,
2161 + "isStateEditable": false,
2162 + "name": "FormState",
2163 + "subHooks": [],
2164 + "value": 0,
2165 + },
2166 + {
2167 + "debugInfo": null,
2168 + "hookSource": {
2169 + "columnNumber": 0,
2170 + "fileName": "**",
2171 + "functionName": "Foo",
2172 + "lineNumber": 0,
2173 + },
2174 + "id": 1,
2175 + "isStateEditable": false,
2176 + "name": "Memo",
2177 + "subHooks": [],
2178 + "value": "memo",
2179 + },
2180 + {
2181 + "debugInfo": null,
2182 + "hookSource": {
2183 + "columnNumber": 0,
2184 + "fileName": "**",
2185 + "functionName": "Foo",
2186 + "lineNumber": 0,
2187 + },
2188 + "id": 2,
2189 + "isStateEditable": false,
2190 + "name": "Memo",
2191 + "subHooks": [],
2192 + "value": "not used",
2193 + },
2194 + ]
2195 + `);
2196 });
2197 });
packages/react-devtools-shared/src/backend/renderer.js
-1
@@ -3301,7 +3301,6 @@ export function attach(
3301 hooks = inspectHooksOfFiber(
3302 fiber,
3303 (renderer.currentDispatcherRef: any),
3304 - true, // Include source location info for hooks
3304 );
3305 } finally {
3306 // Restore original console functionality.
packages/react-devtools-shared/src/hooks/__tests__/parseHookNames-test.js
+2 -2
@@ -98,7 +98,7 @@ describe('parseHookNames', () => {
98 });
99
100 async function getHookNamesForComponent(Component, props = {}) {
101 - const hooksTree = inspectHooks(Component, props, undefined, true);
101 + const hooksTree = inspectHooks(Component, props, undefined);
102 const hookNames = await parseHookNames(hooksTree);
103 return hookNames;
104 }
@@ -928,7 +928,7 @@ describe('parseHookNames worker', () => {
928 });
929
930 async function getHookNamesForComponent(Component, props = {}) {
931 - const hooksTree = inspectHooks(Component, props, undefined, true);
931 + const hooksTree = inspectHooks(Component, props, undefined);
932 const hookNames = await parseHookNames(hooksTree);
933 return hookNames;
934 }