Remove unecessary call to `Subject.Should()` by jnyrup · Pull Request #2402 · fluentassertions/fluentassertions · GitHub
Skip to content

Remove unecessary call to Subject.Should()#2402

Merged
jnyrup merged 1 commit into
fluentassertions:developfrom
jnyrup:remove_extra_should
Oct 26, 2023
Merged

Remove unecessary call to Subject.Should()#2402
jnyrup merged 1 commit into
fluentassertions:developfrom
jnyrup:remove_extra_should

Conversation

@jnyrup

@jnyrup jnyrup commented Oct 22, 2023

Copy link
Copy Markdown
Member

Unless Subject.Should() resolves to a another overload of Should than the initial sut.Should(), calling Subject.Should().Foo() instead of Foo() directly should not add any value, but on the negative side lengthen the stack trace in case the assertion fails.

IMPORTANT

  • If the PR touches the public API, the changes have been approved in a separate issue with the "api-approved" label.
  • The code complies with the Coding Guidelines for C#.
  • The changes are covered by unit tests which follow the Arrange-Act-Assert syntax and the naming conventions such as is used in these tests.
  • If the PR adds a feature or fixes a bug, please update the release notes with a functional description that explains what the change means to consumers of this library, which are published on the website.
  • If the PR changes the public API the changes needs to be included by running AcceptApiChanges.ps1 or AcceptApiChanges.sh.
  • If the PR affects the documentation, please include your changes in this pull request so the documentation will appear on the website.
    • Please also run ./build.sh --target spellcheck or .\build.ps1 --target spellcheck before pushing and check the good outcome

@github-actions

github-actions Bot commented Oct 22, 2023

Copy link
Copy Markdown

@coveralls

coveralls commented Oct 22, 2023

Copy link
Copy Markdown

Pull Request Test Coverage Report for Build 6650591818

  • 3 of 3 (100.0%) changed or added relevant lines in 3 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage remained the same at 97.429%

Totals Coverage Status
Change from base Build 6645924319: 0.0%
Covered Lines: 11676
Relevant Lines: 11863

💛 - Coveralls

using (var scope = new AssertionScope())
{
Subject.Should().BeEquivalentTo(unexpected, config);
BeEquivalentTo(unexpected, config);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What about adding methods called SubjectShouldXXXX(...) which just calls XXX(...)? It's just for the fluent readability 😉

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Or... 😉

Subject.Should().Subject.Should().Subject.Should().Subject.Should().Foo();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ok.. got it ;)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Tounge-Twister ;)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I just realized you weren't joking 🤦‍♂️
I'm fine with the current proposed changed, but also happy to add a AssertSubjectIsEquivalentTo forwarding method.
Note that the three changed lines each call a different BeEquivalentTo method.

Avoiding calling Should() inside FA could help #2253

@dennisdoomen dennisdoomen left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I see what you are trying to do, but it doesn't read very fluent to me.

@IT-VBFK

IT-VBFK commented Oct 23, 2023

Copy link
Copy Markdown
Contributor

@jnyrup You can leave out at least the ...Implement in TypeAssertions, because #2403 change this anyway.

Maybe we can agree to something fluent and descriptive?

@jnyrup

jnyrup commented Oct 23, 2023

Copy link
Copy Markdown
Member Author

I see what you are trying to do, but it doesn't read very fluent to me.

One can hardly disagree that Subject.Should().Foo() reads closer to prose than Foo().

To get some numbers on the table, this pattern gives 134 results

grep -rInE --include=*.cs '^ *(return|=>)? *[A-Z][A-Za-z]+\(.*because, becauseArgs' | wc -l

The vast majority are simple one-liner forwards to another overload.
When filtering them out, left is a handful of places like these two examples.

public AndWhichConstraint<TAssertions, T> BeOfType<T>(string because = "", params object[] becauseArgs)
{
BeOfType(typeof(T), because, becauseArgs);
T typedSubject = Subject is T type
? type
: default;
return new AndWhichConstraint<TAssertions, T>((TAssertions)this, typedSubject);
}

public static AndConstraint<NullableNumericAssertions<double>> BeApproximately(this NullableNumericAssertions<double> parent,
double expectedValue, double precision, string because = "",
params object[] becauseArgs)
{
Guard.ThrowIfArgumentIsNegative(precision);
bool success = Execute.Assertion
.ForCondition(parent.Subject is not null)
.BecauseOf(because, becauseArgs)
.FailWith("Expected {context:value} to approximate {0} +/- {1}{reason}, but it was <null>.", expectedValue,
precision);
if (success)
{
var nonNullableAssertions = new DoubleAssertions(parent.Subject.Value);
BeApproximately(nonNullableAssertions, expectedValue, precision, because, becauseArgs);
}
return new AndConstraint<NullableNumericAssertions<double>>(parent);
}

Another pattern we use around a dozen places is to have non-public methods having Assert or Validate in their names.

Combined with #2403 the four ones calling Implement(interfaceType, because, becauseArgs) could be named AssertSubjectImplements(interfaceType, because, becauseArgs)

@IT-VBFK

IT-VBFK commented Oct 24, 2023

Copy link
Copy Markdown
Contributor

...could be named AssertSubjectImplements(interfaceType, because, becauseArgs)

Is this a third proposal (for #2403)? :)

@dennisdoomen

Copy link
Copy Markdown
Member

@jnyrup jnyrup force-pushed the remove_extra_should branch from 27cef01 to dab1f3c Compare October 26, 2023 07:01
@jnyrup jnyrup merged commit 67fa570 into fluentassertions:develop Oct 26, 2023
@jnyrup jnyrup deleted the remove_extra_should branch October 26, 2023 07:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants