From 7b352d9a8e935e5f78384cc3f2cd126c07d83a24 Mon Sep 17 00:00:00 2001 From: Dan Siegel Date: Fri, 24 Apr 2026 07:37:49 -0600 Subject: [PATCH 1/2] Add unit tests for Prism.Uno.WinUI and Prism.DryIoc.Uno.WinUI Introduces a comprehensive test suite for Uno Platform projects, including API contract verification, container integration, region management, and dialog services. This also enables test execution in the CI/CD workflows and adds coverlet.msbuild to support code coverage reporting. --- .github/workflows/build_uno.yml | 2 +- .github/workflows/ci.yml | 2 +- Directory.Packages.props | 1 + PrismLibrary.sln | 39 ++++++ PrismLibrary_Uno.slnf | 4 +- .../ContainerHelper.cs | 18 +++ .../Prism.DryIoc.Uno.WinUI.Tests.csproj | 35 +++++ .../PrismApplicationFixture.cs | 63 +++++++++ .../ApiContractInventoryFixture.cs | 61 +++++++++ .../CoreRegionCoverageFixture.cs | 129 ++++++++++++++++++ .../DialogAndInteractivityFixture.cs | 96 +++++++++++++ .../InvokeCommandActionFixture.cs | 46 +++++++ .../NavigationViewRegionAdapterFixture.cs | 55 ++++++++ .../Prism.Uno.WinUI.Tests.csproj | 35 +++++ .../PrismApplicationBaseFixture.cs | 50 +++++++ .../RegionManagerRequestNavigateFixture.cs | 102 ++++++++++++++ .../UnoApiUtilityFixture.cs | 33 +++++ 17 files changed, 768 insertions(+), 3 deletions(-) create mode 100644 tests/Uno/Prism.DryIoc.Uno.WinUI.Tests/ContainerHelper.cs create mode 100644 tests/Uno/Prism.DryIoc.Uno.WinUI.Tests/Prism.DryIoc.Uno.WinUI.Tests.csproj create mode 100644 tests/Uno/Prism.DryIoc.Uno.WinUI.Tests/PrismApplicationFixture.cs create mode 100644 tests/Uno/Prism.Uno.WinUI.Tests/ApiContractInventoryFixture.cs create mode 100644 tests/Uno/Prism.Uno.WinUI.Tests/CoreRegionCoverageFixture.cs create mode 100644 tests/Uno/Prism.Uno.WinUI.Tests/DialogAndInteractivityFixture.cs create mode 100644 tests/Uno/Prism.Uno.WinUI.Tests/InvokeCommandActionFixture.cs create mode 100644 tests/Uno/Prism.Uno.WinUI.Tests/NavigationViewRegionAdapterFixture.cs create mode 100644 tests/Uno/Prism.Uno.WinUI.Tests/Prism.Uno.WinUI.Tests.csproj create mode 100644 tests/Uno/Prism.Uno.WinUI.Tests/PrismApplicationBaseFixture.cs create mode 100644 tests/Uno/Prism.Uno.WinUI.Tests/RegionManagerRequestNavigateFixture.cs create mode 100644 tests/Uno/Prism.Uno.WinUI.Tests/UnoApiUtilityFixture.cs diff --git a/.github/workflows/build_uno.yml b/.github/workflows/build_uno.yml index ef2de1b4d6..ce027fc369 100644 --- a/.github/workflows/build_uno.yml +++ b/.github/workflows/build_uno.yml @@ -31,4 +31,4 @@ jobs: uno-check: false uno-check-version: 1.33.1 uno-check-parameters: '--skip xcode --skip gtk3 --skip vswin --skip androidemulator --skip androidsdk --skip vsmac --skip dotnetnewunotemplates' - run-tests: false + run-tests: true diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6adc1e5848..bac6295336 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -65,7 +65,7 @@ jobs: uno-check: false uno-check-version: 1.33.1 uno-check-parameters: '--skip xcode --skip gtk3 --skip vswin --skip androidemulator --skip androidsdk --skip vsmac --skip dotnetnewunotemplates' - run-tests: false + run-tests: true code-sign: false artifact-name: Uno secrets: diff --git a/Directory.Packages.props b/Directory.Packages.props index ae89836179..0a5239f42c 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -75,6 +75,7 @@ + diff --git a/PrismLibrary.sln b/PrismLibrary.sln index 5b2cc2f306..cd343596cf 100644 --- a/PrismLibrary.sln +++ b/PrismLibrary.sln @@ -86,6 +86,16 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Prism.IocContainer.Avalonia EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Avalonia", "Avalonia", "{904D5094-55F9-4581-90AC-D6C1131F8152}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Uno", "Uno", "{8B763117-8E13-0D1A-AFE0-5BC3FACCF29C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Prism.Uno.WinUI.Tests", "tests\Uno\Prism.Uno.WinUI.Tests\Prism.Uno.WinUI.Tests.csproj", "{05132055-211C-42D4-B40A-39E4BB066E7B}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Prism.Uno", "Prism.Uno", "{1E1EDCAE-FD32-8442-764F-7F151A12D8D4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Prism.DryIoc.Uno.WinUI.Tests", "tests\Uno\Prism.DryIoc.Uno.WinUI.Tests\Prism.DryIoc.Uno.WinUI.Tests.csproj", "{158173F6-E776-422C-9127-8994C504867B}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Prism.DryIoc.Uno", "Prism.DryIoc.Uno", "{064C69BC-4576-336C-79BF-6771226CD9DC}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -372,6 +382,30 @@ Global {887E0794-798D-4127-847E-6F68D5C9B334}.Release|x64.Build.0 = Release|Any CPU {887E0794-798D-4127-847E-6F68D5C9B334}.Release|x86.ActiveCfg = Release|Any CPU {887E0794-798D-4127-847E-6F68D5C9B334}.Release|x86.Build.0 = Release|Any CPU + {05132055-211C-42D4-B40A-39E4BB066E7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {05132055-211C-42D4-B40A-39E4BB066E7B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {05132055-211C-42D4-B40A-39E4BB066E7B}.Debug|x64.ActiveCfg = Debug|Any CPU + {05132055-211C-42D4-B40A-39E4BB066E7B}.Debug|x64.Build.0 = Debug|Any CPU + {05132055-211C-42D4-B40A-39E4BB066E7B}.Debug|x86.ActiveCfg = Debug|Any CPU + {05132055-211C-42D4-B40A-39E4BB066E7B}.Debug|x86.Build.0 = Debug|Any CPU + {05132055-211C-42D4-B40A-39E4BB066E7B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {05132055-211C-42D4-B40A-39E4BB066E7B}.Release|Any CPU.Build.0 = Release|Any CPU + {05132055-211C-42D4-B40A-39E4BB066E7B}.Release|x64.ActiveCfg = Release|Any CPU + {05132055-211C-42D4-B40A-39E4BB066E7B}.Release|x64.Build.0 = Release|Any CPU + {05132055-211C-42D4-B40A-39E4BB066E7B}.Release|x86.ActiveCfg = Release|Any CPU + {05132055-211C-42D4-B40A-39E4BB066E7B}.Release|x86.Build.0 = Release|Any CPU + {158173F6-E776-422C-9127-8994C504867B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {158173F6-E776-422C-9127-8994C504867B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {158173F6-E776-422C-9127-8994C504867B}.Debug|x64.ActiveCfg = Debug|Any CPU + {158173F6-E776-422C-9127-8994C504867B}.Debug|x64.Build.0 = Debug|Any CPU + {158173F6-E776-422C-9127-8994C504867B}.Debug|x86.ActiveCfg = Debug|Any CPU + {158173F6-E776-422C-9127-8994C504867B}.Debug|x86.Build.0 = Debug|Any CPU + {158173F6-E776-422C-9127-8994C504867B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {158173F6-E776-422C-9127-8994C504867B}.Release|Any CPU.Build.0 = Release|Any CPU + {158173F6-E776-422C-9127-8994C504867B}.Release|x64.ActiveCfg = Release|Any CPU + {158173F6-E776-422C-9127-8994C504867B}.Release|x64.Build.0 = Release|Any CPU + {158173F6-E776-422C-9127-8994C504867B}.Release|x86.ActiveCfg = Release|Any CPU + {158173F6-E776-422C-9127-8994C504867B}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -409,6 +443,11 @@ Global {03B9C775-9582-409F-B67F-6B8A0CE0C7AF} = {904D5094-55F9-4581-90AC-D6C1131F8152} {887E0794-798D-4127-847E-6F68D5C9B334} = {904D5094-55F9-4581-90AC-D6C1131F8152} {904D5094-55F9-4581-90AC-D6C1131F8152} = {00FFDC13-7397-46F1-897E-A62A7575D28A} + {8B763117-8E13-0D1A-AFE0-5BC3FACCF29C} = {00FFDC13-7397-46F1-897E-A62A7575D28A} + {05132055-211C-42D4-B40A-39E4BB066E7B} = {8B763117-8E13-0D1A-AFE0-5BC3FACCF29C} + {1E1EDCAE-FD32-8442-764F-7F151A12D8D4} = {8F959801-D494-4CAF-9437-90F30472E169} + {158173F6-E776-422C-9127-8994C504867B} = {8B763117-8E13-0D1A-AFE0-5BC3FACCF29C} + {064C69BC-4576-336C-79BF-6771226CD9DC} = {8F959801-D494-4CAF-9437-90F30472E169} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C7433AE2-B1A0-4C1A-887E-5CAA7AAF67A6} diff --git a/PrismLibrary_Uno.slnf b/PrismLibrary_Uno.slnf index b9e1e45ef4..8b995f6cb8 100644 --- a/PrismLibrary_Uno.slnf +++ b/PrismLibrary_Uno.slnf @@ -7,7 +7,9 @@ "src\\Uno\\Prism.DryIoc.Uno\\Prism.DryIoc.Uno.WinUI.csproj", "src\\Uno\\Prism.Uno\\Prism.Uno.WinUI.csproj", "src\\Uno\\Prism.Uno.Markup\\Prism.Uno.WinUI.Markup.csproj", - "tests\\Prism.Core.Tests\\Prism.Core.Tests.csproj" + "tests\\Prism.Core.Tests\\Prism.Core.Tests.csproj", + "tests\\Uno\\Prism.DryIoc.Uno.WinUI.Tests\\Prism.DryIoc.Uno.WinUI.Tests.csproj", + "tests\\Uno\\Prism.Uno.WinUI.Tests\\Prism.Uno.WinUI.Tests.csproj" ] } } diff --git a/tests/Uno/Prism.DryIoc.Uno.WinUI.Tests/ContainerHelper.cs b/tests/Uno/Prism.DryIoc.Uno.WinUI.Tests/ContainerHelper.cs new file mode 100644 index 0000000000..dc6f780244 --- /dev/null +++ b/tests/Uno/Prism.DryIoc.Uno.WinUI.Tests/ContainerHelper.cs @@ -0,0 +1,18 @@ +using DryIoc; +using Prism.Container.DryIoc; +using Prism.Ioc; + +namespace Prism.Container.Uno.Tests; + +public static class ContainerHelper +{ + private static Rules CreateContainerRules() => Rules.Default.WithAutoConcreteTypeResolution() + .With(Made.Of(FactoryMethod.ConstructorWithResolvableArguments)) + .WithDefaultIfAlreadyRegistered(IfAlreadyRegistered.Replace); + + public static IContainer CreateContainer() => new global::DryIoc.Container(CreateContainerRules()); + + public static IContainerExtension CreateContainerExtension() => new DryIocContainerExtension(CreateContainer()); + + public static Type RegisteredFrameworkException => typeof(ContainerException); +} diff --git a/tests/Uno/Prism.DryIoc.Uno.WinUI.Tests/Prism.DryIoc.Uno.WinUI.Tests.csproj b/tests/Uno/Prism.DryIoc.Uno.WinUI.Tests/Prism.DryIoc.Uno.WinUI.Tests.csproj new file mode 100644 index 0000000000..25aa574a5f --- /dev/null +++ b/tests/Uno/Prism.DryIoc.Uno.WinUI.Tests/Prism.DryIoc.Uno.WinUI.Tests.csproj @@ -0,0 +1,35 @@ + + + + net10.0 + false + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + all + runtime; build; native; contentfiles; analyzers + + + + + + + + + diff --git a/tests/Uno/Prism.DryIoc.Uno.WinUI.Tests/PrismApplicationFixture.cs b/tests/Uno/Prism.DryIoc.Uno.WinUI.Tests/PrismApplicationFixture.cs new file mode 100644 index 0000000000..525f1e72d9 --- /dev/null +++ b/tests/Uno/Prism.DryIoc.Uno.WinUI.Tests/PrismApplicationFixture.cs @@ -0,0 +1,63 @@ +using System.Reflection; +using System.Runtime.Serialization; +using DryIoc; +using Prism.Container.DryIoc; +using Prism.Ioc; +using Xunit; +using static Prism.Container.Uno.Tests.ContainerHelper; +using ExceptionExtensions = System.ExceptionExtensions; + +namespace Prism.DryIoc.Uno.WinUI.Tests; + +public class PrismApplicationFixture +{ + [Fact] + public void CreateContainerExtensionReturnsDryIocContainerExtension() + { + var app = (PrismApplication)FormatterServices.GetUninitializedObject(typeof(PrismApplicationProxy)); + var method = typeof(PrismApplication).GetMethod("CreateContainerExtension", BindingFlags.NonPublic | BindingFlags.Instance); + + var container = method!.Invoke(app, null); + + Assert.IsType(container!); + } + + [Fact] + public void RegisterFrameworkExceptionTypesRegistersContainerException() + { + var app = (PrismApplication)FormatterServices.GetUninitializedObject(typeof(PrismApplicationProxy)); + var method = typeof(PrismApplication).GetMethod("RegisterFrameworkExceptionTypes", BindingFlags.NonPublic | BindingFlags.Instance); + + method!.Invoke(app, null); + + Assert.True(ExceptionExtensions.IsFrameworkExceptionRegistered(RegisteredFrameworkException)); + } + + [Fact] + public void CreateContainerRulesReturnsDryIocRules() + { + var app = (PrismApplication)FormatterServices.GetUninitializedObject(typeof(PrismApplicationProxy)); + var method = typeof(PrismApplication).GetMethod("CreateContainerRules", BindingFlags.NonPublic | BindingFlags.Instance); + + var rules = method!.Invoke(app, null); + + Assert.NotNull(rules); + Assert.IsType(rules); + } + + [Fact] + public void PrismApplicationRemainsAbstractAndExtendsPrismApplicationBase() + { + Assert.True(typeof(PrismApplication).IsAbstract); + Assert.Equal(typeof(PrismApplicationBase), typeof(PrismApplication).BaseType); + } + + private sealed class PrismApplicationProxy : PrismApplication + { + protected override UIElement CreateShell() => null!; + + protected override void RegisterTypes(IContainerRegistry containerRegistry) + { + } + } +} diff --git a/tests/Uno/Prism.Uno.WinUI.Tests/ApiContractInventoryFixture.cs b/tests/Uno/Prism.Uno.WinUI.Tests/ApiContractInventoryFixture.cs new file mode 100644 index 0000000000..81791ac631 --- /dev/null +++ b/tests/Uno/Prism.Uno.WinUI.Tests/ApiContractInventoryFixture.cs @@ -0,0 +1,61 @@ +using System.Reflection; +using Xunit; + +namespace Prism.Uno.WinUI.Tests; + +public class ApiContractInventoryFixture +{ + private static readonly Assembly PrismAssembly = typeof(PrismApplicationBase).Assembly; + + public static IEnumerable ExportedPrismTypeCases() + { + return PrismAssembly + .GetExportedTypes() + .Where(t => t.Namespace is not null && t.Namespace.StartsWith("Prism", StringComparison.Ordinal)) + .OrderBy(t => t.FullName, StringComparer.Ordinal) + .Select(t => new object[] { t.FullName! }); + } + + public static IEnumerable PublicMemberCases() + { + const BindingFlags memberFlags = + BindingFlags.Public | + BindingFlags.Instance | + BindingFlags.Static | + BindingFlags.DeclaredOnly; + + return PrismAssembly + .GetExportedTypes() + .Where(t => t.Namespace is not null && t.Namespace.StartsWith("Prism", StringComparison.Ordinal)) + .OrderBy(t => t.FullName, StringComparer.Ordinal) + .SelectMany(t => t + .GetMembers(memberFlags) + .Where(m => m.MemberType is MemberTypes.Method or MemberTypes.Property or MemberTypes.Field or MemberTypes.Event) + .OrderBy(m => m.Name, StringComparer.Ordinal) + .Select(m => new object[] { t.FullName!, m.Name, m.MemberType.ToString() })) + .Take(450); + } + + [Theory] + [MemberData(nameof(ExportedPrismTypeCases))] + public void ExportedPrismTypeIsLoadable(string fullTypeName) + { + Assert.NotNull(PrismAssembly.GetType(fullTypeName)); + } + + [Theory] + [MemberData(nameof(PublicMemberCases))] + public void PublicContractMemberIsDiscoverable(string fullTypeName, string memberName, string memberKind) + { + var type = PrismAssembly.GetType(fullTypeName); + Assert.NotNull(type); + + const BindingFlags lookupFlags = + BindingFlags.Public | + BindingFlags.Instance | + BindingFlags.Static; + + var members = type!.GetMember(memberName, lookupFlags); + Assert.Contains(members, m => string.Equals(m.MemberType.ToString(), memberKind, StringComparison.Ordinal)); + } +} diff --git a/tests/Uno/Prism.Uno.WinUI.Tests/CoreRegionCoverageFixture.cs b/tests/Uno/Prism.Uno.WinUI.Tests/CoreRegionCoverageFixture.cs new file mode 100644 index 0000000000..5fb6eda66d --- /dev/null +++ b/tests/Uno/Prism.Uno.WinUI.Tests/CoreRegionCoverageFixture.cs @@ -0,0 +1,129 @@ +using System.Collections.Specialized; +using Moq; +using Prism.Ioc; +using Prism.Navigation; +using Prism.Navigation.Regions; +using Xunit; + +namespace Prism.Uno.WinUI.Tests; + +public class CoreRegionCoverageFixture +{ + [Fact] + public void RegionManagerCanAddAndRetrieveRegionByName() + { + var regionManager = new RegionManager(); + var region = new Region { Name = "MainRegion" }; + + regionManager.Regions.Add(region); + + Assert.Same(region, regionManager.Regions["MainRegion"]); + } + + [Fact] + public void RegionManagerContainsRegionWithNameReflectsState() + { + var regionManager = new RegionManager(); + Assert.False(regionManager.Regions.ContainsRegionWithName("Target")); + + regionManager.Regions.Add(new Region { Name = "Target" }); + Assert.True(regionManager.Regions.ContainsRegionWithName("Target")); + } + + [Fact] + public void RegionManagerRemovingRegionClearsRegionManagerReference() + { + var regionManager = new RegionManager(); + var region = new Region { Name = "RemoveMe" }; + regionManager.Regions.Add(region); + + var removed = regionManager.Regions.Remove("RemoveMe"); + + Assert.True(removed); + Assert.Null(region.RegionManager); + } + + [Fact] + public void RegionManagerCreateRegionManagerReturnsNewInstance() + { + var manager = new RegionManager(); + var child = manager.CreateRegionManager(); + + Assert.NotNull(child); + Assert.NotSame(manager, child); + Assert.IsType(child); + } + + [Fact] + public void RegionManagerCollectionChangedFiresOnAddAndRemove() + { + var manager = new RegionManager(); + NotifyCollectionChangedEventArgs? lastArgs = null; + manager.Regions.CollectionChanged += (_, e) => lastArgs = e; + var region = new Region { Name = "Region1" }; + + manager.Regions.Add(region); + Assert.NotNull(lastArgs); + Assert.Equal(NotifyCollectionChangedAction.Add, lastArgs!.Action); + + manager.Regions.Remove("Region1"); + Assert.NotNull(lastArgs); + Assert.Equal(NotifyCollectionChangedAction.Remove, lastArgs!.Action); + } + + [Fact] + public void RegionGetViewReturnsNullForUnknownName() + { + var region = new Region(); + Assert.Null(region.GetView("Unknown")); + } + + [Fact] + public void RegionNameCannotBeChangedAfterFirstSet() + { + var region = new Region { Name = "Initial" }; + Assert.Throws(() => region.Name = "Changed"); + } + + [Fact] + public void RegionContextChangeRaisesPropertyChanged() + { + var region = new Region(); + var changed = false; + region.PropertyChanged += (_, e) => + { + if (e.PropertyName == nameof(region.Context)) + { + changed = true; + } + }; + + region.Context = "CTX"; + Assert.True(changed); + } + + [Fact] + public void NavigationContextParsesQueryParametersFromUri() + { + var uri = new Uri("target?name=value", UriKind.Relative); + var navService = new Mock(); + navService.SetupGet(x => x.Journal).Returns(Mock.Of()); + + var context = new NavigationContext(navService.Object, uri); + + Assert.Equal(uri, context.Uri); + Assert.NotNull(context.Parameters); + } + + [Fact] + public void NavigationContextWithoutQueryHasEmptyParameters() + { + var uri = new Uri("target", UriKind.Relative); + var navService = new Mock(); + navService.SetupGet(x => x.Journal).Returns(Mock.Of()); + + var context = new NavigationContext(navService.Object, uri); + + Assert.Empty(context.Parameters); + } +} diff --git a/tests/Uno/Prism.Uno.WinUI.Tests/DialogAndInteractivityFixture.cs b/tests/Uno/Prism.Uno.WinUI.Tests/DialogAndInteractivityFixture.cs new file mode 100644 index 0000000000..3bda29a116 --- /dev/null +++ b/tests/Uno/Prism.Uno.WinUI.Tests/DialogAndInteractivityFixture.cs @@ -0,0 +1,96 @@ +#nullable enable +using Microsoft.Xaml.Interactivity; +using Prism.Dialogs; +using Prism.Interactivity; +using Xunit; + +namespace Prism.Uno.WinUI.Tests; + +public class DialogAndInteractivityFixture +{ + [Fact] + public void KnownDialogParametersContainsUnoDialogPlacementKey() + { + Assert.Equal("dialogPlacement", KnownDialogParameters.DialogPlacement); + } + + [Fact] + public void DialogServiceExposesShowDialogMethod() + { + var method = typeof(DialogService).GetMethod(nameof(DialogService.ShowDialog)); + + Assert.NotNull(method); + Assert.Equal(typeof(void), method!.ReturnType); + Assert.Equal(3, method.GetParameters().Length); + } + + [Fact] + public void InvokeCommandActionImplementsIAction() + { + Assert.Contains(typeof(IAction), typeof(InvokeCommandAction).GetInterfaces()); + } + + [Fact] + public void DialogServiceExposesExpectedInternalConfigurationMethods() + { + Assert.NotNull(typeof(DialogService).GetMethod("CreateDialogWindow", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)); + Assert.NotNull(typeof(DialogService).GetMethod("ConfigureDialogWindowContent", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)); + Assert.NotNull(typeof(DialogService).GetMethod("ConfigureDialogWindowEvents", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)); + } + + [Fact] + public void DialogWindowImplementsIDialogWindowContract() + { + Assert.Contains(typeof(IDialogWindow), typeof(DialogWindow).GetInterfaces()); + + var showAsync = typeof(IDialogWindow).GetMethod("ShowAsync"); + var hide = typeof(IDialogWindow).GetMethod("Hide"); + Assert.NotNull(showAsync); + Assert.NotNull(hide); + } + + [Fact] + public void CreateDialogWindowUsesContainerResolveForNamedWindow() + { + var container = new Moq.Mock(); + container.Setup(x => x.Resolve(typeof(IDialogWindow), "MainWindow")).Returns(new TestDialogWindow()); + var service = new DialogService(container.Object); + var method = typeof(DialogService).GetMethod("CreateDialogWindow", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); + + var result = method!.Invoke(service, new object?[] { "MainWindow" }); + + Assert.NotNull(result); + Assert.IsAssignableFrom(result); + } + + [Fact] + public void ConfigureDialogWindowContentThrowsForNonFrameworkElement() + { + var container = new Moq.Mock(); + container.Setup(x => x.Resolve(typeof(object), "SampleDialog")).Returns(new object()); + var service = new DialogService(container.Object); + var method = typeof(DialogService).GetMethod("ConfigureDialogWindowContent", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); + + var ex = Assert.Throws(() => + method!.Invoke(service, new object[] { "SampleDialog", new TestDialogWindow(), new DialogParameters() })); + + Assert.IsType(ex.InnerException); + } + + private sealed class TestDialogWindow : IDialogWindow + { + public object? DataContext { get; set; } + public Style Style { get; set; } = null!; + public event RoutedEventHandler? Loaded; + public event Windows.Foundation.TypedEventHandler? Closing; + public event Windows.Foundation.TypedEventHandler? Closed; + public IDialogResult? Result { get; set; } + public object? Content { get; set; } + + public Windows.Foundation.IAsyncOperation ShowAsync(ContentDialogPlacement placement) => throw new NotImplementedException(); + + public void Hide() + { + } + } +} diff --git a/tests/Uno/Prism.Uno.WinUI.Tests/InvokeCommandActionFixture.cs b/tests/Uno/Prism.Uno.WinUI.Tests/InvokeCommandActionFixture.cs new file mode 100644 index 0000000000..befde55371 --- /dev/null +++ b/tests/Uno/Prism.Uno.WinUI.Tests/InvokeCommandActionFixture.cs @@ -0,0 +1,46 @@ +using Prism.Interactivity; +using Xunit; + +namespace Prism.Uno.WinUI.Tests; + +public class InvokeCommandActionFixture +{ + [Fact] + public void ImplementsIActionContract() + { + Assert.Contains(typeof(Microsoft.Xaml.Interactivity.IAction), typeof(InvokeCommandAction).GetInterfaces()); + } + + [Fact] + public void ExposesExpectedDependencyProperties() + { + Assert.NotNull(typeof(InvokeCommandAction).GetField("AutoEnableProperty")); + Assert.NotNull(typeof(InvokeCommandAction).GetField("CommandProperty")); + Assert.NotNull(typeof(InvokeCommandAction).GetField("CommandParameterProperty")); + Assert.NotNull(typeof(InvokeCommandAction).GetField("TriggerParameterPathProperty")); + } + + [Fact] + public void ExposesExecuteMethod() + { + var execute = typeof(InvokeCommandAction).GetMethod(nameof(InvokeCommandAction.Execute)); + Assert.NotNull(execute); + Assert.Equal(typeof(object), execute!.ReturnType); + } + + [Fact] + public void ExposesAutoEnableAndCommandProperties() + { + Assert.NotNull(typeof(InvokeCommandAction).GetProperty(nameof(InvokeCommandAction.AutoEnable))); + Assert.NotNull(typeof(InvokeCommandAction).GetProperty(nameof(InvokeCommandAction.Command))); + Assert.NotNull(typeof(InvokeCommandAction).GetProperty(nameof(InvokeCommandAction.CommandParameter))); + Assert.NotNull(typeof(InvokeCommandAction).GetProperty(nameof(InvokeCommandAction.TriggerParameterPath))); + } + + [Fact] + public void ContainsExecutableCommandBehaviorNestedType() + { + var nestedType = typeof(InvokeCommandAction).GetNestedType("ExecutableCommandBehavior", System.Reflection.BindingFlags.NonPublic); + Assert.NotNull(nestedType); + } +} diff --git a/tests/Uno/Prism.Uno.WinUI.Tests/NavigationViewRegionAdapterFixture.cs b/tests/Uno/Prism.Uno.WinUI.Tests/NavigationViewRegionAdapterFixture.cs new file mode 100644 index 0000000000..c12690958e --- /dev/null +++ b/tests/Uno/Prism.Uno.WinUI.Tests/NavigationViewRegionAdapterFixture.cs @@ -0,0 +1,55 @@ +using Prism.Navigation.Regions; +using Xunit; + +namespace Prism.Uno.WinUI.Tests; + +public class NavigationViewRegionAdapterFixture +{ + [Fact] + public void AdapterIsSealedAndTargetsNavigationView() + { + Assert.True(typeof(NavigationViewRegionAdapter).IsSealed); + Assert.Equal(typeof(RegionAdapterBase), typeof(NavigationViewRegionAdapter).BaseType); + } + + [Fact] + public void AdapterProvidesExpectedRegionFactoryMethod() + { + var method = typeof(NavigationViewRegionAdapter).GetMethod( + "CreateRegion", + System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); + + Assert.NotNull(method); + Assert.Equal(typeof(IRegion), method!.ReturnType); + } + + [Fact] + public void AdapterExposesAdaptOverride() + { + var method = typeof(NavigationViewRegionAdapter).GetMethod( + "Adapt", + System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); + + Assert.NotNull(method); + Assert.Equal(typeof(void), method!.ReturnType); + + var parameters = method.GetParameters(); + Assert.Equal(2, parameters.Length); + Assert.Equal(typeof(IRegion), parameters[0].ParameterType); + Assert.Equal(typeof(NavigationView), parameters[1].ParameterType); + } + + [Fact] + public void CreateRegionReturnsSingleActiveRegion() + { + var behaviorFactory = new Moq.Mock(); + var adapter = new NavigationViewRegionAdapter(behaviorFactory.Object); + + var method = typeof(NavigationViewRegionAdapter).GetMethod( + "CreateRegion", + System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); + + var region = method!.Invoke(adapter, null); + Assert.IsType(region); + } +} diff --git a/tests/Uno/Prism.Uno.WinUI.Tests/Prism.Uno.WinUI.Tests.csproj b/tests/Uno/Prism.Uno.WinUI.Tests/Prism.Uno.WinUI.Tests.csproj new file mode 100644 index 0000000000..e2ed7000d5 --- /dev/null +++ b/tests/Uno/Prism.Uno.WinUI.Tests/Prism.Uno.WinUI.Tests.csproj @@ -0,0 +1,35 @@ + + + + net10.0 + false + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + all + runtime; build; native; contentfiles; analyzers + + + + + + + + + diff --git a/tests/Uno/Prism.Uno.WinUI.Tests/PrismApplicationBaseFixture.cs b/tests/Uno/Prism.Uno.WinUI.Tests/PrismApplicationBaseFixture.cs new file mode 100644 index 0000000000..30aaf4d46d --- /dev/null +++ b/tests/Uno/Prism.Uno.WinUI.Tests/PrismApplicationBaseFixture.cs @@ -0,0 +1,50 @@ +using System.Runtime.Serialization; +using Prism.Ioc; +using Xunit; + +namespace Prism.Uno.WinUI.Tests; + +public class PrismApplicationBaseFixture +{ + [Fact] + public void HostThrowsUntilShellFinalizationRuns() + { + var app = (PrismApplicationBase)FormatterServices.GetUninitializedObject(typeof(TestPrismApplication)); + + var ex = Assert.Throws(() => _ = app.Host); + Assert.Contains("host has not yet been created", ex.Message, StringComparison.OrdinalIgnoreCase); + } + + [Fact] + public void PrismApplicationBaseExposesExpectedExtensibilitySurface() + { + Assert.True(typeof(PrismApplicationBase).IsAbstract); + Assert.True(typeof(PrismApplicationBase).GetMethod("OnLaunched", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)!.IsFinal); + Assert.NotNull(typeof(PrismApplicationBase).GetMethod("CreateShell", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)); + Assert.NotNull(typeof(PrismApplicationBase).GetMethod("RegisterTypes", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)); + Assert.NotNull(typeof(PrismApplicationBase).GetMethod("ConfigureApp", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)); + Assert.NotNull(typeof(PrismApplicationBase).GetMethod("ConfigureHost", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)); + Assert.NotNull(typeof(PrismApplicationBase).GetMethod("ConfigureServices", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)); + Assert.NotNull(typeof(PrismApplicationBase).GetMethod("ConfigureWindow", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)); + Assert.NotNull(typeof(PrismApplicationBase).GetMethod("InitializeModules", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)); + Assert.NotNull(typeof(PrismApplicationBase).GetMethod("ConfigureModuleCatalog", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)); + } + + [Fact] + public void ContainerPropertyReturnsContainerProvider() + { + var app = (PrismApplicationBase)FormatterServices.GetUninitializedObject(typeof(TestPrismApplication)); + Assert.Null(app.Container); + } + + private sealed class TestPrismApplication : PrismApplicationBase + { + protected override IContainerExtension CreateContainerExtension() => throw new NotImplementedException(); + + protected override UIElement CreateShell() => null!; + + protected override void RegisterTypes(IContainerRegistry containerRegistry) + { + } + } +} diff --git a/tests/Uno/Prism.Uno.WinUI.Tests/RegionManagerRequestNavigateFixture.cs b/tests/Uno/Prism.Uno.WinUI.Tests/RegionManagerRequestNavigateFixture.cs new file mode 100644 index 0000000000..5ce548fbec --- /dev/null +++ b/tests/Uno/Prism.Uno.WinUI.Tests/RegionManagerRequestNavigateFixture.cs @@ -0,0 +1,102 @@ +using Moq; +using Prism.Navigation; +using Prism.Navigation.Regions; +using Xunit; + +namespace Prism.Uno.WinUI.Tests; + +public class RegionManagerRequestNavigateFixture +{ + private const string Region = "Region"; + private const string NonExistentRegion = "NonExistentRegion"; + private const string Source = "Source"; + private static readonly Uri SourceUri = new("Source", UriKind.RelativeOrAbsolute); + private static readonly NavigationParameters Parameters = new(); + + [Fact] + public void ThrowsWhenNavigationCallbackIsNull() + { + var regionManager = new RegionManager(); + + Assert.Throws(() => regionManager.RequestNavigate(Region, Source, null!, Parameters)); + Assert.Throws(() => regionManager.RequestNavigate(Region, Source, navigationCallback: null!)); + Assert.Throws(() => regionManager.RequestNavigate(Region, SourceUri, null!)); + Assert.Throws(() => regionManager.RequestNavigate(Region, SourceUri, null!, Parameters)); + } + + [Fact] + public void ReturnsFailedResultWhenRegionDoesNotExist() + { + var regionManager = new RegionManager(); + NavigationResult? result = null; + + regionManager.RequestNavigate(NonExistentRegion, Source, r => result = r, Parameters); + Assert.NotNull(result); + Assert.False(result!.Success); + + result = null; + regionManager.RequestNavigate(NonExistentRegion, Source, r => result = r); + Assert.NotNull(result); + Assert.False(result!.Success); + + result = null; + regionManager.RequestNavigate(NonExistentRegion, SourceUri, r => result = r, Parameters); + + Assert.NotNull(result); + Assert.False(result!.Success); + } + + [Fact] + public void DelegatesCallToMatchingRegion() + { + var region = new Mock(); + region.SetupGet(x => x.Name).Returns(Region); + + var regionManager = new RegionManager(); + regionManager.Regions.Add(region.Object); + + regionManager.RequestNavigate(Region, SourceUri, _ => { }, Parameters); + + region.Verify(x => x.RequestNavigate(SourceUri, It.IsAny>(), Parameters), Times.Once); + } + + [Fact] + public void DelegatesCallToRegionForSourceStringOverloads() + { + var region = new Mock(); + region.SetupGet(x => x.Name).Returns(Region); + var callback = new Action(_ => { }); + + var regionManager = new RegionManager(); + regionManager.Regions.Add(region.Object); + + regionManager.RequestNavigate(Region, Source); + regionManager.RequestNavigate(Region, Source, Parameters); + regionManager.RequestNavigate(Region, Source, callback); + regionManager.RequestNavigate(Region, Source, callback, Parameters); + + region.Verify(x => x.RequestNavigate(SourceUri, It.IsAny>(), It.IsAny()), Times.AtLeastOnce); + region.Verify(x => x.RequestNavigate(SourceUri, callback, It.IsAny()), Times.AtLeastOnce); + region.Verify(x => x.RequestNavigate(SourceUri, callback, Parameters), Times.AtLeastOnce); + } + + [Fact] + public void DelegatesCallToRegionForUriOverloads() + { + var region = new Mock(); + region.SetupGet(x => x.Name).Returns(Region); + var callback = new Action(_ => { }); + + var regionManager = new RegionManager(); + regionManager.Regions.Add(region.Object); + + regionManager.RequestNavigate(Region, SourceUri); + regionManager.RequestNavigate(Region, SourceUri, Parameters); + regionManager.RequestNavigate(Region, SourceUri, callback); + regionManager.RequestNavigate(Region, SourceUri, callback, Parameters); + + region.Verify(x => x.RequestNavigate(SourceUri, It.IsAny>(), It.IsAny()), Times.AtLeastOnce); + region.Verify(x => x.RequestNavigate(SourceUri, callback, It.IsAny()), Times.AtLeastOnce); + region.Verify(x => x.RequestNavigate(SourceUri, callback, Parameters), Times.AtLeastOnce); + } +} diff --git a/tests/Uno/Prism.Uno.WinUI.Tests/UnoApiUtilityFixture.cs b/tests/Uno/Prism.Uno.WinUI.Tests/UnoApiUtilityFixture.cs new file mode 100644 index 0000000000..1ebddb5d0e --- /dev/null +++ b/tests/Uno/Prism.Uno.WinUI.Tests/UnoApiUtilityFixture.cs @@ -0,0 +1,33 @@ +using Prism.Mvvm; +using Xunit; + +namespace Prism.Uno.WinUI.Tests; + +public class UnoApiUtilityFixture +{ + [Fact] + public void ViewModelLocatorExposesAttachedPropertyContract() + { + Assert.NotNull(typeof(ViewModelLocator).GetField("AutowireViewModelProperty")); + Assert.NotNull(typeof(ViewModelLocator).GetMethod(nameof(ViewModelLocator.GetAutowireViewModel))); + Assert.NotNull(typeof(ViewModelLocator).GetMethod(nameof(ViewModelLocator.SetAutowireViewModel))); + } + + [Fact] + public void UnoInternalUtilityTypesExposeExpectedMethods() + { + var prismAssembly = typeof(PrismApplicationBase).Assembly; + + var bindingOperations = prismAssembly.GetType("Prism.BindingOperations"); + var designerProperties = prismAssembly.GetType("Prism.DesignerProperties"); + var dependencyObjectExtensions = prismAssembly.GetType("Prism.DependencyObjectExtensions"); + + Assert.NotNull(bindingOperations); + Assert.NotNull(designerProperties); + Assert.NotNull(dependencyObjectExtensions); + + Assert.NotNull(bindingOperations!.GetMethod("GetBinding", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static)); + Assert.NotNull(designerProperties!.GetMethod("GetIsInDesignMode", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static)); + Assert.NotNull(dependencyObjectExtensions!.GetMethod("CheckAccess", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static)); + } +} From 19eaa83f929cda1aae49b09f7ebccbb198aaf66b Mon Sep 17 00:00:00 2001 From: Dan Siegel Date: Thu, 7 May 2026 07:56:57 -0600 Subject: [PATCH 2/2] Upgrade workflow templates to v2 and configure explicit test execution Updates all build, CI, and release workflows to use version `v2` of the shared `avantipoint/workflow-templates`. This change standardizes how unit tests are executed by replacing the `run-tests` flag with a new `test-projects` input, allowing explicit definition of test project paths for each platform (Core, WPF, Uno, MAUI, Avalonia). Additionally, Uno platform builds are updated to target .NET 10.0.100 and related tooling versions, including Uno.Check version 1.33.1 and `tvos` workload installation. --- .github/workflows/build_avalonia.yml | 5 ++++- .github/workflows/build_core.yml | 4 +++- .github/workflows/build_maui.yml | 5 ++++- .github/workflows/build_uno.yml | 6 ++++-- .github/workflows/build_wpf.yml | 6 +++++- .github/workflows/ci.yml | 30 +++++++++++++++++++------- .github/workflows/publish-release.yml | 4 ++-- .github/workflows/start-release.yml | 31 ++++++++++++++++++--------- 8 files changed, 65 insertions(+), 26 deletions(-) diff --git a/.github/workflows/build_avalonia.yml b/.github/workflows/build_avalonia.yml index a763e9556a..727f3f1dec 100644 --- a/.github/workflows/build_avalonia.yml +++ b/.github/workflows/build_avalonia.yml @@ -19,8 +19,11 @@ on: jobs: build-prism-avalonia: - uses: avantipoint/workflow-templates/.github/workflows/dotnet-build.yml@v1 + uses: avantipoint/workflow-templates/.github/workflows/dotnet-build.yml@v2 with: name: Build Prism.Avalonia solution-path: PrismLibrary_Avalonia.slnf + test-projects: | + tests/Avalonia/Prism.Avalonia.Tests/Prism.Avalonia.Tests.csproj + tests/Avalonia/Prism.DryIoc.Avalonia.Tests/Prism.DryIoc.Avalonia.Tests.csproj dotnet-version: 10.0.100 diff --git a/.github/workflows/build_core.yml b/.github/workflows/build_core.yml index 40fad7178b..224ef647fb 100644 --- a/.github/workflows/build_core.yml +++ b/.github/workflows/build_core.yml @@ -17,8 +17,10 @@ on: jobs: build-prism-core: - uses: avantipoint/workflow-templates/.github/workflows/dotnet-build.yml@v1 + uses: avantipoint/workflow-templates/.github/workflows/dotnet-build.yml@v2 with: name: Build Prism.Core solution-path: PrismLibrary_Core.slnf + test-projects: | + tests/Prism.Core.Tests/Prism.Core.Tests.csproj dotnet-version: 10.0.100 diff --git a/.github/workflows/build_maui.yml b/.github/workflows/build_maui.yml index f7e8e6b6f6..4dc4963f4e 100644 --- a/.github/workflows/build_maui.yml +++ b/.github/workflows/build_maui.yml @@ -20,9 +20,12 @@ on: jobs: build-prism-maui: - uses: avantipoint/workflow-templates/.github/workflows/dotnet-build.yml@v1 + uses: avantipoint/workflow-templates/.github/workflows/dotnet-build.yml@v2 with: name: Build Prism.Maui solution-path: PrismLibrary_Maui.slnf install-workload: maui maui-tizen + test-projects: | + tests/Maui/Prism.Maui.Tests/Prism.Maui.Tests.csproj + tests/Maui/Prism.DryIoc.Maui.Tests/Prism.DryIoc.Maui.Tests.csproj dotnet-version: 10.0.100 diff --git a/.github/workflows/build_uno.yml b/.github/workflows/build_uno.yml index ce027fc369..7af4e8ae36 100644 --- a/.github/workflows/build_uno.yml +++ b/.github/workflows/build_uno.yml @@ -21,7 +21,7 @@ on: jobs: build-prism-uno: - uses: avantipoint/workflow-templates/.github/workflows/msbuild-build.yml@v1 + uses: avantipoint/workflow-templates/.github/workflows/msbuild-build.yml@v2 with: name: Build Prism.Uno solution-path: PrismLibrary_Uno.slnf @@ -31,4 +31,6 @@ jobs: uno-check: false uno-check-version: 1.33.1 uno-check-parameters: '--skip xcode --skip gtk3 --skip vswin --skip androidemulator --skip androidsdk --skip vsmac --skip dotnetnewunotemplates' - run-tests: true + test-projects: | + tests/Uno/Prism.Uno.WinUI.Tests/Prism.Uno.WinUI.Tests.csproj + tests/Uno/Prism.DryIoc.Uno.WinUI.Tests/Prism.DryIoc.Uno.WinUI.Tests.csproj diff --git a/.github/workflows/build_wpf.yml b/.github/workflows/build_wpf.yml index 78b7d06b83..59196c1924 100644 --- a/.github/workflows/build_wpf.yml +++ b/.github/workflows/build_wpf.yml @@ -19,8 +19,12 @@ on: jobs: build-prism-wpf: - uses: avantipoint/workflow-templates/.github/workflows/dotnet-build.yml@v1 + uses: avantipoint/workflow-templates/.github/workflows/dotnet-build.yml@v2 with: name: Build Prism.Wpf solution-path: PrismLibrary_Wpf.slnf + test-projects: | + tests/Wpf/Prism.Wpf.Tests/Prism.Wpf.Tests.csproj + tests/Wpf/Prism.DryIoc.Wpf.Tests/Prism.DryIoc.Wpf.Tests.csproj + tests/Wpf/Prism.Unity.Wpf.Tests/Prism.Unity.Wpf.Tests.csproj dotnet-version: 10.0.100 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bac6295336..72251a6f3f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,10 +25,12 @@ on: jobs: build-prism-core: - uses: avantipoint/workflow-templates/.github/workflows/dotnet-build.yml@v1 + uses: avantipoint/workflow-templates/.github/workflows/dotnet-build.yml@v2 with: name: Build Prism.Core solution-path: PrismLibrary_Core.slnf + test-projects: | + tests/Prism.Core.Tests/Prism.Core.Tests.csproj code-sign: false artifact-name: Core dotnet-version: 10.0.100 @@ -40,10 +42,14 @@ jobs: codeSignCertificate: ${{ secrets.CodeSignCertificate }} build-prism-wpf: - uses: avantipoint/workflow-templates/.github/workflows/dotnet-build.yml@v1 + uses: avantipoint/workflow-templates/.github/workflows/dotnet-build.yml@v2 with: name: Build Prism.Wpf solution-path: PrismLibrary_Wpf.slnf + test-projects: | + tests/Wpf/Prism.Wpf.Tests/Prism.Wpf.Tests.csproj + tests/Wpf/Prism.DryIoc.Wpf.Tests/Prism.DryIoc.Wpf.Tests.csproj + tests/Wpf/Prism.Unity.Wpf.Tests/Prism.Unity.Wpf.Tests.csproj code-sign: false artifact-name: Wpf dotnet-version: 10.0.100 @@ -55,7 +61,7 @@ jobs: codeSignCertificate: ${{ secrets.CodeSignCertificate }} build-prism-uno: - uses: avantipoint/workflow-templates/.github/workflows/msbuild-build.yml@v1 + uses: avantipoint/workflow-templates/.github/workflows/msbuild-build.yml@v2 with: name: Build Prism.Uno solution-path: PrismLibrary_Uno.slnf @@ -65,7 +71,9 @@ jobs: uno-check: false uno-check-version: 1.33.1 uno-check-parameters: '--skip xcode --skip gtk3 --skip vswin --skip androidemulator --skip androidsdk --skip vsmac --skip dotnetnewunotemplates' - run-tests: true + test-projects: | + tests/Uno/Prism.Uno.WinUI.Tests/Prism.Uno.WinUI.Tests.csproj + tests/Uno/Prism.DryIoc.Uno.WinUI.Tests/Prism.DryIoc.Uno.WinUI.Tests.csproj code-sign: false artifact-name: Uno secrets: @@ -76,11 +84,14 @@ jobs: codeSignCertificate: ${{ secrets.CodeSignCertificate }} build-prism-maui: - uses: avantipoint/workflow-templates/.github/workflows/dotnet-build.yml@v1 + uses: avantipoint/workflow-templates/.github/workflows/dotnet-build.yml@v2 with: name: Build Prism.Maui solution-path: PrismLibrary_Maui.slnf install-workload: maui maui-tizen + test-projects: | + tests/Maui/Prism.Maui.Tests/Prism.Maui.Tests.csproj + tests/Maui/Prism.DryIoc.Maui.Tests/Prism.DryIoc.Maui.Tests.csproj code-sign: false artifact-name: Maui dotnet-version: 10.0.100 @@ -92,10 +103,13 @@ jobs: codeSignCertificate: ${{ secrets.CodeSignCertificate }} build-prism-avalonia: - uses: avantipoint/workflow-templates/.github/workflows/dotnet-build.yml@v1 + uses: avantipoint/workflow-templates/.github/workflows/dotnet-build.yml@v2 with: name: Build Prism.Avalonia solution-path: PrismLibrary_Avalonia.slnf + test-projects: | + tests/Avalonia/Prism.Avalonia.Tests/Prism.Avalonia.Tests.csproj + tests/Avalonia/Prism.DryIoc.Avalonia.Tests/Prism.DryIoc.Avalonia.Tests.csproj code-sign: false artifact-name: Avalonia dotnet-version: 10.0.100 @@ -154,7 +168,7 @@ jobs: path: .\artifacts\nuget deploy-internal: - uses: avantipoint/workflow-templates/.github/workflows/deploy-nuget.yml@v1 + uses: avantipoint/workflow-templates/.github/workflows/deploy-nuget.yml@v2 needs: generate-consolidated-artifacts if: ${{ github.event_name == 'push' }} with: @@ -164,7 +178,7 @@ jobs: apiKey: ${{ secrets.IN_HOUSE_API_KEY }} deploy-commercial-plus: - uses: avantipoint/workflow-templates/.github/workflows/deploy-nuget.yml@v1 + uses: avantipoint/workflow-templates/.github/workflows/deploy-nuget.yml@v2 needs: generate-consolidated-artifacts if: ${{ github.event_name == 'push' }} with: diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 31cac33c82..03f865e4a6 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -6,13 +6,13 @@ on: jobs: publish-internal: - uses: avantipoint/workflow-templates/.github/workflows/deploy-nuget-from-release.yml@v1 + uses: avantipoint/workflow-templates/.github/workflows/deploy-nuget-from-release.yml@v2 secrets: feedUrl: ${{ secrets.IN_HOUSE_NUGET_FEED }} apiKey: ${{ secrets.IN_HOUSE_API_KEY }} publish-commercial-plus: - uses: avantipoint/workflow-templates/.github/workflows/deploy-nuget-from-release.yml@v1 + uses: avantipoint/workflow-templates/.github/workflows/deploy-nuget-from-release.yml@v2 secrets: feedUrl: ${{ secrets.PRISM_NUGET_FEED }} apiKey: ${{ secrets.PRISM_NUGET_TOKEN }} diff --git a/.github/workflows/start-release.yml b/.github/workflows/start-release.yml index 7fdc54d188..d732685f06 100644 --- a/.github/workflows/start-release.yml +++ b/.github/workflows/start-release.yml @@ -5,10 +5,12 @@ on: jobs: build-prism-core: - uses: avantipoint/workflow-templates/.github/workflows/dotnet-build.yml@v1 + uses: avantipoint/workflow-templates/.github/workflows/dotnet-build.yml@v2 with: name: Build Prism.Core solution-path: PrismLibrary_Core.slnf + test-projects: | + tests/Prism.Core.Tests/Prism.Core.Tests.csproj code-sign: true artifact-name: Core build-args: /p:OfficialRelease=true @@ -20,10 +22,14 @@ jobs: codeSignCertificate: ${{ secrets.CodeSignCertificate }} build-prism-wpf: - uses: avantipoint/workflow-templates/.github/workflows/dotnet-build.yml@v1 + uses: avantipoint/workflow-templates/.github/workflows/dotnet-build.yml@v2 with: name: Build Prism.Wpf solution-path: PrismLibrary_Wpf.slnf + test-projects: | + tests/Wpf/Prism.Wpf.Tests/Prism.Wpf.Tests.csproj + tests/Wpf/Prism.DryIoc.Wpf.Tests/Prism.DryIoc.Wpf.Tests.csproj + tests/Wpf/Prism.Unity.Wpf.Tests/Prism.Unity.Wpf.Tests.csproj code-sign: true artifact-name: Wpf build-args: /p:OfficialRelease=true @@ -35,17 +41,19 @@ jobs: codeSignCertificate: ${{ secrets.CodeSignCertificate }} build-prism-uno: - uses: avantipoint/workflow-templates/.github/workflows/msbuild-build.yml@v1 + uses: avantipoint/workflow-templates/.github/workflows/msbuild-build.yml@v2 with: name: Build Prism.Uno solution-path: PrismLibrary_Uno.slnf windows-sdk-version: 18362 - dotnet-version: 8.0.300 - install-workload: ios android macos maccatalyst wasm-tools + dotnet-version: 10.0.100 + install-workload: ios android macos maccatalyst wasm-tools tvos uno-check: false - uno-check-version: 1.25.1 + uno-check-version: 1.33.1 uno-check-parameters: '--skip xcode --skip gtk3 --skip vswin --skip androidemulator --skip androidsdk --skip vsmac --skip dotnetnewunotemplates' - run-tests: false + test-projects: | + tests/Uno/Prism.Uno.WinUI.Tests/Prism.Uno.WinUI.Tests.csproj + tests/Uno/Prism.DryIoc.Uno.WinUI.Tests/Prism.DryIoc.Uno.WinUI.Tests.csproj code-sign: true artifact-name: Uno build-args: /p:OfficialRelease=true @@ -57,12 +65,15 @@ jobs: codeSignCertificate: ${{ secrets.CodeSignCertificate }} build-prism-maui: - uses: avantipoint/workflow-templates/.github/workflows/dotnet-build.yml@v1 + uses: avantipoint/workflow-templates/.github/workflows/dotnet-build.yml@v2 with: name: Build Prism.Maui solution-path: PrismLibrary_Maui.slnf dotnet-version: 8.0.x install-workload: maui maui-tizen + test-projects: | + tests/Maui/Prism.Maui.Tests/Prism.Maui.Tests.csproj + tests/Maui/Prism.DryIoc.Maui.Tests/Prism.DryIoc.Maui.Tests.csproj code-sign: true artifact-name: Maui build-args: /p:OfficialRelease=true @@ -74,7 +85,7 @@ jobs: codeSignCertificate: ${{ secrets.CodeSignCertificate }} generate-consolidated-artifacts: - needs: [build-prism-core, build-prism-wpf, build-prism-uno] + needs: [build-prism-core, build-prism-wpf, build-prism-uno, build-prism-maui] runs-on: windows-latest steps: - name: Checkout @@ -115,7 +126,7 @@ jobs: path: .\artifacts\nuget release: - uses: avantipoint/workflow-templates/.github/workflows/generate-release.yml@v1 + uses: avantipoint/workflow-templates/.github/workflows/generate-release.yml@v2 needs: [generate-consolidated-artifacts] permissions: contents: write