1212use PHPUnit \Framework \Attributes \DataProviderExternal ;
1313use PHPUnit \Framework \TestCase ;
1414
15+ use function array_fill ;
16+ use function substr_count ;
17+
1518/**
1619 * Unit tests for {@see PanelRenderer} rendering provider-owned declarative panels through the debugger frontend.
1720 *
@@ -63,6 +66,33 @@ public function testCollapseRequiresOptInAndMoreRowsThanThreshold(int $count, bo
6366 );
6467 }
6568
69+ public function testFactStripRendersEveryPairAsADefinitionList (): void
70+ {
71+ $ html = PanelRenderer ::render (
72+ 'Custom ' ,
73+ PanelView ::create ()->facts (
74+ PanelView ::fact ('Charset ' , 'UTF-8 ' ),
75+ PanelView ::fact ('Current language ' , 'en ' ),
76+ ),
77+ );
78+
79+ self ::assertStringContainsString (
80+ '<dl class="yii-debug-fact-strip"> ' ,
81+ $ html ,
82+ 'Strip must be a definition list. ' ,
83+ );
84+ self ::assertStringContainsString (
85+ "<dt class= \"yii-debug-fact-label \"> \nCharset \n</dt> " ,
86+ $ html ,
87+ 'Label must be the term of its pair. ' ,
88+ );
89+ self ::assertStringContainsString (
90+ '<dd class="yii-debug-fact-value" title="UTF-8"> ' ,
91+ $ html ,
92+ 'Value must carry the untruncated text as its title. ' ,
93+ );
94+ }
95+
6696 public function testFilterableTablesReuseTheExistingRowFilter (): void
6797 {
6898 $ html = PanelRenderer ::render (
@@ -275,6 +305,46 @@ public function testLinksRenderAsAnchorsAndIsolateExternalTargets(): void
275305 );
276306 }
277307
308+ public function testManifestGroupsPackagesUnderTheirVendorWithATally (): void
309+ {
310+ $ html = PanelRenderer ::render (
311+ 'Custom ' ,
312+ PanelView ::create ()->manifest (
313+ 'yiisoft/ ' ,
314+ PanelView ::package ('aliases ' , 'v3.1.1 ' ),
315+ PanelView ::package ('arrays ' , 'v3.2.1 ' ),
316+ ),
317+ );
318+
319+ self ::assertStringContainsString (
320+ 'class="yii-debug-manifest" aria-label="yiisoft/" ' ,
321+ $ html ,
322+ 'Manifest must be labelled by its vendor. ' ,
323+ );
324+ self ::assertStringContainsString (
325+ '2 packages ' ,
326+ $ html ,
327+ 'Tally must be pluralised. ' ,
328+ );
329+ self ::assertStringContainsString (
330+ '<span class="yii-debug-manifest-version">v3.1.1</span> ' ,
331+ $ html ,
332+ 'Version must sit beside its package name. ' ,
333+ );
334+ }
335+
336+ public function testManifestTallyUsesTheSingularForOnePackage (): void
337+ {
338+ self ::assertStringContainsString (
339+ '1 package ' ,
340+ PanelRenderer ::render (
341+ 'Custom ' ,
342+ PanelView ::create ()->manifest ('yiisoft/ ' , PanelView ::package ('aliases ' , 'v3.1.1 ' )),
343+ ),
344+ 'A single package must use the singular tally. ' ,
345+ );
346+ }
347+
278348 public function testPanelsWithoutSummaryMetricsOmitTheSummaryStrip (): void
279349 {
280350 $ html = PanelRenderer ::render (
@@ -299,6 +369,60 @@ public function testPanelsWithoutSummaryMetricsOmitTheSummaryStrip(): void
299369 );
300370 }
301371
372+ public function testPillStripRendersEachSubjectWithItsState (): void
373+ {
374+ $ html = PanelRenderer ::render (
375+ 'Custom ' ,
376+ PanelView ::create ()->pills (
377+ PanelView ::pill ('APCu ' , 'on ' , true ),
378+ PanelView ::pill ('Memcache ' , 'off ' , false ),
379+ ),
380+ );
381+
382+ self ::assertStringContainsString (
383+ '<div class="yii-debug-ext-strip"> ' ,
384+ $ html ,
385+ 'Pills must share one strip. ' ,
386+ );
387+ self ::assertStringContainsString (
388+ 'yii-debug-ext-pill is-on ' ,
389+ $ html ,
390+ 'An enabled subject must read as on. ' ,
391+ );
392+ self ::assertStringContainsString (
393+ 'yii-debug-ext-pill is-off ' ,
394+ $ html ,
395+ 'A disabled subject must read as off. ' ,
396+ );
397+ }
398+
399+ public function testReadoutRowRendersCardsAndDropsAnEmptyCaption (): void
400+ {
401+ $ html = PanelRenderer ::render (
402+ 'Custom ' ,
403+ PanelView ::create ()->readouts (
404+ PanelView ::readout ('Yii ' , '3 ' , 'framework ' ),
405+ PanelView ::readout ('PHP ' , '8.5.9 ' ),
406+ ),
407+ );
408+
409+ self ::assertStringContainsString (
410+ '<div class="yii-debug-readout-grid"> ' ,
411+ $ html ,
412+ 'Cards must share one row. ' ,
413+ );
414+ self ::assertStringContainsString (
415+ '<span class="yii-debug-readout-meta">framework</span> ' ,
416+ $ html ,
417+ 'A caption must follow its value. ' ,
418+ );
419+ self ::assertSame (
420+ 1 ,
421+ substr_count ($ html , 'yii-debug-readout-meta ' ),
422+ 'A card without a caption must omit the element. ' ,
423+ );
424+ }
425+
302426 public function testRenderUsesExistingFrontendAndEscapesEveryTextPosition (): void
303427 {
304428 $ hostile = '<script>alert("test")</script> ' ;
@@ -366,6 +490,52 @@ public function testRenderUsesExistingFrontendAndEscapesEveryTextPosition(): voi
366490 );
367491 }
368492
493+ public function testSectionWithoutATallyOmitsTheCount (): void
494+ {
495+ self ::assertStringNotContainsString (
496+ 'yii-debug-section-count ' ,
497+ PanelRenderer ::render (
498+ 'Custom ' ,
499+ PanelView ::create ()->section ('// ' , 'Application details ' , PanelView ::create ()->paragraph ('None. ' )),
500+ ),
501+ 'A section without a tally must omit the count element. ' ,
502+ );
503+ }
504+
505+ public function testSectionWrapsItsBlocksUnderAMarkedTitle (): void
506+ {
507+ $ html = PanelRenderer ::render (
508+ 'Custom ' ,
509+ PanelView ::create ()->section (
510+ ':: ' ,
511+ 'Installed extensions ' ,
512+ PanelView ::create ()->paragraph ('Nothing captured. ' ),
513+ 47 ,
514+ ),
515+ );
516+
517+ self ::assertStringContainsString (
518+ 'class="yii-debug-section" aria-label="Installed extensions" ' ,
519+ $ html ,
520+ 'Section must be labelled by its title. ' ,
521+ );
522+ self ::assertStringContainsString (
523+ '<span class="yii-debug-section-mark">::</span> ' ,
524+ $ html ,
525+ 'Mark must precede the title. ' ,
526+ );
527+ self ::assertStringContainsString (
528+ '<span class="yii-debug-section-count">47</span> ' ,
529+ $ html ,
530+ 'Tally must close the title. ' ,
531+ );
532+ self ::assertStringContainsString (
533+ 'Nothing captured. ' ,
534+ $ html ,
535+ 'Section must render its own blocks. ' ,
536+ );
537+ }
538+
369539 public function testSqlStatementsAreHighlightedAndEscaped (): void
370540 {
371541 $ html = PanelRenderer ::render (
0 commit comments