@@ -25,6 +25,18 @@ function setFindings(scan, next) {
2525 writeFileSync ( file , JSON . stringify ( report ) )
2626}
2727
28+ function components ( manifest ) {
29+ return manifest . components . flatMap ( ( treatment ) => treatment . entries )
30+ }
31+
32+ function variants ( manifest ) {
33+ return components ( manifest ) . flatMap ( ( entry ) => entry . variants ?? [ ] )
34+ }
35+
36+ function extras ( manifest ) {
37+ return manifest . extras . flatMap ( ( treatment ) => treatment . entries )
38+ }
39+
2840function command ( root , executable , args ) {
2941 const result = spawnSync ( executable , args , { cwd : root , encoding : 'utf8' } )
3042 assert . equal ( result . status , 0 , result . stderr )
@@ -136,10 +148,10 @@ test('refresh requires a fixture mapping for each variant axis', () => {
136148 const { refresh } = guardedRefresh ( )
137149 const manifest = refresh ( )
138150 assert . ok (
139- manifest . components . find ( ( entry ) => entry . id === 'component:Example:variant=filled' ) . fixture
151+ variants ( manifest ) . find ( ( entry ) => entry . id === 'component:Example:variant=filled' ) . fixture
140152 )
141153 assert . equal (
142- manifest . components . find ( ( entry ) => entry . id === 'component:Example:size=lg' ) . fixture ,
154+ variants ( manifest ) . find ( ( entry ) => entry . id === 'component:Example:size=lg' ) . fixture ,
143155 null
144156 )
145157} , 60000 )
@@ -161,10 +173,10 @@ test('refresh keeps disabled variants without impossible interaction states', ()
161173 } )
162174 )
163175 const manifest = refresh ( )
164- const enabled = manifest . components . find (
176+ const enabled = variants ( manifest ) . find (
165177 ( entry ) => entry . id === 'component:Example:disabled=false'
166178 )
167- const disabled = manifest . components . find (
179+ const disabled = variants ( manifest ) . find (
168180 ( entry ) => entry . id === 'component:Example:disabled=true'
169181 )
170182 assert . deepEqual ( enabled . states , [ 'open' , 'focus' , 'disabled' ] )
@@ -192,8 +204,8 @@ test('refresh keeps explicitly closed variants out of open states', () => {
192204 } )
193205 )
194206 const manifest = refresh ( )
195- const closed = manifest . components . find ( ( entry ) => entry . id === 'component:Example:open=false' )
196- const opened = manifest . components . find ( ( entry ) => entry . id === 'component:Example:open=true' )
207+ const closed = variants ( manifest ) . find ( ( entry ) => entry . id === 'component:Example:open=false' )
208+ const opened = variants ( manifest ) . find ( ( entry ) => entry . id === 'component:Example:open=true' )
197209 assert . deepEqual ( closed . states , [ 'focus' ] )
198210 assert . equal ( closed . fixture . defaultState , undefined )
199211 assert . deepEqual ( opened . states , [ 'open' , 'focus' ] )
@@ -203,10 +215,10 @@ test('refresh keeps explicitly closed variants out of open states', () => {
203215test ( 'refresh publishes unresolved analysis and scanner limits separately from inspection failures' , ( ) => {
204216 const { refresh } = guardedRefresh ( )
205217 const manifest = refresh ( )
206- assert . deepEqual ( manifest . analysis . stylingUnchecked , [
218+ assert . deepEqual ( manifest . analysis . stylingUncheckedSample , [
207219 { file : 'example.tsx' , line : 1 , reason : 'Computed styling is unchecked' } ,
208220 ] )
209- assert . deepEqual ( manifest . analysis . controlUnchecked , [
221+ assert . deepEqual ( manifest . analysis . controlUncheckedSample , [
210222 { file : 'example.tsx' , line : 2 , reason : 'Unknown spread' } ,
211223 ] )
212224 assert . deepEqual ( manifest . analysis . limitations , [ 'Runtime cascade is unsupported.' ] )
@@ -359,22 +371,31 @@ test('refresh catalogs every detected treatment and new EMCN export', () => {
359371 }
360372
361373 const first = refresh ( )
374+ assert . equal ( first . version , 3 )
375+ assert . equal ( first . counts . components , components ( first ) . length + variants ( first ) . length )
376+ assert . equal ( first . counts . extras , extras ( first ) . length )
377+ assert . equal (
378+ new Set ( [ ...components ( first ) , ...variants ( first ) , ...extras ( first ) ] . map ( ( entry ) => entry . id ) )
379+ . size ,
380+ first . counts . components + first . counts . extras
381+ )
382+ assert . ok ( variants ( first ) . every ( ( entry ) => ! ( 'usages' in entry ) ) )
362383 assert . equal (
363- first . components . some ( ( e ) => e . name === 'SPACING' || e . name === 'Compound' ) ,
384+ components ( first ) . some ( ( e ) => e . name === 'SPACING' || e . name === 'Compound' ) ,
364385 false
365386 )
366387 assert . equal (
367388 first . nonvisualExports . some ( ( e ) => e . name === 'SPACING' ) ,
368389 true
369390 )
370- assert . equal ( first . components . find ( ( e ) => e . name === 'Compound.Part' ) . fixture . id , 'example' )
391+ assert . equal ( components ( first ) . find ( ( e ) => e . name === 'Compound.Part' ) . fixture . id , 'example' )
371392 assert . equal (
372- first . components . find ( ( e ) => e . id === 'component:Compound.Part:size=lg' ) . fixture ,
393+ variants ( first ) . find ( ( e ) => e . id === 'component:Compound.Part:size=lg' ) . fixture ,
373394 null
374395 )
375396
376397 assert . equal (
377- first . components
398+ components ( first )
378399 . find ( ( e ) => e . name === 'Compound.Part' )
379400 . usages . filter ( ( u ) => u . relationship === 'direct' ) . length ,
380401 1
@@ -393,7 +414,10 @@ test('refresh catalogs every detected treatment and new EMCN export', () => {
393414 assert . notEqual ( changedClassMerger . sourceRevision , first . sourceRevision )
394415 write ( repo , 'packages/emcn/src/lib/cn.ts' , '' )
395416 assert . deepEqual (
396- first . components . map ( ( entry ) => entry . id ) ,
417+ components ( first ) . flatMap ( ( entry ) => [
418+ entry . id ,
419+ ...( entry . variants ?? [ ] ) . map ( ( variant ) => variant . id ) ,
420+ ] ) ,
397421 [
398422 'component:Compound.Part' ,
399423 'component:Compound.Part:size=lg' ,
@@ -405,20 +429,20 @@ test('refresh catalogs every detected treatment and new EMCN export', () => {
405429 ]
406430 )
407431 assert . deepEqual (
408- first . components
432+ components ( first )
409433 . find ( ( entry ) => entry . name === 'Example' )
410434 . usages . map ( ( site ) => site . relationship ) ,
411435 [ 'direct' , 'via Wrapper' ]
412436 )
413- assert . equal ( first . extras . length , 2 )
437+ assert . equal ( extras ( first ) . length , 2 )
414438 assert . deepEqual (
415- first . extras . map ( ( entry ) => entry . id ) ,
439+ extras ( first ) . map ( ( entry ) => entry . id ) ,
416440 [ 'finding:finding-one' , 'finding:advisory-one' ]
417441 )
418- assert . equal ( first . extras [ 0 ] . fixture . type , 'sample' )
419- assert . equal ( first . extras [ 0 ] . fixture . sample . kind , 'surface' )
420- assert . equal ( first . extras [ 0 ] . fixture . sample . tag , 'Example' )
421- assert . equal ( first . extras [ 0 ] . previewKind , 'source-style-sample' )
442+ assert . equal ( extras ( first ) [ 0 ] . fixture . type , 'sample' )
443+ assert . equal ( extras ( first ) [ 0 ] . fixture . sample . kind , 'surface' )
444+ assert . equal ( extras ( first ) [ 0 ] . fixture . sample . tag , 'Example' )
445+ assert . equal ( extras ( first ) [ 0 ] . previewKind , 'source-style-sample' )
422446
423447 write (
424448 repo ,
@@ -431,7 +455,7 @@ test('refresh catalogs every detected treatment and new EMCN export', () => {
431455 "export * from './components'\nexport * from './icons'\nexport { RootOnly } from './components/root-only'\n"
432456 )
433457 assert . equal (
434- refresh ( ) . components . find ( ( entry ) => entry . id === 'component:RootOnly' ) ?. status ,
458+ components ( refresh ( ) ) . find ( ( entry ) => entry . id === 'component:RootOnly' ) ?. status ,
435459 'needs-fixture'
436460 )
437461 write (
@@ -448,8 +472,14 @@ test('refresh catalogs every detected treatment and new EMCN export', () => {
448472 "export { Example, SPACING, Compound } from './example/example'\nexport * from './cycle-a'\n"
449473 )
450474 assert . deepEqual (
451- refresh ( ) . components . map ( ( entry ) => entry . id ) ,
452- first . components . map ( ( entry ) => entry . id )
475+ components ( refresh ( ) ) . flatMap ( ( entry ) => [
476+ entry . id ,
477+ ...( entry . variants ?? [ ] ) . map ( ( variant ) => variant . id ) ,
478+ ] ) ,
479+ components ( first ) . flatMap ( ( entry ) => [
480+ entry . id ,
481+ ...( entry . variants ?? [ ] ) . map ( ( variant ) => variant . id ) ,
482+ ] )
453483 )
454484
455485 write (
@@ -459,7 +489,7 @@ test('refresh catalogs every detected treatment and new EMCN export', () => {
459489 )
460490 const changed = refresh ( )
461491 assert . notEqual ( changed . sourceRevision , first . sourceRevision )
462- assert . equal ( changed . components . find ( ( entry ) => entry . name === 'Example' ) . usages . length , 3 )
492+ assert . equal ( components ( changed ) . find ( ( entry ) => entry . name === 'Example' ) . usages . length , 3 )
463493
464494 write (
465495 repo ,
@@ -473,7 +503,7 @@ test('refresh catalogs every detected treatment and new EMCN export', () => {
473503 )
474504 const exported = refresh ( )
475505 assert . equal (
476- exported . components . find ( ( entry ) => entry . id === 'component:NewControl' ) ?. status ,
506+ components ( exported ) . find ( ( entry ) => entry . id === 'component:NewControl' ) ?. status ,
477507 'needs-fixture'
478508 )
479509
@@ -498,11 +528,11 @@ test('refresh catalogs every detected treatment and new EMCN export', () => {
498528 } ,
499529 ] )
500530 const central = refresh ( )
501- assert . equal ( central . extras . length , 4 )
502- assert . equal ( central . extras [ 2 ] . id , 'finding:central-one' )
503- assert . equal ( central . extras [ 3 ] . id , 'finding:unmatched-central' )
531+ assert . equal ( extras ( central ) . length , 4 )
532+ assert . equal ( extras ( central ) [ 2 ] . id , 'finding:central-one' )
533+ assert . equal ( extras ( central ) [ 3 ] . id , 'finding:unmatched-central' )
504534 assert . deepEqual (
505- central . components
535+ components ( central )
506536 . find ( ( entry ) => entry . id === 'component:Example' )
507537 ?. signals ?. map ( ( signal ) => signal . id ) ,
508538 [ 'finding:central-one' ]
@@ -533,7 +563,7 @@ test('refresh catalogs every detected treatment and new EMCN export', () => {
533563 ]
534564 setFindings ( scan , [ ...findings ( scan ) , ...newSignals ] )
535565 const discovered = refresh ( )
536- const newEntries = discovered . extras . filter ( ( entry ) =>
566+ const newEntries = extras ( discovered ) . filter ( ( entry ) =>
537567 entry . source . file . endsWith ( '/new-action.tsx' )
538568 )
539569 assert . equal ( newEntries . length , 2 )
@@ -554,7 +584,7 @@ test('refresh catalogs every detected treatment and new EMCN export', () => {
554584 value : 'WorkflowIcon' ,
555585 } ,
556586 ] )
557- const movedIcon = refresh ( ) . extras . find ( ( entry ) => entry . id === 'finding:moved-icon' )
587+ const movedIcon = extras ( refresh ( ) ) . find ( ( entry ) => entry . id === 'finding:moved-icon' )
558588 assert . deepEqual ( movedIcon . fixture , { type : 'extra' , id : 'workflowIcon' } )
559589
560590 const richCss =
@@ -612,7 +642,7 @@ test('refresh catalogs every detected treatment and new EMCN export', () => {
612642 value : 'bg-black/10' ,
613643 } ,
614644 ] )
615- const semantic = new Map ( refresh ( ) . extras . map ( ( entry ) => [ entry . id , entry ] ) )
645+ const semantic = new Map ( extras ( refresh ( ) ) . map ( ( entry ) => [ entry . id , entry ] ) )
616646 assert . equal ( semantic . get ( 'finding:code-moved' ) . fixture . id , 'rich-code' )
617647 assert . equal ( semantic . get ( 'finding:selection-moved' ) . fixture . id , 'rich-selection' )
618648 assert . equal ( semantic . get ( 'finding:other-css' ) . fixture . type , 'sample' )
0 commit comments