Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions TUnit.Assertions.Tests/Bugs/IsEquivalentTo_TypeProperty_Tests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
namespace TUnit.Assertions.Tests.Bugs;

/// <summary>
/// Tests for IsEquivalentTo with records containing Type properties.
/// Type objects have properties (like DeclaringMethod) that throw InvalidOperationException
/// when accessed on non-generic-parameter types, so Type must be treated as a well-known
/// primitive type and compared by equality rather than structural decomposition.
/// </summary>
public class IsEquivalentTo_TypeProperty_Tests
{
public record RecordWithType(Type Type);

public record RecordWithMultipleTypes(Type First, Type Second, string Name);

[Test]
public async Task IsEquivalentTo_RecordWithTypeProperty_SameType_ShouldSucceed()
{
var r = new RecordWithType(typeof(string));
await Assert.That(r).IsEquivalentTo(r);
}

[Test]
public async Task IsEquivalentTo_RecordWithTypeProperty_EqualTypes_ShouldSucceed()
{
var r1 = new RecordWithType(typeof(string));
var r2 = new RecordWithType(typeof(string));
await Assert.That(r1).IsEquivalentTo(r2);
}

[Test]
public async Task IsEquivalentTo_RecordWithTypeProperty_DifferentTypes_ShouldFail()
{
var r1 = new RecordWithType(typeof(string));
var r2 = new RecordWithType(typeof(int));

var exception = await Assert.ThrowsAsync<TUnitAssertionException>(
async () => await Assert.That(r1).IsEquivalentTo(r2));

await Assert.That(exception).IsNotNull();
}

[Test]
public async Task IsEquivalentTo_RecordWithMultipleTypeProperties_ShouldSucceed()
{
var r1 = new RecordWithMultipleTypes(typeof(string), typeof(int), "test");
var r2 = new RecordWithMultipleTypes(typeof(string), typeof(int), "test");
await Assert.That(r1).IsEquivalentTo(r2);
}

[Test]
public async Task IsEquivalentTo_TypeDirectly_ShouldSucceed()
{
Type t1 = typeof(string);
Type t2 = typeof(string);
await Assert.That(t1).IsEquivalentTo(t2);
}
}
3 changes: 3 additions & 0 deletions TUnit.Assertions/Conditions/Helpers/TypeHelper.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Concurrent;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;

namespace TUnit.Assertions.Conditions.Helpers;

Expand Down Expand Up @@ -78,6 +79,8 @@ public static bool IsPrimitiveOrWellKnownType(Type type)
|| type == typeof(DateTimeOffset)
|| type == typeof(TimeSpan)
|| type == typeof(Guid)
|| typeof(Type).IsAssignableFrom(type)
|| typeof(MemberInfo).IsAssignableFrom(type)
#if NET6_0_OR_GREATER
|| type == typeof(DateOnly)
|| type == typeof(TimeOnly)
Expand Down
Loading