Skip to content

Commit

Permalink
IgnoreCyclicReferences in BeEquivalentTo now works with ComparingByMe…
Browse files Browse the repository at this point in the history
…mbers (#1708)
  • Loading branch information
dennisdoomen committed Oct 17, 2021
1 parent 9190b26 commit b6bab8f
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ namespace FluentAssertions.Equivalency
/// </summary>
public class EquivalencyValidationContext : IEquivalencyValidationContext
{
private static readonly ComplexTypeMap TypeMap = new();
private Tracer tracer;

public EquivalencyValidationContext(INode root, IEquivalencyAssertionOptions options)
Expand Down Expand Up @@ -72,7 +71,8 @@ public IEquivalencyValidationContext Clone()

public bool IsCyclicReference(object expectation)
{
bool isComplexType = TypeMap.IsComplexType(expectation);
bool isComplexType = expectation is not null && Options.GetEqualityStrategy(expectation.GetType())
is EqualityStrategy.Members or EqualityStrategy.ForceMembers;

var reference = new ObjectReference(expectation, CurrentNode.PathAndName, isComplexType);
return CyclicReferenceDetector.IsCyclicReference(reference, Options.CyclicReferenceHandling, Reason);
Expand Down
30 changes: 0 additions & 30 deletions Src/FluentAssertions/Equivalency/Execution/ComplexTypeMap.cs

This file was deleted.

66 changes: 66 additions & 0 deletions Tests/FluentAssertions.Specs/Equivalency/BasicEquivalencySpecs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3756,6 +3756,72 @@ public void When_the_root_object_is_referenced_from_a_nested_object_it_should_tr
action.Should().NotThrow();
}

[Fact]
public void Allow_ignoring_cyclic_references_in_value_types_compared_by_members()
{
// Arrange
var expectation = new ValueTypeCircularDependency()
{
Title = "First"
};

var second = new ValueTypeCircularDependency()
{
Title = "Second",
Previous = expectation
};

expectation.Next = second;

var subject = new ValueTypeCircularDependency()
{
Title = "First"
};

var secondCopy = new ValueTypeCircularDependency()
{
Title = "SecondDifferent",
Previous = subject
};

subject.Next = secondCopy;

// Act
Action act = () => subject.Should()
.BeEquivalentTo(expectation, opt => opt
.ComparingByMembers<ValueTypeCircularDependency>()
.IgnoringCyclicReferences());

// Assert
act.Should().Throw<XunitException>()
.WithMessage("*subject.Next.Title*Second*SecondDifferent*")
.Which.Message.Should().NotContain("maximum recursion depth was reached");
}

public class ValueTypeCircularDependency
{
public string Title { get; set; }

public ValueTypeCircularDependency Previous { get; set; }

public ValueTypeCircularDependency Next { get; set; }

public override bool Equals(object obj)
{
if (ReferenceEquals(this, obj))
{
return true;
}

return (obj is ValueTypeCircularDependency baseObj) && baseObj.Title == Title;
}

public override int GetHashCode()
{
return Title.GetHashCode();
}
}

#endregion

#region Tuples
Expand Down
1 change: 1 addition & 0 deletions docs/_pages/releases.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ sidebar:
* `At` now retains the `DateTimeKind` and keeps sub-second precision when using a `TimeSpan` - [#1687](https://github.com/fluentassertions/fluentassertions/pull/1687).
* Removed iteration over enumerable when generating the `BeEmpty` assertion failure message - [#1692](https://github.com/fluentassertions/fluentassertions/pull/1692).
* Prevent `ArgumentNullException` when formatting a lambda expression containing an extension method - [#1696](https://github.com/fluentassertions/fluentassertions/pull/1696)
* `IgnoringCyclicReferences` in `BeEquivalentTo` now works while comparing value types using `ComparingByMembers` - [#1708](https://github.com/fluentassertions/fluentassertions/pull/1708)

## 6.1.0

Expand Down

0 comments on commit b6bab8f

Please sign in to comment.