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 Source/aweXpect.Core/Core/ExpectationBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ internal void AddReason(string reason)
/// <summary>
/// Adds a <paramref name="reason" /> to the current expectation constraint.
/// </summary>
internal void AddReason(Task<string> reason)
internal void AddReason(Task<string?> reason)
{
AsyncBecauseReason becauseReason = new(reason);
_node.SetReason(becauseReason);
Expand Down
10 changes: 8 additions & 2 deletions Source/aweXpect.Core/Core/Helpers/AsyncBecauseReason.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace aweXpect.Core.Helpers;

internal struct AsyncBecauseReason(Task<string> reason) : IBecauseReason
internal struct AsyncBecauseReason(Task<string?> reason) : IBecauseReason
{
private string? _message;

Expand All @@ -27,7 +27,13 @@ public async Task<ConstraintResult>
{
if (_message is null)
{
_message = CreateMessage(await reason.ConfigureAwait(false));
string? resolvedReason = await reason.ConfigureAwait(false);
if (string.IsNullOrEmpty(resolvedReason))
{
return result;
}

_message = CreateMessage(resolvedReason);
}

string message = _message;
Expand Down
10 changes: 8 additions & 2 deletions Source/aweXpect.Core/Results/ExpectationResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@ public ExpectationResult Because(string? reason)
/// Provide an <see langword="async" /> <paramref name="reason" /> explaining why the constraint is needed.<br />
/// If the phrase does not start with the word <i>because</i>, it is prepended automatically.
/// </summary>
public ExpectationResult Because(Task<string> reason)
/// <remarks>
/// When the <paramref name="reason" /> resolves to <see langword="null" /> or empty, it is ignored.
/// </remarks>
public ExpectationResult Because(Task<string?> reason)
{
expectationBuilder.AddReason(reason);
return this;
Expand Down Expand Up @@ -191,7 +194,10 @@ public TSelf Because(string? reason)
/// Provide an <see langword="async" /> <paramref name="reason" /> explaining why the constraint is needed.<br />
/// If the phrase does not start with the word <i>because</i>, it is prepended automatically.
/// </summary>
public TSelf Because(Task<string> reason)
/// <remarks>
/// When the <paramref name="reason" /> resolves to <see langword="null" /> or empty, it is ignored.
/// </remarks>
public TSelf Because(Task<string?> reason)
{
expectationBuilder.AddReason(reason);
return (TSelf)this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1192,7 +1192,7 @@ namespace aweXpect.Results
public class ExpectationResult : aweXpect.Results.Expectation, aweXpect.Core.IOptionsProvider<aweXpect.Core.ExpectationBuilder>
{
public ExpectationResult(aweXpect.Core.ExpectationBuilder expectationBuilder) { }
public aweXpect.Results.ExpectationResult Because(System.Threading.Tasks.Task<string> reason) { }
public aweXpect.Results.ExpectationResult Because(System.Threading.Tasks.Task<string?> reason) { }
public aweXpect.Results.ExpectationResult Because(string? reason) { }
public System.Runtime.CompilerServices.TaskAwaiter GetAwaiter() { }
public override string? ToString() { }
Expand All @@ -1208,7 +1208,7 @@ namespace aweXpect.Results
where TSelf : aweXpect.Results.ExpectationResult<TType, TSelf>
{
public ExpectationResult(aweXpect.Core.ExpectationBuilder expectationBuilder) { }
public TSelf Because(System.Threading.Tasks.Task<string> reason) { }
public TSelf Because(System.Threading.Tasks.Task<string?> reason) { }
public TSelf Because(string? reason) { }
[System.Diagnostics.StackTraceHidden]
public System.Runtime.CompilerServices.TaskAwaiter<TType> GetAwaiter() { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1192,7 +1192,7 @@ namespace aweXpect.Results
public class ExpectationResult : aweXpect.Results.Expectation, aweXpect.Core.IOptionsProvider<aweXpect.Core.ExpectationBuilder>
{
public ExpectationResult(aweXpect.Core.ExpectationBuilder expectationBuilder) { }
public aweXpect.Results.ExpectationResult Because(System.Threading.Tasks.Task<string> reason) { }
public aweXpect.Results.ExpectationResult Because(System.Threading.Tasks.Task<string?> reason) { }
public aweXpect.Results.ExpectationResult Because(string? reason) { }
public System.Runtime.CompilerServices.TaskAwaiter GetAwaiter() { }
public override string? ToString() { }
Expand All @@ -1208,7 +1208,7 @@ namespace aweXpect.Results
where TSelf : aweXpect.Results.ExpectationResult<TType, TSelf>
{
public ExpectationResult(aweXpect.Core.ExpectationBuilder expectationBuilder) { }
public TSelf Because(System.Threading.Tasks.Task<string> reason) { }
public TSelf Because(System.Threading.Tasks.Task<string?> reason) { }
public TSelf Because(string? reason) { }
[System.Diagnostics.StackTraceHidden]
public System.Runtime.CompilerServices.TaskAwaiter<TType> GetAwaiter() { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1155,7 +1155,7 @@ namespace aweXpect.Results
public class ExpectationResult : aweXpect.Results.Expectation, aweXpect.Core.IOptionsProvider<aweXpect.Core.ExpectationBuilder>
{
public ExpectationResult(aweXpect.Core.ExpectationBuilder expectationBuilder) { }
public aweXpect.Results.ExpectationResult Because(System.Threading.Tasks.Task<string> reason) { }
public aweXpect.Results.ExpectationResult Because(System.Threading.Tasks.Task<string?> reason) { }
public aweXpect.Results.ExpectationResult Because(string? reason) { }
public System.Runtime.CompilerServices.TaskAwaiter GetAwaiter() { }
public override string? ToString() { }
Expand All @@ -1170,7 +1170,7 @@ namespace aweXpect.Results
where TSelf : aweXpect.Results.ExpectationResult<TType, TSelf>
{
public ExpectationResult(aweXpect.Core.ExpectationBuilder expectationBuilder) { }
public TSelf Because(System.Threading.Tasks.Task<string> reason) { }
public TSelf Because(System.Threading.Tasks.Task<string?> reason) { }
public TSelf Because(string? reason) { }
public System.Runtime.CompilerServices.TaskAwaiter<TType> GetAwaiter() { }
public override string? ToString() { }
Expand Down
38 changes: 38 additions & 0 deletions Tests/aweXpect.Core.Tests/Core/BecauseTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

async Task Act()
{
await That(subject).DoesNotThrow().Because(becauseTask);

Check warning on line 16 in Tests/aweXpect.Core.Tests/Core/BecauseTests.cs

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Argument of type 'Task<string>' cannot be used for parameter 'reason' of type 'Task<string?>' in 'ExpectationResult ExpectationResult.Because(Task<string?> reason)' due to differences in the nullability of reference types.

See more on https://sonarcloud.io/project/issues?id=Testably_aweXpect&issues=AZ58y0Md47GWV_L62MED&open=AZ58y0Md47GWV_L62MED&pullRequest=974
}

await That(Act).ThrowsException().WithMessage($"*{because}*").AsWildcard();
Expand All @@ -33,6 +33,23 @@
await That(Act).ThrowsException().WithMessage($"*{because}*").AsWildcard();
}

[Theory]
[InlineData(null)]
[InlineData("")]
public async Task ActionDelegate_WhenAsyncReasonIsNullOrEmpty_ShouldNotIncludeBecause(string? because)
{
Task<string?> becauseTask = Task.FromResult(because);
Action subject = () => throw new MyException();

async Task Act()
{
await That(subject).DoesNotThrow().Because(becauseTask);
}

Exception exception = await That(Act).ThrowsException();
await That(exception.Message).DoesNotContain("because");
}

[Theory]
[InlineData(null)]
[InlineData("")]
Expand Down Expand Up @@ -72,7 +89,7 @@

async Task Act()
{
await That(subject).DoesNotThrow().Because(becauseTask);

Check warning on line 92 in Tests/aweXpect.Core.Tests/Core/BecauseTests.cs

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Argument of type 'Task<string>' cannot be used for parameter 'reason' of type 'Task<string?>' in 'ExpectationResult<int> ExpectationResult<int, ExpectationResult<int>>.Because(Task<string?> reason)' due to differences in the nullability of reference types.

See more on https://sonarcloud.io/project/issues?id=Testably_aweXpect&issues=AZ58y0Md47GWV_L62MEE&open=AZ58y0Md47GWV_L62MEE&pullRequest=974
}

await That(Act).ThrowsException().WithMessage($"*{because}*").AsWildcard();
Expand Down Expand Up @@ -125,6 +142,27 @@
await That(Act).ThrowsException().WithMessage($"*{because1}*").AsWildcard();
}

[Theory]
[InlineData(null)]
[InlineData("")]
public async Task WhenAsyncReasonIsNullOrEmpty_ShouldNotIncludeBecause(string? because)
{
Task<string?> becauseTask = Task.FromResult(because);
bool subject = true;

async Task Act()
{
await That(subject).IsFalse().Because(becauseTask);
}

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

[Fact]
public async Task WhenCombineWithAnd_ShouldApplyBecauseReason()
{
Expand Down
Loading