Skip to content

Commit

Permalink
Fix loading tagged unions from compiled JSON
Browse files Browse the repository at this point in the history
  • Loading branch information
jeskew committed Mar 27, 2024
1 parent 6b0e259 commit 855485d
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 0 deletions.
Expand Up @@ -773,5 +773,93 @@ public void User_defined_discriminated_objects_can_amend_resource_derived_discri
}
""");
}

[TestMethod]
public void Tagged_unions_can_be_imported_from_json_templates()
{
var test1Bicep = """
@export()
type testType = {
subType: subType[]
}

@discriminator('type')
type subType = testSub1 | testSub2 | testSub3

type testSub1 = {
type: '1'
subOption1: string
}

type testSub2 = {
type: '2'
subOption2: int
}

type testSub3 = {
type: '3'
subOption3: bool
}
""";

static string expectedSubTypeSchema(string extension) => $$"""
{
"type": "object",
"discriminator": {
"propertyName": "type",
"mapping": {
"1": {
"$ref": "#/definitions/_1.testSub1"
},
"2": {
"$ref": "#/definitions/_1.testSub2"
},
"3": {
"$ref": "#/definitions/_1.testSub3"
}
}
},
"metadata": {
"__bicep_imported_from!": {
"sourceTemplate": "test1.{{extension}}"
}
}
}
""";

static string mainTypesBicep(string extension) => $$"""
import { testType } from 'test1.{{extension}}'

@export()
type mainType = {
name: string
test: testType[]?
}
""";

var mainBicep = """
import { mainType } from 'main.types.bicep'

param main mainType

output mainOut object = main
""";

var resultFromBicep = CompilationHelper.Compile(
("test1.bicep", test1Bicep),
("main.types.bicep", mainTypesBicep("bicep")),
("main.bicep", mainBicep));

resultFromBicep.Template.Should().NotBeNull();
resultFromBicep.Template.Should().HaveJsonAtPath("$.definitions['_1.subType']", expectedSubTypeSchema("bicep"));

var resultFromJson = CompilationHelper.Compile(
("test1.json", CompilationHelper.Compile(test1Bicep).Template!.ToString()),
("main.types.bicep", mainTypesBicep("json")),
("main.bicep", mainBicep));

resultFromJson.Template.Should().NotBeNull();
resultFromJson.Template.Should().HaveJsonAtPath("$.definitions['_1.subType']", expectedSubTypeSchema("json"));
}
}
}
@@ -1,6 +1,8 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System.Collections.Immutable;
using System.Linq;
using Azure.Deployments.Core.Definitions.Schema;
using Azure.Deployments.Core.Entities;
using Azure.Deployments.Expression.Engines;
Expand Down Expand Up @@ -361,6 +363,20 @@ private TypeExpression ConvertObjectNodeToTypeExpression(ITemplateSchemaNode sch
modifiers.Sealed);
}

if (schemaNode.Discriminator is { } discriminatorConstraint)
{
var unionMembers = discriminatorConstraint.Mapping.OrderByAscendingOrdinalInsensitively(kvp => kvp.Key)
.Select(kvp => ConvertToTypeExpression(kvp.Value))
.ToImmutableArray();

return new DiscriminatedObjectTypeExpression(sourceSyntax,
new(string.Empty,
TypeSymbolValidationFlags.Default,
discriminatorConstraint.PropertyName.Value,
unionMembers.Select(expression => expression.ExpressedType)),
unionMembers);
}

return new ObjectTypeExpression(sourceSyntax,
new(string.Empty,
TypeSymbolValidationFlags.Default,
Expand Down
Expand Up @@ -132,5 +132,13 @@ private static IEnumerable<ArmIdentifier> EnumerateReferencesUsedIn(ITemplateSch
yield return nested;
}
}

if (schemaNode.Discriminator is { } discriminatorConstraint)
{
foreach (var nested in discriminatorConstraint.Mapping.Values.SelectMany(EnumerateReferencesUsedIn))
{
yield return nested;
}
}
}
}

0 comments on commit 855485d

Please sign in to comment.