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
74 changes: 74 additions & 0 deletions Source/aweXpect/That/ThatGeneric.IsEquatableTo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using System;
using aweXpect.Core;
using aweXpect.Core.Constraints;
using aweXpect.Helpers;
Comment thread
vbreuss marked this conversation as resolved.
using aweXpect.Results;

namespace aweXpect;

public static partial class ThatGeneric
{
/// <summary>
/// Verifies that the subject is equal to the <paramref name="expected" /> value
/// using the <see cref="IEquatable{T}.Equals(T)" /> method.
/// </summary>
public static AndOrResult<TEquatable, IThat<TEquatable>> IsEquatableTo<T, TEquatable>(
this IThat<TEquatable> source,
T expected)
where TEquatable : IEquatable<T>
=> new(source.Get().ExpectationBuilder.AddConstraint((it, grammars)
=> new IsEquatableToConstraint<T, TEquatable>(it, grammars, expected)),
source);

/// <summary>
/// Verifies that the subject is not equal to the <paramref name="unexpected" /> value
/// using the <see cref="IEquatable{T}.Equals(T)" /> method.
/// </summary>
public static AndOrResult<TEquatable, IThat<TEquatable>> IsNotEquatableTo<T, TEquatable>(
this IThat<TEquatable> source,
T unexpected)
where TEquatable : IEquatable<T>
=> new(source.Get().ExpectationBuilder.AddConstraint((it, grammars)
=> new IsEquatableToConstraint<T, TEquatable>(it, grammars, unexpected).Invert()),
source);

private sealed class IsEquatableToConstraint<T, TEquatable>(
string it,
ExpectationGrammars grammars,
T expected)
: ConstraintResult.WithValue<IEquatable<T>>(grammars),
IValueConstraint<TEquatable>
where TEquatable : IEquatable<T>
{
public ConstraintResult IsMetBy(TEquatable actual)
{
Actual = actual;
Outcome = actual.Equals(expected) ? Outcome.Success : Outcome.Failure;
return this;
}

protected override void AppendNormalExpectation(StringBuilder stringBuilder, string? indentation = null)
{
stringBuilder.Append("is equatable to ");
Formatter.Format(stringBuilder, expected);
}

protected override void AppendNormalResult(StringBuilder stringBuilder, string? indentation = null)
{
stringBuilder.Append(it).Append(" was ");
Formatter.Format(stringBuilder, Actual);
}

protected override void AppendNegatedExpectation(StringBuilder stringBuilder, string? indentation = null)
{
stringBuilder.Append("is not equatable to ");
Formatter.Format(stringBuilder, expected);
}

protected override void AppendNegatedResult(StringBuilder stringBuilder, string? indentation = null)
{
stringBuilder.Append(it).Append(" was in ");
Formatter.Format(stringBuilder, Actual);
}
}
}
4 changes: 4 additions & 0 deletions Tests/aweXpect.Api.Tests/Expected/aweXpect_net8.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -724,6 +724,10 @@ namespace aweXpect
public static aweXpect.Results.RepeatedCheckResult<T, aweXpect.Core.IThat<T>> DoesNotComplyWith<T>(this aweXpect.Core.IThat<T> source, System.Action<aweXpect.Core.IThat<T>> expectations) { }
public static aweXpect.Results.AndOrResult<T, aweXpect.Core.IThat<T>> DoesNotSatisfy<T>(this aweXpect.Core.IThat<T> source, System.Func<T, bool> predicate, [System.Runtime.CompilerServices.CallerArgumentExpression("predicate")] string doNotPopulateThisValue = "") { }
public static aweXpect.Results.AndOrResult<T, aweXpect.Core.IThat<T>> For<T, TMember>(this aweXpect.Core.IThat<T> source, System.Func<T, TMember?> memberSelector, System.Action<aweXpect.Core.IThat<TMember?>> expectations, [System.Runtime.CompilerServices.CallerArgumentExpression("memberSelector")] string doNotPopulateThisValue = "") { }
public static aweXpect.Results.AndOrResult<TEquatable, aweXpect.Core.IThat<TEquatable>> IsEquatableTo<T, TEquatable>(this aweXpect.Core.IThat<TEquatable> source, T expected)
where TEquatable : System.IEquatable<T> { }
public static aweXpect.Results.AndOrResult<TEquatable, aweXpect.Core.IThat<TEquatable>> IsNotEquatableTo<T, TEquatable>(this aweXpect.Core.IThat<TEquatable> source, T unexpected)
where TEquatable : System.IEquatable<T> { }
public static aweXpect.Results.RepeatedCheckResult<T, aweXpect.Core.IThat<T>> Satisfies<T>(this aweXpect.Core.IThat<T> source, System.Func<T, bool> predicate, [System.Runtime.CompilerServices.CallerArgumentExpression("predicate")] string doNotPopulateThisValue = "") { }
}
public static class ThatGuid
Expand Down
4 changes: 4 additions & 0 deletions Tests/aweXpect.Api.Tests/Expected/aweXpect_netstandard2.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,10 @@ namespace aweXpect
public static aweXpect.Results.RepeatedCheckResult<T, aweXpect.Core.IThat<T>> DoesNotComplyWith<T>(this aweXpect.Core.IThat<T> source, System.Action<aweXpect.Core.IThat<T>> expectations) { }
public static aweXpect.Results.AndOrResult<T, aweXpect.Core.IThat<T>> DoesNotSatisfy<T>(this aweXpect.Core.IThat<T> source, System.Func<T, bool> predicate, [System.Runtime.CompilerServices.CallerArgumentExpression("predicate")] string doNotPopulateThisValue = "") { }
public static aweXpect.Results.AndOrResult<T, aweXpect.Core.IThat<T>> For<T, TMember>(this aweXpect.Core.IThat<T> source, System.Func<T, TMember?> memberSelector, System.Action<aweXpect.Core.IThat<TMember?>> expectations, [System.Runtime.CompilerServices.CallerArgumentExpression("memberSelector")] string doNotPopulateThisValue = "") { }
public static aweXpect.Results.AndOrResult<TEquatable, aweXpect.Core.IThat<TEquatable>> IsEquatableTo<T, TEquatable>(this aweXpect.Core.IThat<TEquatable> source, T expected)
where TEquatable : System.IEquatable<T> { }
public static aweXpect.Results.AndOrResult<TEquatable, aweXpect.Core.IThat<TEquatable>> IsNotEquatableTo<T, TEquatable>(this aweXpect.Core.IThat<TEquatable> source, T unexpected)
where TEquatable : System.IEquatable<T> { }
public static aweXpect.Results.RepeatedCheckResult<T, aweXpect.Core.IThat<T>> Satisfies<T>(this aweXpect.Core.IThat<T> source, System.Func<T, bool> predicate, [System.Runtime.CompilerServices.CallerArgumentExpression("predicate")] string doNotPopulateThisValue = "") { }
}
public static class ThatGuid
Expand Down
150 changes: 150 additions & 0 deletions Tests/aweXpect.Tests/ThatGeneric.IsEquatableTo.Tests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
namespace aweXpect.Tests;

public sealed partial class ThatGeneric
{
public sealed class IsEquatableTo
{
public sealed class Tests
{
[Fact]
public async Task WhenComparingToMatchingLong_ShouldSucceed()
{
Wrapper subject = new(1);

async Task Act()
=> await That(subject).IsEquatableTo(1L);

await That(Act).DoesNotThrow();
}

[Fact]
public async Task WhenComparingToMatchingWrapper_ShouldSucceed()
{
Wrapper subject = new(1);
Wrapper expected = new(1);

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

await That(Act).DoesNotThrow();
}

[Fact]
public async Task WhenComparingToNotMatchingLong_ShouldFail()
{
Wrapper subject = new(1);

async Task Act()
=> await That(subject).IsEquatableTo(2L);

await That(Act).Throws<XunitException>()
.WithMessage("""
Expected that subject
is equatable to 2,
but it was ThatGeneric.IsEquatableTo.Wrapper {
Value = 1
}
""");
}

[Fact]
public async Task WhenComparingToNotMatchingWrapper_ShouldFail()
{
Wrapper subject = new(1);
Wrapper expected = new(3);

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

await That(Act).Throws<XunitException>()
.WithMessage("""
Expected that subject
is equatable to ThatGeneric.IsEquatableTo.Wrapper {
Value = 3
},
but it was ThatGeneric.IsEquatableTo.Wrapper {
Value = 1
}
""");
}
}

public sealed class NegatedTests
{
[Fact]
public async Task WhenComparingToMatchingLong_ShouldFail()
{
Wrapper subject = new(1);

async Task Act()
=> await That(subject).DoesNotComplyWith(it => it.IsEquatableTo(1L));

await That(Act).Throws<XunitException>()
.WithMessage("""
Expected that subject
is not equatable to 1,
but it was in ThatGeneric.IsEquatableTo.Wrapper {
Value = 1
}
""");
}

[Fact]
public async Task WhenComparingToMatchingWrapper_ShouldFail()
{
Wrapper subject = new(1);
Wrapper expected = new(1);

async Task Act()
=> await That(subject).DoesNotComplyWith(it => it.IsEquatableTo(expected));

await That(Act).Throws<XunitException>()
.WithMessage("""
Expected that subject
is not equatable to ThatGeneric.IsEquatableTo.Wrapper {
Value = 1
},
but it was in ThatGeneric.IsEquatableTo.Wrapper {
Value = 1
}
""");
}

[Fact]
public async Task WhenComparingToNotMatchingLong_ShouldSucceed()
{
Wrapper subject = new(1);

async Task Act()
=> await That(subject).DoesNotComplyWith(it => it.IsEquatableTo(2L));

await That(Act).DoesNotThrow();
}

[Fact]
public async Task WhenComparingToNotMatchingWrapper_ShouldSucceed()
{
Wrapper subject = new(1);
Wrapper expected = new(3);

async Task Act()
=> await That(subject).DoesNotComplyWith(it => it.IsEquatableTo(expected));

await That(Act).DoesNotThrow();
}
}

private readonly struct Wrapper(long value)
: IEquatable<Wrapper>,
IEquatable<long>
{
public long Value { get; } = value;

public bool Equals(Wrapper other)
=> Value == other.Value;

public bool Equals(long other)
=> Value == other;
}
}
}
150 changes: 150 additions & 0 deletions Tests/aweXpect.Tests/ThatGeneric.IsNotEquatableTo.Tests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
namespace aweXpect.Tests;

public sealed partial class ThatGeneric
{
public sealed class IsNotEquatableTo
{
public sealed class Tests
{
[Fact]
public async Task WhenComparingToMatchingLong_ShouldFail()
{
Wrapper subject = new(1);

async Task Act()
=> await That(subject).IsNotEquatableTo(1L);

await That(Act).Throws<XunitException>()
.WithMessage("""
Expected that subject
is not equatable to 1,
but it was in ThatGeneric.IsNotEquatableTo.Wrapper {
Value = 1
}
""");
}

[Fact]
public async Task WhenComparingToMatchingWrapper_ShouldFail()
{
Wrapper subject = new(1);
Wrapper expected = new(1);

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

await That(Act).Throws<XunitException>()
.WithMessage("""
Expected that subject
is not equatable to ThatGeneric.IsNotEquatableTo.Wrapper {
Value = 1
},
but it was in ThatGeneric.IsNotEquatableTo.Wrapper {
Value = 1
}
""");
}

[Fact]
public async Task WhenComparingToNotMatchingLong_ShouldSucceed()
{
Wrapper subject = new(1);

async Task Act()
=> await That(subject).IsNotEquatableTo(2L);

await That(Act).DoesNotThrow();
}

[Fact]
public async Task WhenComparingToNotMatchingWrapper_ShouldSucceed()
{
Wrapper subject = new(1);
Wrapper expected = new(3);

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

await That(Act).DoesNotThrow();
}
}

public sealed class NegatedTests
{
[Fact]
public async Task WhenComparingToMatchingLong_ShouldSucceed()
{
Wrapper subject = new(1);

async Task Act()
=> await That(subject).DoesNotComplyWith(it => it.IsNotEquatableTo(1L));

await That(Act).DoesNotThrow();
}

[Fact]
public async Task WhenComparingToMatchingWrapper_ShouldSucceed()
{
Wrapper subject = new(1);
Wrapper expected = new(1);

async Task Act()
=> await That(subject).DoesNotComplyWith(it => it.IsNotEquatableTo(expected));

await That(Act).DoesNotThrow();
}

[Fact]
public async Task WhenComparingToNotMatchingLong_ShouldFail()
{
Wrapper subject = new(1);

async Task Act()
=> await That(subject).DoesNotComplyWith(it => it.IsNotEquatableTo(2L));

await That(Act).Throws<XunitException>()
.WithMessage("""
Expected that subject
is equatable to 2,
but it was ThatGeneric.IsNotEquatableTo.Wrapper {
Value = 1
}
""");
}

[Fact]
public async Task WhenComparingToNotMatchingWrapper_ShouldFail()
{
Wrapper subject = new(1);
Wrapper expected = new(3);

async Task Act()
=> await That(subject).DoesNotComplyWith(it => it.IsNotEquatableTo(expected));

await That(Act).Throws<XunitException>()
.WithMessage("""
Expected that subject
is equatable to ThatGeneric.IsNotEquatableTo.Wrapper {
Value = 3
},
but it was ThatGeneric.IsNotEquatableTo.Wrapper {
Value = 1
}
""");
}
}

private readonly struct Wrapper(long value)
: IEquatable<Wrapper>,
IEquatable<long>
{
public long Value { get; } = value;

public bool Equals(Wrapper other)
=> Value == other.Value;

public bool Equals(long other)
=> Value == other;
}
}
}
Loading