diff --git a/.editorconfig b/.editorconfig index b922094c..d01072b8 100644 --- a/.editorconfig +++ b/.editorconfig @@ -7,7 +7,7 @@ insert_final_newline = true charset = utf-8 trim_trailing_whitespace = true -[*.{json,js}] +[*.{json,js,yaml,yml}] indent_size = 2 tab_width = 2 diff --git a/src/PAModel/Exceptions/SerializationException.cs b/src/PAModel/Exceptions/SerializationException.cs deleted file mode 100644 index 91209645..00000000 --- a/src/PAModel/Exceptions/SerializationException.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -namespace Microsoft.PowerPlatform.Formulas.Tools; - -internal class SerializationException : Exception -{ - public string FileName { get; init; } - - public SerializationException(string message) - : base(message) - { - } - - public SerializationException(string message, Exception innerException) - : base(message, innerException) - { - } - - public SerializationException(string message, string fileName, Exception innerException) - { - FileName = fileName; - } -} diff --git a/src/PAModel/Microsoft.PowerPlatform.Formulas.Tools.csproj b/src/PAModel/Microsoft.PowerPlatform.Formulas.Tools.csproj index ddb5d0b2..5bbbf5e6 100644 --- a/src/PAModel/Microsoft.PowerPlatform.Formulas.Tools.csproj +++ b/src/PAModel/Microsoft.PowerPlatform.Formulas.Tools.csproj @@ -55,7 +55,6 @@ - diff --git a/src/PAModel/Model/Control.cs b/src/PAModel/Model/Control.cs deleted file mode 100644 index 4b12697d..00000000 --- a/src/PAModel/Model/Control.cs +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System.Diagnostics; -using YamlDotNet.Serialization; - -namespace Microsoft.PowerPlatform.Formulas.Tools.Model; - -[DebuggerDisplay("{Name}")] -public record Control -{ - public Control() - { - - } - - public Control(ControlEditorState editorState) - { - EditorState = editorState ?? throw new ArgumentNullException(nameof(editorState)); - Name = editorState.Name; - Type = editorState.Type; - - if (editorState.Children != null) - { - var childControls = new List(); - foreach (var child in editorState.Children) - { - childControls.Add(new Control(child)); - } - Controls = childControls; - editorState.Children = null; - } - } - - [YamlIgnore] - public ControlEditorState EditorState { get; set; } - - public string Name { get; init; } - - [YamlMember(Alias = "Control")] - public string Type { get; init; } - - public IList Controls { get; init; } - - public IDictionary Properties { get; init; } -} diff --git a/src/PAModel/Model/ControlEditorState.cs b/src/PAModel/Model/ControlEditorState.cs deleted file mode 100644 index 5f02d371..00000000 --- a/src/PAModel/Model/ControlEditorState.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System.Text.Json.Serialization; -using Microsoft.PowerPlatform.Formulas.Tools.JsonConverters; - -namespace Microsoft.PowerPlatform.Formulas.Tools.Model; - -public record ControlEditorState -{ - public string Name { get; init; } - - public string Type { get; set; } - - [JsonConverter(typeof(JsonDoubleToIntConverter))] - public int Index { get; set; } - - public ControlEditorState[] Children { get; set; } - - public IList Rules { get; init; } -} diff --git a/src/PAModel/Model/RuleEditorState.cs b/src/PAModel/Model/RuleEditorState.cs deleted file mode 100644 index 69c42ce1..00000000 --- a/src/PAModel/Model/RuleEditorState.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System.Diagnostics; - -namespace Microsoft.PowerPlatform.Formulas.Tools.Model; - -[DebuggerDisplay("{Category} / {Property} / {InvariantScript}")] -public record RuleEditorState -{ - public string Category { get; init; } - public string Property { get; init; } - public string NameMap { get; init; } - public string InvariantScript { get; init; } - public string RuleProviderType { get; init; } - public IList TaggedRuleArray { get; init; } -} diff --git a/src/PAModel/Model/TaggedRuleEditorState.cs b/src/PAModel/Model/TaggedRuleEditorState.cs deleted file mode 100644 index 46ecee27..00000000 --- a/src/PAModel/Model/TaggedRuleEditorState.cs +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -namespace Microsoft.PowerPlatform.Formulas.Tools.Model; - -public record TaggedRuleEditorState : RuleEditorState -{ - public string Tag { get; init; } -} diff --git a/src/PAModel/packages.lock.json b/src/PAModel/packages.lock.json index d650fb01..ae72a3de 100644 --- a/src/PAModel/packages.lock.json +++ b/src/PAModel/packages.lock.json @@ -2,19 +2,6 @@ "version": 1, "dependencies": { "net7.0": { - "Microsoft.Extensions.Logging": { - "type": "Direct", - "requested": "[6.0.0, )", - "resolved": "6.0.0", - "contentHash": "eIbyj40QDg1NDz0HBW0S5f3wrLVnKWnDJ/JtZ+yJDFnDj90VoPuoPmFkeaXrtu+0cKm5GRAwoDf+dBWXK0TUdg==", - "dependencies": { - "Microsoft.Extensions.DependencyInjection": "6.0.0", - "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", - "Microsoft.Extensions.Logging.Abstractions": "6.0.0", - "Microsoft.Extensions.Options": "6.0.0", - "System.Diagnostics.DiagnosticSource": "6.0.0" - } - }, "Newtonsoft.Json": { "type": "Direct", "requested": "[13.0.1, )", @@ -46,46 +33,73 @@ "resolved": "15.1.0", "contentHash": "fXrqmKkzBtXeJiHEsZOPEWkonHweiwk/l0Hqhz4yMIZPh57kZy03Xbj2/e8HV1QIkTw7yeBe9bbphuE3YiI4vQ==" }, - "Microsoft.Extensions.DependencyInjection": { + "Microsoft.Bcl.AsyncInterfaces": { "type": "Transitive", "resolved": "6.0.0", - "contentHash": "k6PWQMuoBDGGHOQTtyois2u4AwyVcIwL2LaSLlTZQm2CYcJ1pxbt6jfAnpWmzENA/wfrYRI/X9DTLoUkE4AsLw==", + "contentHash": "UcSjPsst+DfAdJGVDsu346FX0ci0ah+lw3WRtn18NUwEqRt70HaOQ7lI72vy3+1LxtqI3T5GWwV39rQSrCzAeg==" + }, + "Microsoft.Extensions.DependencyInjection": { + "type": "Transitive", + "resolved": "7.0.0", + "contentHash": "elNeOmkeX3eDVG6pYVeV82p29hr+UKDaBhrZyWvWLw/EVZSYEkZlQdkp0V39k/Xehs2Qa0mvoCvkVj3eQxNQ1Q==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", - "System.Runtime.CompilerServices.Unsafe": "6.0.0" + "Microsoft.Extensions.DependencyInjection.Abstractions": "7.0.0" } }, "Microsoft.Extensions.DependencyInjection.Abstractions": { "type": "Transitive", - "resolved": "6.0.0", - "contentHash": "xlzi2IYREJH3/m6+lUrQlujzX8wDitm4QGnUu6kUXTQAWPuZY8i+ticFJbzfqaetLA6KR/rO6Ew/HuYD+bxifg==" + "resolved": "7.0.0", + "contentHash": "h3j/QfmFN4S0w4C2A6X7arXij/M/OVw3uQHSOFxnND4DyAzO1F9eMX7Eti7lU/OkSthEE0WzRsfT/Dmx86jzCw==" + }, + "Microsoft.Extensions.Logging": { + "type": "Transitive", + "resolved": "7.0.0", + "contentHash": "Nw2muoNrOG5U5qa2ZekXwudUn2BJcD41e65zwmDHb1fQegTX66UokLWZkJRpqSSHXDOWZ5V0iqhbxOEky91atA==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "7.0.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "7.0.0", + "Microsoft.Extensions.Logging.Abstractions": "7.0.0", + "Microsoft.Extensions.Options": "7.0.0" + } }, "Microsoft.Extensions.Logging.Abstractions": { "type": "Transitive", - "resolved": "6.0.0", - "contentHash": "/HggWBbTwy8TgebGSX5DBZ24ndhzi93sHUBDvP1IxbZD7FDokYzdAr6+vbWGjw2XAfR2EJ1sfKUotpjHnFWPxA==" + "resolved": "7.0.0", + "contentHash": "kmn78+LPVMOWeITUjIlfxUPDsI0R6G0RkeAMBmQxAJ7vBJn4q2dTva7pWi65ceN5vPGjJ9q/Uae2WKgvfktJAw==" }, "Microsoft.Extensions.Options": { "type": "Transitive", - "resolved": "6.0.0", - "contentHash": "dzXN0+V1AyjOe2xcJ86Qbo233KHuLEY0njf/P2Kw8SfJU+d45HNS2ctJdnEnrWbM9Ye2eFgaC5Mj9otRMU6IsQ==", + "resolved": "7.0.0", + "contentHash": "lP1yBnTTU42cKpMozuafbvNtQ7QcBjr/CcK3bYOGEMH55Fjt+iecXjT6chR7vbgCMqy3PG3aNQSZgo/EuY/9qQ==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0", - "Microsoft.Extensions.Primitives": "6.0.0" + "Microsoft.Extensions.DependencyInjection.Abstractions": "7.0.0", + "Microsoft.Extensions.Primitives": "7.0.0" } }, "Microsoft.Extensions.Primitives": { "type": "Transitive", - "resolved": "6.0.0", - "contentHash": "9+PnzmQFfEFNR9J2aDTfJGGupShHjOuGw4VUv+JB044biSHrnmCIMD+mJHmb2H7YryrfBEXDurxQ47gJZdCKNQ==", + "resolved": "7.0.0", + "contentHash": "um1KU5kxcRp3CNuI8o/GrZtD4AIOXDk+RLsytjZ9QPok3ttLUelLKpilVPuaFT3TFjOhSibUAso0odbOaCDj3Q==" + }, + "Microsoft.PowerFx.Core": { + "type": "Transitive", + "resolved": "1.2.0", + "contentHash": "M9DY6FqWUXUPgjbbHsB3vt7+b4QPFaoKBZ7ixSU7cPgHKzo/aNohzYWxYasXwTV6pamv5gX9AqLuF13RimMPdg==", "dependencies": { - "System.Runtime.CompilerServices.Unsafe": "6.0.0" + "Microsoft.Bcl.AsyncInterfaces": "6.0.0", + "Microsoft.PowerFx.Transport.Attributes": "1.2.0", + "System.Collections.Immutable": "6.0.0" } }, - "System.Diagnostics.DiagnosticSource": { + "Microsoft.PowerFx.Transport.Attributes": { + "type": "Transitive", + "resolved": "1.2.0", + "contentHash": "zlvi59W/4MdDJeR2rIL8k633V+FIHtxbhyaurNBZevksNWCZ49AV0bUhpB6cUjD/vwci8ZXXWziw0yYnjXIzNg==" + }, + "System.Collections.Immutable": { "type": "Transitive", "resolved": "6.0.0", - "contentHash": "frQDfv0rl209cKm1lnwTgFPzNigy2EKk1BS3uAvHvlBVKe5cymGyHO+Sj+NLv5VF/AhHsqPIUUwya5oV4CHMUw==", + "contentHash": "l4zZJ1WU2hqpQQHXz1rvC3etVZN+2DLmQMO79FhOTZHMn8tDRr+WU287sbomD0BETlmKDn0ygUgVy9k5xkkJdA==", "dependencies": { "System.Runtime.CompilerServices.Unsafe": "6.0.0" } @@ -98,6 +112,8 @@ "microsoft.powerplatform.powerapps.persistence": { "type": "Project", "dependencies": { + "Microsoft.Extensions.Logging": "[7.0.0, )", + "Microsoft.PowerFx.Core": "[1.2.0, )", "YamlDotNet": "[15.1.0, )" } } diff --git a/src/PAModelTests/Apps/WithYaml/HelloWorld.msapp b/src/PAModelTests/Apps/WithYaml/HelloWorld.msapp deleted file mode 100644 index 2eab3da5..00000000 Binary files a/src/PAModelTests/Apps/WithYaml/HelloWorld.msapp and /dev/null differ diff --git a/src/PAModelTests/DataSourceTests.cs b/src/PAModelTests/DataSourceTests.cs index 78e708da..84a2aac7 100644 --- a/src/PAModelTests/DataSourceTests.cs +++ b/src/PAModelTests/DataSourceTests.cs @@ -9,7 +9,7 @@ using Microsoft.PowerPlatform.Formulas.Tools; using Microsoft.PowerPlatform.Formulas.Tools.Extensions; using Microsoft.PowerPlatform.Formulas.Tools.IO; -using Microsoft.PowerPlatform.Formulas.Tools.MsApp; +using Microsoft.PowerPlatform.PowerApps.Persistence.MsApp; namespace PAModelTests; diff --git a/src/PASopa.sln b/src/PASopa.sln index 78c6ddc3..35b00095 100644 --- a/src/PASopa.sln +++ b/src/PASopa.sln @@ -18,7 +18,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerPlatform.PowerApps.Persistence", "Persistence\Microsoft.PowerPlatform.PowerApps.Persistence.csproj", "{906B4EA5-F287-4D0E-A511-0D89B2DD9C14}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.PowerPlatform.PowerApps.Persistence.Tests", "Persistence.Tests\Microsoft.PowerPlatform.PowerApps.Persistence.Tests.csproj", "{8AB1C901-FE5E-44BF-AA21-B8F20A9D7CDD}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Persistence.Tests", "Persistence.Tests\Persistence.Tests.csproj", "{8AB1C901-FE5E-44BF-AA21-B8F20A9D7CDD}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/src/Persistence.Tests/Extensions/StringExtensions.cs b/src/Persistence.Tests/Extensions/StringExtensions.cs new file mode 100644 index 00000000..fd86147a --- /dev/null +++ b/src/Persistence.Tests/Extensions/StringExtensions.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace Persistence.Tests.Extensions; + +internal static class StringExtensions +{ + public static string NormalizeNewlines(this string x) + { + return x.Replace("\r\n", "\n").Replace("\r", "\n"); + } +} diff --git a/src/Persistence.Tests/Microsoft.PowerPlatform.PowerApps.Persistence.Tests.csproj b/src/Persistence.Tests/Microsoft.PowerPlatform.PowerApps.Persistence.Tests.csproj deleted file mode 100644 index adea0f14..00000000 --- a/src/Persistence.Tests/Microsoft.PowerPlatform.PowerApps.Persistence.Tests.csproj +++ /dev/null @@ -1,31 +0,0 @@ - - - - $(TargetFrameworkVersion) - enable - enable - - false - true - false - - - - - - - - - - - - - - - - - - - - diff --git a/src/Persistence.Tests/Model/InvalidControls.cs b/src/Persistence.Tests/Model/InvalidControls.cs new file mode 100644 index 00000000..0b7069a6 --- /dev/null +++ b/src/Persistence.Tests/Model/InvalidControls.cs @@ -0,0 +1,22 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using Microsoft.PowerPlatform.PowerApps.Persistence.Models; + +namespace Persistence.Tests.Model; + +[TestClass] +public class InvalidControls +{ + [TestMethod] + [DataRow("")] + [DataRow(" ")] + public void Constructor_InvalidControlName_Throws(string controlName) + { + // Act + Action act = () => new Screen(controlName); + + // Assert + act.Should().Throw(); + } +} diff --git a/src/PAModelTests/MsApp/MsappArchiveTests.cs b/src/Persistence.Tests/MsApp/MsappArchiveTests.cs similarity index 81% rename from src/PAModelTests/MsApp/MsappArchiveTests.cs rename to src/Persistence.Tests/MsApp/MsappArchiveTests.cs index 3f5b25b4..0751b182 100644 --- a/src/PAModelTests/MsApp/MsappArchiveTests.cs +++ b/src/Persistence.Tests/MsApp/MsappArchiveTests.cs @@ -1,12 +1,11 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -using System.IO; using System.IO.Compression; -using System.Linq; -using Microsoft.PowerPlatform.Formulas.Tools.MsApp; +using Microsoft.PowerPlatform.PowerApps.Persistence.MsApp; +using Microsoft.PowerPlatform.PowerApps.Persistence.Yaml; -namespace PAModelTests.MsApp; +namespace Persistence.Tests.MsApp; [TestClass] public class MsappArchiveTests @@ -74,22 +73,19 @@ public void AddEntryTests(string[] entries) } [TestMethod] - [DataRow(@"Apps/WithYaml/HelloWorld.msapp", 14, 2, "HelloScreen", "screen", 8)] - [DataRow(@"Apps/AppWithLabel.msapp", 11, 2, "Screen1", "ControlInfo", 8)] - public void GetTopLevelControlsTests(string testFile, int allEntriesCount, int controlsCount, + [DataRow(@"_TestData/AppsWithYaml/HelloWorld.msapp", 14, 2, "HelloScreen", "screen", 8)] + public void Msapp_ShouldHave_Screens(string testFile, int allEntriesCount, int controlsCount, string topLevelControlName, string topLevelControlType, int topLevelRulesCount) { // Arrange: Create new ZipArchive in memory - using var msappArchive = new MsappArchive(testFile); + using var msappArchive = new MsappArchive(testFile, YamlSerializationFactory.CreateDeserializer()); // Assert msappArchive.CanonicalEntries.Count.Should().Be(allEntriesCount); - msappArchive.TopLevelControls.Count.Should().Be(controlsCount); - msappArchive.TopLevelControls.Should().ContainSingle(c => c.Name == "App"); + msappArchive.Screens.Count.Should().Be(controlsCount); + msappArchive.Screens.Should().ContainSingle(c => c.Name == "App"); - var topLevelControl = msappArchive.TopLevelControls.Single(c => c.Name == topLevelControlName); - topLevelControl.EditorState.Rules.Count.Should().Be(topLevelRulesCount); - topLevelControl.Type.Should().Be(topLevelControlType); + var screen = msappArchive.Screens.Single(c => c.Name == topLevelControlName); } } diff --git a/src/Persistence.Tests/Persistence.Tests.csproj b/src/Persistence.Tests/Persistence.Tests.csproj new file mode 100644 index 00000000..494e525e --- /dev/null +++ b/src/Persistence.Tests/Persistence.Tests.csproj @@ -0,0 +1,36 @@ + + + + $(TargetFrameworkVersion) + enable + enable + + false + true + false + + + + + PreserveNewest + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Persistence.Tests/Yaml/DeserializerInvalidTests.cs b/src/Persistence.Tests/Yaml/DeserializerInvalidTests.cs new file mode 100644 index 00000000..3b30b0f7 --- /dev/null +++ b/src/Persistence.Tests/Yaml/DeserializerInvalidTests.cs @@ -0,0 +1,39 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using Microsoft.PowerPlatform.PowerApps.Persistence.MsApp; +using Microsoft.PowerPlatform.PowerApps.Persistence.Yaml; + +namespace Persistence.Tests.Yaml; + +[TestClass] +public class DeserializerInvalidTests +{ + [TestMethod] + public void Deserialize_ShouldFail() + { + // Arrange + var deserializer = YamlSerializationFactory.CreateDeserializer(); + + var files = Directory.GetFiles(@"_TestData/InvalidYaml", $"*{MsappArchive.YamlFxFileExtension}", SearchOption.AllDirectories); + // Uncomment to test single file + // var files = new string[] { @"_TestData/InvalidYaml/InvalidName.fx.yaml" }; + + Parallel.ForEach(files, file => + { + using var yamlStream = File.OpenRead(file); + using var yamlReader = new StreamReader(yamlStream); + + // Act + try + { + var screen = deserializer.Deserialize(yamlReader); + Assert.Fail($"Expected exception for file {file}"); + } + catch (Exception) + { + // Assert exceptions are thrown + } + }); + } +} diff --git a/src/Persistence.Tests/Yaml/YamlDeserializerTests.cs b/src/Persistence.Tests/Yaml/DeserializerValidTests.cs similarity index 77% rename from src/Persistence.Tests/Yaml/YamlDeserializerTests.cs rename to src/Persistence.Tests/Yaml/DeserializerValidTests.cs index be86a515..f1fde363 100644 --- a/src/Persistence.Tests/Yaml/YamlDeserializerTests.cs +++ b/src/Persistence.Tests/Yaml/DeserializerValidTests.cs @@ -4,10 +4,10 @@ using Microsoft.PowerPlatform.PowerApps.Persistence.Models; using Microsoft.PowerPlatform.PowerApps.Persistence.Yaml; -namespace Microsoft.PowerPlatform.PowerApps.Persistence.Tests.Yaml; +namespace Persistence.Tests.Yaml; [TestClass] -public class YamlDeserializerTests +public class DeserializerValidTests { [TestMethod] [DataRow("I am a screen with spaces", "42")] @@ -19,9 +19,8 @@ public class YamlDeserializerTests [DataRow("Cos'è questo?", "---")] public void Deserialize_ShouldParseSimpleStructure(string textValue, string xValue) { - var graph = new Screen() + var graph = new Screen("Screen1") { - Name = "Screen1", Properties = new Dictionary() { { "Text", new() { Value = textValue } }, @@ -38,7 +37,7 @@ public void Deserialize_ShouldParseSimpleStructure(string textValue, string xVal var sut = deserializer.Deserialize(yaml); sut.Should().NotBeNull().And.BeOfType(); sut.Name.Should().Be("Screen1"); - sut.ControlUri.Should().Be(BuiltInTemplatesUris.Screen); + sut.ControlUri.Should().Be(BuiltInTemplates.Screen); sut.Controls.Should().NotBeNull().And.BeEmpty(); sut.Properties.Should().NotBeNull() .And.HaveCount(3) @@ -51,26 +50,23 @@ public void Deserialize_ShouldParseSimpleStructure(string textValue, string xVal [TestMethod] public void Deserialize_ShouldParseYamlWithChildNodes() { - var graph = new Screen() + var graph = new Screen("Screen1") { - Name = "Screen1", Properties = new Dictionary() { { "Text", new() { Value = "I am a screen" } }, }, Controls = new Control[] { - new Text() + new Text("Label1") { - Name = "Label1", Properties = new Dictionary() { { "Text", new() { Value = "lorem ipsum" } }, }, }, - new Button() + new Button("Button1") { - Name = "Button1", Properties = new Dictionary() { { "Text", new() { Value = "click me" } }, @@ -89,7 +85,7 @@ public void Deserialize_ShouldParseYamlWithChildNodes() var sut = deserializer.Deserialize(yaml); sut.Should().NotBeNull().And.BeOfType(); sut.Name.Should().Be("Screen1"); - sut.ControlUri.Should().Be(BuiltInTemplatesUris.Screen); + sut.ControlUri.Should().Be(BuiltInTemplates.Screen); sut.Properties.Should().NotBeNull() .And.HaveCount(1) .And.ContainKey("Text"); @@ -98,7 +94,7 @@ public void Deserialize_ShouldParseYamlWithChildNodes() sut.Controls.Should().NotBeNull().And.HaveCount(2); sut.Controls![0].Should().BeOfType(); sut.Controls![0].Name.Should().Be("Label1"); - sut.Controls![0].ControlUri.Should().Be(BuiltInTemplatesUris.Text); + sut.Controls![0].ControlUri.Should().Be(BuiltInTemplates.Text); sut.Controls![0].Properties.Should().NotBeNull() .And.HaveCount(1) .And.ContainKey("Text"); @@ -106,7 +102,7 @@ public void Deserialize_ShouldParseYamlWithChildNodes() sut.Controls![1].Should().BeOfType