@@ -5,14 +5,16 @@ import {
55 formatSearchResults ,
66 formatCount ,
77 formatStatus ,
8+ formatProfileSummary ,
89 formatProfileReport ,
910 formatSlowest ,
1011 formatRerenders ,
1112 formatTimeline ,
13+ formatCommitDetail ,
1214} from '../formatters.js' ;
1315import type { TreeNode } from '../component-tree.js' ;
1416import type { InspectedElement , StatusInfo , ComponentRenderReport } from '../types.js' ;
15- import type { TimelineEntry } from '../profiler.js' ;
17+ import type { ProfileSummary , TimelineEntry , CommitDetail } from '../profiler.js' ;
1618
1719describe ( 'formatTree' , ( ) => {
1820 it ( 'should format empty tree' , ( ) => {
@@ -27,9 +29,9 @@ describe('formatTree', () => {
2729 ] ;
2830
2931 const result = formatTree ( nodes ) ;
30- expect ( result ) . toContain ( '@c1 [fn] " App" ' ) ;
31- expect ( result ) . toContain ( '@c2 [memo] " Header" ' ) ;
32- expect ( result ) . toContain ( '@c3 [host] " Footer" ' ) ;
32+ expect ( result ) . toContain ( '@c1 [fn] App' ) ;
33+ expect ( result ) . toContain ( '@c2 [memo] Header' ) ;
34+ expect ( result ) . toContain ( '@c3 [host] Footer' ) ;
3335 expect ( result ) . toContain ( '├─' ) ;
3436 expect ( result ) . toContain ( '└─' ) ;
3537 } ) ;
@@ -41,7 +43,7 @@ describe('formatTree', () => {
4143 ] ;
4244
4345 const result = formatTree ( nodes ) ;
44- expect ( result ) . toContain ( 'key=" item-1" ' ) ;
46+ expect ( result ) . toContain ( 'key=item-1' ) ;
4547 } ) ;
4648} ) ;
4749
@@ -63,7 +65,7 @@ describe('formatComponent', () => {
6365 } ;
6466
6567 const result = formatComponent ( element , '@c5' ) ;
66- expect ( result ) . toContain ( '@c5 [fn] " UserProfile" ' ) ;
68+ expect ( result ) . toContain ( '@c5 [fn] UserProfile' ) ;
6769 expect ( result ) . toContain ( 'props:' ) ;
6870 expect ( result ) . toContain ( ' userId: 42' ) ;
6971 expect ( result ) . toContain ( ' theme: "dark"' ) ;
@@ -72,6 +74,23 @@ describe('formatComponent', () => {
7274 expect ( result ) . toContain ( 'hooks:' ) ;
7375 expect ( result ) . toContain ( ' useState: false' ) ;
7476 } ) ;
77+
78+ it ( 'should show key without quotes' , ( ) => {
79+ const element : InspectedElement = {
80+ id : 5 ,
81+ displayName : 'Item' ,
82+ type : 'function' ,
83+ key : 'abc' ,
84+ props : { } ,
85+ state : null ,
86+ hooks : null ,
87+ renderedAt : null ,
88+ } ;
89+
90+ const result = formatComponent ( element , '@c5' ) ;
91+ expect ( result ) . toContain ( 'key=abc' ) ;
92+ expect ( result ) . not . toContain ( 'key="abc"' ) ;
93+ } ) ;
7594} ) ;
7695
7796describe ( 'formatSearchResults' , ( ) => {
@@ -86,9 +105,9 @@ describe('formatSearchResults', () => {
86105 ] ;
87106
88107 const result = formatSearchResults ( results ) ;
89- expect ( result ) . toContain ( '@c2 [fn] " UserProfile" ' ) ;
90- expect ( result ) . toContain ( '@c3 [memo] " UserCard" ' ) ;
91- expect ( result ) . toContain ( 'key=" bob" ' ) ;
108+ expect ( result ) . toContain ( '@c2 [fn] UserProfile' ) ;
109+ expect ( result ) . toContain ( '@c3 [memo] UserCard' ) ;
110+ expect ( result ) . toContain ( 'key=bob' ) ;
92111 } ) ;
93112} ) ;
94113
@@ -122,54 +141,113 @@ describe('formatStatus', () => {
122141 } ) ;
123142} ) ;
124143
144+ describe ( 'formatProfileSummary' , ( ) => {
145+ it ( 'should format summary with labels and types' , ( ) => {
146+ const summary : ProfileSummary = {
147+ name : 'test-session' ,
148+ duration : 5000 ,
149+ commitCount : 3 ,
150+ componentRenderCounts : [
151+ { id : 1 , displayName : 'App' , label : '@c1' , type : 'function' , count : 10 } ,
152+ { id : 2 , displayName : 'Header' , label : '@c2' , type : 'memo' , count : 5 } ,
153+ ] ,
154+ } ;
155+
156+ const result = formatProfileSummary ( summary ) ;
157+ expect ( result ) . toContain ( 'test-session' ) ;
158+ expect ( result ) . toContain ( '5.0s' ) ;
159+ expect ( result ) . toContain ( '3 commits' ) ;
160+ expect ( result ) . toContain ( '@c1 [fn] App' ) ;
161+ expect ( result ) . toContain ( '10 renders' ) ;
162+ expect ( result ) . toContain ( '@c2 [memo] Header' ) ;
163+ expect ( result ) . toContain ( '5 renders' ) ;
164+ } ) ;
165+
166+ it ( 'should fallback for missing labels' , ( ) => {
167+ const summary : ProfileSummary = {
168+ name : 'sess' ,
169+ duration : 1000 ,
170+ commitCount : 1 ,
171+ componentRenderCounts : [
172+ { id : 1 , displayName : 'App' , count : 3 } ,
173+ ] ,
174+ } ;
175+
176+ const result = formatProfileSummary ( summary ) ;
177+ expect ( result ) . toContain ( '? [?] App' ) ;
178+ } ) ;
179+ } ) ;
180+
125181describe ( 'formatProfileReport' , ( ) => {
126- it ( 'should format a render report' , ( ) => {
182+ it ( 'should format a render report with type tag ' , ( ) => {
127183 const report : ComponentRenderReport = {
128184 id : 5 ,
129185 displayName : 'UserProfile' ,
186+ label : '@c5' ,
187+ type : 'function' ,
130188 renderCount : 12 ,
131189 totalDuration : 540 ,
132190 avgDuration : 45 ,
133191 maxDuration : 120 ,
134192 causes : [ 'props-changed' , 'state-changed' ] ,
135193 } ;
136194
137- const result = formatProfileReport ( report , '@c5' ) ;
138- expect ( result ) . toContain ( '@c5 " UserProfile" ' ) ;
195+ const result = formatProfileReport ( report ) ;
196+ expect ( result ) . toContain ( '@c5 [fn] UserProfile' ) ;
139197 expect ( result ) . toContain ( 'renders:12' ) ;
140198 expect ( result ) . toContain ( 'avg:45.0ms' ) ;
141199 expect ( result ) . toContain ( 'max:120.0ms' ) ;
142200 expect ( result ) . toContain ( 'props-changed' ) ;
143201 } ) ;
202+
203+ it ( 'should prefer explicit label param over report.label' , ( ) => {
204+ const report : ComponentRenderReport = {
205+ id : 5 ,
206+ displayName : 'UserProfile' ,
207+ label : '@c5' ,
208+ type : 'function' ,
209+ renderCount : 1 ,
210+ totalDuration : 10 ,
211+ avgDuration : 10 ,
212+ maxDuration : 10 ,
213+ causes : [ ] ,
214+ } ;
215+
216+ const result = formatProfileReport ( report , '@c99' ) ;
217+ expect ( result ) . toContain ( '@c99 [fn] UserProfile' ) ;
218+ } ) ;
144219} ) ;
145220
146221describe ( 'formatSlowest' , ( ) => {
147222 it ( 'should format empty data' , ( ) => {
148223 expect ( formatSlowest ( [ ] ) ) . toContain ( 'No profiling data' ) ;
149224 } ) ;
150225
151- it ( 'should format slowest components' , ( ) => {
226+ it ( 'should format slowest components with labels and all causes ' , ( ) => {
152227 const reports : ComponentRenderReport [ ] = [
153- { id : 1 , displayName : 'SlowComp' , renderCount : 5 , totalDuration : 250 , avgDuration : 50 , maxDuration : 100 , causes : [ 'props-changed' ] } ,
154- { id : 2 , displayName : 'FastComp' , renderCount : 10 , totalDuration : 100 , avgDuration : 10 , maxDuration : 20 , causes : [ 'state-changed' ] } ,
228+ { id : 1 , displayName : 'SlowComp' , label : '@c1' , type : 'function' , renderCount : 5 , totalDuration : 250 , avgDuration : 50 , maxDuration : 100 , causes : [ 'props-changed' , 'state -changed'] } ,
229+ { id : 2 , displayName : 'FastComp' , label : '@c2' , type : 'memo' , renderCount : 10 , totalDuration : 100 , avgDuration : 10 , maxDuration : 20 , causes : [ 'state-changed' ] } ,
155230 ] ;
156231
157232 const result = formatSlowest ( reports ) ;
158233 expect ( result ) . toContain ( 'Slowest' ) ;
159- expect ( result ) . toContain ( 'SlowComp' ) ;
160- expect ( result ) . toContain ( 'FastComp' ) ;
234+ expect ( result ) . toContain ( '@c1 [fn] SlowComp' ) ;
235+ expect ( result ) . toContain ( '@c2 [memo] FastComp' ) ;
236+ expect ( result ) . toContain ( 'causes:props-changed, state-changed' ) ;
237+ expect ( result ) . toContain ( 'causes:state-changed' ) ;
161238 } ) ;
162239} ) ;
163240
164241describe ( 'formatRerenders' , ( ) => {
165- it ( 'should format rerender data' , ( ) => {
242+ it ( 'should format rerender data with labels and all causes ' , ( ) => {
166243 const reports : ComponentRenderReport [ ] = [
167- { id : 1 , displayName : 'Chatty' , renderCount : 50 , totalDuration : 100 , avgDuration : 2 , maxDuration : 5 , causes : [ 'parent-rendered' ] } ,
244+ { id : 1 , displayName : 'Chatty' , label : '@c1' , type : 'function' , renderCount : 50 , totalDuration : 100 , avgDuration : 2 , maxDuration : 5 , causes : [ 'parent-rendered' , 'props-changed '] } ,
168245 ] ;
169246
170247 const result = formatRerenders ( reports ) ;
171248 expect ( result ) . toContain ( '50 renders' ) ;
172- expect ( result ) . toContain ( 'parent-rendered' ) ;
249+ expect ( result ) . toContain ( '@c1 [fn] Chatty' ) ;
250+ expect ( result ) . toContain ( 'causes:parent-rendered, props-changed' ) ;
173251 } ) ;
174252} ) ;
175253
@@ -187,3 +265,44 @@ describe('formatTimeline', () => {
187265 expect ( result ) . toContain ( '8.3ms' ) ;
188266 } ) ;
189267} ) ;
268+
269+ describe ( 'formatCommitDetail' , ( ) => {
270+ it ( 'should format commit detail with labels and types' , ( ) => {
271+ const detail : CommitDetail = {
272+ index : 0 ,
273+ timestamp : 1000 ,
274+ duration : 15.5 ,
275+ components : [
276+ { id : 1 , displayName : 'App' , label : '@c1' , type : 'function' , actualDuration : 15.5 , selfDuration : 5.2 , causes : [ 'state-changed' ] } ,
277+ { id : 2 , displayName : 'Header' , label : '@c2' , type : 'memo' , actualDuration : 10.3 , selfDuration : 10.3 , causes : [ 'props-changed' , 'hooks-changed' ] } ,
278+ ] ,
279+ totalComponents : 2 ,
280+ } ;
281+
282+ const result = formatCommitDetail ( detail ) ;
283+ expect ( result ) . toContain ( 'Commit #0' ) ;
284+ expect ( result ) . toContain ( '15.5ms' ) ;
285+ expect ( result ) . toContain ( '2 components' ) ;
286+ expect ( result ) . toContain ( '@c1 [fn] App' ) ;
287+ expect ( result ) . toContain ( 'self:5.2ms' ) ;
288+ expect ( result ) . toContain ( 'total:15.5ms' ) ;
289+ expect ( result ) . toContain ( 'causes:state-changed' ) ;
290+ expect ( result ) . toContain ( '@c2 [memo] Header' ) ;
291+ expect ( result ) . toContain ( 'causes:props-changed, hooks-changed' ) ;
292+ } ) ;
293+
294+ it ( 'should show hidden count' , ( ) => {
295+ const detail : CommitDetail = {
296+ index : 1 ,
297+ timestamp : 2000 ,
298+ duration : 10 ,
299+ components : [
300+ { id : 1 , displayName : 'App' , label : '@c1' , type : 'function' , actualDuration : 10 , selfDuration : 10 , causes : [ ] } ,
301+ ] ,
302+ totalComponents : 5 ,
303+ } ;
304+
305+ const result = formatCommitDetail ( detail ) ;
306+ expect ( result ) . toContain ( '... 4 more' ) ;
307+ } ) ;
308+ } ) ;
0 commit comments