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();
+ }
}
///