@@ -212,6 +212,154 @@ describe('ReactHooksInspectionIntergration', () => {
212212 ] ) ;
213213 } ) ;
214214
215+ describe ( 'useDebugValue' , ( ) => {
216+ it ( 'should support inspectable values for multiple custom hooks' , ( ) => {
217+ function useLabeledValue ( label ) {
218+ let [ value ] = React . useState ( label ) ;
219+ React . useDebugValue ( `custom label ${ label } ` ) ;
220+ return value ;
221+ }
222+ function useAnonymous ( label ) {
223+ let [ value ] = React . useState ( label ) ;
224+ return value ;
225+ }
226+ function Example ( ) {
227+ useLabeledValue ( 'a' ) ;
228+ React . useState ( 'b' ) ;
229+ useAnonymous ( 'c' ) ;
230+ useLabeledValue ( 'd' ) ;
231+ return null ;
232+ }
233+ let renderer = ReactTestRenderer . create ( < Example /> ) ;
234+ let childFiber = renderer . root . findByType ( Example ) . _currentFiber ( ) ;
235+ let tree = ReactDebugTools . inspectHooksOfFiber ( childFiber ) ;
236+ expect ( tree ) . toEqual ( [
237+ {
238+ name : 'LabeledValue' ,
239+ value : __DEV__ ? 'custom label a' : undefined ,
240+ subHooks : [ { name : 'State' , value : 'a' , subHooks : [ ] } ] ,
241+ } ,
242+ {
243+ name : 'State' ,
244+ value : 'b' ,
245+ subHooks : [ ] ,
246+ } ,
247+ {
248+ name : 'Anonymous' ,
249+ value : undefined ,
250+ subHooks : [ { name : 'State' , value : 'c' , subHooks : [ ] } ] ,
251+ } ,
252+ {
253+ name : 'LabeledValue' ,
254+ value : __DEV__ ? 'custom label d' : undefined ,
255+ subHooks : [ { name : 'State' , value : 'd' , subHooks : [ ] } ] ,
256+ } ,
257+ ] ) ;
258+ } ) ;
259+
260+ it ( 'should support inspectable values for nested custom hooks' , ( ) => {
261+ function useInner ( ) {
262+ React . useDebugValue ( 'inner' ) ;
263+ React . useState ( 0 ) ;
264+ }
265+ function useOuter ( ) {
266+ React . useDebugValue ( 'outer' ) ;
267+ useInner ( ) ;
268+ }
269+ function Example ( ) {
270+ useOuter ( ) ;
271+ return null ;
272+ }
273+ let renderer = ReactTestRenderer . create ( < Example /> ) ;
274+ let childFiber = renderer . root . findByType ( Example ) . _currentFiber ( ) ;
275+ let tree = ReactDebugTools . inspectHooksOfFiber ( childFiber ) ;
276+ expect ( tree ) . toEqual ( [
277+ {
278+ name : 'Outer' ,
279+ value : __DEV__ ? 'outer' : undefined ,
280+ subHooks : [
281+ {
282+ name : 'Inner' ,
283+ value : __DEV__ ? 'inner' : undefined ,
284+ subHooks : [ { name : 'State' , value : 0 , subHooks : [ ] } ] ,
285+ } ,
286+ ] ,
287+ } ,
288+ ] ) ;
289+ } ) ;
290+
291+ it ( 'should support multiple inspectable values per custom hooks' , ( ) => {
292+ function useMultiLabelCustom ( ) {
293+ React . useDebugValue ( 'one' ) ;
294+ React . useDebugValue ( 'two' ) ;
295+ React . useDebugValue ( 'three' ) ;
296+ React . useState ( 0 ) ;
297+ }
298+ function useSingleLabelCustom ( value ) {
299+ React . useDebugValue ( `single ${ value } ` ) ;
300+ React . useState ( 0 ) ;
301+ }
302+ function Example ( ) {
303+ useSingleLabelCustom ( 'one' ) ;
304+ useMultiLabelCustom ( ) ;
305+ useSingleLabelCustom ( 'two' ) ;
306+ return null ;
307+ }
308+ let renderer = ReactTestRenderer . create ( < Example /> ) ;
309+ let childFiber = renderer . root . findByType ( Example ) . _currentFiber ( ) ;
310+ let tree = ReactDebugTools . inspectHooksOfFiber ( childFiber ) ;
311+ expect ( tree ) . toEqual ( [
312+ {
313+ name : 'SingleLabelCustom' ,
314+ value : __DEV__ ? 'single one' : undefined ,
315+ subHooks : [ { name : 'State' , value : 0 , subHooks : [ ] } ] ,
316+ } ,
317+ {
318+ name : 'MultiLabelCustom' ,
319+ value : __DEV__ ? [ 'one' , 'two' , 'three' ] : undefined ,
320+ subHooks : [ { name : 'State' , value : 0 , subHooks : [ ] } ] ,
321+ } ,
322+ {
323+ name : 'SingleLabelCustom' ,
324+ value : __DEV__ ? 'single two' : undefined ,
325+ subHooks : [ { name : 'State' , value : 0 , subHooks : [ ] } ] ,
326+ } ,
327+ ] ) ;
328+ } ) ;
329+
330+ it ( 'should ignore useDebugValue() made outside of a custom hook' , ( ) => {
331+ function Example ( ) {
332+ React . useDebugValue ( 'this is invalid' ) ;
333+ return null ;
334+ }
335+ let renderer = ReactTestRenderer . create ( < Example /> ) ;
336+ let childFiber = renderer . root . findByType ( Example ) . _currentFiber ( ) ;
337+ let tree = ReactDebugTools . inspectHooksOfFiber ( childFiber ) ;
338+ expect ( tree ) . toHaveLength ( 0 ) ;
339+ } ) ;
340+
341+ it ( 'should support an optional formatter function param' , ( ) => {
342+ function useCustom ( ) {
343+ React . useDebugValue ( { bar : 123 } , object => `bar:${ object . bar } ` ) ;
344+ React . useState ( 0 ) ;
345+ }
346+ function Example ( ) {
347+ useCustom ( ) ;
348+ return null ;
349+ }
350+ let renderer = ReactTestRenderer . create ( < Example /> ) ;
351+ let childFiber = renderer . root . findByType ( Example ) . _currentFiber ( ) ;
352+ let tree = ReactDebugTools . inspectHooksOfFiber ( childFiber ) ;
353+ expect ( tree ) . toEqual ( [
354+ {
355+ name : 'Custom' ,
356+ value : __DEV__ ? 'bar:123' : undefined ,
357+ subHooks : [ { name : 'State' , subHooks : [ ] , value : 0 } ] ,
358+ } ,
359+ ] ) ;
360+ } ) ;
361+ } ) ;
362+
215363 it ( 'should support defaultProps and lazy' , async ( ) => {
216364 let Suspense = React . Suspense ;
217365
0 commit comments