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
2 changes: 1 addition & 1 deletion Pipeline/Build.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ partial class Build : NukeBuild
/// <para />
/// Afterward, you can update the package reference in `Directory.Packages.props` and reset this flag.
/// </summary>
readonly BuildScope BuildScope = BuildScope.Default;
readonly BuildScope BuildScope = BuildScope.CoreOnly;

[Parameter("Github Token")] readonly string GithubToken;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ public sealed partial class WithValue<T>
/// <summary>
/// Verifies that the delegate does not throw any exception.
/// </summary>
public AndResult<T, WithValue<T>> DoesNotThrow()
public DelegateWithValueResult<T> DoesNotThrow()
=> new(ExpectationBuilder.AddConstraint((it, grammars) =>
new DoesNotThrowConstraint(it, grammars, typeof(Exception))),
this);

/// <summary>
/// Verifies that the delegate does not throw an exception of type <typeparamref name="TException" />.
/// </summary>
public AndResult<T, WithValue<T>> DoesNotThrow<TException>()
public DelegateWithValueResult<T> DoesNotThrow<TException>()
where TException : Exception
=> new(ExpectationBuilder.AddConstraint((it, grammars) =>
new DoesNotThrowConstraint(it, grammars, typeof(TException))),
Expand All @@ -33,7 +33,7 @@ public AndResult<T, WithValue<T>> DoesNotThrow<TException>()
/// <summary>
/// Verifies that the delegate does not throw an exception of type <paramref name="exceptionType" />.
/// </summary>
public AndResult<T, WithValue<T>> DoesNotThrow(Type exceptionType)
public DelegateWithValueResult<T> DoesNotThrow(Type exceptionType)
=> new(ExpectationBuilder.AddConstraint((it, grammars) =>
new DoesNotThrowConstraint(it, grammars, exceptionType)),
this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public sealed partial class WithValue<T>
/// <summary>
/// Verifies that the delegate does not throw an exception of type <typeparamref name="TException" />.
/// </summary>
public AndResult<T, WithValue<T>> DoesNotThrowExactly<TException>()
public DelegateWithValueResult<T> DoesNotThrowExactly<TException>()
where TException : Exception
=> new(ExpectationBuilder.AddConstraint((it, grammars) =>
new DoesNotThrowExactlyConstraint(it, grammars, typeof(TException))),
Expand All @@ -25,7 +25,7 @@ public AndResult<T, WithValue<T>> DoesNotThrowExactly<TException>()
/// <summary>
/// Verifies that the delegate does not throw an exception of type <paramref name="exceptionType" />.
/// </summary>
public AndResult<T, WithValue<T>> DoesNotThrowExactly(Type exceptionType)
public DelegateWithValueResult<T> DoesNotThrowExactly(Type exceptionType)
=> new(ExpectationBuilder.AddConstraint((it, grammars) =>
new DoesNotThrowExactlyConstraint(it, grammars, exceptionType)),
this);
Expand Down
84 changes: 84 additions & 0 deletions Source/aweXpect.Core/Results/DelegateWithValueResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
using System.Diagnostics.CodeAnalysis;
using System.Text;
using aweXpect.Core;
using aweXpect.Core.Constraints;
using aweXpect.Core.Sources;
using aweXpect.Delegates;

namespace aweXpect.Results;

/// <summary>
/// Result for a delegate with a value that does not throw.
/// </summary>
public class DelegateWithValueResult<T>(ExpectationBuilder expectationBuilder, ThatDelegate.WithValue<T> returnValue)
: AndResult<T, ThatDelegate.WithValue<T>>(expectationBuilder, returnValue)
Comment thread
vbreuss marked this conversation as resolved.
{
private readonly ExpectationBuilder _expectationBuilder = expectationBuilder;

/// <summary>
/// Returns the result returned from the delegate.
/// </summary>
public IThat<T> AndWhoseResult
{
get
{
_expectationBuilder.And("")
.AddConstraint((it, grammars) => new DoesNotThrowAnyExceptionConstraint(it, grammars))
.ForWhich<DelegateValue<T>, T?>(d => d.Value, " and whose result ", "the result");
return new ThatSubject<T?>(_expectationBuilder);
}
}

private sealed class DoesNotThrowAnyExceptionConstraint(
string it,
ExpectationGrammars grammars)
: ConstraintResult(grammars),
IValueConstraint<DelegateValue<T>>
{
private DelegateValue<T>? _actual;

/// <inheritdoc />
public ConstraintResult IsMetBy(DelegateValue<T> value)
{
_actual = value;
if (value.IsNull)
{
Outcome = Outcome.Failure;
return this;
}

Outcome = value.Exception is null
? Outcome.Success
: Outcome.Failure;
return this;
}

public override void AppendExpectation(StringBuilder stringBuilder, string? indentation = null)
{
// Do not append any expectation
}

public override void AppendResult(StringBuilder stringBuilder, string? indentation = null)
{
if (_actual?.Exception is not null)
{
stringBuilder.Append(it).Append(" did throw ");
stringBuilder.Append(ThatDelegate.FormatForMessage(_actual.Exception));
}
}

public override bool TryGetValue<TValue>([NotNullWhen(true)] out TValue? value) where TValue : default
{
if (_actual is { Value: TValue typedValue, })
{
value = typedValue;
return true;
}

value = default;
return typeof(TValue).IsAssignableFrom(typeof(T));
}

public override ConstraintResult Negate() => this;
}
}
15 changes: 10 additions & 5 deletions Tests/aweXpect.Core.Api.Tests/Expected/aweXpect.Core_net8.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -463,12 +463,12 @@ namespace aweXpect.Delegates
public sealed class WithValue<T> : aweXpect.Delegates.ThatDelegate, aweXpect.Core.IExpectThat<aweXpect.Delegates.ThatDelegate.WithValue<T>>, aweXpect.Core.IThat<aweXpect.Delegates.ThatDelegate.WithValue<T>>
{
public WithValue(aweXpect.Core.ExpectationBuilder expectationBuilder) { }
public aweXpect.Results.AndResult<T, aweXpect.Delegates.ThatDelegate.WithValue<T>> DoesNotThrow() { }
public aweXpect.Results.AndResult<T, aweXpect.Delegates.ThatDelegate.WithValue<T>> DoesNotThrow(System.Type exceptionType) { }
public aweXpect.Results.AndResult<T, aweXpect.Delegates.ThatDelegate.WithValue<T>> DoesNotThrow<TException>()
public aweXpect.Results.DelegateWithValueResult<T> DoesNotThrow() { }
public aweXpect.Results.DelegateWithValueResult<T> DoesNotThrow(System.Type exceptionType) { }
public aweXpect.Results.DelegateWithValueResult<T> DoesNotThrow<TException>()
where TException : System.Exception { }
public aweXpect.Results.AndResult<T, aweXpect.Delegates.ThatDelegate.WithValue<T>> DoesNotThrowExactly(System.Type exceptionType) { }
public aweXpect.Results.AndResult<T, aweXpect.Delegates.ThatDelegate.WithValue<T>> DoesNotThrowExactly<TException>()
public aweXpect.Results.DelegateWithValueResult<T> DoesNotThrowExactly(System.Type exceptionType) { }
public aweXpect.Results.DelegateWithValueResult<T> DoesNotThrowExactly<TException>()
where TException : System.Exception { }
public aweXpect.Results.ExecutesInResult<aweXpect.Results.AndResult<aweXpect.Delegates.ThatDelegate.WithValue<T>>> ExecutesIn() { }
}
Expand Down Expand Up @@ -999,6 +999,11 @@ namespace aweXpect.Results
public TTarget Once() { }
public TTarget Twice() { }
}
public class DelegateWithValueResult<T> : aweXpect.Results.AndResult<T, aweXpect.Delegates.ThatDelegate.WithValue<T>>
{
public DelegateWithValueResult(aweXpect.Core.ExpectationBuilder expectationBuilder, aweXpect.Delegates.ThatDelegate.WithValue<T> returnValue) { }
public aweXpect.Core.IThat<T> AndWhoseResult { get; }
}
public class ExecutesInResult<TResult>
{
public ExecutesInResult(TResult returnValue, aweXpect.Options.TimeSpanEqualityOptions options) { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -463,12 +463,12 @@ namespace aweXpect.Delegates
public sealed class WithValue<T> : aweXpect.Delegates.ThatDelegate, aweXpect.Core.IExpectThat<aweXpect.Delegates.ThatDelegate.WithValue<T>>, aweXpect.Core.IThat<aweXpect.Delegates.ThatDelegate.WithValue<T>>
{
public WithValue(aweXpect.Core.ExpectationBuilder expectationBuilder) { }
public aweXpect.Results.AndResult<T, aweXpect.Delegates.ThatDelegate.WithValue<T>> DoesNotThrow() { }
public aweXpect.Results.AndResult<T, aweXpect.Delegates.ThatDelegate.WithValue<T>> DoesNotThrow(System.Type exceptionType) { }
public aweXpect.Results.AndResult<T, aweXpect.Delegates.ThatDelegate.WithValue<T>> DoesNotThrow<TException>()
public aweXpect.Results.DelegateWithValueResult<T> DoesNotThrow() { }
public aweXpect.Results.DelegateWithValueResult<T> DoesNotThrow(System.Type exceptionType) { }
public aweXpect.Results.DelegateWithValueResult<T> DoesNotThrow<TException>()
where TException : System.Exception { }
public aweXpect.Results.AndResult<T, aweXpect.Delegates.ThatDelegate.WithValue<T>> DoesNotThrowExactly(System.Type exceptionType) { }
public aweXpect.Results.AndResult<T, aweXpect.Delegates.ThatDelegate.WithValue<T>> DoesNotThrowExactly<TException>()
public aweXpect.Results.DelegateWithValueResult<T> DoesNotThrowExactly(System.Type exceptionType) { }
public aweXpect.Results.DelegateWithValueResult<T> DoesNotThrowExactly<TException>()
where TException : System.Exception { }
public aweXpect.Results.ExecutesInResult<aweXpect.Results.AndResult<aweXpect.Delegates.ThatDelegate.WithValue<T>>> ExecutesIn() { }
}
Expand Down Expand Up @@ -982,6 +982,11 @@ namespace aweXpect.Results
public TTarget Once() { }
public TTarget Twice() { }
}
public class DelegateWithValueResult<T> : aweXpect.Results.AndResult<T, aweXpect.Delegates.ThatDelegate.WithValue<T>>
{
public DelegateWithValueResult(aweXpect.Core.ExpectationBuilder expectationBuilder, aweXpect.Delegates.ThatDelegate.WithValue<T> returnValue) { }
public aweXpect.Core.IThat<T> AndWhoseResult { get; }
}
public class ExecutesInResult<TResult>
{
public ExecutesInResult(TResult returnValue, aweXpect.Options.TimeSpanEqualityOptions options) { }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
namespace aweXpect.Tests;

public sealed partial class ThatDelegate
{
public sealed partial class DoesNotThrow
{
public sealed class AndWhoseResult
{
public sealed class Tests
{
[Fact]
public async Task WhenDelegateThrows_ShouldFail()
{
Func<int> @delegate = () => throw new CustomException();

async Task Act() => await That(@delegate).DoesNotThrow().AndWhoseResult.IsGreaterThan(5);

await That(Act).Throws<XunitException>()
.WithMessage("""
Expected that @delegate
does not throw any exception and whose result is greater than 5,
but it did throw a ThatDelegate.CustomException:
WhenDelegateThrows_ShouldFail
""");
}

[Theory]
[AutoData]
public async Task WhenReturnValueDoesNotMatch_ShouldFail(int value)
{
Func<int> @delegate = () => value;

async Task Act() => await That(@delegate).DoesNotThrow().AndWhoseResult.IsLessThan(value);

await That(Act).Throws<XunitException>()
.WithMessage($"""
Expected that @delegate
does not throw any exception and whose result is less than {value},
but the result was {value}
""");
}

[Theory]
[AutoData]
public async Task WhenReturnValueMatches_ShouldSucceed(int value)
{
Func<int> @delegate = () => value;

await That(@delegate).DoesNotThrow().AndWhoseResult.IsEqualTo(value);
}
}

public sealed class GenericTests
{
[Fact]
public async Task WhenDelegateThrowsExpectedException_ShouldFail()
{
Func<int> @delegate = () => throw new CustomException();

async Task Act()
=> await That(@delegate).DoesNotThrow<CustomException>().AndWhoseResult.IsEqualTo(5);

await That(Act).Throws<XunitException>()
.WithMessage("""
Expected that @delegate
does not throw a ThatDelegate.CustomException and whose result is equal to 5,
but it did throw a ThatDelegate.CustomException:
WhenDelegateThrowsExpectedException_ShouldFail
""");
}

[Fact]
public async Task WhenDelegateThrowsOtherException_ShouldFail()
{
Func<int> @delegate = () => throw new CustomException();

async Task Act()
=> await That(@delegate).DoesNotThrow<OtherException>().AndWhoseResult.IsEqualTo(5);

await That(Act).Throws<XunitException>()
.WithMessage("""
Expected that @delegate
does not throw a ThatDelegate.OtherException and whose result is equal to 5,
but it did throw a ThatDelegate.CustomException:
WhenDelegateThrowsOtherException_ShouldFail
""");
}

[Theory]
[AutoData]
public async Task WhenReturnValueDoesNotMatch_ShouldFail(int value)
{
Func<int> @delegate = () => value;

async Task Act() => await That(@delegate).DoesNotThrow<CustomException>().AndWhoseResult
.IsEqualTo(value + 1);

await That(Act).Throws<XunitException>()
.WithMessage($"""
Expected that @delegate
does not throw a ThatDelegate.CustomException and whose result is equal to {value + 1},
but the result was {value} which differs by -1
""");
}

[Theory]
[AutoData]
public async Task WhenReturnValueMatches_ShouldSucceed(int value)
{
Func<int> @delegate = () => value;

await That(@delegate).DoesNotThrow<CustomException>().AndWhoseResult.IsEqualTo(value);
}
}

public sealed class TypeTests
{
[Fact]
public async Task WhenDelegateThrowsExpectedException_ShouldFail()
{
Func<int> @delegate = () => throw new CustomException();

async Task Act()
=> await That(@delegate).DoesNotThrow(typeof(CustomException)).AndWhoseResult.IsEqualTo(5);

await That(Act).Throws<XunitException>()
.WithMessage("""
Expected that @delegate
does not throw a ThatDelegate.CustomException and whose result is equal to 5,
but it did throw a ThatDelegate.CustomException:
WhenDelegateThrowsExpectedException_ShouldFail
""");
}

[Fact]
public async Task WhenDelegateThrowsOtherException_ShouldFail()
{
Func<int> @delegate = () => throw new CustomException();

async Task Act()
=> await That(@delegate).DoesNotThrow(typeof(OtherException)).AndWhoseResult.IsEqualTo(5);

await That(Act).Throws<XunitException>()
.WithMessage("""
Expected that @delegate
does not throw a ThatDelegate.OtherException and whose result is equal to 5,
but it did throw a ThatDelegate.CustomException:
WhenDelegateThrowsOtherException_ShouldFail
""");
}

[Theory]
[AutoData]
public async Task WhenReturnValueDoesNotMatch_ShouldFail(int value)
{
Func<int> @delegate = () => value;

async Task Act() => await That(@delegate).DoesNotThrow(typeof(CustomException)).AndWhoseResult
.IsEqualTo(value + 1);

await That(Act).Throws<XunitException>()
.WithMessage($"""
Expected that @delegate
does not throw a ThatDelegate.CustomException and whose result is equal to {value + 1},
but the result was {value} which differs by -1
""");
}

[Theory]
[AutoData]
public async Task WhenReturnValueMatches_ShouldSucceed(int value)
{
Func<int> @delegate = () => value;

await That(@delegate).DoesNotThrow(typeof(CustomException)).AndWhoseResult.IsEqualTo(value);
}
}
}
}
}
Loading