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
88 changes: 88 additions & 0 deletions Source/aweXpect.Core/Core/ThatBool.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
using System;
using System.Diagnostics;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using aweXpect.Core.Constraints;
using aweXpect.Core.Nodes;
using aweXpect.Core.TimeSystem;
using aweXpect.Results;

namespace aweXpect.Core;

/// <summary>
/// Wraps the <see cref="ExpectationBuilder" /> for a bool.
/// </summary>
[DebuggerDisplay("ThatBool: {ExpectationBuilder}")]
public class ThatBool : ExpectationResult<bool>, IExpectThat<bool>
{
/// <inheritdoc cref="ThatBool" />
public ThatBool(ExpectationBuilder expectationBuilder) : this(
new WithDefaultExpectationBuilderProxy(expectationBuilder))
{
}

private ThatBool(WithDefaultExpectationBuilderProxy expectationBuilder) : base(expectationBuilder)
{
ExpectationBuilder = expectationBuilder;
}

/// <inheritdoc cref="IExpectThat{T}.ExpectationBuilder" />
public ExpectationBuilder ExpectationBuilder { get; }

private sealed class WithDefaultExpectationBuilderProxy(ExpectationBuilder inner)
: ExpectationBuilder(inner.Subject, inner.ExpectationGrammars)
{
public override ExpectationBuilder UpdateContexts(Action<ResultContexts> callback)
=> inner.UpdateContexts(callback);

internal override Task<ConstraintResult> IsMet(Node rootNode, EvaluationContext.EvaluationContext context,
ITimeSystem timeSystem, TimeSpan? timeout,
CancellationToken cancellationToken)
{
if (rootNode is ExpectationNode expectationNode && expectationNode.IsEmpty())
{
rootNode.AddConstraint(new IsTrueConstraint(inner.ExpectationGrammars));
}

return inner.IsMet(rootNode, context, timeSystem, timeout, cancellationToken);
}

private sealed class IsTrueConstraint(ExpectationGrammars grammars)
: ConstraintResult.WithEqualToValue<bool>("it", grammars, false),
IValueConstraint<bool>
{
public ConstraintResult IsMetBy(bool actual)
{
Actual = actual;
Outcome = true.Equals(actual) ? Outcome.Success : Outcome.Failure;
return this;
}

protected override void AppendNormalExpectation(StringBuilder stringBuilder, string? indentation = null)
{
stringBuilder.Append("is ");
Formatter.Format(stringBuilder, true, FormattingOptions.Indented(indentation));
}

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

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

protected override void AppendNegatedResult(StringBuilder stringBuilder, string? indentation = null)
{
stringBuilder.Append(It);
stringBuilder.Append(" was");
Comment thread
vbreuss marked this conversation as resolved.
}
}
}
}
8 changes: 8 additions & 0 deletions Source/aweXpect.Core/Expect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,14 @@ public static ThatDelegate.WithValue<TValue> That<TValue>(
doNotPopulateThisValue));
#endif

/// <summary>
/// Specify expectations for the current boolean <paramref name="subject" />.
/// </summary>
public static ThatBool That(bool subject,
[CallerArgumentExpression("subject")] string doNotPopulateThisValue = "")
=> new(new ExpectationBuilder<bool>(
new ValueSource<bool>(subject), doNotPopulateThisValue));

/// <summary>
/// Verifies that all provided <paramref name="expectations" /> are met.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,12 @@ namespace aweXpect.Core
{
public static aweXpect.Core.StringDifferenceSettings WithMatchType(this aweXpect.Core.StringDifferenceSettings? settings, aweXpect.Core.StringDifference.MatchType matchType) { }
}
[System.Diagnostics.DebuggerDisplay("ThatBool: {ExpectationBuilder}")]
public class ThatBool : aweXpect.Results.ExpectationResult<bool>, aweXpect.Core.IExpectThat<bool>, aweXpect.Core.IThat<bool>
{
public ThatBool(aweXpect.Core.ExpectationBuilder expectationBuilder) { }
public aweXpect.Core.ExpectationBuilder ExpectationBuilder { get; }
}
[System.Diagnostics.DebuggerDisplay("ThatSubject<{typeof(T)}>: {ExpectationBuilder}")]
public readonly struct ThatSubject<T> : aweXpect.Core.IExpectThat<T>, aweXpect.Core.IThat<T>
{
Expand Down Expand Up @@ -627,6 +633,7 @@ namespace aweXpect
public static aweXpect.Delegates.ThatDelegate.WithoutValue That(System.Func<System.Threading.Tasks.ValueTask> @delegate, [System.Runtime.CompilerServices.CallerArgumentExpression("delegate")] string doNotPopulateThisValue = "") { }
public static aweXpect.Delegates.ThatDelegate.WithoutValue That(System.Func<System.Threading.CancellationToken, System.Threading.Tasks.Task> @delegate, [System.Runtime.CompilerServices.CallerArgumentExpression("delegate")] string doNotPopulateThisValue = "") { }
public static aweXpect.Delegates.ThatDelegate.WithoutValue That(System.Func<System.Threading.CancellationToken, System.Threading.Tasks.ValueTask> @delegate, [System.Runtime.CompilerServices.CallerArgumentExpression("delegate")] string doNotPopulateThisValue = "") { }
public static aweXpect.Core.ThatBool That(bool subject, [System.Runtime.CompilerServices.CallerArgumentExpression("subject")] string doNotPopulateThisValue = "") { }
public static aweXpect.Delegates.ThatDelegate.WithValue<TValue> That<TValue>(System.Func<System.Threading.Tasks.Task<TValue>> @delegate, [System.Runtime.CompilerServices.CallerArgumentExpression("delegate")] string doNotPopulateThisValue = "") { }
public static aweXpect.Delegates.ThatDelegate.WithValue<TValue> That<TValue>(System.Func<System.Threading.Tasks.ValueTask<TValue>> @delegate, [System.Runtime.CompilerServices.CallerArgumentExpression("delegate")] string doNotPopulateThisValue = "") { }
public static aweXpect.Delegates.ThatDelegate.WithValue<TValue> That<TValue>(System.Func<TValue> @delegate, [System.Runtime.CompilerServices.CallerArgumentExpression("delegate")] string doNotPopulateThisValue = "") { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,12 @@ namespace aweXpect.Core
{
public static aweXpect.Core.StringDifferenceSettings WithMatchType(this aweXpect.Core.StringDifferenceSettings? settings, aweXpect.Core.StringDifference.MatchType matchType) { }
}
[System.Diagnostics.DebuggerDisplay("ThatBool: {ExpectationBuilder}")]
public class ThatBool : aweXpect.Results.ExpectationResult<bool>, aweXpect.Core.IExpectThat<bool>, aweXpect.Core.IThat<bool>
{
public ThatBool(aweXpect.Core.ExpectationBuilder expectationBuilder) { }
public aweXpect.Core.ExpectationBuilder ExpectationBuilder { get; }
}
[System.Diagnostics.DebuggerDisplay("ThatSubject<{typeof(T)}>: {ExpectationBuilder}")]
public readonly struct ThatSubject<T> : aweXpect.Core.IExpectThat<T>, aweXpect.Core.IThat<T>
{
Expand Down Expand Up @@ -611,6 +617,7 @@ namespace aweXpect
public static aweXpect.Delegates.ThatDelegate.WithoutValue That(System.Action<System.Threading.CancellationToken> @delegate, [System.Runtime.CompilerServices.CallerArgumentExpression("delegate")] string doNotPopulateThisValue = "") { }
public static aweXpect.Delegates.ThatDelegate.WithoutValue That(System.Func<System.Threading.Tasks.Task> @delegate, [System.Runtime.CompilerServices.CallerArgumentExpression("delegate")] string doNotPopulateThisValue = "") { }
public static aweXpect.Delegates.ThatDelegate.WithoutValue That(System.Func<System.Threading.CancellationToken, System.Threading.Tasks.Task> @delegate, [System.Runtime.CompilerServices.CallerArgumentExpression("delegate")] string doNotPopulateThisValue = "") { }
public static aweXpect.Core.ThatBool That(bool subject, [System.Runtime.CompilerServices.CallerArgumentExpression("subject")] string doNotPopulateThisValue = "") { }
public static aweXpect.Delegates.ThatDelegate.WithValue<TValue> That<TValue>(System.Func<System.Threading.Tasks.Task<TValue>> @delegate, [System.Runtime.CompilerServices.CallerArgumentExpression("delegate")] string doNotPopulateThisValue = "") { }
public static aweXpect.Delegates.ThatDelegate.WithValue<TValue> That<TValue>(System.Func<TValue> @delegate, [System.Runtime.CompilerServices.CallerArgumentExpression("delegate")] string doNotPopulateThisValue = "") { }
public static aweXpect.Delegates.ThatDelegate.WithValue<TValue> That<TValue>(System.Func<System.Threading.CancellationToken, System.Threading.Tasks.Task<TValue>> @delegate, [System.Runtime.CompilerServices.CallerArgumentExpression("delegate")] string doNotPopulateThisValue = "") { }
Expand Down
4 changes: 2 additions & 2 deletions Tests/aweXpect.Core.Tests/Results/ExpectationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ public async Task GetType_ShouldForwardToBase()
public async Task ToString_ShouldForwardToExpectationBuilder()
{
#pragma warning disable aweXpect0001
Expectation sut = That(true).IsTrue();
Expectation sut = That(1).IsGreaterThan(0);
#pragma warning restore aweXpect0001

string? result = sut.ToString();

await That(result)
.IsEqualTo("aweXpect.Core.ExpectationBuilder`1[System.Boolean]");
.IsEqualTo("aweXpect.Core.ExpectationBuilder`1[System.Int32]");
}
}
51 changes: 50 additions & 1 deletion Tests/aweXpect.Tests/Booleans/ThatBool.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,53 @@
namespace aweXpect.Tests;

// ReSharper disable once ClassNeverInstantiated.Global
public sealed partial class ThatBool;
public sealed partial class ThatBool
{
/* TODO: Enable after next Core update
public sealed class Tests
{
[Fact]
public async Task WhenFalse_ShouldFail()
{
bool subject = false;

async Task Act()
=> await That(subject);

await That(Act).Throws<XunitException>()
.WithMessage("""
Expected that subject
is True,
but it was False
""");
}

[Fact]
public async Task WhenFalse_ShouldFailWithDescriptiveMessage()
{
bool subject = false;

async Task Act()
=> await That(subject).Because("we want to test the failure");

await That(Act).Throws<XunitException>()
.WithMessage("""
Expected that subject
is True, because we want to test the failure,
but it was False
""");
}

[Fact]
public async Task WhenTrue_ShouldSucceed()
{
bool subject = true;

async Task Act()
=> await That(subject);

await That(Act).DoesNotThrow();
}
}
*/
}
Loading