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

BeEquivalentTo fails when comparing lists containing lists #965

Closed
michaelestermann opened this issue Nov 15, 2018 · 3 comments
Closed

BeEquivalentTo fails when comparing lists containing lists #965

michaelestermann opened this issue Nov 15, 2018 · 3 comments
Assignees
Labels

Comments

@michaelestermann
Copy link

Description

When we updated fluentassertions to the latest version 5.5.0, we encountered an issue with the BeEquivalentTo assertion.
When we compare a list of objects, which contains another list with the same items but different order, the test will fail, even though strict ordering is disabled.

Repro

To reproduce this issue, I've created a repro repo which can be found here:
https://github.com/michaelestermann/OrderingRepro

Expected behavior:

Expected behaviour would be, that the lists are the same, even though the order of the lists are not the same.

Actual behavior:

Since the update, the test fails, because of the of the mismatching ordering of the list

Versions

We use the latest FluentAssertions 5.5.0 along with .NET Core SDK 2.1.500

@dennisdoomen
Copy link
Member

Hmm, that is very weird. Comparisons of collections never take into account the order, expect for byte[].

@jnyrup
Copy link
Member

jnyrup commented Nov 15, 2018

Here's a minimal example:

[Fact]
public void ListInList_MustBeEquivalent()
{
    var items = new[]
    {
        new int[0],
        new int[] { 42 }
    };

    items.Should().BeEquivalentTo(
        new int[] { 42 },
        new int[0]
    );
}

It hits an Exception in GetBestResultSets() when calling set.Values.Min(r => r.Length), where set is an empty Dictionary.

Here's the stack when hitting that exception:

at FluentAssertions.Equivalency.AssertionResultSet.GetBestResultSets()
at FluentAssertions.Equivalency.AssertionResultSet.SelectClosestMatchFor(Object key)
at FluentAssertions.Equivalency.EnumerableEquivalencyValidator.LooselyMatchAgainst[T](IList`1 subjects, T expectation, Int32 expectationIndex)
at FluentAssertions.Equivalency.EnumerableEquivalencyValidator.AssertElementGraphEquivalencyWithLooseOrdering[T](Object[] subjects, T[] expectations)
at FluentAssertions.Equivalency.EnumerableEquivalencyValidator.AssertElementGraphEquivalency[T](Object[] subjects, T[] expectations)
at FluentAssertions.Equivalency.EnumerableEquivalencyValidator.Execute[T](Object[] subject, T[] expectation)
at lambda_method(Closure )
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Delegate.DynamicInvokeImpl(Object[] args)
at System.Delegate.DynamicInvoke(Object[] args)
at FluentAssertions.Equivalency.GenericEnumerableEquivalencyStep.Handle(IEquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config)
at FluentAssertions.Equivalency.EquivalencyValidator.AssertEqualityUsing(IEquivalencyValidationContext context)
at FluentAssertions.Equivalency.EnumerableEquivalencyValidator.TryToMatch[T](Object subject, T expectation, Int32 expectationIndex)
at FluentAssertions.Equivalency.EnumerableEquivalencyValidator.LooselyMatchAgainst[T](IList`1 subjects, T expectation, Int32 expectationIndex)
at FluentAssertions.Equivalency.EnumerableEquivalencyValidator.AssertElementGraphEquivalencyWithLooseOrdering[T](Object[] subjects, T[] expectations)
at FluentAssertions.Equivalency.EnumerableEquivalencyValidator.AssertElementGraphEquivalency[T](Object[] subjects, T[] expectations)
at FluentAssertions.Equivalency.EnumerableEquivalencyValidator.Execute[T](Object[] subject, T[] expectation)
at lambda_method(Closure )
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Delegate.DynamicInvokeImpl(Object[] args)
at System.Delegate.DynamicInvoke(Object[] args)
at FluentAssertions.Equivalency.GenericEnumerableEquivalencyStep.Handle(IEquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config)
at FluentAssertions.Equivalency.EquivalencyValidator.AssertEqualityUsing(IEquivalencyValidationContext context)
at FluentAssertions.Equivalency.EquivalencyValidator.AssertEquality(EquivalencyValidationContext context)
at FluentAssertions.Collections.CollectionAssertions`2.BeEquivalentTo[TExpectation](IEnumerable`1 expectation, Func`2 config, String because, Object[] becauseArgs)
at FluentAssertions.Collections.CollectionAssertions`2.BeEquivalentTo(Object[] expectations)
at ListInList_MustBeEquivalent()

I just checked #911 caused the change.
If I revert the addition of

.Then
.ClearExpectation();

to AssertCollectionsHaveSameCount it works again.

@dennisdoomen
Copy link
Member

Will be part of 5.5.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants