@@ -1086,3 +1086,107 @@ test('the relocated registry remains a central-system change and formatting stay
10861086 expect ( ( await compare ( '{"version":1}' , '{"version":2}' ) ) . findings [ 0 ] . kind ) . toBe ( 'system-change' )
10871087 expect ( ( await compare ( '{"version":1}' , '{ "version": 1 }' ) ) . flagged ) . toBe ( false )
10881088} )
1089+
1090+ test . each ( [
1091+ {
1092+ name : 'namespace export' ,
1093+ use : 'cn(styles.palette)' ,
1094+ before : "{'bg-red-500':true}" ,
1095+ after : "{'bg-blue-500':true}" ,
1096+ notify : true ,
1097+ } ,
1098+ {
1099+ name : 'nested namespace export member' ,
1100+ use : 'cn(styles.palette.tone)' ,
1101+ before : "{tone:{'bg-red-500':true}}" ,
1102+ after : "{tone:{'bg-blue-500':true}}" ,
1103+ notify : true ,
1104+ } ,
1105+ {
1106+ name : 'namespace barrel export alias' ,
1107+ use : 'cn(styles.colors)' ,
1108+ before : "{'bg-red-500':true}" ,
1109+ after : "{'bg-blue-500':true}" ,
1110+ barrel : true ,
1111+ notify : true ,
1112+ } ,
1113+ {
1114+ name : 'local namespace binding alias' ,
1115+ use : 'cn(forwarded.palette.tone)' ,
1116+ prefix : 'const forwarded=styles;' ,
1117+ before : "{tone:{'bg-red-500':true}}" ,
1118+ after : "{tone:{'bg-blue-500':true}}" ,
1119+ notify : true ,
1120+ } ,
1121+ {
1122+ name : 'named import alias control' ,
1123+ use : 'cn(colors.tone)' ,
1124+ named : true ,
1125+ before : "{tone:{'bg-red-500':true}}" ,
1126+ after : "{tone:{'bg-blue-500':true}}" ,
1127+ notify : true ,
1128+ } ,
1129+ {
1130+ name : 'unused nested namespace member' ,
1131+ use : 'cn(styles.palette.tone)' ,
1132+ before : "{tone:{'bg-red-500':true},unused:{'bg-green-500':true}}" ,
1133+ after : "{tone:{'bg-red-500':true},unused:{'bg-blue-500':true}}" ,
1134+ notify : false ,
1135+ } ,
1136+ {
1137+ name : 'shadowed namespace binding' ,
1138+ use : 'cn(styles.palette)' ,
1139+ prefix : "const styles={palette:{'rounded-md':true}};" ,
1140+ shadow : true ,
1141+ before : "{'bg-red-500':true}" ,
1142+ after : "{'bg-blue-500':true}" ,
1143+ notify : false ,
1144+ } ,
1145+ {
1146+ name : 'dynamic namespace export' ,
1147+ use : 'cn(styles[choice])' ,
1148+ prefix : 'declare const choice:string;' ,
1149+ before : "{'bg-red-500':true}" ,
1150+ after : "{'bg-blue-500':true}" ,
1151+ notify : false ,
1152+ } ,
1153+ {
1154+ name : 'dynamic nested namespace member' ,
1155+ use : 'cn(styles.palette[choice])' ,
1156+ prefix : 'declare const choice:string;' ,
1157+ before : "{tone:{'bg-red-500':true}}" ,
1158+ after : "{tone:{'bg-blue-500':true}}" ,
1159+ notify : false ,
1160+ } ,
1161+ ] ) ( 'namespace class inputs survive source-only edits through the real CLI: $name' , ( scenario ) => {
1162+ const { repo } = fixture ( )
1163+ const sourceFile = 'packages/emcn/src/lib/palette.ts'
1164+ const write = ( file : string , source : string ) => {
1165+ mkdirSync ( path . dirname ( path . join ( repo , file ) ) , { recursive : true } )
1166+ writeFileSync ( path . join ( repo , file ) , source )
1167+ }
1168+ write ( 'packages/emcn/src/index.ts' , "export {palette} from './lib/palette'" )
1169+ write ( 'packages/emcn/src/lib/barrel.ts' , "export {palette as colors} from './palette'" )
1170+ write ( sourceFile , `export const palette=${ scenario . before } as const` )
1171+ const imported = scenario . named
1172+ ? "import {palette as colors} from '../lib/palette'"
1173+ : `import * as styles from '../lib/${ scenario . barrel ? 'barrel' : 'palette' } '`
1174+ write (
1175+ 'packages/emcn/src/components/consumer.tsx' ,
1176+ `${ imported } ;declare function cn(...args:unknown[]):string;${ scenario . shadow ? `function Consumer(){${ scenario . prefix } return <div className={${ scenario . use } }/>}` : `${ scenario . prefix ?? '' } const Consumer=()=> <div className={${ scenario . use } }/>` } `
1177+ )
1178+ write ( ui , 'const A=()=> <div/>' )
1179+ const base = commit ( repo )
1180+ write ( sourceFile , `export const palette=${ scenario . after } as const` )
1181+ const child = run ( [ '--repo' , repo , '--base' , base , '--working-tree' , '--format' , 'json' ] )
1182+ expect ( [ 0 , 1 ] , child . stderr ) . toContain ( child . status )
1183+ const report = JSON . parse ( child . stdout ) as Report
1184+ expect ( report . status , child . stdout ) . toBe ( 'completed' )
1185+ expect ( git ( repo , [ 'diff' , '--name-only' , base ] ) . toString ( ) . trim ( ) ) . toBe ( sourceFile )
1186+ expect (
1187+ report . findings . filter (
1188+ ( finding ) => finding . file === sourceFile && finding . property === 'background-color'
1189+ ) ,
1190+ child . stdout
1191+ ) . toHaveLength ( scenario . notify ? 1 : 0 )
1192+ } )
0 commit comments