public void Parent_property_formats_names_and_dependsOn_correctly() { var(template, diags, _) = CompilationHelper.Compile(@" resource vnet 'Microsoft.Network/virtualNetworks@2020-06-01' = { location: resourceGroup().location name: 'myVnet' properties: { addressSpace: { addressPrefixes: [ '10.0.0.0/20' ] } } } resource subnet1 'Microsoft.Network/virtualNetworks/subnets@2020-06-01' = { parent: vnet name: 'subnet1' properties: { addressPrefix: '10.0.0.0/24' } } resource subnet2 'Microsoft.Network/virtualNetworks/subnets@2020-06-01' = { parent: vnet name: 'subnet2' properties: { addressPrefix: '10.0.1.0/24' } } output subnet1prefix string = subnet1.properties.addressPrefix output subnet1name string = subnet1.name output subnet1type string = subnet1.type output subnet1id string = subnet1.id "); using (new AssertionScope()) { diags.Should().BeEmpty(); template.Should().HaveValueAtPath("$.resources[0].name", "myVnet"); template.Should().NotHaveValueAtPath("$.resources[0].dependsOn"); template.Should().HaveValueAtPath("$.resources[1].name", "[format('{0}/{1}', 'myVnet', 'subnet1')]"); template.Should().HaveValueAtPath("$.resources[1].dependsOn", new JArray { "[resourceId('Microsoft.Network/virtualNetworks', 'myVnet')]" }); template.Should().HaveValueAtPath("$.resources[2].name", "[format('{0}/{1}', 'myVnet', 'subnet2')]"); template.Should().HaveValueAtPath("$.resources[2].dependsOn", new JArray { "[resourceId('Microsoft.Network/virtualNetworks', 'myVnet')]" }); template.Should().HaveValueAtPath("$.outputs['subnet1prefix'].value", "[reference(resourceId('Microsoft.Network/virtualNetworks/subnets', 'myVnet', 'subnet1')).addressPrefix]"); template.Should().HaveValueAtPath("$.outputs['subnet1name'].value", "subnet1"); template.Should().HaveValueAtPath("$.outputs['subnet1type'].value", "Microsoft.Network/virtualNetworks/subnets"); template.Should().HaveValueAtPath("$.outputs['subnet1id'].value", "[resourceId('Microsoft.Network/virtualNetworks/subnets', 'myVnet', 'subnet1')]"); } }
public void Output_can_have_object_type(bool enableResourceTypeParameters) { var context = enableResourceTypeParameters ? ResourceTypedFeatureContext : new CompilationHelper.CompilationHelperContext(); var result = CompilationHelper.Compile(context, @" resource resource 'Microsoft.Storage/storageAccounts@2019-06-01' = { name: 'test' location: 'eastus' kind: 'StorageV2' sku: { name: 'Standard_LRS' } identity: { type: 'SystemAssigned' } properties:{ accessTier: 'Cool' } } output out object = resource "); result.ExcludingLinterDiagnostics().Should().NotHaveAnyDiagnostics(); result.Template.Should().HaveValueAtPath("$.outputs.out", new JObject() { ["type"] = "object", ["value"] = "[reference(resourceId('Microsoft.Storage/storageAccounts', 'test'), '2019-06-01', 'full')]", }); }
public void Basic_arithmetic_expressions_are_evaluated_successfully() { var(template, _, _) = CompilationHelper.Compile(@" var sum = 1 + 3 var mult = sum * 5 var modulo = mult % 7 var div = modulo / 11 var sub = div - 13 output sum int = sum output mult int = mult output modulo int = modulo output div int = div output sub int = sub "); using (new AssertionScope()) { var evaluated = TemplateEvaluator.Evaluate(template); evaluated.Should().HaveValueAtPath("$.outputs['sum'].value", 4); evaluated.Should().HaveValueAtPath("$.outputs['mult'].value", 20); evaluated.Should().HaveValueAtPath("$.outputs['modulo'].value", 6); evaluated.Should().HaveValueAtPath("$.outputs['div'].value", 0); evaluated.Should().HaveValueAtPath("$.outputs['sub'].value", -13); } }
public void Parent_property_works_with_existing_resources() { var(template, diags, _) = CompilationHelper.Compile(@" resource res1 'Microsoft.Rp1/resource1@2020-06-01' existing = { name: 'res1' } resource child1 'Microsoft.Rp1/resource1/child1@2020-06-01' = { parent: res1 name: 'child1' } output res1childprop string = child1.properties.someProp output res1childname string = child1.name output res1childtype string = child1.type output res1childid string = child1.id "); using (new AssertionScope()) { diags.ExcludingMissingTypes().Should().BeEmpty(); // child1 template.Should().HaveValueAtPath("$.resources[0].name", "[format('{0}/{1}', 'res1', 'child1')]"); template.Should().HaveValueAtPath("$.resources[0].dependsOn", new JArray()); template.Should().NotHaveValueAtPath("$.resources[1]"); template.Should().HaveValueAtPath("$.outputs['res1childprop'].value", "[reference(resourceId('Microsoft.Rp1/resource1/child1', 'res1', 'child1')).someProp]"); template.Should().HaveValueAtPath("$.outputs['res1childname'].value", "child1"); template.Should().HaveValueAtPath("$.outputs['res1childtype'].value", "Microsoft.Rp1/resource1/child1"); template.Should().HaveValueAtPath("$.outputs['res1childid'].value", "[resourceId('Microsoft.Rp1/resource1/child1', 'res1', 'child1')]"); } }
public void Parent_property_formats_references_correctly_for_existing_resources() { var(template, diags, _) = CompilationHelper.Compile(@" resource res1 'Microsoft.Rp1/resource1@2020-06-01' existing = { scope: tenant() name: 'res1' } resource child1 'Microsoft.Rp1/resource1/child1@2020-06-01' existing = { parent: res1 name: 'child1' } output res1childprop string = child1.properties.someProp output res1childname string = child1.name output res1childtype string = child1.type output res1childid string = child1.id "); using (new AssertionScope()) { diags.ExcludingMissingTypes().Should().BeEmpty(); template.Should().NotHaveValueAtPath("$.resources[0]"); template.Should().HaveValueAtPath("$.outputs['res1childprop'].value", "[reference(tenantResourceId('Microsoft.Rp1/resource1/child1', 'res1', 'child1'), '2020-06-01').someProp]"); template.Should().HaveValueAtPath("$.outputs['res1childname'].value", "child1"); template.Should().HaveValueAtPath("$.outputs['res1childtype'].value", "Microsoft.Rp1/resource1/child1"); template.Should().HaveValueAtPath("$.outputs['res1childid'].value", "[tenantResourceId('Microsoft.Rp1/resource1/child1', 'res1', 'child1')]"); } }
public void Imports_are_disabled_unless_feature_is_enabled() { var result = CompilationHelper.Compile(@" import az as foo "); result.Should().HaveDiagnostics(new[] {
public void Parameter_with_resource_type_can_have_decorators() { var result = CompilationHelper.Compile( ResourceTypedFeatureContext, @" @description('cool') param p resource 'Microsoft.Storage/storageAccounts@2019-06-01' resource resource 'Microsoft.Storage/storageAccounts@2019-06-01' = { name: 'test' location: 'eastus' kind: 'StorageV2' sku: { name: 'Standard_LRS' } identity: { type: 'SystemAssigned' } properties:{ accessTier: p.properties.accessTier } } "); result.ExcludingLinterDiagnostics().Should().NotHaveAnyDiagnostics(); result.Template.Should().HaveValueAtPath("$.parameters.p", new JObject() { ["type"] = new JValue("string"), ["metadata"] = new JObject() { ["resourceType"] = new JValue("Microsoft.Storage/storageAccounts@2019-06-01"), ["description"] = new JValue("cool"), }, }); }
public void Emitter_should_generate_correct_extension_scope_property_and_correct_dependsOn() { var(template, diags, _) = CompilationHelper.Compile(@" resource resourceA 'My.Rp/myResource@2020-01-01' = { name: 'resourceA' } resource resourceB 'My.Rp/myResource@2020-01-01' = { scope: resourceA name: 'resourceB' } resource resourceC 'My.Rp/myResource@2020-01-01' = { scope: resourceB name: 'resourceC' }"); template !.Should().NotBeNull(); using (new AssertionScope()) { template !.SelectToken("$.resources[?(@.name == 'resourceB')].scope") !.Should().DeepEqual("[format('My.Rp/myResource/{0}', 'resourceA')]"); template.SelectToken("$.resources[?(@.name == 'resourceB')].dependsOn[0]") !.Should().DeepEqual("[resourceId('My.Rp/myResource', 'resourceA')]"); template.SelectToken("$.resources[?(@.name == 'resourceC')].scope") !.Should().DeepEqual("[extensionResourceId(resourceId('My.Rp/myResource', 'resourceA'), 'My.Rp/myResource', 'resourceB')]"); template.SelectToken("$.resources[?(@.name == 'resourceC')].dependsOn[0]") !.Should().DeepEqual("[extensionResourceId(resourceId('My.Rp/myResource', 'resourceA'), 'My.Rp/myResource', 'resourceB')]"); } }
public void Emitter_should_generate_correct_extension_scope_property_and_correct_dependsOn() { var(template, _, _) = CompilationHelper.Compile(@" resource resourceA 'My.Rp/myResource@2020-01-01' = { name: 'resourceA' } resource resourceB 'My.Rp/myResource@2020-01-01' = { scope: resourceA name: 'resourceB' } resource resourceC 'My.Rp/myResource@2020-01-01' = { scope: resourceB name: 'resourceC' }"); using (new AssertionScope()) { template.Should().HaveValueAtPath("$.resources[?(@.name == 'resourceB')].scope", "[format('My.Rp/myResource/{0}', 'resourceA')]"); template.Should().HaveValueAtPath("$.resources[?(@.name == 'resourceB')].dependsOn[0]", "[resourceId('My.Rp/myResource', 'resourceA')]"); template.Should().HaveValueAtPath("$.resources[?(@.name == 'resourceC')].scope", "[extensionResourceId(format('My.Rp/myResource/{0}', 'resourceA'), 'My.Rp/myResource', 'resourceB')]"); template.Should().HaveValueAtPath("$.resources[?(@.name == 'resourceC')].dependsOn[0]", "[extensionResourceId(resourceId('My.Rp/myResource', 'resourceA'), 'My.Rp/myResource', 'resourceB')]"); } }
public void Output_can_have_decorators() { var result = CompilationHelper.Compile(ResourceTypedFeatureContext, @" resource resource 'Microsoft.Storage/storageAccounts@2019-06-01' = { name: 'test' location: 'eastus' kind: 'StorageV2' sku: { name: 'Standard_LRS' } identity: { type: 'SystemAssigned' } properties:{ accessTier: 'Cool' } } @description('cool beans') output out resource 'Microsoft.Storage/storageAccounts@2019-06-01' = resource "); result.ExcludingLinterDiagnostics().Should().NotHaveAnyDiagnostics(); result.Template.Should().HaveValueAtPath("$.outputs.out", new JObject() { ["type"] = "string", ["value"] = "[resourceId('Microsoft.Storage/storageAccounts', 'test')]", ["metadata"] = new JObject() { ["resourceType"] = new JValue("Microsoft.Storage/storageAccounts@2019-06-01"), ["description"] = new JValue("cool beans"), }, }); }
public void Function_arguments_must_be_separated_by_a_comma() { var result = CompilationHelper.Compile(@" output test1 string = concat('foo' 'bar') "); result.ExcludingLinterDiagnostics().Should().HaveDiagnostics(new[] {
public void Emitter_should_generate_correct_references_for_existing_resources(string targetScope, string expectedScopeExpression, string expectedReferenceExpression) { var(template, diags, _) = CompilationHelper.Compile(@" targetScope = '$targetScope' resource resourceA 'My.Rp/myResource@2020-01-01' existing = { name: 'resourceA' } resource resourceB 'My.Rp/myResource@2020-01-01' = { scope: resourceA name: 'resourceB' } output resourceARef string = resourceA.properties.myProp ".Replace("$targetScope", targetScope)); using (new AssertionScope()) { template.Should().HaveValueAtPath("$.resources[?(@.name == 'resourceB')].scope", expectedScopeExpression); template.Should().NotHaveValueAtPath("$.resources[?(@.name == 'resourceB')].dependsOn"); template.Should().HaveValueAtPath("$.outputs['resourceARef'].value", expectedReferenceExpression); } }
public void ParameterDecorator_MissingDeclaration_ExpectedParameterDeclaration() { var(template, diagnostics, _) = CompilationHelper.Compile(@" @secure() "); using (new AssertionScope()) { template.Should().NotHaveValue(); diagnostics.Should().HaveDiagnostics(new[] {
// https://github.com/azure/bicep/issues/746 public void Test_Issue746() { var result = CompilationHelper.Compile(@" var l = l param l "); result.Template.Should().NotHaveValue(); result.Should().HaveDiagnostics(new[] {
public void Storage_import_bad_config_is_blocked() { var result = CompilationHelper.Compile(GetCompilationContext(), @" import stg from storage { madeUpProperty: 'asdf' } "); result.Should().HaveDiagnostics(new[] {
public void Function_argument_commas_are_permitted() { var result = CompilationHelper.Compile(@" output test1 string = concat('foo', 'bar') "); result.ExcludingLinterDiagnostics().Should().NotHaveAnyDiagnostics(); result.Template.Should().HaveValueAtPath("$.outputs['test1'].value", "[concat('foo', 'bar')]"); }
public void MissingResourceExpectedVariantPropertiesShouldProduceNoWarning() { const string text = @" resource foos 'Microsoft.Network/dnsZones@2018-05-01' = [for (item, i) in []: { location:'s' }]"; var result = CompilationHelper.Compile(text); result.Should().HaveDiagnostics(new[]
public void Parent_property_works_with_extension_resources() { var(template, diags, _) = CompilationHelper.Compile(@" resource res1 'Microsoft.Rp1/resource1@2020-06-01' = { name: 'res1' } resource res1child 'Microsoft.Rp1/resource1/child1@2020-06-01' = { parent: res1 name: 'child1' } resource res2 'Microsoft.Rp2/resource2@2020-06-01' = { scope: res1child name: 'res2' } resource res2child 'Microsoft.Rp2/resource2/child2@2020-06-01' = { parent: res2 name: 'child2' } output res2childprop string = res2child.properties.someProp output res2childname string = res2child.name output res2childtype string = res2child.type output res2childid string = res2child.id "); using (new AssertionScope()) { diags.ExcludingMissingTypes().Should().BeEmpty(); template.Should().HaveValueAtPath("$.resources[0].name", "res1"); template.Should().NotHaveValueAtPath("$.resources[0].dependsOn"); template.Should().HaveValueAtPath("$.resources[1].name", "[format('{0}/{1}', 'res1', 'child1')]"); template.Should().HaveValueAtPath("$.resources[1].dependsOn", new JArray { "[resourceId('Microsoft.Rp1/resource1', 'res1')]" }); template.Should().HaveValueAtPath("$.resources[2].name", "res2"); template.Should().HaveValueAtPath("$.resources[2].dependsOn", new JArray { "[resourceId('Microsoft.Rp1/resource1/child1', 'res1', 'child1')]" }); template.Should().HaveValueAtPath("$.resources[3].name", "[format('{0}/{1}', 'res2', 'child2')]"); template.Should().HaveValueAtPath("$.resources[3].dependsOn", new JArray { "[extensionResourceId(resourceId('Microsoft.Rp1/resource1/child1', 'res1', 'child1'), 'Microsoft.Rp2/resource2', 'res2')]" }); template.Should().HaveValueAtPath("$.outputs['res2childprop'].value", "[reference(extensionResourceId(resourceId('Microsoft.Rp1/resource1/child1', 'res1', 'child1'), 'Microsoft.Rp2/resource2/child2', 'res2', 'child2')).someProp]"); template.Should().HaveValueAtPath("$.outputs['res2childname'].value", "child2"); template.Should().HaveValueAtPath("$.outputs['res2childtype'].value", "Microsoft.Rp2/resource2/child2"); template.Should().HaveValueAtPath("$.outputs['res2childid'].value", "[extensionResourceId(resourceId('Microsoft.Rp1/resource1/child1', 'res1', 'child1'), 'Microsoft.Rp2/resource2/child2', 'res2', 'child2')]"); } }
public void Test_Issue746() { var(template, diags, _) = CompilationHelper.Compile(@" var l = l param l "); using (new AssertionScope()) { template !.Should().BeNull(); diags.Should().HaveDiagnostics(new[] {
public void Output_can_have_warnings_for_missing_type() { var result = CompilationHelper.Compile(ResourceTypedFeatureContext, @" resource resource 'Some.Fake/Type@2019-06-01' = { name: 'test' } output out resource 'Some.Fake/Type@2019-06-01' = resource "); result.ExcludingLinterDiagnostics().Should().HaveDiagnostics(new []
public void Function_argument_leading_and_trailing_newlines_can_be_dropped() { var result = CompilationHelper.Compile(@" output test1 string = concat('foo', 'bar') "); result.ExcludingLinterDiagnostics().Should().NotHaveAnyDiagnostics(); result.Template.Should().HaveValueAtPath("$.outputs['test1'].value", "[concat('foo', 'bar')]"); }
public void Parameter_can_have_warnings_for_missing_type() { var result = CompilationHelper.Compile( ResourceTypedFeatureContext, @" param p resource 'Some.Fake/Type@2019-06-01' output id string = p.id "); result.ExcludingLinterDiagnostics().Should().HaveDiagnostics(new []
public void VariantResourcePropertiesShouldProduceNoWarning() { const string text = @" // variant name resource foos 'Microsoft.Network/dnsZones@2018-05-01' = [for (item, i) in []: { name: 's2${item.name}' location:'s' }] // variant parent resource c2 'Microsoft.Network/dnsZones/CNAME@2018-05-01' = [for (cname,i) in []: { parent: foos[i] name: 's' }] // variant parent and name resource c3 'Microsoft.Network/dnsZones/CNAME@2018-05-01' = [for (cname,i) in []: { parent: foos[i] name: string(i) }] // variant name in a discriminated type resource ds2 'Microsoft.Resources/deploymentScripts@2020-10-01' = [for script in []: { kind: 'AzureCLI' name: script.name properties: { azCliVersion: 's' retentionInterval: 's' } location: resourceGroup().location }] // variant name by index resource foos2 'Microsoft.Network/dnsZones@2018-05-01' = [for (item, i) in []: { name: 's2${i}' location:'s' }] // variant name by index in a discriminated type resource ds3 'Microsoft.Resources/deploymentScripts@2020-10-01' = [for (script, i) in []: { kind: 'AzureCLI' name: string(i) properties: { azCliVersion: 's' retentionInterval: 's' } location: resourceGroup().location }] "; var result = CompilationHelper.Compile(text); result.Should().NotHaveAnyDiagnostics(); }
public void Parent_property_blocks_existing_parents_at_different_scopes(string parentScope) { var result = CompilationHelper.Compile(@" resource res1 'Microsoft.Rp1/resource1@2020-06-01' existing = { scope: " + parentScope + @" name: 'res1' } resource child1 'Microsoft.Rp1/resource1/child1@2020-06-01' = { parent: res1 name: 'child1' } "); result.Diagnostics.ExcludingLinterDiagnostics().ExcludingMissingTypes().Should().HaveDiagnostics(new[] {
public void DtcValidation_EntireResourceOrModuleAccessAtInvalidLocations_ProducesDiagnostics() { var result = CompilationHelper.Compile(@" var foo = [for x in [ dnsZone storageAccounts[0] dnsZone::aRecord ]: { value1: appPlan value2: [ bar ] }] var bar = { value: dnsZone::aRecord } resource appPlan 'Microsoft.Web/serverfarms@2020-12-01' = if (dnsZone::aRecord != null) { name: 'appPlan' location: resourceGroup().location sku: { name: 'F1' capacity: 1 } } resource dnsZone 'Microsoft.Network/dnsZones@2018-05-01' = { name: 'dnsZone' location: 'global' resource aRecord 'A' = { name: 'aRecord' } } resource storageAccounts 'Microsoft.Storage/storageAccounts@2021-02-01' = [for i in range(0, 2): { name: 'mystorage-${i}' location: resourceGroup().location kind: 'StorageV2' sku: { name: 'Premium_LRS' tier: 'Premium' } }] "); result.Should().HaveDiagnostics(new[]
public void Function_argument_multiple_newlines_are_permitted() { var result = CompilationHelper.Compile(@" output test1 string = concat( // this is the foo parameter! 'foo', // this is the bar parameter! 'bar' ) "); result.ExcludingLinterDiagnostics().Should().NotHaveAnyDiagnostics(); result.Template.Should().HaveValueAtPath("$.outputs['test1'].value", "[concat('foo', 'bar')]"); }
public void Parameter_can_have_resource_type() { var result = CompilationHelper.Compile( ResourceTypedFeatureContext, @" param p resource 'Microsoft.Storage/storageAccounts@2019-06-01' resource resource 'Microsoft.Storage/storageAccounts@2019-06-01' = { name: 'test' location: 'eastus' kind: 'StorageV2' sku: { name: 'Standard_LRS' } identity: { type: 'SystemAssigned' } properties:{ accessTier: p.properties.accessTier } } "); result.ExcludingLinterDiagnostics().Should().NotHaveAnyDiagnostics(); var model = result.Compilation.GetEntrypointSemanticModel(); var parameterSymbol = model.Root.ParameterDeclarations.Should().ContainSingle().Subject; var typeInfo = model.GetTypeInfo(parameterSymbol.DeclaringSyntax); typeInfo.Should().BeOfType <ResourceType>().Which.TypeReference.FormatName().Should().BeEquivalentTo("Microsoft.Storage/storageAccounts@2019-06-01"); var reference = model.FindReferences(parameterSymbol).OfType <VariableAccessSyntax>().Should().ContainSingle().Subject; model.GetDeclaredType(reference).Should().NotBeNull(); model.GetTypeInfo(reference).Should().NotBeNull(); result.Template.Should().HaveValueAtPath("$.resources[0].properties.accessTier", "[reference(parameters('p'), '2019-06-01').accessTier]"); result.Template.Should().HaveValueAtPath("$.parameters.p", new JObject() { ["type"] = new JValue("string"), ["metadata"] = new JObject() { ["resourceType"] = new JValue("Microsoft.Storage/storageAccounts@2019-06-01"), }, }); }
public void Existing_resources_can_be_referenced_at_other_scopes() { var typeName = "My.Rp/myResource@2020-01-01"; var typeProvider = ResourceTypeProviderHelper.CreateAzResourceTypeProvider(factory => { var stringType = factory.Create(() => new Azure.Bicep.Types.Concrete.BuiltInType(BuiltInTypeKind.String)); var objectType = factory.Create(() => new Azure.Bicep.Types.Concrete.ObjectType(typeName, new Dictionary <string, ObjectProperty> { ["name"] = new ObjectProperty(factory.GetReference(stringType), ObjectPropertyFlags.DeployTimeConstant), ["kind"] = new ObjectProperty(factory.GetReference(stringType), ObjectPropertyFlags.ReadOnly), }, null)); var resourceType = factory.Create(() => new Azure.Bicep.Types.Concrete.ResourceType(typeName, ScopeType.ResourceGroup, factory.GetReference(objectType))); }); // explicitly pass a valid scope var(template, _, _) = CompilationHelper.Compile(typeProvider, ("main.bicep", @" resource resourceA 'My.Rp/myResource@2020-01-01' existing = { name: 'resourceA' scope: resourceGroup() } output resourceARef string = resourceA.kind ")); template !.Should().NotBeNull(); using (new AssertionScope()) { template !.SelectToken("$.outputs['resourceARef'].value") !.Should().DeepEqual("[reference(extensionResourceId(resourceGroup().id, 'My.Rp/myResource', 'resourceA'), '2020-01-01', 'full').kind]"); } // use a valid targetScope without setting the scope property (template, _, _) = CompilationHelper.Compile(typeProvider, ("main.bicep", @" targetScope = 'resourceGroup' resource resourceA 'My.Rp/myResource@2020-01-01' existing = { name: 'resourceA' } output resourceARef string = resourceA.kind ")); template !.Should().NotBeNull(); using (new AssertionScope()) { template !.SelectToken("$.outputs['resourceARef'].value") !.Should().DeepEqual("[reference(resourceId('My.Rp/myResource', 'resourceA'), '2020-01-01', 'full').kind]"); } }
public void Parent_property_blocks_existing_parents_at_different_scopes() { var(template, diags, _) = CompilationHelper.Compile(@" resource res1 'Microsoft.Rp1/resource1@2020-06-01' existing = { scope: tenant() name: 'res1' } resource child1 'Microsoft.Rp1/resource1/child1@2020-06-01' = { parent: res1 name: 'child1' } "); using (new AssertionScope()) { template.Should().NotHaveValue(); diags.ExcludingMissingTypes().Should().HaveDiagnostics(new[] {
public void Errors_are_raised_for_existing_resources_at_invalid_scopes() { var typeReference = ResourceTypeReference.Parse("My.Rp/myResource@2020-01-01"); var typeLoader = TestTypeHelper.CreateAzResourceTypeLoaderWithTypes(new [] { new ResourceTypeComponents(typeReference, ResourceScope.ResourceGroup, new ObjectType(typeReference.FormatName(), TypeSymbolValidationFlags.Default, new [] { new TypeProperty("name", LanguageConstants.String, TypePropertyFlags.DeployTimeConstant, "name property"), }, null)) }); // explicitly pass an invalid scope var(_, diags, _) = CompilationHelper.Compile(typeLoader, ("main.bicep", @" resource resourceA 'My.Rp/myResource@2020-01-01' existing = { name: 'resourceA' scope: subscription() } ")); diags.Should().HaveDiagnostics(new[] {