Skip to content

Conversation

@dennisdoomen
Copy link
Member

Closes #3070

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

CONTRIBUTOR LICENSE GRANT

By submitting this contribution, the contributor hereby irrevocably grants to the project owners and maintainers a perpetual, worldwide, royalty-free, irrevocable license to use, reproduce, modify, distribute, sublicense, and create derivative works of the contribution for any purpose and under any terms, including proprietary licensing.

The contributor waives any moral rights in the contribution to the extent permitted by law and agrees not to assert any claim of authorship or control over the contribution. The contributor represents that they are the sole author of the contribution and that it is provided free of any third-party claims.

The contributor understands and agrees that the maintainers may, at their sole discretion, use, license, or redistribute the contribution as part of any work and under any terms they choose, without further permission or attribution.

  • I have read the Contributor License Grant and accept the conditions
  • I'm interested in a free license for Fluent Assertions and will share my email address through sales@xceed.com

@github-actions
Copy link

github-actions bot commented Jul 31, 2025

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

Contact Qodana team

Contact us at qodana-support@jetbrains.com

@dennisdoomen dennisdoomen force-pushed the inline-assertions branch 2 times, most recently from 4752b7b to 3518996 Compare August 1, 2025 20:03
@dennisdoomen dennisdoomen requested a review from Copilot August 1, 2025 20:05
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR introduces support for inline assertions in equivalency comparisons through two new methods: Value.ThatMatches for condition-based assertions and Value.ThatSatisfies for action-based assertions.

  • Adds Value.ThatMatches<T>() to check conditions inline during equivalency comparisons
  • Adds Value.ThatSatisfies<T>() to run assertion actions inline during equivalency comparisons
  • Implements a new equivalency step to handle inline assertions in the comparison pipeline

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
Tests/FluentAssertions.Equivalency.Specs/InlineAssertionsSpecs.cs Comprehensive test coverage for both ThatMatches and ThatSatisfies functionality
Src/FluentAssertions/Value.cs Public API entry point providing the ThatMatches and ThatSatisfies static methods
Src/FluentAssertions/Equivalency/Inlining/InlineEquivalencyStep.cs Equivalency step that handles inline assertions during comparisons
Src/FluentAssertions/Equivalency/Inlining/IInlineEquivalencyAssertion.cs Interface defining the contract for inline assertions
Src/FluentAssertions/Equivalency/Inlining/ConditionBasedInlineAssertion.cs Implementation for condition-based inline assertions (ThatMatches)
Src/FluentAssertions/Equivalency/Inlining/ActionBasedInlineAssertion.cs Implementation for action-based inline assertions (ThatSatisfies)
Src/FluentAssertions/Equivalency/EquivalencyPlan.cs Integration of the new inline equivalency step into the comparison pipeline

@dennisdoomen dennisdoomen force-pushed the inline-assertions branch 2 times, most recently from e6e0dc2 to 50b3fb8 Compare August 2, 2025 13:35
@dennisdoomen dennisdoomen added this to the 8.6 milestone Aug 2, 2025
@coveralls
Copy link

coveralls commented Aug 2, 2025

Pull Request Test Coverage Report for Build 16694245755

Details

  • 27 of 27 (100.0%) changed or added relevant lines in 5 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage decreased (-0.006%) to 97.292%

Totals Coverage Status
Change from base Build 16440491610: -0.006%
Covered Lines: 12573
Relevant Lines: 12775

💛 - Coveralls

@dennisdoomen dennisdoomen enabled auto-merge (rebase) August 2, 2025 13:57
@dennisdoomen dennisdoomen disabled auto-merge August 2, 2025 14:01
@dennisdoomen dennisdoomen merged commit 56fa7c8 into fluentassertions:main Aug 2, 2025
8 checks passed
@dennisdoomen dennisdoomen deleted the inline-assertions branch August 2, 2025 14:02
Copy link
Member

@jnyrup jnyrup left a comment

Choose a reason for hiding this comment

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

Great feature!

Comment on lines +18 to +21
if (condition is null)
{
throw new ArgumentNullException(nameof(condition), "A boolean condition is required");
}
Copy link
Member

@jnyrup jnyrup Aug 9, 2025

Choose a reason for hiding this comment

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

Not sure why we evaluate this here instead of in Value.ThatMatches using Guard.ThrowIfArgumentIsNull? 🤔

Included in draft-PR #3079

.ForCondition(comparands.Subject is T)
.FailWith("Expected {context:subject} to be of type {0}, but found {1}.", typeof(T), comparands.Subject?.GetType())
.Then
.ForCondition(condition.Compile()((T)comparands.Subject))
Copy link
Member

@jnyrup jnyrup Aug 9, 2025

Choose a reason for hiding this comment

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

If the call to BeEquivalentTo is inside an AssertionScope, we don't stop evaluating and get an InvalidCastException.

Can be observed adding using var _ = new AssertionScope(); to The_type_of_the_condition_must_be_met_too and running it in debug mode.

Included in draft-PR #3079

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[API Proposal]: Inline custom assertions when using BeEquivalentTo

3 participants