Skip to content

Improve reporting the differences between differently sized collections in BeEquivalentTo#3133

Merged
dennisdoomen merged 1 commit intofluentassertions:mainfrom
dennisdoomen:fix-378
Feb 21, 2026
Merged

Improve reporting the differences between differently sized collections in BeEquivalentTo#3133
dennisdoomen merged 1 commit intofluentassertions:mainfrom
dennisdoomen:fix-378

Conversation

@dennisdoomen
Copy link
Copy Markdown
Member

@dennisdoomen dennisdoomen commented Dec 14, 2025

This commit significantly improves how FluentAssertions reports differences when comparing collections of different sizes using BeEquivalentTo.

Previously, the error messages would simply state that collections had different counts. Now, the messages explicitly identify which items are missing from the actual collection and which items are extraneous (unexpected). The commit refactors the collection comparison logic by extracting two strategies: one for strictly-ordered comparisons and another for loosely-ordered comparisons that uses permutation analysis to find the best matches between items.

Additionally, it introduces a new WithFullDump() option that includes the complete contents of the subject collection in failure messages, making it easier to diagnose complex comparison failures. The implementation adds helper classes to track indexed items and uses caching to avoid redundant comparisons during the matching process.

An example of what it can report now is

Expected property actual[0].Name to be "Dennis" with a length of 6, but "Jits" has a length of 4, differs near "Jit" (index 0).
Expected property actual[0].Age to be 52, but found 13.
Expected actual to contain exactly one item, but found one extraneous item FluentAssertions.Equivalency.Specs.Customer
{
    Age = 16,
    Birthdate = <0001-01-01 00:00:00.000>,
    Id = 0L,
    Name = "Teddie"
}

Full dump of actual: {
    FluentAssertions.Equivalency.Specs.Customer
    {
        Age = 13,
        Birthdate = <0001-01-01 00:00:00.000>,
        Id = 0L,
        Name = "Jits"
    },
    FluentAssertions.Equivalency.Specs.Customer
    {
        Age = 16,
        Birthdate = <0001-01-01 00:00:00.000>,
        Id = 0L,
        Name = "Teddie"
    }
}

With configuration:
- Prefer the declared type of the members
- Compare enums by value
- Compare tuples by their properties
- Compare anonymous types by their properties
- Compare records by their members
- Include non-browsable members
- Include all non-private properties
- Include all non-private fields
- Exclude member Id
- Match (JSON) member by name (or throw)
- Be strict about the order of items in byte arrays
- Without automatic conversion

#378

@github-actions
Copy link
Copy Markdown

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 [email protected]

@github-actions
Copy link
Copy Markdown

github-actions bot commented Jan 1, 2026

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 [email protected]

@dennisdoomen dennisdoomen force-pushed the fix-378 branch 13 times, most recently from be98b04 to 4faab61 Compare January 7, 2026 18:11
@dennisdoomen dennisdoomen force-pushed the fix-378 branch 14 times, most recently from bb5e10a to 367d811 Compare January 11, 2026 19:15
This was referenced Apr 1, 2026
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.

4 participants