diff --git a/Src/FluentAssertions/Common/MemberPath.cs b/Src/FluentAssertions/Common/MemberPath.cs
index f3618c91c8..c981d94194 100644
--- a/Src/FluentAssertions/Common/MemberPath.cs
+++ b/Src/FluentAssertions/Common/MemberPath.cs
@@ -11,9 +11,9 @@ namespace FluentAssertions.Common
///
internal class MemberPath
{
- private readonly string dottedPath;
- private readonly Type reflectedType;
- private readonly Type declaringType;
+ private string dottedPath;
+ private Type reflectedType;
+ private Type declaringType;
private string[] segments;
@@ -38,6 +38,10 @@ public MemberPath(string dottedPath)
this.dottedPath = dottedPath;
}
+ private MemberPath()
+ {
+ }
+
///
/// Gets a value indicating whether the current object represents a child member of the
/// or that it is the parent of that candidate.
@@ -96,6 +100,19 @@ public bool HasSameParentAs(MemberPath path)
///
public bool GetContainsSpecificCollectionIndex() => dottedPath.ContainsSpecificCollectionIndex();
+ ///
+ /// Returns a copy of the current object as if it represented an un-indexed item in a collection.
+ ///
+ public MemberPath WithCollectionAsRoot()
+ {
+ return new MemberPath
+ {
+ dottedPath = "[]." + dottedPath,
+ reflectedType = reflectedType,
+ declaringType = declaringType
+ };
+ }
+
private string[] Segments => segments ??= dottedPath.Split(new[] { '.', '[', ']' }, StringSplitOptions.RemoveEmptyEntries);
///
diff --git a/Src/FluentAssertions/Equivalency/Matching/MappedPathMatchingRule.cs b/Src/FluentAssertions/Equivalency/Matching/MappedPathMatchingRule.cs
index 305695558d..d710ac0e98 100644
--- a/Src/FluentAssertions/Equivalency/Matching/MappedPathMatchingRule.cs
+++ b/Src/FluentAssertions/Equivalency/Matching/MappedPathMatchingRule.cs
@@ -35,7 +35,13 @@ public MappedPathMatchingRule(string expectationMemberPath, string subjectMember
public IMember Match(IMember expectedMember, object subject, INode parent, IEquivalencyAssertionOptions options)
{
- if (expectationPath.IsEquivalentTo(expectedMember.PathAndName))
+ MemberPath path = expectationPath;
+ if (expectedMember.RootIsCollection)
+ {
+ path = path.WithCollectionAsRoot();
+ }
+
+ if (path.IsEquivalentTo(expectedMember.PathAndName))
{
var member = MemberFactory.Find(subject, subjectPath.MemberName, expectedMember.Type, parent);
if (member is null)
diff --git a/Tests/FluentAssertions.Equivalency.Specs/MemberMatchingSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/MemberMatchingSpecs.cs
index 2a813ea8ef..3f313839ef 100644
--- a/Tests/FluentAssertions.Equivalency.Specs/MemberMatchingSpecs.cs
+++ b/Tests/FluentAssertions.Equivalency.Specs/MemberMatchingSpecs.cs
@@ -475,6 +475,44 @@ public void Mapping_works_with_exclusion_of_missing_members()
);
}
+ [Fact]
+ public void Can_map_members_of_a_root_collection()
+ {
+ // Arrange
+ var entity = new Entity
+ {
+ EntityId = 1,
+ Name = "Test"
+ };
+
+ var dto = new EntityDto
+ {
+ Id = 1,
+ Name = "Test"
+ };
+
+ var entityCol = new[] { entity };
+ var dtoCol = new[] { dto };
+
+ // Act / Assert
+ dtoCol.Should().BeEquivalentTo(entityCol, c =>
+ c.WithMapping(s => s.EntityId, d => d.Id));
+ }
+
+ private class Entity
+ {
+ public int EntityId { get; init; }
+
+ public string Name { get; init; }
+ }
+
+ private class EntityDto
+ {
+ public int Id { get; init; }
+
+ public string Name { get; init; }
+ }
+
internal class ParentOfExpectationWithProperty2
{
public ExpectationWithProperty2[] Parent { get; }
diff --git a/docs/_pages/releases.md b/docs/_pages/releases.md
index c3f0021dcb..be536b9c60 100644
--- a/docs/_pages/releases.md
+++ b/docs/_pages/releases.md
@@ -18,6 +18,7 @@ sidebar:
* `EnumAssertions.Be` did not determine the caller name - [#1835](https://github.com/fluentassertions/fluentassertions/pull/1835)
* Ensure `ExcludingMissingMembers` doesn't undo usage of `WithMapping` in `BeEquivalentTo` - [#1838](https://github.com/fluentassertions/fluentassertions/pull/1838)
* Better handling of NaN in various numeric assertions - [#1822](https://github.com/fluentassertions/fluentassertions/pull/1822)
+* `WithMapping` in `BeEquivalentTo` now also works when the root is a collection - [#1858](https://github.com/fluentassertions/fluentassertions/pull/1858)
### Fixes (Extensibility)