Skip to content

Commit

Permalink
CustomProperty ordering (#633)
Browse files Browse the repository at this point in the history
Co-authored-by: Andrew Petrochuk (from Dev Box) <[email protected]>
  • Loading branch information
petrochuk and anpetroc authored Apr 12, 2024
1 parent 2bf4beb commit 5aa975a
Show file tree
Hide file tree
Showing 24 changed files with 472 additions and 274 deletions.
81 changes: 81 additions & 0 deletions src/Persistence.Tests/TestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

using Microsoft.PowerPlatform.PowerApps.Persistence.Extensions;
using Microsoft.PowerPlatform.PowerApps.Persistence.Models;
using Microsoft.PowerPlatform.PowerApps.Persistence.MsApp;
using Microsoft.PowerPlatform.PowerApps.Persistence.Templates;
using Microsoft.PowerPlatform.PowerApps.Persistence.Yaml;
Expand Down Expand Up @@ -74,4 +75,84 @@ public static string GetTestFilePath(string path, bool isControlIdentifiers = fa
{
return string.Format(path, isControlIdentifiers ? "-CI" : string.Empty);
}

public static IEnumerable<object[]> ComponentCustomProperties_Data => new List<object[]>()
{
new object[]
{
new CustomProperty[] {
new () { Name = "MyTextProp1", DataType = "String", Default = "lorem",
Direction = CustomProperty.PropertyDirection.Input, Type = CustomProperty.PropertyType.Data
}
},
@"_TestData/ValidYaml{0}/Components/CustomProperty1.pa.yaml", false
},
new object[]
{
new CustomProperty[] {
new () { Name = "MyTextProp1", DataType = "String", Default = "lorem",
Direction = CustomProperty.PropertyDirection.Input, Type = CustomProperty.PropertyType.Data
}
},
@"_TestData/ValidYaml{0}/Components/CustomProperty1.pa.yaml", true
},
new object[]
{
new CustomProperty[] {
new () { Name = "MyFuncProp1", DataType = "String", Default = "lorem",
Direction = CustomProperty.PropertyDirection.Input, Type = CustomProperty.PropertyType.Function,
Parameters = new[] {
new CustomPropertyParameter(){
Name = "param1",
DataType = "String",
IsRequired = true,
}
},
}
},
@"_TestData/ValidYaml{0}/Components/CustomProperty2.pa.yaml", false
},
new object[]
{
new CustomProperty[] {
new () { Name = "MyFuncProp1", DataType = "String", Default = "lorem",
Direction = CustomProperty.PropertyDirection.Input, Type = CustomProperty.PropertyType.Function,
Parameters = new[] {
new CustomPropertyParameter(){
Name = "param1",
DataType = "String",
IsRequired = true,
}
},
}
},
@"_TestData/ValidYaml{0}/Components/CustomProperty2.pa.yaml", true
},
new object[]
{
new CustomProperty[] {
new () { Name = "MyTextProp1", DataType = "String", Default = "lorem",
Direction = CustomProperty.PropertyDirection.Input, Type = CustomProperty.PropertyType.Data
},
new () { Name = "MyTextProp2", DataType = "String", Default = "lorem",
Direction = CustomProperty.PropertyDirection.Input, Type = CustomProperty.PropertyType.Data
}
},
@"_TestData/ValidYaml{0}/Components/with-two-properties.pa.yaml", false
},
new object[]
{
new CustomProperty[] {
new () { Name = "MyTextProp1", DataType = "String", Default = "lorem",
Direction = CustomProperty.PropertyDirection.Input, Type = CustomProperty.PropertyType.Data
},
new () { Name = "MyTextProp2", DataType = "String", Default = "lorem",
Direction = CustomProperty.PropertyDirection.Input, Type = CustomProperty.PropertyType.Data
}
},
@"_TestData/ValidYaml{0}/Components/with-two-properties.pa.yaml", true
},

};

}
41 changes: 41 additions & 0 deletions src/Persistence.Tests/Yaml/DeserializeComponentTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using Microsoft.PowerPlatform.PowerApps.Persistence.Models;

namespace Persistence.Tests.Yaml;

[TestClass]
public class DeserializeComponentTests : TestBase
{
[TestMethod]
[DataRow(@"_TestData/ValidYaml{0}/Components/with-custom-properties.pa.yaml", true, 6, 1, 3,
"inputFuncImage", 1, "reqColorParam", "a required color param")]
public void Deserialize_Component_Should_Succeed(string path, bool isControlIdentifiers,
int customPropertiesCount, int childrenCount, int propertiesCount,
string firstCustomProperyName, int firstCustomProperyParametersCount,
string firstCustomProperyParameterName, string firstCustomProperyParameterDescription)
{
// Arrange
var deserializer = CreateDeserializer(isControlIdentifiers);
using var yamlStream = File.OpenRead(GetTestFilePath(path, isControlIdentifiers));
using var yamlReader = new StreamReader(yamlStream);

// Act
var component = deserializer.Deserialize<Control>(yamlReader) as Component;
if (component == null)
throw new InvalidOperationException("Failed to deserialize component");

// Assert
component.Should().NotBeNull();
component.Children!.Count.Should().Be(childrenCount);
component.Properties!.Count.Should().Be(propertiesCount);
component.Template.Should().NotBeNull();
component.Template!.Name.Should().Be("Component");
component.CustomProperties.Count.Should().Be(customPropertiesCount);
component.CustomProperties[0].Name.Should().Be(firstCustomProperyName);
component.CustomProperties[0].Parameters.Count.Should().Be(firstCustomProperyParametersCount);
component.CustomProperties[0].Parameters[0].Name.Should().Be(firstCustomProperyParameterName);
component.CustomProperties[0].Parameters[0].Description.Should().Be(firstCustomProperyParameterDescription);
}
}
80 changes: 8 additions & 72 deletions src/Persistence.Tests/Yaml/DeserializerValidTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -435,86 +435,22 @@ public void Deserialize_Should_AddGalleryTemplate(string path, bool isControlIde
galleryTemplate.Properties.Should().ContainKeys("TemplateFill");
}

public static IEnumerable<object[]> Deserialize_ShouldParseYamlForComponentCustomProperties_Data => new List<object[]>()
{
new object[]
{
new CustomProperty()
{
Name = "MyTextProp1",
DataType = "String",
Default = "lorem",
Direction = CustomProperty.PropertyDirection.Input,
Type = CustomProperty.PropertyType.Data
},
@"_TestData/ValidYaml{0}/Components/CustomProperty1.pa.yaml", false
},
new object[]
{
new CustomProperty()
{
Name = "MyTextProp1",
DataType = "String",
Default = "lorem",
Direction = CustomProperty.PropertyDirection.Input,
Type = CustomProperty.PropertyType.Data
},
@"_TestData/ValidYaml{0}/Components/CustomProperty1.pa.yaml", true
},
new object[]
{
new CustomProperty()
{
Name = "MyFuncProp1",
DataType = "String",
Default = "lorem",
Direction = CustomProperty.PropertyDirection.Input,
Type = CustomProperty.PropertyType.Function,
Parameters = new[] {
new CustomPropertyParameter(){
Name = "param1",
DataType = "String",
IsRequired = true,
}
},
},
@"_TestData/ValidYaml{0}/Components/CustomProperty2.pa.yaml", false
},
new object[]
{
new CustomProperty()
{
Name = "MyFuncProp1",
DataType = "String",
Default = "lorem",
Direction = CustomProperty.PropertyDirection.Input,
Type = CustomProperty.PropertyType.Function,
Parameters = new[] {
new CustomPropertyParameter(){
Name = "param1",
DataType = "String",
IsRequired = true,
}
},
},
@"_TestData/ValidYaml{0}/Components/CustomProperty2.pa.yaml", true
}
};

[TestMethod]
[DynamicData(nameof(Deserialize_ShouldParseYamlForComponentCustomProperties_Data))]
public void Deserialize_ShouldParseYamlForComponentCustomProperties(CustomProperty expectedCustomProperty, string yamlFile, bool isControlIdentifiers)
[DynamicData(nameof(ComponentCustomProperties_Data), typeof(TestBase))]
public void Deserialize_ShouldParseYamlForComponentCustomProperties(CustomProperty[] expectedCustomProperties, string yamlFile, bool isControlIdentifiers)
{
var expectedYaml = File.ReadAllText(GetTestFilePath(yamlFile, isControlIdentifiers));
var deserializer = CreateDeserializer(isControlIdentifiers);

var component = deserializer.Deserialize<Control>(expectedYaml) as Component;
var component = deserializer.Deserialize<Component>(expectedYaml);
component.Should().NotBeNull();
component!.CustomProperties.Should().NotBeNull()
.And.HaveCount(1)
.And.ContainKey(expectedCustomProperty.Name);
.And.HaveCount(expectedCustomProperties.Length);

component.CustomProperties[expectedCustomProperty.Name].Should().BeEquivalentTo(expectedCustomProperty);
for (var i = 0; i < expectedCustomProperties.Length; i++)
{
component.CustomProperties[i].Should().BeEquivalentTo(expectedCustomProperties[i]);
}
}

[TestMethod]
Expand Down
76 changes: 6 additions & 70 deletions src/Persistence.Tests/Yaml/ValidSerializerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -275,81 +275,17 @@ public void Should_Serialize_List_Of_Controls(string expectedPath, bool isContro
sut.Should().Be(expectedYaml);
}


public static IEnumerable<object[]> Serialize_ShouldCreateValidYamlForComponentCustomProperties_Data => new List<object[]>()
{
new object[]
{
new CustomProperty()
{
Name = "MyTextProp1",
DataType = "String",
Default = "lorem",
Direction = CustomProperty.PropertyDirection.Input,
Type = CustomProperty.PropertyType.Data
},
@"_TestData/ValidYaml{0}/Components/CustomProperty1.pa.yaml", false
},
new object[]
{
new CustomProperty()
{
Name = "MyTextProp1",
DataType = "String",
Default = "lorem",
Direction = CustomProperty.PropertyDirection.Input,
Type = CustomProperty.PropertyType.Data
},
@"_TestData/ValidYaml{0}/Components/CustomProperty1.pa.yaml", true
},
new object[]
{
new CustomProperty()
{
Name = "MyFuncProp1",
DataType = "String",
Default = "lorem",
Direction = CustomProperty.PropertyDirection.Input,
Type = CustomProperty.PropertyType.Function,
Parameters = new[] {
new CustomPropertyParameter(){
Name = "param1",
DataType= "String",
IsRequired = true,
}
},
},
@"_TestData/ValidYaml{0}/Components/CustomProperty2.pa.yaml", false
},
new object[]
{
new CustomProperty()
{
Name = "MyFuncProp1",
DataType = "String",
Default = "lorem",
Direction = CustomProperty.PropertyDirection.Input,
Type = CustomProperty.PropertyType.Function,
Parameters = new[] {
new CustomPropertyParameter(){
Name = "param1",
DataType= "String",
IsRequired = true,
}
},
},
@"_TestData/ValidYaml{0}/Components/CustomProperty2.pa.yaml", true
}
};

[TestMethod]
[DynamicData(nameof(Serialize_ShouldCreateValidYamlForComponentCustomProperties_Data))]
public void Serialize_ShouldCreateValidYamlForComponentCustomProperties(CustomProperty customProperty, string expectedYamlFile, bool isControlIdentifiers)
[DynamicData(nameof(ComponentCustomProperties_Data), typeof(TestBase))]
public void Serialize_ShouldCreateValidYamlForComponentCustomProperties(CustomProperty[] customProperties, string expectedYamlFile, bool isControlIdentifiers)
{
var component = ControlFactory.Create("Component1", "Component") as Component;
component.Should().NotBeNull();
component!.CustomProperties.Should().NotBeNull();
component.CustomProperties.Add(customProperty.Name, customProperty);
foreach (var prop in customProperties)
{
component.CustomProperties.Add(prop);
}

var sut = CreateSerializer(isControlIdentifiers);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Component1:
Control: Component
CustomProperties:
MyTextProp1:
- MyTextProp1:
Direction: Input
PropertyType: Data
DataType: String
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
Component1:
Control: Component
CustomProperties:
MyFuncProp1:
- MyFuncProp1:
Direction: Input
PropertyType: Function
DataType: String
IsResettable: false
Default: lorem
Parameters:
param1:
- param1:
DataType: String
IsRequired: true
Loading

0 comments on commit 5aa975a

Please sign in to comment.