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

Remove unecessary call to Subject.Should() #2402

Merged
merged 1 commit into from Oct 26, 2023

Conversation

jnyrup
Copy link
Member

@jnyrup jnyrup commented Oct 22, 2023

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
Copy link

github-actions bot commented Oct 22, 2023

Qodana for .NET

It seems all right 👌

No new problems were found according to the checks applied

💡 Qodana analysis was run in the pull request mode: only the changed files were checked

View the detailed Qodana report

To be able to view the detailed Qodana report, you can either:

  1. Register at Qodana Cloud and configure the action
  2. Use GitHub Code Scanning with Qodana
  3. Host Qodana report at GitHub Pages
  4. Inspect and use qodana.sarif.json (see the Qodana SARIF format for details)

To get *.log files or any other Qodana artifacts, run the action with upload-result option set to true,
so that the action will upload the files as the job artifacts:

      - name: 'Qodana Scan'
        uses: JetBrains/qodana-action@v2023.2.8
        with:
          upload-result: true
Contact Qodana team

Contact us at qodana-support@jetbrains.com

@coveralls
Copy link

coveralls commented Oct 22, 2023

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

@@ -1845,7 +1845,7 @@ public AndConstraint<TAssertions> NotBeEmpty(string because = "", params object[

using (var scope = new AssertionScope())
{
Subject.Should().BeEquivalentTo(unexpected, config);
BeEquivalentTo(unexpected, config);
Copy link
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
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
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
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
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

Copy link
Member

@dennisdoomen dennisdoomen left a comment

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
Copy link
Contributor

IT-VBFK commented Oct 23, 2023

@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
Copy link
Member Author

jnyrup commented Oct 23, 2023

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
Copy link
Contributor

IT-VBFK commented Oct 24, 2023

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

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

@dennisdoomen
Copy link
Member

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

Funny that this is exactly what I just suggested for #2403.

@jnyrup jnyrup merged commit 67fa570 into fluentassertions:develop Oct 26, 2023
5 checks passed
@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.

None yet

4 participants