diff --git a/TUnit.Assertions.Tests/Bugs/Issue5720Tests.cs b/TUnit.Assertions.Tests/Bugs/Issue5720Tests.cs index 7081355ec3..eb28eb2cbd 100644 --- a/TUnit.Assertions.Tests/Bugs/Issue5720Tests.cs +++ b/TUnit.Assertions.Tests/Bugs/Issue5720Tests.cs @@ -1,3 +1,5 @@ +// Gated to match ImplicitConversionEqualityExtensions.cs — see issue #5765. +#if NET9_0_OR_GREATER namespace TUnit.Assertions.Tests.Bugs; /// @@ -191,3 +193,5 @@ await Assert.That(assertionException.InnerException!.Message).StartsWith( $"No implicit conversion operator from '{typeof(UnrelatedType)}' to '{typeof(string)}' was found."); } } + +#endif diff --git a/TUnit.Assertions.Tests/Bugs/Issue5765Tests.cs b/TUnit.Assertions.Tests/Bugs/Issue5765Tests.cs new file mode 100644 index 0000000000..c63b38d8e4 --- /dev/null +++ b/TUnit.Assertions.Tests/Bugs/Issue5765Tests.cs @@ -0,0 +1,40 @@ +using System.Net; + +namespace TUnit.Assertions.Tests.Bugs; + +public class Issue5765Tests +{ + [Test] + public async Task IsEqualTo_SameType_Enum() + { + var status = HttpStatusCode.OK; + + await Assert.That(status).IsEqualTo(HttpStatusCode.OK); + } + + [Test] + public async Task IsEqualTo_SameType_Primitive() + { + var value = 42; + + await Assert.That(value).IsEqualTo(42); + } + + [Test] + public async Task IsEqualTo_SameType_Record() + { + var point = new Point(1, 2); + + await Assert.That(point).IsEqualTo(new Point(1, 2)); + } + + [Test] + public async Task IsNotEqualTo_SameType_Enum() + { + var status = HttpStatusCode.OK; + + await Assert.That(status).IsNotEqualTo(HttpStatusCode.NotFound); + } + + private sealed record Point(int X, int Y); +} diff --git a/TUnit.Assertions/Extensions/ImplicitConversionEqualityExtensions.cs b/TUnit.Assertions/Extensions/ImplicitConversionEqualityExtensions.cs index e9c792fde8..b91c0e0486 100644 --- a/TUnit.Assertions/Extensions/ImplicitConversionEqualityExtensions.cs +++ b/TUnit.Assertions/Extensions/ImplicitConversionEqualityExtensions.cs @@ -1,3 +1,8 @@ +// Gated to .NET 9+ because these overloads rely on [OverloadResolutionPriority] to +// lose to the source-generated single-generic IsEqualTo / IsNotEqualTo on same-type +// calls, and that attribute is silently dropped on net8.0 / netstandard2.0 (Polyfill +// does not supply it), causing CS0121. See issue #5765. +#if NET9_0_OR_GREATER using System.Collections.Concurrent; using System.Diagnostics.CodeAnalysis; using System.Reflection; @@ -146,3 +151,4 @@ internal static class ImplicitConversionCache return null; } } +#endif diff --git a/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet8_0.verified.txt b/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet8_0.verified.txt index c184337bb5..0503d5c1c0 100644 --- a/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet8_0.verified.txt +++ b/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet8_0.verified.txt @@ -3767,9 +3767,6 @@ namespace .Extensions { public static . IsEqualTo(this . source, TValue? expected, [.("expected")] string? expectedExpression = null) { } public static . IsEqualTo(this . source, TValue? expected, . comparer, [.("expected")] string? expectedExpression = null, [.("comparer")] string? comparerExpression = null) { } - [.("Looks up implicit conversion operators via reflection. Trimming may remove user-d" + - "efined operators.")] - public static . IsEqualTo(this . source, TOther? expected, [.("expected")] string? expectedExpression = null) { } } public static class EquatableAssertionExtensions { @@ -4696,9 +4693,6 @@ namespace .Extensions public static class NotEqualsAssertionExtensions { public static . IsNotEqualTo(this . source, TValue notExpected, .? comparer = null, [.("notExpected")] string? notExpectedExpression = null, [.("comparer")] string? comparerExpression = null) { } - [.("Looks up implicit conversion operators via reflection. Trimming may remove user-d" + - "efined operators.")] - public static . IsNotEqualTo(this . source, TOther? notExpected, [.("notExpected")] string? notExpectedExpression = null) { } } public static class NotEquivalentToAssertionExtensions { diff --git a/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.Net4_7.verified.txt b/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.Net4_7.verified.txt index 8b9183194a..d4b8c212ba 100644 --- a/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.Net4_7.verified.txt +++ b/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.Net4_7.verified.txt @@ -3360,7 +3360,6 @@ namespace .Extensions { public static . IsEqualTo(this . source, TValue? expected, [.("expected")] string? expectedExpression = null) { } public static . IsEqualTo(this . source, TValue? expected, . comparer, [.("expected")] string? expectedExpression = null, [.("comparer")] string? comparerExpression = null) { } - public static . IsEqualTo(this . source, TOther? expected, [.("expected")] string? expectedExpression = null) { } } public static class EquatableAssertionExtensions { @@ -4189,7 +4188,6 @@ namespace .Extensions public static class NotEqualsAssertionExtensions { public static . IsNotEqualTo(this . source, TValue notExpected, .? comparer = null, [.("notExpected")] string? notExpectedExpression = null, [.("comparer")] string? comparerExpression = null) { } - public static . IsNotEqualTo(this . source, TOther? notExpected, [.("notExpected")] string? notExpectedExpression = null) { } } public static class NotEquivalentToAssertionExtensions {