@@ -7,6 +7,7 @@ import { ArmLifecycleOperationKind } from "../src/operations.js";
77import {
88 ArmResourceDetails ,
99 getArmResources ,
10+ getFeature ,
1011 getResourceFeature ,
1112 getResourceFeatureSet ,
1213} from "../src/resource.js" ;
@@ -517,9 +518,9 @@ enum Features {
517518 } ) ;
518519
519520 const fooFeature = getResourceFeature ( result . program , result . FooResource ) ;
520- expect ( fooFeature ) . toMatch ( "FeatureA" ) ;
521+ expect ( fooFeature ?. name ) . toMatch ( "FeatureA" ) ;
521522 const barFeature = getResourceFeature ( result . program , result . BarResource ) ;
522- expect ( barFeature ) . toMatch ( "FeatureB" ) ;
523+ expect ( barFeature ?. name ) . toMatch ( "FeatureB" ) ;
523524 } ) ;
524525 it ( "allows customizing features and feature options" , async ( ) => {
525526 const [ result , diagnostics ] = await Tester . compileAndDiagnose ( t . code `
@@ -575,9 +576,118 @@ enum Features {
575576 } ) ;
576577
577578 const fooFeature = getResourceFeature ( result . program , result . FooResource ) ;
578- expect ( fooFeature ) . toMatch ( "FeatureA" ) ;
579+ expect ( fooFeature ?. name ) . toMatch ( "FeatureA" ) ;
579580 const barFeature = getResourceFeature ( result . program , result . BarResource ) ;
580- expect ( barFeature ) . toMatch ( "FeatureB" ) ;
581+ expect ( barFeature ?. name ) . toMatch ( "FeatureB" ) ;
582+ } ) ;
583+ it ( "reports correct features for child types" , async ( ) => {
584+ const [ result , diagnostics ] = await Tester . compileAndDiagnose ( t . code `
585+
586+ @Azure.ResourceManager.Legacy.features(Features)
587+ @versioned(Versions)
588+ @armProviderNamespace("Microsoft.Test")
589+ namespace ${ t . namespace ( "MSTest" ) } ;
590+ /** Contoso API versions */
591+ enum Versions {
592+ /** 2021-10-01-preview version */
593+ v2025_11_19_preview: "2025-11-19-preview",
594+ }
595+ enum Features {
596+ /** Feature A */
597+ @Azure.ResourceManager.Legacy.featureOptions(#{featureName: "FeatureA", fileName: "feature-a", description: "The data for feature A"})
598+ FeatureA: "Feature A",
599+ /** Feature B */
600+ @Azure.ResourceManager.Legacy.featureOptions(#{featureName: "FeatureB", fileName: "feature-b", description: "The data for feature B"})
601+ FeatureB: "Feature B",
602+ }
603+ @secret
604+ scalar secretString extends string;
605+
606+ @Azure.ResourceManager.Legacy.feature(Features.FeatureA)
607+ model ${ t . model ( "FooResource" ) } is TrackedResource<FooResourceProperties> {
608+ ...ResourceNameParameter<FooResource>;
609+ }
610+
611+ @Azure.ResourceManager.Legacy.feature(Features.FeatureA)
612+ model ${ t . model ( "FooResourceProperties" ) } {
613+ ...DefaultProvisioningStateProperty;
614+ password: secretString;
615+ }
616+
617+ @Azure.ResourceManager.Legacy.feature(Features.FeatureB)
618+ model ${ t . model ( "BarResource" ) } is ProxyResource<BarResourceProperties> {
619+ ...ResourceNameParameter<BarResource>;
620+ }
621+ model ${ t . model ( "BarResourceProperties" ) } {
622+ ...DefaultProvisioningStateProperty;
623+ password: secretString;
624+ }
625+
626+ @Azure.ResourceManager.Legacy.feature(Features.FeatureA)
627+ @armResourceOperations
628+ interface ${ t . interface ( "Foos" ) } extends Azure.ResourceManager.TrackedResourceOperations<FooResource, FooResourceProperties> {}
629+
630+ @Azure.ResourceManager.Legacy.feature(Features.FeatureB)
631+ @armResourceOperations
632+ interface ${ t . interface ( "Bars" ) } extends Azure.ResourceManager.TrackedResourceOperations<BarResource, BarResourceProperties> {}
633+ ` ) ;
634+ const featureAObject = {
635+ featureName : "FeatureA" ,
636+ fileName : "feature-a" ,
637+ description : "The data for feature A" ,
638+ } ;
639+ const featureBObject = {
640+ featureName : "FeatureB" ,
641+ fileName : "feature-b" ,
642+ description : "The data for feature B" ,
643+ } ;
644+
645+ const defaultObject = {
646+ featureName : "Common" ,
647+ fileName : "common" ,
648+ description : "" ,
649+ } ;
650+ expectDiagnosticEmpty ( diagnostics ) ;
651+ const features = getResourceFeatureSet ( result . program , result . MSTest ) ;
652+ expect ( features ) . toBeDefined ( ) ;
653+ ok ( features ) ;
654+ const keys = Array . from ( features . keys ( ) ) ;
655+ expect ( keys ) . toEqual ( [ "FeatureA" , "FeatureB" ] ) ;
656+ expect ( features ?. get ( "FeatureA" ) ) . toEqual ( featureAObject ) ;
657+ expect ( features ?. get ( "FeatureB" ) ) . toEqual ( featureBObject ) ;
658+
659+ const fooFeature = getFeature ( result . program , result . FooResource ) ;
660+ expect ( fooFeature ) . toMatchObject ( featureAObject ) ;
661+ const fooPropertiesFeature = getFeature ( result . program , result . FooResourceProperties ) ;
662+ expect ( fooPropertiesFeature ) . toMatchObject ( featureAObject ) ;
663+ const fooPasswordProperty = result . FooResourceProperties . properties . get ( "password" ) ;
664+ expect ( fooPasswordProperty ) . toBeDefined ( ) ;
665+ const fooPasswordFeature = getFeature ( result . program , fooPasswordProperty ! ) ;
666+ expect ( fooPasswordFeature ) . toMatchObject ( featureAObject ) ;
667+ const fooPasswordTypeFeature = getFeature ( result . program , fooPasswordProperty ! . type ) ;
668+ expect ( fooPasswordTypeFeature ) . toMatchObject ( defaultObject ) ;
669+ const foosFeature = getFeature ( result . program , result . Foos ) ;
670+ expect ( foosFeature ) . toMatchObject ( featureAObject ) ;
671+ for ( const op of [ ...result . Foos . operations . values ( ) ] ) {
672+ const opFeature = getFeature ( result . program , op ) ;
673+ expect ( opFeature ) . toMatchObject ( featureAObject ) ;
674+ }
675+ const barFeature = getFeature ( result . program , result . BarResource ) ;
676+ expect ( barFeature ) . toMatchObject ( featureBObject ) ;
677+ const barPropertiesFeature = getFeature ( result . program , result . BarResourceProperties ) ;
678+ expect ( barPropertiesFeature ) . toMatchObject ( defaultObject ) ;
679+ const barPasswordProperty = result . BarResourceProperties . properties . get ( "password" ) ;
680+ expect ( barPasswordProperty ) . toBeDefined ( ) ;
681+ const barPasswordFeature = getFeature ( result . program , barPasswordProperty ! ) ;
682+ expect ( barPasswordFeature ) . toMatchObject ( defaultObject ) ;
683+ const barPasswordTypeFeature = getFeature ( result . program , barPasswordProperty ! . type ) ;
684+ expect ( barPasswordTypeFeature ) . toMatchObject ( defaultObject ) ;
685+ const barsFeature = getFeature ( result . program , result . Bars ) ;
686+ expect ( barsFeature ) . toMatchObject ( featureBObject ) ;
687+ for ( const op of [ ...result . Bars . operations . values ( ) ] ) {
688+ const opFeature = getFeature ( result . program , op ) ;
689+ expect ( opFeature ) . toMatchObject ( featureBObject ) ;
690+ }
581691 } ) ;
582692 } ) ;
583693 describe ( "network security perimeter" , ( ) => {
0 commit comments