-
-
Notifications
You must be signed in to change notification settings - Fork 155
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: clone array when deepcloning is enabled and target is an IEnumer…
…able If the source type is an array, the target type is an IEnumerable, the source should be cloned instead of casted This also extracts deep cloning enumerable tests into a separate test class.
- Loading branch information
Showing
3 changed files
with
199 additions
and
179 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
197 changes: 197 additions & 0 deletions
197
test/Riok.Mapperly.Tests/Mapping/EnumerableDeepCloningTest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,197 @@ | ||
namespace Riok.Mapperly.Tests.Mapping; | ||
|
||
public class EnumerableDeepCloningTest | ||
{ | ||
[Fact] | ||
public void ArrayOfPrimitivesToReadOnlyCollectionDeepCloning() | ||
{ | ||
var source = TestSourceBuilder.Mapping("int[]", "IReadOnlyCollection<int>", TestSourceBuilderOptions.WithDeepCloning); | ||
TestHelper | ||
.GenerateMapper(source) | ||
.Should() | ||
.HaveSingleMethodBody("return (global::System.Collections.Generic.IReadOnlyCollection<int>)source.Clone();"); | ||
} | ||
|
||
[Fact] | ||
public void ArrayOfPrimitivesToEnumerableDeepCloning() | ||
{ | ||
var source = TestSourceBuilder.Mapping("int[]", "IEnumerable<int>", TestSourceBuilderOptions.WithDeepCloning); | ||
TestHelper | ||
.GenerateMapper(source) | ||
.Should() | ||
.HaveSingleMethodBody("return (global::System.Collections.Generic.IEnumerable<int>)source.Clone();"); | ||
} | ||
|
||
[Fact] | ||
public void ArrayToArrayOfPrimitiveTypesDeepCloning() | ||
{ | ||
var source = TestSourceBuilder.Mapping("int[]", "int[]", TestSourceBuilderOptions.WithDeepCloning); | ||
TestHelper.GenerateMapper(source).Should().HaveSingleMethodBody("return (int[])source.Clone();"); | ||
} | ||
|
||
[Fact] | ||
public void ArrayOfNullablePrimitiveTypesToNonNullableArrayDeepCloning() | ||
{ | ||
var source = TestSourceBuilder.Mapping("int?[]", "int[]", TestSourceBuilderOptions.WithDeepCloning); | ||
TestHelper | ||
.GenerateMapper(source) | ||
.Should() | ||
.HaveSingleMethodBody( | ||
""" | ||
var target = new int[source.Length]; | ||
for (var i = 0; i < source.Length; i++) | ||
{ | ||
target[i] = source[i] == null ? throw new System.NullReferenceException($"Sequence {nameof(source)}, contained a null value at index {i}.") : source[i].Value; | ||
} | ||
return target; | ||
""" | ||
); | ||
} | ||
|
||
[Fact] | ||
public void ArrayOfPrimitiveTypesToNullablePrimitiveTypesArrayDeepCloning() | ||
{ | ||
var source = TestSourceBuilder.Mapping("int[]", "int?[]", TestSourceBuilderOptions.WithDeepCloning); | ||
TestHelper | ||
.GenerateMapper(source) | ||
.Should() | ||
.HaveSingleMethodBody( | ||
""" | ||
var target = new int? [source.Length]; | ||
for (var i = 0; i < source.Length; i++) | ||
{ | ||
target[i] = (int? )source[i]; | ||
} | ||
return target; | ||
""" | ||
); | ||
} | ||
|
||
[Fact] | ||
public void ArrayCustomClassToArrayCustomClassDeepCloning() | ||
{ | ||
var source = TestSourceBuilder.Mapping( | ||
"B[]", | ||
"B[]", | ||
TestSourceBuilderOptions.WithDeepCloning, | ||
"class B { public int Value { get; set; }}" | ||
); | ||
TestHelper | ||
.GenerateMapper(source) | ||
.Should() | ||
.HaveMapMethodBody( | ||
""" | ||
var target = new global::B[source.Length]; | ||
for (var i = 0; i < source.Length; i++) | ||
{ | ||
target[i] = MapToB(source[i]); | ||
} | ||
return target; | ||
""" | ||
); | ||
} | ||
|
||
[Fact] | ||
public void ArrayToArrayOfStringDeepCloning() | ||
{ | ||
var source = TestSourceBuilder.Mapping("string[]", "string[]", TestSourceBuilderOptions.WithDeepCloning); | ||
TestHelper.GenerateMapper(source).Should().HaveSingleMethodBody("return (string[])source.Clone();"); | ||
} | ||
|
||
[Fact] | ||
public void ArrayToArrayOfNullableStringDeepCloning() | ||
{ | ||
var source = TestSourceBuilder.Mapping("string[]", "string?[]", TestSourceBuilderOptions.WithDeepCloning); | ||
TestHelper.GenerateMapper(source).Should().HaveSingleMethodBody("return (string? [])source.Clone();"); | ||
} | ||
|
||
[Fact] | ||
public void ArrayToArrayOfReadOnlyStructDeepCloning() | ||
{ | ||
var source = TestSourceBuilder.Mapping("A[]", "A[]", TestSourceBuilderOptions.WithDeepCloning, "readonly struct A{}"); | ||
TestHelper.GenerateMapper(source).Should().HaveSingleMethodBody("return (global::A[])source.Clone();"); | ||
} | ||
|
||
[Fact] | ||
public void ArrayToArrayOfMutableStructDeepCloning() | ||
{ | ||
var source = TestSourceBuilder.Mapping( | ||
"A[]", | ||
"A[]", | ||
TestSourceBuilderOptions.WithDeepCloning, | ||
"struct A{ public string Value { get; set; } }" | ||
); | ||
TestHelper | ||
.GenerateMapper(source) | ||
.Should() | ||
.HaveMapMethodBody( | ||
""" | ||
var target = new global::A[source.Length]; | ||
for (var i = 0; i < source.Length; i++) | ||
{ | ||
target[i] = MapToA(source[i]); | ||
} | ||
return target; | ||
""" | ||
); | ||
} | ||
|
||
[Fact] | ||
public void ArrayToArrayOfUnmanagedStructDeepCloning() | ||
{ | ||
var source = TestSourceBuilder.Mapping("A[]", "A[]", TestSourceBuilderOptions.WithDeepCloning, "struct A{}"); | ||
TestHelper.GenerateMapper(source).Should().HaveMapMethodBody("return (global::A[])source.Clone();"); | ||
} | ||
|
||
[Fact] | ||
public void ArrayToArrayOfMutableStructDeepCloningLoopNameTaken() | ||
{ | ||
var source = TestSourceBuilder.MapperWithBodyAndTypes( | ||
"partial A[] Map(A[] i);", | ||
TestSourceBuilderOptions.WithDeepCloning, | ||
"struct A{ public string Value { get; set; } }" | ||
); | ||
TestHelper | ||
.GenerateMapper(source) | ||
.Should() | ||
.HaveMapMethodBody( | ||
""" | ||
var target = new global::A[i.Length]; | ||
for (var i1 = 0; i1 < i.Length; i1++) | ||
{ | ||
target[i1] = MapToA(i[i1]); | ||
} | ||
return target; | ||
""" | ||
); | ||
} | ||
|
||
[Fact] | ||
public void ArrayToArrayOfMutableStructDeepCloningTargetNameTaken() | ||
{ | ||
var source = TestSourceBuilder.MapperWithBodyAndTypes( | ||
"partial A[] Map(A[] target);", | ||
TestSourceBuilderOptions.WithDeepCloning, | ||
"struct A{ public string Value { get; set; } }" | ||
); | ||
TestHelper | ||
.GenerateMapper(source) | ||
.Should() | ||
.HaveMapMethodBody( | ||
""" | ||
var target1 = new global::A[target.Length]; | ||
for (var i = 0; i < target.Length; i++) | ||
{ | ||
target1[i] = MapToA(target[i]); | ||
} | ||
return target1; | ||
""" | ||
); | ||
} | ||
} |
Oops, something went wrong.