Skip to content

Commit

Permalink
SAVEPOINT
Browse files Browse the repository at this point in the history
  • Loading branch information
dennisdoomen committed Nov 28, 2024
1 parent 4647b6f commit bcdaff2
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 2 deletions.
2 changes: 1 addition & 1 deletion Src/FluentAssertions/Common/MemberPath.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ internal class MemberPath
private static readonly MemberPathSegmentEqualityComparer MemberPathSegmentEqualityComparer = new();

public MemberPath(IMember member, string parentPath)
: this(member.ReflectedType, member.DeclaringType, parentPath.Combine(member.Name))
: this(member.ReflectedType, member.DeclaringType, parentPath.Combine(member.OriginalName ?? member.Name))
{
}

Expand Down
1 change: 1 addition & 0 deletions Src/FluentAssertions/Equivalency/Field.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public Field(Type reflectedType, FieldInfo fieldInfo, INode parent)
DeclaringType = fieldInfo.DeclaringType;
ReflectedType = reflectedType;
Path = parent.PathAndName;
OriginalPath = parent.OriginalPathAndName;
GetSubjectId = parent.GetSubjectId;
Name = fieldInfo.Name;
Type = fieldInfo.FieldType;
Expand Down
20 changes: 20 additions & 0 deletions Src/FluentAssertions/Equivalency/INode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,24 @@ public interface INode
/// Gets a value indicating if the root of this graph is a collection.
/// </summary>
bool RootIsCollection { get; }

[CanBeNull]
string OriginalPath { get; set; }

/// <summary>
/// Gets the original name of this node before <see cref="Name"/> was updated, for example
/// when the expectation is mapped to a different member of the subject.
/// </summary>
[CanBeNull]
string OriginalName { get; set; }

/// <summary>
/// Gets the full path from the root object up to and including the name of the node as it was originally defined, for example
/// when the expectation is mapped to a different member of the subject.
/// </summary>
/// <example>
/// "Parent[0]"
/// </example>
[CanBeNull]
string OriginalPathAndName { get; }
}
19 changes: 19 additions & 0 deletions Src/FluentAssertions/Equivalency/Node.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ public static INode FromCollectionItem<T>(string index, INode parent)
ParentType = parent.Type,
Name = "[" + index + "]",
Path = parent.PathAndName,
OriginalPath = parent.OriginalPath,
GetSubjectId = parent.GetSubjectId,
RootIsCollection = parent.RootIsCollection
};
Expand All @@ -106,11 +107,29 @@ public static INode FromDictionaryItem<T>(object key, INode parent)
ParentType = parent.Type,
Name = "[" + key + "]",
Path = parent.PathAndName,
OriginalPath = parent.OriginalPath,
GetSubjectId = parent.GetSubjectId,
RootIsCollection = parent.RootIsCollection
};
}

public string OriginalPath { get; set; }

public string OriginalName { get; set; }

public string OriginalPathAndName
{
get
{
if (OriginalPath is not null || OriginalName is not null)
{
return (OriginalPath ?? string.Empty).Combine(OriginalName ?? Name);
}

return null;
}
}

public override bool Equals(object obj)
{
if (obj is null)
Expand Down
1 change: 1 addition & 0 deletions Src/FluentAssertions/Equivalency/Property.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public Property(Type reflectedType, PropertyInfo propertyInfo, INode parent)
Type = propertyInfo.PropertyType;
ParentType = propertyInfo.DeclaringType;
Path = parent.PathAndName;
OriginalPath = parent.OriginalPathAndName;
GetSubjectId = parent.GetSubjectId;
RootIsCollection = parent.RootIsCollection;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ private static void AssertMemberEquality(Comparands comparands, IEquivalencyVali
{
// In case the matching process selected a different member on the subject,
// adjust the current member so that assertion failures report the proper name.
selectedMember.OriginalName = selectedMember.Name;
selectedMember.Name = matchingMember.Name;
}

Expand Down
53 changes: 52 additions & 1 deletion Tests/FluentAssertions.Equivalency.Specs/MemberMatchingSpecs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ public void Nested_properties_can_be_mapped_using_a_nested_type_and_property_nam
public void Nested_explicitly_implemented_properties_can_be_mapped_using_a_nested_type_and_property_names()
{
// Arrange
var subject = new ParentOfSubjectWithExplicitlyImplementedProperty(new[] { new SubjectWithExplicitImplementedProperty() });
var subject =
new ParentOfSubjectWithExplicitlyImplementedProperty(new[] { new SubjectWithExplicitImplementedProperty() });

((IProperty)subject.Children[0]).Property = "Hello";

Expand Down Expand Up @@ -135,6 +136,56 @@ public void Nested_properties_can_be_mapped_using_a_nested_type_and_a_property_e
e => e.Property2, s => s.Property1));
}

private class Customer
{
public Residence Address { get; set; }

public class Residence
{
public string Address { get; set; }
}
}

private class CustomerDto
{
public ResidenceDto AddressInformation { get; set; }

public class ResidenceDto
{
public string Address { get; set; }

public bool IsValidated { get; set; }
}
}

[Fact]
public void CustomerDto_To_Customer_ShouldBeEquivalent()
{
//Arrange
var expectation = new CustomerDto
{
AddressInformation = new CustomerDto.ResidenceDto
{
Address = "123 Main St",
IsValidated = true,
},
};

//Act
var subject = new Customer
{
Address = new Customer.Residence
{
Address = "123 Main St",
},
};

//Assert
subject.Should().BeEquivalentTo(expectation, o => o
.Excluding(r => r.AddressInformation.IsValidated)
.WithMapping<CustomerDto, Customer>(s => s.AddressInformation, d => d.Address));
}

[Fact]
public void Nested_properties_on_a_collection_can_be_mapped_using_a_dotted_path()
{
Expand Down

0 comments on commit bcdaff2

Please sign in to comment.