Skip to content

Commit 7b352d9

Browse files
committed
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.
1 parent a185bf1 commit 7b352d9

17 files changed

Lines changed: 768 additions & 3 deletions

.github/workflows/build_uno.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,4 @@ jobs:
3131
uno-check: false
3232
uno-check-version: 1.33.1
3333
uno-check-parameters: '--skip xcode --skip gtk3 --skip vswin --skip androidemulator --skip androidsdk --skip vsmac --skip dotnetnewunotemplates'
34-
run-tests: false
34+
run-tests: true

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ jobs:
6565
uno-check: false
6666
uno-check-version: 1.33.1
6767
uno-check-parameters: '--skip xcode --skip gtk3 --skip vswin --skip androidemulator --skip androidsdk --skip vsmac --skip dotnetnewunotemplates'
68-
run-tests: false
68+
run-tests: true
6969
code-sign: false
7070
artifact-name: Uno
7171
secrets:

Directory.Packages.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
<!-- Tests -->
7676
<ItemGroup>
7777
<PackageVersion Include="coverlet.collector" Version="6.0.2" />
78+
<PackageVersion Include="coverlet.msbuild" Version="6.0.2" />
7879
<PackageVersion Include="GitHubActionsTestLogger" Version="2.4.1" />
7980
<PackageVersion Include="Xamarin.Forms.Mocks" Version="4.7.0.1" />
8081
<PackageVersion Include="Humanizer.Core" Version="2.14.1" />

PrismLibrary.sln

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,16 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Prism.IocContainer.Avalonia
8686
EndProject
8787
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Avalonia", "Avalonia", "{904D5094-55F9-4581-90AC-D6C1131F8152}"
8888
EndProject
89+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Uno", "Uno", "{8B763117-8E13-0D1A-AFE0-5BC3FACCF29C}"
90+
EndProject
91+
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}"
92+
EndProject
93+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Prism.Uno", "Prism.Uno", "{1E1EDCAE-FD32-8442-764F-7F151A12D8D4}"
94+
EndProject
95+
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}"
96+
EndProject
97+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Prism.DryIoc.Uno", "Prism.DryIoc.Uno", "{064C69BC-4576-336C-79BF-6771226CD9DC}"
98+
EndProject
8999
Global
90100
GlobalSection(SolutionConfigurationPlatforms) = preSolution
91101
Debug|Any CPU = Debug|Any CPU
@@ -372,6 +382,30 @@ Global
372382
{887E0794-798D-4127-847E-6F68D5C9B334}.Release|x64.Build.0 = Release|Any CPU
373383
{887E0794-798D-4127-847E-6F68D5C9B334}.Release|x86.ActiveCfg = Release|Any CPU
374384
{887E0794-798D-4127-847E-6F68D5C9B334}.Release|x86.Build.0 = Release|Any CPU
385+
{05132055-211C-42D4-B40A-39E4BB066E7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
386+
{05132055-211C-42D4-B40A-39E4BB066E7B}.Debug|Any CPU.Build.0 = Debug|Any CPU
387+
{05132055-211C-42D4-B40A-39E4BB066E7B}.Debug|x64.ActiveCfg = Debug|Any CPU
388+
{05132055-211C-42D4-B40A-39E4BB066E7B}.Debug|x64.Build.0 = Debug|Any CPU
389+
{05132055-211C-42D4-B40A-39E4BB066E7B}.Debug|x86.ActiveCfg = Debug|Any CPU
390+
{05132055-211C-42D4-B40A-39E4BB066E7B}.Debug|x86.Build.0 = Debug|Any CPU
391+
{05132055-211C-42D4-B40A-39E4BB066E7B}.Release|Any CPU.ActiveCfg = Release|Any CPU
392+
{05132055-211C-42D4-B40A-39E4BB066E7B}.Release|Any CPU.Build.0 = Release|Any CPU
393+
{05132055-211C-42D4-B40A-39E4BB066E7B}.Release|x64.ActiveCfg = Release|Any CPU
394+
{05132055-211C-42D4-B40A-39E4BB066E7B}.Release|x64.Build.0 = Release|Any CPU
395+
{05132055-211C-42D4-B40A-39E4BB066E7B}.Release|x86.ActiveCfg = Release|Any CPU
396+
{05132055-211C-42D4-B40A-39E4BB066E7B}.Release|x86.Build.0 = Release|Any CPU
397+
{158173F6-E776-422C-9127-8994C504867B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
398+
{158173F6-E776-422C-9127-8994C504867B}.Debug|Any CPU.Build.0 = Debug|Any CPU
399+
{158173F6-E776-422C-9127-8994C504867B}.Debug|x64.ActiveCfg = Debug|Any CPU
400+
{158173F6-E776-422C-9127-8994C504867B}.Debug|x64.Build.0 = Debug|Any CPU
401+
{158173F6-E776-422C-9127-8994C504867B}.Debug|x86.ActiveCfg = Debug|Any CPU
402+
{158173F6-E776-422C-9127-8994C504867B}.Debug|x86.Build.0 = Debug|Any CPU
403+
{158173F6-E776-422C-9127-8994C504867B}.Release|Any CPU.ActiveCfg = Release|Any CPU
404+
{158173F6-E776-422C-9127-8994C504867B}.Release|Any CPU.Build.0 = Release|Any CPU
405+
{158173F6-E776-422C-9127-8994C504867B}.Release|x64.ActiveCfg = Release|Any CPU
406+
{158173F6-E776-422C-9127-8994C504867B}.Release|x64.Build.0 = Release|Any CPU
407+
{158173F6-E776-422C-9127-8994C504867B}.Release|x86.ActiveCfg = Release|Any CPU
408+
{158173F6-E776-422C-9127-8994C504867B}.Release|x86.Build.0 = Release|Any CPU
375409
EndGlobalSection
376410
GlobalSection(SolutionProperties) = preSolution
377411
HideSolutionNode = FALSE
@@ -409,6 +443,11 @@ Global
409443
{03B9C775-9582-409F-B67F-6B8A0CE0C7AF} = {904D5094-55F9-4581-90AC-D6C1131F8152}
410444
{887E0794-798D-4127-847E-6F68D5C9B334} = {904D5094-55F9-4581-90AC-D6C1131F8152}
411445
{904D5094-55F9-4581-90AC-D6C1131F8152} = {00FFDC13-7397-46F1-897E-A62A7575D28A}
446+
{8B763117-8E13-0D1A-AFE0-5BC3FACCF29C} = {00FFDC13-7397-46F1-897E-A62A7575D28A}
447+
{05132055-211C-42D4-B40A-39E4BB066E7B} = {8B763117-8E13-0D1A-AFE0-5BC3FACCF29C}
448+
{1E1EDCAE-FD32-8442-764F-7F151A12D8D4} = {8F959801-D494-4CAF-9437-90F30472E169}
449+
{158173F6-E776-422C-9127-8994C504867B} = {8B763117-8E13-0D1A-AFE0-5BC3FACCF29C}
450+
{064C69BC-4576-336C-79BF-6771226CD9DC} = {8F959801-D494-4CAF-9437-90F30472E169}
412451
EndGlobalSection
413452
GlobalSection(ExtensibilityGlobals) = postSolution
414453
SolutionGuid = {C7433AE2-B1A0-4C1A-887E-5CAA7AAF67A6}

PrismLibrary_Uno.slnf

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
"src\\Uno\\Prism.DryIoc.Uno\\Prism.DryIoc.Uno.WinUI.csproj",
88
"src\\Uno\\Prism.Uno\\Prism.Uno.WinUI.csproj",
99
"src\\Uno\\Prism.Uno.Markup\\Prism.Uno.WinUI.Markup.csproj",
10-
"tests\\Prism.Core.Tests\\Prism.Core.Tests.csproj"
10+
"tests\\Prism.Core.Tests\\Prism.Core.Tests.csproj",
11+
"tests\\Uno\\Prism.DryIoc.Uno.WinUI.Tests\\Prism.DryIoc.Uno.WinUI.Tests.csproj",
12+
"tests\\Uno\\Prism.Uno.WinUI.Tests\\Prism.Uno.WinUI.Tests.csproj"
1113
]
1214
}
1315
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using DryIoc;
2+
using Prism.Container.DryIoc;
3+
using Prism.Ioc;
4+
5+
namespace Prism.Container.Uno.Tests;
6+
7+
public static class ContainerHelper
8+
{
9+
private static Rules CreateContainerRules() => Rules.Default.WithAutoConcreteTypeResolution()
10+
.With(Made.Of(FactoryMethod.ConstructorWithResolvableArguments))
11+
.WithDefaultIfAlreadyRegistered(IfAlreadyRegistered.Replace);
12+
13+
public static IContainer CreateContainer() => new global::DryIoc.Container(CreateContainerRules());
14+
15+
public static IContainerExtension CreateContainerExtension() => new DryIocContainerExtension(CreateContainer());
16+
17+
public static Type RegisteredFrameworkException => typeof(ContainerException);
18+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net10.0</TargetFramework>
5+
<IsPackable>false</IsPackable>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<PackageReference Include="coverlet.collector">
10+
<PrivateAssets>all</PrivateAssets>
11+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
12+
</PackageReference>
13+
<PackageReference Include="coverlet.msbuild">
14+
<PrivateAssets>all</PrivateAssets>
15+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
16+
</PackageReference>
17+
<PackageReference Include="GitHubActionsTestLogger">
18+
<PrivateAssets>all</PrivateAssets>
19+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
20+
</PackageReference>
21+
<PackageReference Include="Microsoft.NET.Test.Sdk" />
22+
<PackageReference Include="Moq" />
23+
<PackageReference Include="xunit" />
24+
<PackageReference Include="xunit.runner.visualstudio">
25+
<PrivateAssets>all</PrivateAssets>
26+
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
27+
</PackageReference>
28+
<PackageReference Include="Xunit.StaFact" />
29+
</ItemGroup>
30+
31+
<ItemGroup>
32+
<ProjectReference Include="..\..\..\src\Uno\Prism.DryIoc.Uno\Prism.DryIoc.Uno.WinUI.csproj" />
33+
</ItemGroup>
34+
35+
</Project>
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
using System.Reflection;
2+
using System.Runtime.Serialization;
3+
using DryIoc;
4+
using Prism.Container.DryIoc;
5+
using Prism.Ioc;
6+
using Xunit;
7+
using static Prism.Container.Uno.Tests.ContainerHelper;
8+
using ExceptionExtensions = System.ExceptionExtensions;
9+
10+
namespace Prism.DryIoc.Uno.WinUI.Tests;
11+
12+
public class PrismApplicationFixture
13+
{
14+
[Fact]
15+
public void CreateContainerExtensionReturnsDryIocContainerExtension()
16+
{
17+
var app = (PrismApplication)FormatterServices.GetUninitializedObject(typeof(PrismApplicationProxy));
18+
var method = typeof(PrismApplication).GetMethod("CreateContainerExtension", BindingFlags.NonPublic | BindingFlags.Instance);
19+
20+
var container = method!.Invoke(app, null);
21+
22+
Assert.IsType<DryIocContainerExtension>(container!);
23+
}
24+
25+
[Fact]
26+
public void RegisterFrameworkExceptionTypesRegistersContainerException()
27+
{
28+
var app = (PrismApplication)FormatterServices.GetUninitializedObject(typeof(PrismApplicationProxy));
29+
var method = typeof(PrismApplication).GetMethod("RegisterFrameworkExceptionTypes", BindingFlags.NonPublic | BindingFlags.Instance);
30+
31+
method!.Invoke(app, null);
32+
33+
Assert.True(ExceptionExtensions.IsFrameworkExceptionRegistered(RegisteredFrameworkException));
34+
}
35+
36+
[Fact]
37+
public void CreateContainerRulesReturnsDryIocRules()
38+
{
39+
var app = (PrismApplication)FormatterServices.GetUninitializedObject(typeof(PrismApplicationProxy));
40+
var method = typeof(PrismApplication).GetMethod("CreateContainerRules", BindingFlags.NonPublic | BindingFlags.Instance);
41+
42+
var rules = method!.Invoke(app, null);
43+
44+
Assert.NotNull(rules);
45+
Assert.IsType<Rules>(rules);
46+
}
47+
48+
[Fact]
49+
public void PrismApplicationRemainsAbstractAndExtendsPrismApplicationBase()
50+
{
51+
Assert.True(typeof(PrismApplication).IsAbstract);
52+
Assert.Equal(typeof(PrismApplicationBase), typeof(PrismApplication).BaseType);
53+
}
54+
55+
private sealed class PrismApplicationProxy : PrismApplication
56+
{
57+
protected override UIElement CreateShell() => null!;
58+
59+
protected override void RegisterTypes(IContainerRegistry containerRegistry)
60+
{
61+
}
62+
}
63+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
using System.Reflection;
2+
using Xunit;
3+
4+
namespace Prism.Uno.WinUI.Tests;
5+
6+
public class ApiContractInventoryFixture
7+
{
8+
private static readonly Assembly PrismAssembly = typeof(PrismApplicationBase).Assembly;
9+
10+
public static IEnumerable<object[]> ExportedPrismTypeCases()
11+
{
12+
return PrismAssembly
13+
.GetExportedTypes()
14+
.Where(t => t.Namespace is not null && t.Namespace.StartsWith("Prism", StringComparison.Ordinal))
15+
.OrderBy(t => t.FullName, StringComparer.Ordinal)
16+
.Select(t => new object[] { t.FullName! });
17+
}
18+
19+
public static IEnumerable<object[]> PublicMemberCases()
20+
{
21+
const BindingFlags memberFlags =
22+
BindingFlags.Public |
23+
BindingFlags.Instance |
24+
BindingFlags.Static |
25+
BindingFlags.DeclaredOnly;
26+
27+
return PrismAssembly
28+
.GetExportedTypes()
29+
.Where(t => t.Namespace is not null && t.Namespace.StartsWith("Prism", StringComparison.Ordinal))
30+
.OrderBy(t => t.FullName, StringComparer.Ordinal)
31+
.SelectMany(t => t
32+
.GetMembers(memberFlags)
33+
.Where(m => m.MemberType is MemberTypes.Method or MemberTypes.Property or MemberTypes.Field or MemberTypes.Event)
34+
.OrderBy(m => m.Name, StringComparer.Ordinal)
35+
.Select(m => new object[] { t.FullName!, m.Name, m.MemberType.ToString() }))
36+
.Take(450);
37+
}
38+
39+
[Theory]
40+
[MemberData(nameof(ExportedPrismTypeCases))]
41+
public void ExportedPrismTypeIsLoadable(string fullTypeName)
42+
{
43+
Assert.NotNull(PrismAssembly.GetType(fullTypeName));
44+
}
45+
46+
[Theory]
47+
[MemberData(nameof(PublicMemberCases))]
48+
public void PublicContractMemberIsDiscoverable(string fullTypeName, string memberName, string memberKind)
49+
{
50+
var type = PrismAssembly.GetType(fullTypeName);
51+
Assert.NotNull(type);
52+
53+
const BindingFlags lookupFlags =
54+
BindingFlags.Public |
55+
BindingFlags.Instance |
56+
BindingFlags.Static;
57+
58+
var members = type!.GetMember(memberName, lookupFlags);
59+
Assert.Contains(members, m => string.Equals(m.MemberType.ToString(), memberKind, StringComparison.Ordinal));
60+
}
61+
}

0 commit comments

Comments
 (0)