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
16 changes: 13 additions & 3 deletions Source/aweXpect.Core/Equivalency/EquivalencyExpectationBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,18 @@ public override async Task<ConstraintResult> IsMetBy<TValue>(
else if (value is null)
{
T? typedDefault = default;
_result = new NotMatchingTypesResult(typedDefault,
await GetRootNode().IsMetBy(typedDefault, context, cancellationToken));
if (typedDefault is not null)
{
_result = new NotMatchingTypesResult(typedDefault, null);
}
else
{
// ReSharper disable ExpressionIsAlwaysNull
// typedDefault is used to have the correct generic overload in `IsMetBy`.
_result = new NotMatchingTypesResult(typedDefault,
await GetRootNode().IsMetBy(typedDefault, context, cancellationToken));
// ReSharper restore ExpressionIsAlwaysNull
}
}
else
{
Expand All @@ -66,7 +76,7 @@ public NotMatchingTypesResult(object? value, ConstraintResult? inner) : base(Fur
{
_value = value;
_inner = inner;
Outcome = Outcome.Failure;
Outcome = inner?.Outcome ?? Outcome.Failure;
}

public override void AppendExpectation(StringBuilder stringBuilder, string? indentation = null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,42 @@ Property IntValue was 42
""");
}

/// <summary>
/// It is not possible to determine the type of <see langword="null" />!
/// </summary>
[Fact]
public async Task WhenAnyNotNullCheckAndItIsNull_ShouldFail()
{
DummyClass subject = new()
{
StringValue = null,
NullableIntValue = null,
IntValue = 42,
};
var expected = new
{
StringValue = It.Is<string>().That.IsEmpty(),
NullableIntValue = It.Is<int?>().That.IsEqualTo(0),
IntValue = It.Is<int>().That.IsGreaterThan(2),
};

async Task Act()
=> await That(subject).IsEquivalentTo(expected);

await That(Act).Throws<XunitException>()
.WithMessage("""
Expected that subject
is equivalent to { StringValue = is string that is empty, NullableIntValue = is int? that is equal to 0, IntValue = is int that is greater than 2 },
but it was not:
Property StringValue was <null>
and
Property NullableIntValue was <null>

Equivalency options:
- include public fields and properties
""");
}

[Fact]
public async Task WhenAnyTypeDoesNotMatch_ShouldFail()
{
Expand Down Expand Up @@ -164,8 +200,8 @@ Property StringValue was ""
/// <summary>
/// It is not possible to determine the type of <see langword="null" />!
/// </summary>
[Fact]
public async Task WhenCheckForNullAndItIsNull_ShouldStillFail()
[Fact(Skip="TODO: Re-Enable after the next Core update")]
public async Task WhenCheckForNullAndItIsNull_ShouldSucceed()
{
DummyClass subject = new()
{
Expand All @@ -181,27 +217,19 @@ public async Task WhenCheckForNullAndItIsNull_ShouldStillFail()
async Task Act()
=> await That(subject).IsEquivalentTo(expected);

await That(Act).Throws<XunitException>()
.WithMessage("""
Expected that subject
is equivalent to { StringValue = is string that is null, IntValue = is int that is greater than 2 },
but it was not:
Property StringValue was <null>

Equivalency options:
- include public fields and properties
""");
await That(Act).DoesNotThrow();
}
}

// ReSharper disable UnusedAutoPropertyAccessor.Local
private sealed class DummyClass
{
public string? StringValue { get; set; }
public int IntValue { get; set; }
public bool BoolValue { get; set; }
// ReSharper disable UnusedAutoPropertyAccessor.Local
private sealed class DummyClass
{
public string? StringValue { get; set; }
public int? NullableIntValue { get; set; }
public int IntValue { get; set; }
public bool BoolValue { get; set; }
}
// ReSharper restore UnusedAutoPropertyAccessor.Local
}
// ReSharper restore UnusedAutoPropertyAccessor.Local
}
}
}
Loading