Skip to content

Extended BeEquivalentTo with support for checking the type of the properties#3066

Merged
dennisdoomen merged 1 commit intofluentassertions:mainfrom
dennisdoomen:feature/strict-typing
Jun 30, 2025
Merged

Extended BeEquivalentTo with support for checking the type of the properties#3066
dennisdoomen merged 1 commit intofluentassertions:mainfrom
dennisdoomen:feature/strict-typing

Conversation

@dennisdoomen
Copy link
Member

@dennisdoomen dennisdoomen commented Jun 27, 2025

By default, BeEquivalentTo will consider objects equivalent as long as their members match, regardless of whether the types are exactly the same. This means that objects of different types can be considered equivalent if they have the same structure and values.

However, sometimes you may want to ensure that not only the values match, but also the types are exactly the same. For such scenarios, you can use the strict typing options WithStrictTyping and WithStrictTypingFor.

Closes #798

  • Release notes
  • Documentation

@github-actions
Copy link

github-actions bot commented Jun 27, 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 feature/strict-typing branch 6 times, most recently from 39828ec to d51474e Compare June 28, 2025 12:28
@dennisdoomen dennisdoomen requested a review from Copilot June 28, 2025 12:28
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 extends the BeEquivalentTo API to support strict typing, ensuring that the types of properties are compared exactly between the subject and expectation.

  • Updated release notes documentation to include the new WithStrictTyping and WithStrictTypingFor options.
  • Added comprehensive tests for type equality, including new test cases in TypeEqualitySpecs.cs.
  • Implemented strict typing support across several modules (e.g., ITypingRule, AlwaysBeStrictTypingRule, PredicateBasedTypingRule, and TypeEquivalencyStep) and integrated them into the equivalency options.

Reviewed Changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated no comments.

Show a summary per file
File Description
docs/_pages/releases.md Release notes updated with new strict typing features.
Tests/FluentAssertions.Equivalency.Specs/TypeEqualitySpecs.cs New tests to validate strict typing behaviors in equivalency assertions.
Tests/Benchmarks/UsersOfGetClosedGenericInterfaces.cs Benchmark config updated to include TypingRules.
Tests/Approval.Tests/ApprovedApi/FluentAssertions/*.verified.txt Approval tests updated for new strict typing API members.
Src/FluentAssertions/Equivalency/Steps/TypeEquivalencyStep.cs New equivalency step implementation for enforcing strict typing.
Src/FluentAssertions/Equivalency/Typing/*.cs New strict typing rule implementations added and exposed in the API.
Src/FluentAssertions/Equivalency/SelfReferenceEquivalencyOptions.cs Integrated strict typing rules into equivalency options for global override.
Comments suppressed due to low confidence (1)

Src/FluentAssertions/Equivalency/IEquivalencyStep.cs:13

  • It appears that the documentation comment is truncated (''). Please update this comment to correctly reflect the intended message.
    /// have to be executed. Should return <see cref="EquivalencyResult.ContinueWithNext"/> otherwise. <see langword="tru"/>

@dennisdoomen dennisdoomen force-pushed the feature/strict-typing branch from d51474e to e14b254 Compare June 28, 2025 12:37
@dennisdoomen dennisdoomen marked this pull request as ready for review June 28, 2025 12:38
@coveralls
Copy link

coveralls commented Jun 28, 2025

Pull Request Test Coverage Report for Build 15982170862

Warning: This coverage report may be inaccurate.

This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.

Details

  • 37 of 38 (97.37%) changed or added relevant lines in 6 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage decreased (-0.02%) to 97.308%

Changes Missing Coverage Covered Lines Changed/Added Lines %
Src/FluentAssertions/Equivalency/Steps/TypeEquivalencyStep.cs 15 16 93.75%
Totals Coverage Status
Change from base Build 15980707080: -0.02%
Covered Lines: 12541
Relevant Lines: 12741

💛 - Coveralls

@dennisdoomen dennisdoomen force-pushed the feature/strict-typing branch from e14b254 to bab34e5 Compare June 28, 2025 12:41
@dennisdoomen dennisdoomen requested a review from jnyrup June 28, 2025 12:42
@dennisdoomen dennisdoomen force-pushed the feature/strict-typing branch from bab34e5 to db63a3f Compare June 29, 2025 06:24
@dennisdoomen dennisdoomen force-pushed the feature/strict-typing branch from db63a3f to 5ee62a4 Compare June 29, 2025 16:53
@dennisdoomen dennisdoomen requested a review from jnyrup June 29, 2025 16:55
@dennisdoomen dennisdoomen changed the title Extended BeEquivalentTo to support checking the type of the properties Extended BeEquivalentTo with support for checking the type of the properties Jun 29, 2025
@dennisdoomen dennisdoomen force-pushed the feature/strict-typing branch from 5ee62a4 to 86fb81c Compare June 30, 2025 19:41
@dennisdoomen dennisdoomen force-pushed the feature/strict-typing branch from 86fb81c to 58a0949 Compare June 30, 2025 19:43
@dennisdoomen dennisdoomen requested a review from jnyrup June 30, 2025 19:43
@dennisdoomen dennisdoomen merged commit 74f07de into fluentassertions:main Jun 30, 2025
6 checks passed
@dennisdoomen dennisdoomen deleted the feature/strict-typing branch June 30, 2025 19:52
ITHedgeHog pushed a commit to ITHedgeHog/IntervalGenerator that referenced this pull request Jan 27, 2026
Updated
[FluentAssertions](https://github.com/fluentassertions/fluentassertions)
from 8.0.0 to 8.8.0.

<details>
<summary>Release notes</summary>

_Sourced from [FluentAssertions's
releases](https://github.com/fluentassertions/fluentassertions/releases)._

## 8.8.0

<!-- Release notes generated using configuration in .github/release.yml
at main -->

## What's Changed
### New features
* Add support for MSTest4 by @​jnyrup in
fluentassertions/fluentassertions#3111
### Improvements
* Allow WithoutMessage when using Should().Throw() and ThrowAsync() by
@​dennisdoomen in
fluentassertions/fluentassertions#3100
* Improve reporting of the differences between long strings by
@​dennisdoomen in
fluentassertions/fluentassertions#3101
* Allow customizing the equivalency behavior for BeXmlSerializable by
@​logiclrd in
fluentassertions/fluentassertions#3107
### Documentation
* Add docs for `config` parameter by @​jnyrup in
fluentassertions/fluentassertions#3104
### Others
* Refreshed readme by @​dennisdoomen in
fluentassertions/fluentassertions#3106
* Merge hotfix 8.7.1 back to main by @​dennisdoomen in
fluentassertions/fluentassertions#3109
* Fix release notes by @​jnyrup in
fluentassertions/fluentassertions#3112
* Bump github/codeql-action from 3 to 4 by @​dependabot[bot] in
fluentassertions/fluentassertions#3113


**Full Changelog**:
fluentassertions/fluentassertions@8.7.1...8.8.0

## 8.7.1

<!-- Release notes generated using configuration in .github/release.yml
at hotfix/8.7.1 -->

## What's Changed
### Others
* JSON assertions did not properly handle floats, doubles and unsigned …
by @​dennisdoomen in
fluentassertions/fluentassertions#3105
* Fixed ambiguity when using Should on a JsonNode derived class ... by
@​JSkimming in
fluentassertions/fluentassertions#3102


**Full Changelog**:
fluentassertions/fluentassertions@8.7.0...8.7.1

## 8.7.0

<!-- Release notes generated using configuration in .github/release.yml
at ae620add07cf6666841e568fd3bf8a0733478bb5 -->

## What's Changed
### New features
* Added System.Text.Json assertion APIs and BeEquivalentTo support by
@​dennisdoomen in
fluentassertions/fluentassertions#3094
### Others
* Address a bunch of Qodana issues by @​dennisdoomen in
fluentassertions/fluentassertions#3082
* Bump actions/checkout from 4 to 5 by @​dependabot[bot] in
fluentassertions/fluentassertions#3085
* Bump JetBrains/qodana-action from 2025.1 to 2025.2 by
@​dependabot[bot] in
fluentassertions/fluentassertions#3086
* Bump actions/download-artifact from 4 to 5 by @​dependabot[bot] in
fluentassertions/fluentassertions#3087
* Bump cspell from 9.2.0 to 9.2.1 by @​dependabot[bot] in
fluentassertions/fluentassertions#3090
* Bump actions/setup-dotnet from 4 to 5 by @​dependabot[bot] in
fluentassertions/fluentassertions#3092
* Add lock file for nuget packages by @​jnyrup in
fluentassertions/fluentassertions#3084
* Set `DisableImplicitNuGetFallbackFolder` by @​jnyrup in
fluentassertions/fluentassertions#3095
* Bump Nugets by @​jnyrup in
fluentassertions/fluentassertions#3096
* Revert package locking by @​jnyrup in
fluentassertions/fluentassertions#3098
* Clean-up tests related to exceptions by @​dennisdoomen in
fluentassertions/fluentassertions#3099


**Full Changelog**:
fluentassertions/fluentassertions@8.6.0...8.7.0

## 8.6.0

<!-- Release notes generated using configuration in .github/release.yml
at main -->

## What's Changed
### Improvements
* Add support for inline assertions using `Value.ThatMatches` and
`Value.ThatSatisfies` by @​dennisdoomen in
fluentassertions/fluentassertions#3076
### Others
* Remove Microsoft.SourceLink.GitHub by @​SimonCropp in
fluentassertions/fluentassertions#3072
* Bump cspell from 9.1.3 to 9.1.5 by @​dependabot[bot] in
fluentassertions/fluentassertions#3073
* Added PackageGuard to the build pipeline by @​dennisdoomen in
fluentassertions/fluentassertions#3075
* Bump cspell from 9.1.5 to 9.2.0 by @​dependabot[bot] in
fluentassertions/fluentassertions#3077
* Remove dependencies on Bogus by @​jnyrup in
fluentassertions/fluentassertions#3080
* Update nuget packages by @​jnyrup in
fluentassertions/fluentassertions#3081
* Follow-up to #​3076 by @​jnyrup in
fluentassertions/fluentassertions#3079
* Documentation and typo fixes by @​jnyrup in
fluentassertions/fluentassertions#3078

## New Contributors
* @​SimonCropp made their first contribution in
fluentassertions/fluentassertions#3072

**Full Changelog**:
fluentassertions/fluentassertions@8.5.0...8.6.0

## 8.5.0

<!-- Release notes generated using configuration in .github/release.yml
at main -->

## What's Changed
### New features
* Extended BeEquivalentTo with support for checking the type of the
properties by @​dennisdoomen in
fluentassertions/fluentassertions#3066
### Fixes
* Ensured WithTracing is safe when used with BeEquivalentTo globally by
@​dennisdoomen in
fluentassertions/fluentassertions#3067
### Others
* Revisit the .editorconfig rules by @​dennisdoomen in
fluentassertions/fluentassertions#3063
* Bump cspell from 9.1.1 to 9.1.2 by @​dependabot[bot] in
fluentassertions/fluentassertions#3068
* Use .NET 9 SDK by @​jnyrup in
fluentassertions/fluentassertions#3069
* Bump cspell from 9.1.2 to 9.1.3 by @​dependabot[bot] in
fluentassertions/fluentassertions#3071


**Full Changelog**:
fluentassertions/fluentassertions@8.4.0...8.5.0

## 8.4.0

<!-- Release notes generated using configuration in .github/release.yml
at main -->

## What's Changed
### Improvements
* Allow excluding properties by name anywhere in the graph by
@​dennisdoomen in
fluentassertions/fluentassertions#3062
* Added Should().Throw(), ThrowAsync() and ThrowWithinAsync() flavors
that don’t require a specific exception type by @​Xceed-DelvaJB in
fluentassertions/fluentassertions#3059
### Others
* Bump cspell from 9.0.1 to 9.0.2 by @​dependabot in
fluentassertions/fluentassertions#3050
* Bump JetBrains/qodana-action from 2024.2 to 2025.1 by @​dependabot in
fluentassertions/fluentassertions#3044
* Fix qodana warnings by @​jnyrup in
fluentassertions/fluentassertions#3053
* Add contributor grant by @​dennisdoomen in
fluentassertions/fluentassertions#3055
* Bump cspell from 9.0.2 to 9.1.1 by @​dependabot in
fluentassertions/fluentassertions#3058

## New Contributors
* @​Xceed-DelvaJB made their first contribution in
fluentassertions/fluentassertions#3059

**Full Changelog**:
fluentassertions/fluentassertions@8.3.0...8.4.0

## 8.3.0

<!-- Release notes generated using configuration in .github/release.yml
at main -->

## What's Changed
### Improvements
* Improve rendering of exception messages when using WithMessage by
@​dennisdoomen in
fluentassertions/fluentassertions#3039
* Clarify the date/time type when comparing dates, times and
combinations of those by @​dennisdoomen in
fluentassertions/fluentassertions#3049
### Others
* Bump cspell from 8.17.5 to 8.18.1 by @​dependabot in
fluentassertions/fluentassertions#3041
* Bump cspell from 8.18.1 to 8.19.2 by @​dependabot in
fluentassertions/fluentassertions#3042
* Bump cspell from 8.19.2 to 8.19.3 by @​dependabot in
fluentassertions/fluentassertions#3043
* Bump cspell from 8.19.3 to 9.0.0 by @​dependabot in
fluentassertions/fluentassertions#3045
* Bump cspell from 9.0.0 to 9.0.1 by @​dependabot in
fluentassertions/fluentassertions#3046
* Fix links to test suites in bug report template by @​robvanuden in
fluentassertions/fluentassertions#3047


**Full Changelog**:
fluentassertions/fluentassertions@8.2.0...8.3.0

## 8.2.0

<!-- Release notes generated using configuration in .github/release.yml
at main -->

## What's Changed
### Improvements
* Optimize various string operations by @​jnyrup in
fluentassertions/fluentassertions#3037
* Reworked formatting and support multi-dimensional arrays. by
@​dennisdoomen in
fluentassertions/fluentassertions#3009
### Fixes
* Restore `StringSyntax` annotations by @​jnyrup in
fluentassertions/fluentassertions#3033
* Regex fixups by @​jnyrup in
fluentassertions/fluentassertions#3034
* Handle missing caller identifier by @​jnyrup in
fluentassertions/fluentassertions#3036
### Others
* Bump cspell from 8.17.3 to 8.17.5 by @​dependabot in
fluentassertions/fluentassertions#3035


**Full Changelog**:
fluentassertions/fluentassertions@8.1.1...8.2.0

## 8.1.1

<!-- Release notes generated using configuration in .github/release.yml
at main -->

## What's Changed
### Fixes
* Fix a formatting exception when {} is used as a dictionary key. by
@​dennisdoomen in
fluentassertions/fluentassertions#3029
* Removed the PS script that opens the FA website because it misbehaves.
by @​dennisdoomen in
fluentassertions/fluentassertions#3030


**Full Changelog**:
fluentassertions/fluentassertions@8.1.0...8.1.1

## 8.1.0

<!-- Release notes generated using configuration in .github/release.yml
at main -->

## What's Changed
### Improvements
* Add [NotNull] attribute on the Should() method for object assertions
by @​0xced in
fluentassertions/fluentassertions#2987
* Improves the subject identification for chained assertions and those
that use Which by @​dennisdoomen in
fluentassertions/fluentassertions#3000
### Fixes
* Fixed a regression in which CompleteWithinAsync treated a canceled
task as an exception by @​dennisdoomen in
fluentassertions/fluentassertions#2853
### Documentation
* Reconnected the new license to the history of the old license by
@​dennisdoomen in
fluentassertions/fluentassertions#2985
* Removed an incorrect date/time example from the docs by @​dennisdoomen
in fluentassertions/fluentassertions#2989
### Others
* Make sure developers don't accidentally update to v8 without
understanding the new license by @​dennisdoomen in
fluentassertions/fluentassertions#2988
* Bump Microsoft.Testing.Extensions.TrxReport from 1.5.1 to 1.5.3 by
@​dependabot in
fluentassertions/fluentassertions#2993
* Bump TUnit from 0.6.154 to 0.7.24 by @​dependabot in
fluentassertions/fluentassertions#2992
* Bump the mstest group with 2 updates by @​dependabot in
fluentassertions/fluentassertions#2991
* Backport updates to pipelines by @​jnyrup in
fluentassertions/fluentassertions#3001
* Bump cspell from 8.17.2 to 8.17.3 by @​dependabot in
fluentassertions/fluentassertions#3005
* Bump Roslynator.Analyzers from 4.12.10 to 4.12.11 by @​dependabot in
fluentassertions/fluentassertions#3004
* Bump TUnit from 0.7.24 to 0.10.6 by @​dependabot in
fluentassertions/fluentassertions#3002
* Upmerge from v7 by @​dennisdoomen in
fluentassertions/fluentassertions#3006
* Renamed CallerStatementBuilder to StatementParser by @​dennisdoomen in
fluentassertions/fluentassertions#3007
* Bump Meziantou.Analyzer and Microsoft.NETFramework.ReferenceAssemblies
by @​dependabot in
fluentassertions/fluentassertions#3014
* Bump Microsoft.NET.Test.Sdk,
Microsoft.NETFramework.ReferenceAssemblies and Newtonsoft.Json by
@​dependabot in
fluentassertions/fluentassertions#3013
* Bump Microsoft.NETFramework.ReferenceAssemblies and
Roslynator.Analyzers by @​dependabot in
fluentassertions/fluentassertions#3012
* Bump the xunit group with 3 updates by @​dependabot in
fluentassertions/fluentassertions#3010
* Adjust dependencies by @​jnyrup in
fluentassertions/fluentassertions#3015
* Bump NUnit3TestAdapter from 4.6.0 to 5.0.0 in the nunit group by
@​dependabot in
fluentassertions/fluentassertions#3011
* Fixed typo in introduction page by @​tealamore in
fluentassertions/fluentassertions#3019
* Bump Verify.Xunit from 28.10.1 to 28.11.0 in the xunit group by
@​dependabot in
fluentassertions/fluentassertions#3022
* Bump TUnit from 0.10.6 to 0.13.3 by @​dependabot in
fluentassertions/fluentassertions#3026
* Bump Microsoft.Testing.Extensions.CodeCoverage from 17.13.1 to 17.14.1
by @​dependabot in
fluentassertions/fluentassertions#3024
* Bump the mstest group with 2 updates by @​dependabot in
fluentassertions/fluentassertions#3023
* Bump Microsoft.NETFramework.ReferenceAssemblies,
System.Collections.Immutable and System.Reflection.Metadata by
@​dependabot in
fluentassertions/fluentassertions#3025
* Upmerge from v7 by @​jnyrup in
fluentassertions/fluentassertions#3028
* Fixed a regression in which CompleteWithinAsync treated a canceled ta…
by @​dennisdoomen in
fluentassertions/fluentassertions#3027

## New Contributors
* @​tealamore made their first contribution in
fluentassertions/fluentassertions#3019

**Full Changelog**:
fluentassertions/fluentassertions@8.0.1...8.1.0

## 8.0.1

<!-- Release notes generated using configuration in .github/release.yml
at main -->

## What's Changed
### Improvements
* Provide a toggle to suppress the soft warning about commercial use by
@​dennisdoomen in
fluentassertions/fluentassertions#2984

### Others
* Update docs to make license change more clear by @​jnyrup in
fluentassertions/fluentassertions#2953
* Bump all dependencies by @​dennisdoomen in
fluentassertions/fluentassertions#2962
* Bump System.Collections.Immutable and System.Reflection.Metadata by
@​dependabot in
fluentassertions/fluentassertions#2969
* Bump SharpCompress from 0.38.0 to 0.39.0 by @​dependabot in
fluentassertions/fluentassertions#2968
* Bump the nuke group with 2 updates by @​dependabot in
fluentassertions/fluentassertions#2967
* Bump Verify.Xunit from 28.8.1 to 28.9.0 in the xunit group by
@​dependabot in
fluentassertions/fluentassertions#2965
* Bump the mstest group with 2 updates by @​dependabot in
fluentassertions/fluentassertions#2966
* Bump cspell from 8.17.1 to 8.17.2 by @​dependabot in
fluentassertions/fluentassertions#2964
* Discard backported changes from 7 by @​dennisdoomen in
fluentassertions/fluentassertions#2974
* Various textual and styling fixes as well as some clarification of v7
and v8. by @​dennisdoomen in
fluentassertions/fluentassertions#2978
* Bump Xunit.StaFact from 1.1.11 to 1.2.69 in the xunit group by
@​dependabot in
fluentassertions/fluentassertions#2979
* Bump TUnit from 0.6.33 to 0.6.154 by @​dependabot in
fluentassertions/fluentassertions#2980
* Bump Reflectify from 1.4.0 to 1.5.0 by @​dependabot in
fluentassertions/fluentassertions#2981
* Bump System.Formats.Asn1 from 9.0.0 to 9.0.1 by @​dependabot in
fluentassertions/fluentassertions#2983
* Bump coverlet.collector from 6.0.3 to 6.0.4 by @​dependabot in
fluentassertions/fluentassertions#2982


**Full Changelog**:
fluentassertions/fluentassertions@8.0.0...8.0.1

Commits viewable in [compare
view](fluentassertions/fluentassertions@8.0.0...8.8.0).
</details>

[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=FluentAssertions&package-manager=nuget&previous-version=8.0.0&new-version=8.8.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This was referenced Jan 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add an option to BeEquivalentTo that compares types of objects recursively.

3 participants