diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bc28a23..82c6a1e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -62,7 +62,7 @@ jobs: - name: Build - CI run: | $adjustedPackageVersion="${{ steps.gitversion.outputs.semVer }}".ToLower(); - dotnet pack -c Release -p:PackageVersion=$adjustedPackageVersion -p:Version=${{ steps.gitversion.outputs.assemblySemVer }} -o .\artifacts src/Resizetizer/src/Resizetizer.csproj + dotnet pack -c Release -p:PackageVersion=$adjustedPackageVersion -p:Version=${{ steps.gitversion.outputs.assemblySemVer }} -o .\artifacts src/Resizetizer/src/Resizetizer.csproj - name: Upload Artifacts uses: actions/upload-artifact@v4 @@ -72,7 +72,7 @@ jobs: - name: Run UnitTests run: | - dotnet test src/Resizetizer/test/UnitTests/Resizetizer.UnitTests.csproj + dotnet test src/Resizetizer/test/UnitTests/Resizetizer.UnitTests.csproj -c Release -p:PackageVersion=$adjustedPackageVersion -p:Version=${{ steps.gitversion.outputs.assemblySemVer }} --logger GitHubActions --blame-crash --collect:"XPlat Code Coverage" -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=opencover validation_5_2: name: Validate 5.2 Samples diff --git a/src/.nuspec/Uno.Resizetizer.windows.skia.targets b/src/.nuspec/Uno.Resizetizer.windows.skia.targets index 53264b3..f2c28b2 100644 --- a/src/.nuspec/Uno.Resizetizer.windows.skia.targets +++ b/src/.nuspec/Uno.Resizetizer.windows.skia.targets @@ -21,7 +21,7 @@ diff --git a/src/Resizetizer/src/GeneratePackageAppxManifest.cs b/src/Resizetizer/src/GeneratePackageAppxManifest.cs index d9c4f98..b992a18 100644 --- a/src/Resizetizer/src/GeneratePackageAppxManifest.cs +++ b/src/Resizetizer/src/GeneratePackageAppxManifest.cs @@ -4,6 +4,7 @@ using System; using System.IO; using System.Linq; +using System.Xml; using System.Xml.Linq; namespace Uno.Resizetizer @@ -15,9 +16,9 @@ public class GeneratePackageAppxManifest_v0 : Task const string PackageVersionPlaceholder = "0.0.0.0"; const string ImageExtension = ".png"; - const string ErrorVersionNumberCombination = "ApplicationDisplayVersion '{0}' was not a valid 3 part semver version number and/or ApplicationVersion '{1}' was not a valid integer."; + const string UapNamespace = "http://schemas.microsoft.com/appx/manifest/uap/windows10"; - static readonly XNamespace xmlnsUap = "http://schemas.microsoft.com/appx/manifest/uap/windows10"; + const string ErrorVersionNumberCombination = "ApplicationDisplayVersion '{0}' was not a valid 3 part semver version number and/or ApplicationVersion '{1}' was not a valid integer."; [Required] public string IntermediateOutputPath { get; set; } = null!; @@ -91,7 +92,17 @@ public override bool Execute() UpdateManifest(appx); - appx.Save(writer); + // Define the settings for the XmlWriter + var settings = new XmlWriterSettings + { + Indent = true, + Encoding = writer.Encoding, + NamespaceHandling = NamespaceHandling.OmitDuplicates, + OmitXmlDeclaration = false // Ensure the XML declaration is included + }; + + using var xmlWriter = XmlWriter.Create(writer, settings); + appx.Save(xmlWriter); }); GeneratedAppxManifest = new TaskItem(filename); @@ -109,6 +120,10 @@ void UpdateManifest(XDocument appx) var appIconInfo = AppIcon?.Length > 0 ? ResizeImageInfo.Parse(AppIcon[0]) : null; var splashInfo = SplashScreen?.Length > 0 ? ResizeImageInfo.Parse(SplashScreen[0]) : null; + var xmlnsUap = appx.Root.Attributes() + .Where(a => a.IsNamespaceDeclaration && a.Value == UapNamespace) + .Select(a => XNamespace.Get(a.Value)) + .FirstOrDefault(); var xmlns = appx.Root!.GetDefaultNamespace(); // @@ -498,10 +513,10 @@ private static void SetDependencyTargetDeviceFamily(XDocument appx, string targe if (targetDeviceFamilyElements is null || !targetDeviceFamilyElements.Any()) { var universal = new XElement(xmlns + "TargetDeviceFamily"); - universal.SetAttributeValue(xmlns + "Name", "Windows.Universal"); + universal.SetAttributeValue("Name", "Windows.Universal"); var desktop = new XElement(xmlns + "TargetDeviceFamily"); - desktop.SetAttributeValue(xmlns + "Name", "Windows.Desktop"); + desktop.SetAttributeValue("Name", "Windows.Desktop"); dependencies.Add(universal, desktop); targetDeviceFamilyElements = [universal, desktop]; @@ -509,8 +524,8 @@ private static void SetDependencyTargetDeviceFamily(XDocument appx, string targe foreach (var target in targetDeviceFamilyElements) { - SetVersion(target, xmlns + "MinVersion", targetPlatformMinVersion); - SetVersion(target, xmlns + "MaxVersionTested", targetPlatformVersion); + SetVersion(target, "MinVersion", targetPlatformMinVersion); + SetVersion(target, "MaxVersionTested", targetPlatformVersion); } } @@ -523,19 +538,19 @@ private static void SetVersion(XElement target, XName attributeName, string vers } } - static bool IsVersionAttribute(XAttribute attribute, XName attributeName) - { - var currentAttributeName = attribute.Name.LocalName; - var expectedAttributeName = attributeName.LocalName; - - var currentAttributeNamespace = attribute.Name.Namespace.NamespaceName; - var expectedAttributeNamespace = attributeName.NamespaceName; - - // The Version may not have a current Namespace and should use the default namespace - if (string.IsNullOrEmpty(currentAttributeNamespace)) - return currentAttributeName == expectedAttributeName; - - return currentAttributeName == expectedAttributeName && currentAttributeNamespace == expectedAttributeNamespace; + static bool IsVersionAttribute(XAttribute attribute, XName attributeName) + { + var currentAttributeName = attribute.Name.LocalName; + var expectedAttributeName = attributeName.LocalName; + + var currentAttributeNamespace = attribute.Name.Namespace.NamespaceName; + var expectedAttributeNamespace = attributeName.NamespaceName; + + // The Version may not have a current Namespace and should use the default namespace + if (string.IsNullOrEmpty(currentAttributeNamespace)) + return currentAttributeName == expectedAttributeName; + + return currentAttributeName == expectedAttributeName && currentAttributeNamespace == expectedAttributeNamespace; } public static bool TryMergeVersionNumbers(string? displayVersion, string? version, out string? finalVersion) diff --git a/src/Resizetizer/test/UnitTests/GeneratePackageAppxManifestTests.cs b/src/Resizetizer/test/UnitTests/GeneratePackageAppxManifestTests.cs index 8ed738f..2517f4a 100644 --- a/src/Resizetizer/test/UnitTests/GeneratePackageAppxManifestTests.cs +++ b/src/Resizetizer/test/UnitTests/GeneratePackageAppxManifestTests.cs @@ -1,61 +1,92 @@ #nullable enable +//#define WRITE_EXPECTED + using Microsoft.Build.Framework; using Microsoft.Build.Utilities; -using System; -using System.Collections; +using Resizetizer.UnitTests.Mocks; using System.IO; using System.Linq; using System.Xml.Linq; using Xunit; +using Xunit.Abstractions; namespace Uno.Resizetizer.Tests -{ - public class GeneratePackageAppxManifestTests : MSBuildTaskTestFixture - { +{ + public class GeneratePackageAppxManifestTests(ITestOutputHelper testOutput) : MSBuildTaskTestFixture(testOutput) + { + protected GeneratePackageAppxManifest_v0 GetNewTask( + string appxManifest, + string? generatedFilename = null, + string? applicationId = null, + string? applicationDisplayVersion = null, + string? applicationVersion = null, + string? applicationTitle = null, + string? description = null, + string? applicationPublisher = null, + ITaskItem? appIcon = null, + ITaskItem? splashScreen = null, + string? targetPlatformVersion = null, + string? targetPlatformMinVersion = null, + string? authors = null) => + GetNewTask( + [new TaskItem(appxManifest)], + generatedFilename, + applicationId, + applicationDisplayVersion, + applicationVersion, + applicationTitle, + description, + applicationPublisher, + appIcon, + splashScreen, + targetPlatformVersion, + targetPlatformMinVersion, + authors); + protected GeneratePackageAppxManifest_v0 GetNewTask( - string manifest, + ITaskItem appxManifest, string? generatedFilename = null, string? applicationId = null, - string? displayVersion = null, - string? version = null, - string? displayName = null, + string? applicationDisplayVersion = null, + string? applicationVersion = null, + string? applicationTitle = null, string? description = null, string? applicationPublisher = null, ITaskItem? appIcon = null, - ITaskItem? splashScreen = null) - { - return new() - { - IntermediateOutputPath = DestinationDirectory, - BuildEngine = this, - GeneratedFilename = generatedFilename, - AppxManifest = new []{new TaskItem(manifest)}, - ApplicationId = applicationId, - ApplicationDisplayVersion = displayVersion, - ApplicationVersion = version, - ApplicationTitle = displayName, - AssemblyName = GetType().Assembly.FullName, - Description = description, - ApplicationPublisher = applicationPublisher, - AppIcon = appIcon == null ? null : new[] { appIcon }, - SplashScreen = splashScreen == null ? null : new[] { splashScreen }, - TargetFramework = "windows" - }; - } + ITaskItem? splashScreen = null, + string? targetPlatformVersion = null, + string? targetPlatformMinVersion = null, + string? authors = null) => + GetNewTask( + [appxManifest], + generatedFilename, + applicationId, + applicationDisplayVersion, + applicationVersion, + applicationTitle, + description, + applicationPublisher, + appIcon, + splashScreen, + targetPlatformVersion, + targetPlatformMinVersion, + authors); + protected GeneratePackageAppxManifest_v0 GetNewTask( - ITaskItem[] appxManifests, - string? generatedFilename = null, - string? applicationId = null, - string? displayVersion = null, - string? version = null, - string? displayName = null, - string? description = null, - string? applicationPublisher = null, - ITaskItem? appIcon = null, - ITaskItem? splashScreen = null, - string? targetPlatformVersion = null, - string? targetPlatformMinVersion = null) + ITaskItem[] appxManifests, + string? generatedFilename = null, + string? applicationId = null, + string? applicationDisplayVersion = null, + string? applicationVersion = null, + string? applicationTitle = null, + string? description = null, + string? applicationPublisher = null, + ITaskItem? appIcon = null, + ITaskItem? splashScreen = null, + string? targetPlatformVersion = null, + string? targetPlatformMinVersion = null, + string? authors = null) { return new() { @@ -64,15 +95,16 @@ protected GeneratePackageAppxManifest_v0 GetNewTask( GeneratedFilename = generatedFilename, AppxManifest = appxManifests, ApplicationId = applicationId, - ApplicationDisplayVersion = displayVersion, - ApplicationVersion = version, - ApplicationTitle = displayName, + ApplicationDisplayVersion = applicationDisplayVersion, + ApplicationVersion = applicationVersion, + ApplicationTitle = applicationTitle, Description = description, ApplicationPublisher = applicationPublisher, AssemblyName = GetType().Assembly.GetName().Name, - AppIcon = appIcon == null ? null : new[] { appIcon }, - SplashScreen = splashScreen == null ? null : new[] { splashScreen }, + AppIcon = appIcon == null ? null : [appIcon], + SplashScreen = splashScreen == null ? null : [splashScreen], TargetFramework = "windows", + Authors = authors, TargetPlatformVersion = targetPlatformVersion, TargetPlatformMinVersion = targetPlatformMinVersion }; @@ -95,109 +127,65 @@ public void FileIsGenerated(string? specificFn, string outputFn) [Fact] public void ManifestTakesPriority() { - var appIcon = new TaskItem("images/camera.svg"); - appIcon.SetMetadata("ForegroundFile", "images/loginbg.png"); - appIcon.SetMetadata("IsAppIcon", "true"); + var appIcon = MockTaskItem.CreateAppIcon("images/camera.svg", "images/loginbg.png"); + var splashScreen = MockTaskItem.CreateSplashScreen("images/dotnet_logo.svg", "#FFFFFF"); - var splashScreen = new TaskItem("images/dotnet_logo.svg"); - splashScreen.SetMetadata("Color", "#FFFFFF"); - - var inputFilename = $"testdata/appxmanifest/typical.appxmanifest"; + var inputFilename = $"testdata/appxmanifest/manifestTakesPriority.input.appxmanifest"; var task = GetNewTask(inputFilename, applicationId: "com.contoso.myapp", - displayVersion: "2.5", - version: "3", - displayName: "Fishy Things", + applicationDisplayVersion: "2.5", + applicationVersion: "3", + applicationTitle: "Fishy Things", appIcon: appIcon, splashScreen: splashScreen); var success = task.Execute(); Assert.True(success, $"{task.GetType()}.Execute() failed: " + LogErrorEvents.FirstOrDefault()?.Message); - var outputFilename = Path.Combine(DestinationDirectory, "Package.appxmanifest"); - var expectedFilename = $"testdata/appxmanifest/typical.appxmanifest"; - - var outputDoc = XDocument.Load(outputFilename); - var expectedDoc = XDocument.Load(expectedFilename); - - if (!XNode.DeepEquals(outputDoc, expectedDoc)) - { - Assert.Equal(expectedDoc.ToString(), outputDoc.ToString()); - } + AssertExpectedManifest(task, inputFilename); } [Fact] public void CorrectGenerationWhenUserSpecifyBackgroundColor() { - var input = "empty"; - var expected = "typicalWithNoBackground"; - var appIcon = new TaskItem("images\\appicon.svg"); - appIcon.SetMetadata("ForegroundFile", "images\\appiconfg.svg"); - appIcon.SetMetadata("Link", "images\\appicon.svg"); - appIcon.SetMetadata("IsAppIcon", "true"); - - var splashScreen = new TaskItem("images/dotnet_bot.svg"); - splashScreen.SetMetadata("Color", "#FFFFFF"); + var appIcon = MockTaskItem.CreateAppIcon("images/appicon.svg", "images/appiconfg.svg"); appIcon.SetMetadata("Color", "#FFFFFF"); + var splashScreen = MockTaskItem.CreateSplashScreen("images/dotnet_bot.svg", "#FFFFFF"); - var inputFilename = $"testdata/appxmanifest/{input}.appxmanifest"; + var inputFilename = $"testdata/appxmanifest/correctGenerationWhenUserSpecifyBackgroundColor.input.appxmanifest"; var task = GetNewTask(inputFilename, applicationId: "com.contoso.myapp", - displayVersion: "1.0.0", - version: "1", - displayName: "Sample App", + applicationDisplayVersion: "1.0.0", + applicationVersion: "1", + applicationTitle: "Sample App", appIcon: appIcon, splashScreen: splashScreen); var success = task.Execute(); - Assert.True(success, $"{task.GetType()}.Execute() failed: " + LogErrorEvents.FirstOrDefault()?.Message); - - var outputFilename = Path.Combine(DestinationDirectory, "Package.appxmanifest"); - var expectedFilename = $"testdata/appxmanifest/{expected}.appxmanifest"; - - var outputDoc = XDocument.Load(outputFilename); - var expectedDoc = XDocument.Load(expectedFilename); - if (!XNode.DeepEquals(outputDoc, expectedDoc)) - { - Assert.Equal(expectedDoc.ToString(), outputDoc.ToString()); - } + Assert.True(success, $"{task.GetType()}.Execute() failed: " + LogErrorEvents.FirstOrDefault()?.Message); + AssertExpectedManifest(task, inputFilename); } [Fact] - public void CorrectGenerationWhitOutBackgroundColor() + public void CorrectGenerationWithOutBackgroundColor() { - var input = "typical"; - var expected = "typical"; - var appIcon = new TaskItem("images/appicon.svg"); - appIcon.SetMetadata("ForegroundFile", "images/appiconfg.svg"); - appIcon.SetMetadata("IsAppIcon", "true"); - - var splashScreen = new TaskItem("images/dotnet_bot.svg"); - splashScreen.SetMetadata("Color", "#FFFFFF"); + var appIcon = MockTaskItem.CreateAppIcon("images/appicon.svg", "images/appiconfg.svg"); + var splashScreen = MockTaskItem.CreateSplashScreen("images/dotnet_bot.svg", "#FFFFFF"); - var inputFilename = $"testdata/appxmanifest/{input}.appxmanifest"; + var inputFilename = $"testdata/appxmanifest/correctGenerationWithOutBackgroundColor.input.appxmanifest"; var task = GetNewTask(inputFilename, applicationId: "com.contoso.myapp", - displayVersion: "1.0.0", - version: "1", - displayName: "Sample App", + applicationDisplayVersion: "1.0.0", + applicationVersion: "1", + applicationTitle: "Sample App", appIcon: appIcon, splashScreen: splashScreen); var success = task.Execute(); Assert.True(success, $"{task.GetType()}.Execute() failed: " + LogErrorEvents.FirstOrDefault()?.Message); - var outputFilename = Path.Combine(DestinationDirectory, "Package.appxmanifest"); - var expectedFilename = $"testdata/appxmanifest/{expected}.appxmanifest"; - - var outputDoc = XDocument.Load(outputFilename); - var expectedDoc = XDocument.Load(expectedFilename); - - if (!XNode.DeepEquals(outputDoc, expectedDoc)) - { - Assert.Equal(expectedDoc.ToString(), outputDoc.ToString()); - } + AssertExpectedManifest(task, inputFilename); } [Theory] @@ -229,7 +217,7 @@ public void TaskShouldFileAWarningIfMoreThanOneManifestIsProvided() { // Arrange var taskItem = new TaskItem("testdata/appxmanifest/typical.appxmanifest"); - var task = GetNewTask(appxManifests: new [] {taskItem, taskItem}); + var task = GetNewTask(appxManifests: [taskItem, taskItem]); // Act task.Execute(); @@ -252,18 +240,46 @@ public void TaskShouldNotDuplicateTargetVersions() task.Execute(); // Assert - AssertExpectedManifest(task.GeneratedAppxManifest.ItemSpec, taskItem.ItemSpec); + AssertExpectedManifest(task, taskItem); + } + + [Theory] + [InlineData("template")] + public void GeneratesExpectedAppxManifest(string manifestName) + { + // Arrange + var appIcon = MockTaskItem.CreateAppIcon("images/camera.svg", "images/loginbg.png"); + var splashScreen = MockTaskItem.CreateSplashScreen("images/dotnet_logo.svg", "#FFFFFF"); + + var taskItem = $"testdata/appxmanifest/{manifestName}.input.appxmanifest"; + var task = GetNewTask( + appxManifest: taskItem, + applicationId: "com.contoso.myapp", + applicationDisplayVersion: "1.0.0", + applicationVersion: "1", + applicationTitle: "Sample App", + description: "This is a sample from the Unit Tests", + appIcon: appIcon, + splashScreen: splashScreen, + targetPlatformVersion: "10.0.19041.0", + targetPlatformMinVersion: "10.0.17763.0"); + + // Act + task.Execute(); + + // Assert + AssertExpectedManifest(task, taskItem); } [Fact] public void TaskShouldBeAbleToOverwriteAppxManifest() { // Arrange - var taskItem = new TaskItem("testdata/appxmanifest/empty.appxmanifest"); + var taskItem = "testdata/appxmanifest/empty.appxmanifest"; var task = GetNewTask( - appxManifests: [taskItem], - displayVersion: "1.0.0", - version: "1", + appxManifest: taskItem, + applicationDisplayVersion: "1.0.0", + applicationVersion: "1", targetPlatformVersion: "10.0.19041.0", targetPlatformMinVersion: "10.0.17763.0"); @@ -290,12 +306,58 @@ public void TaskShouldBeAbleToOverwriteAppxManifest() } } - static void AssertExpectedManifest(string generatedManifestPath, string inputManifestPath) + [Fact] + public void UnoIssue17199() + { + var appIcon = MockTaskItem.CreateAppIcon(@"images\appicon.svg", @"images\appiconfg.svg"); + appIcon.SetMetadata("ForegroundScale", "0.65"); + appIcon.SetMetadata("Color", "#00000000"); + appIcon.SetMetadata("IsDefaultItem", "true"); + + var splashScreen = MockTaskItem.CreateSplashScreen(@"images\dotnet_bot.svg"); + splashScreen.SetMetadata("BaseSize", "128,128"); + + var inputFile = "testdata/appxmanifest/unoIssue17199.input.appxmanifest"; + + var task = GetNewTask( + appxManifest: inputFile, + applicationTitle: "Sample App", + description: "SampleApp powered by Uno Platform", + applicationVersion: "1", + applicationPublisher: "Uno Platform", + applicationDisplayVersion: "1.0", + targetPlatformVersion: "10.0.19041.0", + targetPlatformMinVersion: "10.0.18362.0", + applicationId: "com.contoso.sampleapp", + authors: "Uno Platform", + appIcon: appIcon, + splashScreen: splashScreen + ); + + // Act + task.Execute(); + + // Assert + AssertExpectedManifest(task, inputFile); + + } + + static void AssertExpectedManifest(GeneratePackageAppxManifest_v0 task, string inputManifest) => + AssertExpectedManifest(task, new TaskItem(inputManifest)); + + static void AssertExpectedManifest(GeneratePackageAppxManifest_v0 task, ITaskItem inputManifest) { - var generated = XDocument.Load(generatedManifestPath).ToString(); - var expected = XDocument.Load(inputManifestPath.Replace(".input.", ".expected.")).ToString(); + Assert.False(task.Log.HasLoggedErrors); + Assert.NotNull(task.GeneratedAppxManifest); + + var generated = File.ReadAllText(task.GeneratedAppxManifest.ItemSpec); + var expectedFile = inputManifest.ItemSpec.Replace(".input.", ".expected."); +#if WRITE_EXPECTED + File.WriteAllText(expectedFile, generated); +#endif + var expected = File.ReadAllText(expectedFile); - Assert.Equal(expected, generated); + Assert.Equal(expected, generated, ignoreLineEndingDifferences: true, ignoreWhiteSpaceDifferences: true); } } } diff --git a/src/Resizetizer/test/UnitTests/MSBuildTaskFixture.cs b/src/Resizetizer/test/UnitTests/MSBuildTaskFixture.cs index eb20c49..6cc57bc 100644 --- a/src/Resizetizer/test/UnitTests/MSBuildTaskFixture.cs +++ b/src/Resizetizer/test/UnitTests/MSBuildTaskFixture.cs @@ -1,13 +1,24 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Reflection.Metadata.Ecma335; using Microsoft.Build.Framework; +using Xunit.Abstractions; namespace Uno.Resizetizer.Tests { public abstract class MSBuildTaskTestFixture : BaseTest, IBuildEngine - where TTask : Microsoft.Build.Framework.ITask + where TTask : Microsoft.Build.Framework.ITask, new() { + private readonly ITestOutputHelper? _testOutputHelper; + + protected MSBuildTaskTestFixture() { } + + protected MSBuildTaskTestFixture(ITestOutputHelper testOutputHelper) + { + _testOutputHelper = testOutputHelper; + } + protected readonly TestLogger Logger; protected List LogErrorEvents = new List(); @@ -27,12 +38,34 @@ public abstract class MSBuildTaskTestFixture : BaseTest, IBuildEngine bool IBuildEngine.BuildProjectFile(string projectFileName, string[] targetNames, IDictionary globalProperties, IDictionary targetOutputs) => throw new NotImplementedException(); - void IBuildEngine.LogCustomEvent(CustomBuildEventArgs e) => LogCustomEvents.Add(e); + void IBuildEngine.LogCustomEvent(CustomBuildEventArgs e) + { + _testOutputHelper?.WriteLine("CUSTOM - ({0}) {1}: {2}", e.SenderName, e.Timestamp, e.Message); + LogCustomEvents.Add(e); + } + + void IBuildEngine.LogErrorEvent(BuildErrorEventArgs e) + { + _testOutputHelper?.WriteLine("ERROR - ({0}) {1}: {2}", e.SenderName, e.Timestamp, e.Message); + LogErrorEvents.Add(e); + } - void IBuildEngine.LogErrorEvent(BuildErrorEventArgs e) => LogErrorEvents.Add(e); + void IBuildEngine.LogMessageEvent(BuildMessageEventArgs e) + { + _testOutputHelper?.WriteLine("LOG - ({0}) {1}: {2}", e.SenderName, e.Timestamp, e.Message); + LogMessageEvents.Add(e); + } - void IBuildEngine.LogMessageEvent(BuildMessageEventArgs e) => LogMessageEvents.Add(e); + void IBuildEngine.LogWarningEvent(BuildWarningEventArgs e) + { + _testOutputHelper?.WriteLine("WARNING - ({0}) {1}: {2}", e.SenderName, e.Timestamp, e.Message); + LogWarningEvents.Add(e); + } - void IBuildEngine.LogWarningEvent(BuildWarningEventArgs e) => LogWarningEvents.Add(e); + protected TTask CreateTask() => + new() + { + BuildEngine = this, + }; } } \ No newline at end of file diff --git a/src/Resizetizer/test/UnitTests/Mocks/MockTaskItem.cs b/src/Resizetizer/test/UnitTests/Mocks/MockTaskItem.cs new file mode 100644 index 0000000..060be67 --- /dev/null +++ b/src/Resizetizer/test/UnitTests/Mocks/MockTaskItem.cs @@ -0,0 +1,76 @@ +using Microsoft.Build.Framework; +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace Resizetizer.UnitTests.Mocks; + +internal class MockTaskItem(string itemSpec, Dictionary metadata, bool useLink) : ITaskItem +{ + private readonly IDictionary _metadata = metadata; + + public string ItemSpec + { + get => itemSpec; + set => throw new NotImplementedException(); + } + + public ICollection MetadataNames => _metadata.Keys.ToArray(); + public int MetadataCount => MetadataNames.Count; + + public IDictionary CloneCustomMetadata() + { + throw new NotImplementedException(); + } + + public void CopyMetadataTo(ITaskItem destinationItem) + { + throw new NotImplementedException(); + } + + public string GetMetadata(string metadataName) + { + if (_metadata.ContainsKey(metadataName)) + { + return _metadata[metadataName]; + } + + return metadataName switch + { + "Link" => useLink ? ItemSpec : string.Empty, + "FullPath" => Path.GetFullPath(ItemSpec), + "DefiningProjectDirectory" => Environment.CurrentDirectory, + _ => string.Empty + }; + } + + public void RemoveMetadata(string metadataName) + { + throw new NotImplementedException(); + } + + public void SetMetadata(string metadataName, string metadataValue) + { + _metadata[metadataName] = metadataValue; + } + + public static ITaskItem CreateAppIcon(string itemSpec, string foregroundFile, bool useLink = true) + { + return new MockTaskItem(itemSpec, + new Dictionary + { + { "ForegroundFile", foregroundFile }, + { "IsAppIcon", "true" } + }, useLink); + } + + public static ITaskItem CreateSplashScreen(string itemSpec, string color = "#FFFFFF", bool useLink = true) + { + return new MockTaskItem(itemSpec, new Dictionary + { + { "Color", color } + }, useLink); + } +} diff --git a/src/Resizetizer/test/UnitTests/Resizetizer.UnitTests.csproj b/src/Resizetizer/test/UnitTests/Resizetizer.UnitTests.csproj index a7bd72a..475889b 100644 --- a/src/Resizetizer/test/UnitTests/Resizetizer.UnitTests.csproj +++ b/src/Resizetizer/test/UnitTests/Resizetizer.UnitTests.csproj @@ -10,6 +10,10 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/Resizetizer/test/UnitTests/testdata/appxmanifest/correctGenerationWhenUserSpecifyBackgroundColor.expected.appxmanifest b/src/Resizetizer/test/UnitTests/testdata/appxmanifest/correctGenerationWhenUserSpecifyBackgroundColor.expected.appxmanifest new file mode 100644 index 0000000..e49f472 --- /dev/null +++ b/src/Resizetizer/test/UnitTests/testdata/appxmanifest/correctGenerationWhenUserSpecifyBackgroundColor.expected.appxmanifest @@ -0,0 +1,33 @@ + + + + + Uno Platform + Sample App + images\appiconStoreLogo.png + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Resizetizer/test/UnitTests/testdata/appxmanifest/correctGenerationWhenUserSpecifyBackgroundColor.input.appxmanifest b/src/Resizetizer/test/UnitTests/testdata/appxmanifest/correctGenerationWhenUserSpecifyBackgroundColor.input.appxmanifest new file mode 100644 index 0000000..2377e8b --- /dev/null +++ b/src/Resizetizer/test/UnitTests/testdata/appxmanifest/correctGenerationWhenUserSpecifyBackgroundColor.input.appxmanifest @@ -0,0 +1,24 @@ + + + + + Uno Platform + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Resizetizer/test/UnitTests/testdata/appxmanifest/correctGenerationWithOutBackgroundColor.expected.appxmanifest b/src/Resizetizer/test/UnitTests/testdata/appxmanifest/correctGenerationWithOutBackgroundColor.expected.appxmanifest new file mode 100644 index 0000000..645e66f --- /dev/null +++ b/src/Resizetizer/test/UnitTests/testdata/appxmanifest/correctGenerationWithOutBackgroundColor.expected.appxmanifest @@ -0,0 +1,33 @@ + + + + + Uno Platform + Sample App + images\appiconStoreLogo.png + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Resizetizer/test/UnitTests/testdata/appxmanifest/correctGenerationWithOutBackgroundColor.input.appxmanifest b/src/Resizetizer/test/UnitTests/testdata/appxmanifest/correctGenerationWithOutBackgroundColor.input.appxmanifest new file mode 100644 index 0000000..458ae41 --- /dev/null +++ b/src/Resizetizer/test/UnitTests/testdata/appxmanifest/correctGenerationWithOutBackgroundColor.input.appxmanifest @@ -0,0 +1,36 @@ + + + + + Uno Platform + Sample App + images\appiconStoreLogo.png + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Resizetizer/test/UnitTests/testdata/appxmanifest/duplicate-versions.expected.appxmanifest b/src/Resizetizer/test/UnitTests/testdata/appxmanifest/duplicate-versions.expected.appxmanifest index 9b443c0..a43047d 100644 --- a/src/Resizetizer/test/UnitTests/testdata/appxmanifest/duplicate-versions.expected.appxmanifest +++ b/src/Resizetizer/test/UnitTests/testdata/appxmanifest/duplicate-versions.expected.appxmanifest @@ -1,28 +1,28 @@ - + - - - Uno.Themes.WinUI.Samples - Uno.Themes.WinUI.Samples - - - - - - - - - - - - - - - - - - - - - + + + Uno.Themes.WinUI.Samples + Uno.Themes.WinUI.Samples + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Resizetizer/test/UnitTests/testdata/appxmanifest/empty.appxmanifest b/src/Resizetizer/test/UnitTests/testdata/appxmanifest/empty.appxmanifest index 2f11a43..2377e8b 100644 --- a/src/Resizetizer/test/UnitTests/testdata/appxmanifest/empty.appxmanifest +++ b/src/Resizetizer/test/UnitTests/testdata/appxmanifest/empty.appxmanifest @@ -1,4 +1,4 @@ - + + + + + Uno Platform + Sample App + images\appiconStoreLogo.png + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Resizetizer/test/UnitTests/testdata/appxmanifest/manifestTakesPriority.input.appxmanifest b/src/Resizetizer/test/UnitTests/testdata/appxmanifest/manifestTakesPriority.input.appxmanifest new file mode 100644 index 0000000..458ae41 --- /dev/null +++ b/src/Resizetizer/test/UnitTests/testdata/appxmanifest/manifestTakesPriority.input.appxmanifest @@ -0,0 +1,36 @@ + + + + + Uno Platform + Sample App + images\appiconStoreLogo.png + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Resizetizer/test/UnitTests/testdata/appxmanifest/template.expected.appxmanifest b/src/Resizetizer/test/UnitTests/testdata/appxmanifest/template.expected.appxmanifest new file mode 100644 index 0000000..1a3e3f1 --- /dev/null +++ b/src/Resizetizer/test/UnitTests/testdata/appxmanifest/template.expected.appxmanifest @@ -0,0 +1,33 @@ + + + + + Uno Platform + Sample App + images\cameraStoreLogo.png + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Resizetizer/test/UnitTests/testdata/appxmanifest/template.input.appxmanifest b/src/Resizetizer/test/UnitTests/testdata/appxmanifest/template.input.appxmanifest new file mode 100644 index 0000000..2f11a43 --- /dev/null +++ b/src/Resizetizer/test/UnitTests/testdata/appxmanifest/template.input.appxmanifest @@ -0,0 +1,24 @@ + + + + + Uno Platform + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Resizetizer/test/UnitTests/testdata/appxmanifest/unoIssue17199.expected.appxmanifest b/src/Resizetizer/test/UnitTests/testdata/appxmanifest/unoIssue17199.expected.appxmanifest new file mode 100644 index 0000000..67489f2 --- /dev/null +++ b/src/Resizetizer/test/UnitTests/testdata/appxmanifest/unoIssue17199.expected.appxmanifest @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + Sample App + Uno Platform + images\appiconStoreLogo.png + + \ No newline at end of file diff --git a/src/Resizetizer/test/UnitTests/testdata/appxmanifest/unoIssue17199.input.appxmanifest b/src/Resizetizer/test/UnitTests/testdata/appxmanifest/unoIssue17199.input.appxmanifest new file mode 100644 index 0000000..7d40f4b --- /dev/null +++ b/src/Resizetizer/test/UnitTests/testdata/appxmanifest/unoIssue17199.input.appxmanifest @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + +