@@ -1197,6 +1197,144 @@ describe('interactive prompts lead to the correct function calls', () => {
11971197 } ) ;
11981198} ) ;
11991199
1200+ describe ( 'CLI context parameters' , ( ) => {
1201+ beforeEach ( ( ) => {
1202+ setupMockToolkitForPrototyping ( mockToolkit ) ;
1203+ jest . clearAllMocks ( ) ;
1204+ } ) ;
1205+
1206+ test ( 'CLI context values are merged with file context during prototyping' , async ( ) => {
1207+ const cdkJsonPath = await createCdkJsonFile ( {
1208+ '@aws-cdk/core:existingFlag' : true ,
1209+ } ) ;
1210+
1211+ setupMockToolkitForPrototyping ( mockToolkit ) ;
1212+
1213+ const requestResponseSpy = jest . spyOn ( ioHelper , 'requestResponse' ) ;
1214+ requestResponseSpy . mockResolvedValue ( false ) ;
1215+
1216+ const cliContextValues = {
1217+ foo : 'bar' ,
1218+ myContextParam : 'myValue' ,
1219+ } ;
1220+
1221+ const options : FlagsOptions = {
1222+ FLAGNAME : [ '@aws-cdk/core:testFlag' ] ,
1223+ set : true ,
1224+ value : 'true' ,
1225+ } ;
1226+
1227+ const flagOperations = new FlagCommandHandler ( mockFlagsData , ioHelper , options , mockToolkit , cliContextValues ) ;
1228+ await flagOperations . processFlagsCommand ( ) ;
1229+
1230+ // Verify that fromCdkApp was called with a context store
1231+ expect ( mockToolkit . fromCdkApp ) . toHaveBeenCalledTimes ( 2 ) ;
1232+
1233+ // Get the first call's context store
1234+ const firstCallArgs = mockToolkit . fromCdkApp . mock . calls [ 0 ] ;
1235+ const contextStore = firstCallArgs [ 1 ] ?. contextStore ;
1236+
1237+ // Verify the context store is a MemoryContext that contains both file and CLI context
1238+ expect ( contextStore ) . toBeDefined ( ) ;
1239+
1240+ await cleanupCdkJsonFile ( cdkJsonPath ) ;
1241+ requestResponseSpy . mockRestore ( ) ;
1242+ } ) ;
1243+
1244+ test ( 'CLI context values are passed to synthesis during safe flag checking' , async ( ) => {
1245+ const cdkJsonPath = await createCdkJsonFile ( { } ) ;
1246+
1247+ mockToolkit . diff . mockResolvedValue ( {
1248+ TestStack : { differenceCount : 0 } as any ,
1249+ } ) ;
1250+
1251+ const requestResponseSpy = jest . spyOn ( ioHelper , 'requestResponse' ) ;
1252+ requestResponseSpy . mockResolvedValue ( false ) ;
1253+
1254+ const cliContextValues = {
1255+ myCliParam : 'cliValue' ,
1256+ } ;
1257+
1258+ const options : FlagsOptions = {
1259+ safe : true ,
1260+ concurrency : 4 ,
1261+ } ;
1262+
1263+ const flagOperations = new FlagCommandHandler ( mockFlagsData , ioHelper , options , mockToolkit , cliContextValues ) ;
1264+ await flagOperations . processFlagsCommand ( ) ;
1265+
1266+ // Verify that fromCdkApp was called during safe flag checking
1267+ expect ( mockToolkit . fromCdkApp ) . toHaveBeenCalled ( ) ;
1268+
1269+ await cleanupCdkJsonFile ( cdkJsonPath ) ;
1270+ requestResponseSpy . mockRestore ( ) ;
1271+ } ) ;
1272+
1273+ test ( 'works correctly when no CLI context is provided' , async ( ) => {
1274+ const cdkJsonPath = await createCdkJsonFile ( {
1275+ '@aws-cdk/core:existingFlag' : false ,
1276+ } ) ;
1277+
1278+ setupMockToolkitForPrototyping ( mockToolkit ) ;
1279+
1280+ const requestResponseSpy = jest . spyOn ( ioHelper , 'requestResponse' ) ;
1281+ requestResponseSpy . mockResolvedValue ( false ) ;
1282+
1283+ const options : FlagsOptions = {
1284+ FLAGNAME : [ '@aws-cdk/core:testFlag' ] ,
1285+ set : true ,
1286+ value : 'true' ,
1287+ } ;
1288+
1289+ // Not passing cliContextValues (defaults to empty object)
1290+ const flagOperations = new FlagCommandHandler ( mockFlagsData , ioHelper , options , mockToolkit ) ;
1291+ await flagOperations . processFlagsCommand ( ) ;
1292+
1293+ expect ( mockToolkit . fromCdkApp ) . toHaveBeenCalledTimes ( 2 ) ;
1294+ expect ( mockToolkit . synth ) . toHaveBeenCalledTimes ( 2 ) ;
1295+
1296+ await cleanupCdkJsonFile ( cdkJsonPath ) ;
1297+ requestResponseSpy . mockRestore ( ) ;
1298+ } ) ;
1299+
1300+ test ( 'FlagCommandHandler constructor accepts CLI context values' , ( ) => {
1301+ const cliContextValues = {
1302+ myParam : 'myValue' ,
1303+ foo : 'bar' ,
1304+ } ;
1305+
1306+ const options : FlagsOptions = {
1307+ all : true ,
1308+ } ;
1309+
1310+ // Verify that constructor accepts CLI context values parameter
1311+ const handler = new FlagCommandHandler ( mockFlagsData , ioHelper , options , mockToolkit , cliContextValues ) ;
1312+ expect ( handler ) . toBeDefined ( ) ;
1313+ } ) ;
1314+
1315+ test ( 'FlagCommandHandler passes CLI context to FlagOperations' , async ( ) => {
1316+ const cdkJsonPath = await createCdkJsonFile ( { } ) ;
1317+
1318+ setupMockToolkitForPrototyping ( mockToolkit ) ;
1319+
1320+ const cliContextValues = {
1321+ cliParam : 'cliValue' ,
1322+ } ;
1323+
1324+ const options : FlagsOptions = {
1325+ all : true ,
1326+ } ;
1327+
1328+ const handler = new FlagCommandHandler ( mockFlagsData , ioHelper , options , mockToolkit , cliContextValues ) ;
1329+ await handler . processFlagsCommand ( ) ;
1330+
1331+ // Just verify it doesn't throw and completes successfully
1332+ expect ( mockToolkit . fromCdkApp ) . not . toHaveBeenCalled ( ) ; // Display mode doesn't call synthesis
1333+
1334+ await cleanupCdkJsonFile ( cdkJsonPath ) ;
1335+ } ) ;
1336+ } ) ;
1337+
12001338describe ( 'setSafeFlags' , ( ) => {
12011339 beforeEach ( ( ) => {
12021340 setupMockToolkitForPrototyping ( mockToolkit ) ;
@@ -1390,7 +1528,13 @@ async function displayFlags(params: FlagOperationsParams): Promise<void> {
13901528 await f . displayFlags ( params ) ;
13911529}
13921530
1393- async function handleFlags ( flagData : FeatureFlag [ ] , _ioHelper : IoHelper , options : FlagsOptions , toolkit : Toolkit ) {
1394- const f = new FlagCommandHandler ( flagData , _ioHelper , options , toolkit ) ;
1531+ async function handleFlags (
1532+ flagData : FeatureFlag [ ] ,
1533+ _ioHelper : IoHelper ,
1534+ options : FlagsOptions ,
1535+ toolkit : Toolkit ,
1536+ cliContextValues : Record < string , any > = { } ,
1537+ ) {
1538+ const f = new FlagCommandHandler ( flagData , _ioHelper , options , toolkit , cliContextValues ) ;
13951539 await f . processFlagsCommand ( ) ;
13961540}
0 commit comments