Skip to content

Commit

Permalink
feat: add BeEquivalentTo assertions to Maybe<T> and Result<T>
Browse files Browse the repository at this point in the history
  • Loading branch information
Tr00d committed Dec 6, 2023
1 parent 038c24e commit 364d43d
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 0 deletions.
28 changes: 28 additions & 0 deletions Vonage.Common.Test/Extensions/MaybeAssertionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,21 @@ public AndConstraint<MaybeAssertionExtensions<T>> Be(Maybe<T> expected)
return new AndConstraint<MaybeAssertionExtensions<T>>(this);
}

public AndConstraint<MaybeAssertionExtensions<T>> BeEquivalentTo(Maybe<T> expected)
{
Execute.Assertion
.WithExpectation($"Expected {this.Subject} to be equivalent to {expected}, ")
.Given(() => new {this.Subject, Expected = expected})
.ForCondition(data => data.Subject.IsSome == data.Subject.IsSome)
.FailWith($"States differs between {this.Subject} and {expected}.")
.Then
.Given(data => data.Subject.Merge(data.Expected, (s, e) => new {Subject = s, Expected = e}))
.ForCondition(
data => data.Match(some => EvaluateValueEquality(some.Subject, some.Expected), () => true))
.FailWith($"Value equality failed between {this.Subject} and {expected}.");
return new AndConstraint<MaybeAssertionExtensions<T>>(this);
}

public AndConstraint<MaybeAssertionExtensions<T>> BeNone()
{
Execute.Assertion
Expand Down Expand Up @@ -55,6 +70,19 @@ public AndConstraint<MaybeAssertionExtensions<T>> BeSome(T expected)
return new AndConstraint<MaybeAssertionExtensions<T>>(this);
}

private static bool EvaluateValueEquality(T subject, T expected)
{
try
{
subject.Should().BeEquivalentTo(expected);
return true;
}
catch
{
return false;
}
}

protected override string Identifier => "maybe";
}
}
35 changes: 35 additions & 0 deletions Vonage.Common.Test/Extensions/ResultAssertionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,28 @@ public ResultAssertionExtensions(Result<T> subject) : base(subject)
{
}

public AndConstraint<ResultAssertionExtensions<T>> BeEquivalentTo(Result<T> expected)
{
Execute.Assertion
.WithExpectation($"Expected {this.Subject} to be equivalent to {expected}, ")
.Given(() => new {this.Subject, Expected = expected})
.ForCondition(data => data.Subject.IsSuccess == data.Subject.IsSuccess)
.FailWith($"States differs between {this.Subject} and {expected}.")
.Then
.Given(data => new
{
IsSuccess = data.Subject.IsSuccess && data.Expected.IsSuccess,
data.Subject,
data.Expected,
})
.ForCondition(data =>
data.IsSuccess
? EvaluateValueEquality(data.Subject.GetSuccessUnsafe(), data.Expected.GetSuccessUnsafe())
: EvaluateValueEquality(data.Subject.GetFailureUnsafe(), data.Expected.GetFailureUnsafe()))
.FailWith($"Value equality failed between {this.Subject} and {expected}.");
return new AndConstraint<ResultAssertionExtensions<T>>(this);
}

public AndConstraint<ResultAssertionExtensions<T>> BeFailure(Action<IResultFailure> action)
{
this.BuildFailureExpectation();
Expand Down Expand Up @@ -95,6 +117,19 @@ public AndConstraint<ResultAssertionExtensions<T>> BeSuccess(T expected)
.ForCondition(subject => subject.IsSuccess)
.FailWith(this.BuildResultFailureMessage());

private static bool EvaluateValueEquality<TA>(TA subject, TA expected)
{
try
{
subject.Should().BeEquivalentTo(expected);
return true;
}
catch
{
return false;
}
}

private string GetResultFailure() =>
this.Subject.Match(_ => string.Empty, failure => failure.GetFailureMessage());

Expand Down

0 comments on commit 364d43d

Please sign in to comment.