FFFF The expectation node identified as a cyclic reference is still compared to the subject node using simple equality. by dennisdoomen · Pull Request #2819 · fluentassertions/fluentassertions · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.507">
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.556">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand Down
19 changes: 18 additions & 1 deletion Src/FluentAssertions/Equivalency/EquivalencyValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ public void RecursivelyAssertEquality(Comparands comparands, IEquivalencyValidat
{
TrackWhatIsNeededToProvideContextToFailures(scope, comparands, context.CurrentNode);

if (!context.IsCyclicReference(comparands.Expectation))
if (context.IsCyclicReference(comparands.Expectation))
{
AssertComparandsPointToActualObjects(comparands);
}
else
{
TryToProveNodesAreEquivalent(comparands, context);
}
Expand All @@ -62,6 +66,19 @@ private static void TrackWhatIsNeededToProvideContextToFailures(AssertionScope s
scope.TrackComparands(comparands.Subject, comparands.Expectation);
}

private static void AssertComparandsPointToActualObjects(Comparands comparands)
{
if (ReferenceEquals(comparands.Subject, comparands.Expectation))
{
return;
}

if (comparands.Subject is null)
{
comparands.Subject.Should().BeSameAs(comparands.Expectation);
}
}

private void TryToProveNodesAreEquivalent(Comparands comparands, IEquivalencyValidationContext context)
{
using var _ = context.Tracer.WriteBlock(node => node.Description);
Expand Down
79 changes: 75 additions & 4 deletions Tests/FluentAssertions.Equivalency.Specs/CyclicReferencesSpecs.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using JetBrains.Annotations;
using Xunit;
using Xunit.Sdk;

Expand Down Expand Up @@ -68,6 +69,73 @@ public void By_default_cyclic_references_are_not_valid()
.WithMessage("Expected property cyclicRoot.Level.Root to be*but it contains a cyclic reference*");
}

[Fact]
public void The_cyclic_reference_itself_will_be_compared_using_simple_equality()
{
// Arrange
var expectedChild = new Child
{
Stuff = 1
};

var expectedParent = new Parent
{
Child1 = expectedChild
};

expectedChild.Parent = expectedParent;

var actualChild = new Child
{
Stuff = 1
};

var actualParent = new Parent
{
Child1 = actualChild
};

// Act
var act = () => actualParent.Should().BeEquivalentTo(expectedParent, options => options.IgnoringCyclicReferences());

// Assert
act.Should().Throw<XunitException>()
.WithMessage("Expected property actualParent.Child1.Parent to refer to*but found*null*");
}

[Fact]
public void The_cyclic_reference_can_be_ignored_if_the_comparands_point_to_the_same_object()
{
// Arrange
var expectedChild = new Child
{
Stuff = 1
};

var expectedParent = new Parent
{
Child1 = expectedChild
};

expectedChild.Parent = expectedParent;

var actualChild = new Child
{
Stuff = 1
};

var actualParent = new Parent
{
Child1 = actualChild
};

// Connect this child to the same parent as the expectation child
actualChild.Parent = expectedParent;

// Act
actualParent.Should().BeEquivalentTo(expectedParent, options => options.IgnoringCyclicReferences());
}

[Fact]
public void Two_graphs_with_ignored_cyclic_references_can_be_compared()
{
Expand All @@ -93,20 +161,23 @@ private class Parent
{
public Child Child1 { get; set; }

[UsedImplicitly]
public Child Child2 { get; set; }
}

private class Child
{
public Child(Parent parent, int stuff = 0)
public Child(Parent parent = null, int stuff = 0)
{
Parent = parent;
Stuff = stuff;
}

public Parent Parent { get; }
[UsedImplicitly]
public Parent Parent { get; set; }

public int Stuff { get; }
[UsedImplicitly]
public int Stuff { get; set; }
}

[Fact]
Expand Down Expand Up @@ -216,7 +287,7 @@ public void Can_ignore_cyclic_references_for_inequivalency_assertions()

// Act / Assert
recursiveClass1.Should().NotBeEquivalentTo(recursiveClass2,
options => options.AllowingInfiniteRecursion());
options => options.AllowingInfiniteRecursion());
}

[Fact]
Expand Down
6 changes: 6 additions & 0 deletions docs/_pages/releases.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ sidebar:
nav: "sidebar"
---

## 6.12.3

### Fixes

* The expectation node identified as a cyclic reference is still compared to the subject node using simple equality - [2819](https://github.com/fluentassertions/fluentassertions/pull/2819)

## 6.12.2

### Fixes
Expand Down
0