From 851bd00c47ef8d980c13efc086b177175c0f849a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 14 Feb 2026 17:38:36 +0000 Subject: [PATCH 1/3] Convert template test project from xUnit to TUnit Co-authored-by: ascott18 <5017521+ascott18@users.noreply.github.com> --- Directory.Packages.props | 1 + .../Coalesce.Starter.Vue.Data.Test.csproj | 11 +----- .../UnitTest1.cs | 8 ++-- .../Utilities/AssertionExtensions.cs | 38 +++++++++++-------- .../Utilities/GlobalUsings.cs | 4 +- 5 files changed, 31 insertions(+), 31 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 8ae1be165..c9b6f520c 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -72,5 +72,6 @@ + \ No newline at end of file diff --git a/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data.Test/Coalesce.Starter.Vue.Data.Test.csproj b/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data.Test/Coalesce.Starter.Vue.Data.Test.csproj index 71baae0b3..aea7b9f17 100644 --- a/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data.Test/Coalesce.Starter.Vue.Data.Test.csproj +++ b/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data.Test/Coalesce.Starter.Vue.Data.Test.csproj @@ -8,16 +8,7 @@ - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data.Test/UnitTest1.cs b/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data.Test/UnitTest1.cs index 10364c2be..dc90c8f5a 100644 --- a/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data.Test/UnitTest1.cs +++ b/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data.Test/UnitTest1.cs @@ -2,8 +2,8 @@ namespace Coalesce.Starter.Vue.Data.Test; public class UnitTest1 : TestBase { - [Fact] - public void Test1() + [Test] + public async Task Test1() { #if ExampleModel // Arrange @@ -17,11 +17,11 @@ public void Test1() var widget2 = Db.Widgets.Single(); // Assert - Assert.Equal(WidgetCategory.Sprecklesprockets, widget2.Category); + await Assert.That(widget2.Category).IsEqualTo(WidgetCategory.Sprecklesprockets); // After calling RefreshServices, we have a different DbContext instance // and so we'll get a different entity instance. - Assert.NotEqual(widget1, widget2); + await Assert.That(widget1).IsNotEqualTo(widget2); #endif } } \ No newline at end of file diff --git a/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data.Test/Utilities/AssertionExtensions.cs b/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data.Test/Utilities/AssertionExtensions.cs index f108d51b8..fbd072350 100644 --- a/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data.Test/Utilities/AssertionExtensions.cs +++ b/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data.Test/Utilities/AssertionExtensions.cs @@ -7,37 +7,41 @@ public static class AssertionExtensions /// /// Asserts that the result was a failure. /// - public static void AssertError(this ApiResult result) + public static async Task AssertError(this ApiResult result) { - Assert.False(result.WasSuccessful); + await Assert.That(result.WasSuccessful).IsFalse(); } /// /// Asserts that the result was a failure. /// /// Expected error message. - public static void AssertError(this ApiResult result, string message) + public static async Task AssertError(this ApiResult result, string message) { - result.AssertError(); - Assert.Equal(message, result.Message); + await result.AssertError(); + await Assert.That(result.Message).IsEqualTo(message); } /// /// Asserts that the result was successful. /// - public static void AssertSuccess(this ApiResult result, string? message = null) + public static async Task AssertSuccess(this ApiResult result, string? message = null) { - Assert.True(result.WasSuccessful, result.Message); - Assert.Equal(message, result.Message); + await Assert.That(result.WasSuccessful) + .IsTrue() + .WithMessage(() => result.Message ?? ""); + await Assert.That(result.Message).IsEqualTo(message); } /// /// Asserts that the result was successful. /// - public static T AssertSuccess(this ItemResult result) + public static async Task AssertSuccess(this ItemResult result) { - Assert.True(result.WasSuccessful, result.Message); - Assert.Null(result.Message); + await Assert.That(result.WasSuccessful) + .IsTrue() + .WithMessage(() => result.Message ?? ""); + await Assert.That(result.Message).IsNull(); return result.Object ?? throw new ArgumentException("Successful result unexpectedly returned null object"); } @@ -47,7 +51,7 @@ public static T AssertSuccess(this ItemResult result) public static async Task AssertSuccess(this Task> resultTask) { var result = await resultTask; - return result.AssertSuccess(); + return await result.AssertSuccess(); } /// @@ -56,16 +60,18 @@ public static async Task AssertSuccess(this Task> resultTask public static async Task AssertSuccess(this Task resultTask) { var result = await resultTask; - Assert.True(result.WasSuccessful, result.Message); + await Assert.That(result.WasSuccessful) + .IsTrue() + .WithMessage(() => result.Message ?? ""); } /// /// Asserts that the result was successful. /// /// Expected value on the result. - public static void AssertSuccess(this ItemResult result, T expectedValue) + public static async Task AssertSuccess(this ItemResult result, T expectedValue) { - result.AssertSuccess(); - Assert.Equal(expectedValue, result.Object); + await result.AssertSuccess(); + await Assert.That(result.Object).IsEqualTo(expectedValue); } } diff --git a/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data.Test/Utilities/GlobalUsings.cs b/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data.Test/Utilities/GlobalUsings.cs index 632ebe709..33b6ae59e 100644 --- a/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data.Test/Utilities/GlobalUsings.cs +++ b/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data.Test/Utilities/GlobalUsings.cs @@ -1,5 +1,7 @@ -global using Xunit; +global using TUnit.Core; +global using TUnit.Assertions; +global using TUnit.Assertions.Extensions; global using Moq; global using IntelliTect.Coalesce; global using IntelliTect.Coalesce.Api; From 3908847427e4dde9b03b5b93db1df6472ee07dd6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 14 Feb 2026 17:44:20 +0000 Subject: [PATCH 2/3] fix: use Because() for custom TUnit messages and add global.json for dotnet test support Co-authored-by: ascott18 <5017521+ascott18@users.noreply.github.com> --- CHANGELOG.md | 3 +++ .../Utilities/AssertionExtensions.cs | 6 +++--- templates/Coalesce.Vue.Template/content/global.json | 5 +++++ 3 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 templates/Coalesce.Vue.Template/content/global.json diff --git a/CHANGELOG.md b/CHANGELOG.md index a57a2edf0..0fa6873e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # 6.2.1 +## Template Changes +- Template test projects now use TUnit instead of xUnit. + # 6.2.0 - Add COA0014 analyzer to avoid incorrect usage of `NoAutoInclude`. - Added `DefaultOrderByAttribute.Suppress` property to prevent properties from being used as fallback ordering. diff --git a/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data.Test/Utilities/AssertionExtensions.cs b/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data.Test/Utilities/AssertionExtensions.cs index fbd072350..42ae1cb98 100644 --- a/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data.Test/Utilities/AssertionExtensions.cs +++ b/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data.Test/Utilities/AssertionExtensions.cs @@ -29,7 +29,7 @@ public static async Task AssertSuccess(this ApiResult result, string? message = { await Assert.That(result.WasSuccessful) .IsTrue() - .WithMessage(() => result.Message ?? ""); + .Because(result.Message ?? ""); await Assert.That(result.Message).IsEqualTo(message); } @@ -40,7 +40,7 @@ public static async Task AssertSuccess(this ItemResult result) { await Assert.That(result.WasSuccessful) .IsTrue() - .WithMessage(() => result.Message ?? ""); + .Because(result.Message ?? ""); await Assert.That(result.Message).IsNull(); return result.Object ?? throw new ArgumentException("Successful result unexpectedly returned null object"); } @@ -62,7 +62,7 @@ public static async Task AssertSuccess(this Task resultTask) var result = await resultTask; await Assert.That(result.WasSuccessful) .IsTrue() - .WithMessage(() => result.Message ?? ""); + .Because(result.Message ?? ""); } /// diff --git a/templates/Coalesce.Vue.Template/content/global.json b/templates/Coalesce.Vue.Template/content/global.json new file mode 100644 index 000000000..3140116df --- /dev/null +++ b/templates/Coalesce.Vue.Template/content/global.json @@ -0,0 +1,5 @@ +{ + "test": { + "runner": "Microsoft.Testing.Platform" + } +} From 3f30e4caaec781d91ffd57d5d57dd70b9a245cf8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 14 Feb 2026 17:49:38 +0000 Subject: [PATCH 3/3] refactor: only add Because() clause when result.Message is not empty Co-authored-by: ascott18 <5017521+ascott18@users.noreply.github.com> --- .../Utilities/AssertionExtensions.cs | 33 ++++++++++++++----- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data.Test/Utilities/AssertionExtensions.cs b/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data.Test/Utilities/AssertionExtensions.cs index 42ae1cb98..3207df626 100644 --- a/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data.Test/Utilities/AssertionExtensions.cs +++ b/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data.Test/Utilities/AssertionExtensions.cs @@ -27,9 +27,14 @@ public static async Task AssertError(this ApiResult result, string message) /// public static async Task AssertSuccess(this ApiResult result, string? message = null) { - await Assert.That(result.WasSuccessful) - .IsTrue() - .Because(result.Message ?? ""); + if (!string.IsNullOrEmpty(result.Message)) + { + await Assert.That(result.WasSuccessful).IsTrue().Because(result.Message); + } + else + { + await Assert.That(result.WasSuccessful).IsTrue(); + } await Assert.That(result.Message).IsEqualTo(message); } @@ -38,9 +43,14 @@ await Assert.That(result.WasSuccessful) /// public static async Task AssertSuccess(this ItemResult result) { - await Assert.That(result.WasSuccessful) - .IsTrue() - .Because(result.Message ?? ""); + if (!string.IsNullOrEmpty(result.Message)) + { + await Assert.That(result.WasSuccessful).IsTrue().Because(result.Message); + } + else + { + await Assert.That(result.WasSuccessful).IsTrue(); + } await Assert.That(result.Message).IsNull(); return result.Object ?? throw new ArgumentException("Successful result unexpectedly returned null object"); } @@ -60,9 +70,14 @@ public static async Task AssertSuccess(this Task> resultTask public static async Task AssertSuccess(this Task resultTask) { var result = await resultTask; - await Assert.That(result.WasSuccessful) - .IsTrue() - .Because(result.Message ?? ""); + if (!string.IsNullOrEmpty(result.Message)) + { + await Assert.That(result.WasSuccessful).IsTrue().Because(result.Message); + } + else + { + await Assert.That(result.WasSuccessful).IsTrue(); + } } ///