Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert early returns for project consistency #2105

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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
114 changes: 55 additions & 59 deletions Src/FluentAssertions/Specialized/AsyncFunctionAssertions.cs
Expand Up @@ -132,21 +132,21 @@ public AsyncFunctionAssertions(Func<TTask> subject, IExtractExceptions extractor
.BecauseOf(because, becauseArgs)
.FailWith("Expected {context} to throw exactly {0}{reason}, but found <null>.", expectedType);

if (!success)
if (success)
{
return new ExceptionAssertions<TException>(Array.Empty<TException>());
}
Exception exception = await InvokeWithInterceptionAsync(Subject);

Exception exception = await InvokeWithInterceptionAsync(Subject);
Execute.Assertion
.ForCondition(exception is not null)
.BecauseOf(because, becauseArgs)
.FailWith("Expected {0}{reason}, but no exception was thrown.", expectedType);

Execute.Assertion
.ForCondition(exception is not null)
.BecauseOf(because, becauseArgs)
.FailWith("Expected {0}{reason}, but no exception was thrown.", expectedType);
exception.Should().BeOfType(expectedType, because, becauseArgs);

exception.Should().BeOfType(expectedType, because, becauseArgs);
return new ExceptionAssertions<TException>(new[] { exception as TException });
jnyrup marked this conversation as resolved.
Show resolved Hide resolved
}

return new ExceptionAssertions<TException>(new[] { exception as TException });
return new ExceptionAssertions<TException>(Array.Empty<TException>());
}

/// <summary>
Expand All @@ -168,13 +168,13 @@ public AsyncFunctionAssertions(Func<TTask> subject, IExtractExceptions extractor
.BecauseOf(because, becauseArgs)
.FailWith("Expected {context} to throw {0}{reason}, but found <null>.", typeof(TException));

if (!success)
if (success)
{
return new ExceptionAssertions<TException>(Array.Empty<TException>());
Exception exception = await InvokeWithInterceptionAsync(Subject);
return ThrowInternal<TException>(exception, because, becauseArgs);
}

Exception exception = await InvokeWithInterceptionAsync(Subject);
return ThrowInternal<TException>(exception, because, becauseArgs);
return new ExceptionAssertions<TException>(Array.Empty<TException>());
}

/// <summary>
Expand All @@ -194,18 +194,16 @@ public async Task<AndConstraint<TAssertions>> NotThrowAsync(string because = "",
.BecauseOf(because, becauseArgs)
.FailWith("Expected {context} not to throw{reason}, but found <null>.");

if (!success)
{
return new AndConstraint<TAssertions>((TAssertions)this);
}

try
{
await Subject.Invoke();
}
catch (Exception exception)
if (success)
{
NotThrowInternal(exception, because, becauseArgs);
try
{
await Subject.Invoke();
}
catch (Exception exception)
{
return NotThrowInternal(exception, because, becauseArgs);
}
}

return new AndConstraint<TAssertions>((TAssertions)this);
Expand All @@ -229,18 +227,16 @@ public async Task<AndConstraint<TAssertions>> NotThrowAsync<TException>(string b
.BecauseOf(because, becauseArgs)
.FailWith("Expected {context} not to throw{reason}, but found <null>.");

if (!success)
{
return new AndConstraint<TAssertions>((TAssertions)this);
}

try
{
await Subject.Invoke();
}
catch (Exception exception)
if (success)
{
NotThrowInternal<TException>(exception, because, becauseArgs);
try
{
await Subject.Invoke();
}
catch (Exception exception)
{
return NotThrowInternal<TException>(exception, because, becauseArgs);
}
}

return new AndConstraint<TAssertions>((TAssertions)this);
Expand Down Expand Up @@ -279,37 +275,37 @@ public Task<AndConstraint<TAssertions>> NotThrowAfterAsync(TimeSpan waitTime, Ti
.BecauseOf(because, becauseArgs)
.FailWith("Expected {context} not to throw any exceptions after {0}{reason}, but found <null>.", waitTime);

if (!success)
{
return Task.FromResult(new AndConstraint<TAssertions>((TAssertions)this));
}

return AssertionTaskAsync();

async Task<AndConstraint<TAssertions>> AssertionTaskAsync()
if (success)
{
TimeSpan? invocationEndTime = null;
Exception exception = null;
ITimer timer = Clock.StartTimer();
return AssertionTaskAsync();

while (invocationEndTime is null || invocationEndTime < waitTime)
async Task<AndConstraint<TAssertions>> AssertionTaskAsync()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might still want to keep local functions at the bottom of the parent method. Effectively, they work as "private methods in a method scope", meaning treating them as if they were private puts the focus on the public code of the method first, which can improve readability: people tend to want to look at the high level concepts first, and then drill down into the lower level ones as needed.

The justification would be similar as to why the recommendation is to keep private methods below public ones in classes.

{
exception = await InvokeWithInterceptionAsync(Subject);
if (exception is null)
TimeSpan? invocationEndTime = null;
Exception exception = null;
ITimer timer = Clock.StartTimer();

while (invocationEndTime is null || invocationEndTime < waitTime)
{
return new AndConstraint<TAssertions>((TAssertions)this);
exception = await InvokeWithInterceptionAsync(Subject);
if (exception is null)
{
return new AndConstraint<TAssertions>((TAssertions)this);
}

await Clock.DelayAsync(pollInterval, CancellationToken.None);
invocationEndTime = timer.Elapsed;
}

await Clock.DelayAsync(pollInterval, CancellationToken.None);
invocationEndTime = timer.Elapsed;
}

Execute.Assertion
.BecauseOf(because, becauseArgs)
.FailWith("Did not expect any exceptions after {0}{reason}, but found {1}.", waitTime, exception);
Execute.Assertion
.BecauseOf(because, becauseArgs)
.FailWith("Did not expect any exceptions after {0}{reason}, but found {1}.", waitTime, exception);

return new AndConstraint<TAssertions>((TAssertions)this);
return new AndConstraint<TAssertions>((TAssertions)this);
}
}

return Task.FromResult(new AndConstraint<TAssertions>((TAssertions)this));
}

/// <summary>
Expand Down
92 changes: 45 additions & 47 deletions Src/FluentAssertions/Specialized/DelegateAssertions.cs
Expand Up @@ -43,14 +43,14 @@ public ExceptionAssertions<TException> Throw<TException>(string because = "", pa
.BecauseOf(because, becauseArgs)
.FailWith("Expected {context} to throw {0}{reason}, but found <null>.", typeof(TException));

if (!success)
if (success)
{
return new ExceptionAssertions<TException>(Array.Empty<TException>());
FailIfSubjectIsAsyncVoid();
Exception exception = InvokeSubjectWithInterception();
return ThrowInternal<TException>(exception, because, becauseArgs);
}

FailIfSubjectIsAsyncVoid();
Exception exception = InvokeSubjectWithInterception();
return ThrowInternal<TException>(exception, because, becauseArgs);
return new ExceptionAssertions<TException>(Array.Empty<TException>());
}

/// <summary>
Expand All @@ -71,14 +71,14 @@ public AndConstraint<TAssertions> NotThrow<TException>(string because = "", para
.BecauseOf(because, becauseArgs)
.FailWith("Expected {context} not to throw {0}{reason}, but found <null>.", typeof(TException));

if (!success)
if (success)
{
return new AndConstraint<TAssertions>((TAssertions)this);
FailIfSubjectIsAsyncVoid();
Exception exception = InvokeSubjectWithInterception();
return NotThrowInternal<TException>(exception, because, becauseArgs);
}

FailIfSubjectIsAsyncVoid();
Exception exception = InvokeSubjectWithInterception();
return NotThrowInternal<TException>(exception, because, becauseArgs);
return new AndConstraint<TAssertions>((TAssertions)this);
}

/// <summary>
Expand All @@ -98,14 +98,14 @@ public AndConstraint<TAssertions> NotThrow(string because = "", params object[]
.BecauseOf(because, becauseArgs)
.FailWith("Expected {context} not to throw{reason}, but found <null>.");

if (!success)
if (success)
{
return new AndConstraint<TAssertions>((TAssertions)this);
FailIfSubjectIsAsyncVoid();
Exception exception = InvokeSubjectWithInterception();
return NotThrowInternal(exception, because, becauseArgs);
}

FailIfSubjectIsAsyncVoid();
Exception exception = InvokeSubjectWithInterception();
return NotThrowInternal(exception, because, becauseArgs);
return new AndConstraint<TAssertions>((TAssertions)this);
}

/// <summary>
Expand Down Expand Up @@ -133,24 +133,24 @@ public AndConstraint<TAssertions> NotThrow(string because = "", params object[]
.BecauseOf(because, becauseArgs)
.FailWith("Expected {context} to throw exactly {0}{reason}, but found <null>.", typeof(TException));

if (!success)
if (success)
{
return new ExceptionAssertions<TException>(Array.Empty<TException>());
}
FailIfSubjectIsAsyncVoid();
Exception exception = InvokeSubjectWithInterception();

FailIfSubjectIsAsyncVoid();
Exception exception = InvokeSubjectWithInterception();
Type expectedType = typeof(TException);

Type expectedType = typeof(TException);
Execute.Assertion
.ForCondition(exception is not null)
.BecauseOf(because, becauseArgs)
.FailWith("Expected {0}{reason}, but no exception was thrown.", expectedType);

Execute.Assertion
.ForCondition(exception is not null)
.BecauseOf(because, becauseArgs)
.FailWith("Expected {0}{reason}, but no exception was thrown.", expectedType);
exception.Should().BeOfType(expectedType, because, becauseArgs);

exception.Should().BeOfType(expectedType, because, becauseArgs);
return new ExceptionAssertions<TException>(new[] { exception as TException });
}

return new ExceptionAssertions<TException>(new[] { exception as TException });
return new ExceptionAssertions<TException>(Array.Empty<TException>());
}

/// <summary>
Expand Down Expand Up @@ -186,34 +186,32 @@ public AndConstraint<TAssertions> NotThrowAfter(TimeSpan waitTime, TimeSpan poll
.BecauseOf(because, becauseArgs)
.FailWith("Expected {context} not to throw after {0}{reason}, but found <null>.", waitTime);

if (!success)
if (success)
{
return new AndConstraint<TAssertions>((TAssertions)this);
}

FailIfSubjectIsAsyncVoid();
FailIfSubjectIsAsyncVoid();

TimeSpan? invocationEndTime = null;
Exception exception = null;
ITimer timer = Clock.StartTimer();
TimeSpan? invocationEndTime = null;
Exception exception = null;
ITimer timer = Clock.StartTimer();

while (invocationEndTime is null || invocationEndTime < waitTime)
{
exception = InvokeSubjectWithInterception();
if (exception is null)
while (invocationEndTime is null || invocationEndTime < waitTime)
{
break;
exception = InvokeSubjectWithInterception();
if (exception is null)
{
break;
}

Clock.Delay(pollInterval);
invocationEndTime = timer.Elapsed;
}

Clock.Delay(pollInterval);
invocationEndTime = timer.Elapsed;
Execute.Assertion
.BecauseOf(because, becauseArgs)
.ForCondition(exception is null)
.FailWith("Did not expect any exceptions after {0}{reason}, but found {1}.", waitTime, exception);
}

Execute.Assertion
.BecauseOf(because, becauseArgs)
.ForCondition(exception is null)
.FailWith("Did not expect any exceptions after {0}{reason}, but found {1}.", waitTime, exception);

return new AndConstraint<TAssertions>((TAssertions)this);
}

Expand Down