Skip to content

Commit

Permalink
remove obsolete attribute of MapProperty.ctor(string[], string[])
Browse files Browse the repository at this point in the history
  • Loading branch information
latonz committed Oct 14, 2024
1 parent 37ddff5 commit 042ca8d
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 11 deletions.
8 changes: 0 additions & 8 deletions docs/docs/breaking-changes/4-0.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ description: How to upgrade to Mapperly v4.0 and a list of all its breaking chan

## Migration guide from v3.6.0

- `MapPropertyAttribute.ctor(string[], string[])` is marked as obsolete, replace either with `MapPropertyAttribute.ctor(string[], string)` or `MapPropertyAttribute.ctor(string, string[])`.
- Strict mappings are enabled by default, either use `MapperAttribute.RequiredMappingStrategy`/`MapperRequiredMappingAttribute` or revert to non-strict mappings (see [strict mappings by default](#strict-mappings-by-default)).
- If the `ExplicitCast` conversion is disabled, disable the new `EnumUnderlyingType` conversion too.
- Members of foreach mappings are now mapped, which may result in additional members being mapped or new diagnostics being reported.
Expand All @@ -20,13 +19,6 @@ description: How to upgrade to Mapperly v4.0 and a list of all its breaking chan
- Well-known .NET immutable types are not copied, even if `UseDeepCloning` is enabled.
- For long property names, auto-flattening may not work anymore and may need to be configured manually by applying the `MapPropertyAttribute`.

## MapPropertyAttribute constructors

Since Mapperly does not support source nested member to target nested member mappings,
the constructor `MapPropertyAttribute.ctor(string[], string[])` is marked as obsolete
and will be removed in a future release.
Use `MapPropertyAttribute.ctor(string[], string)` or `MapPropertyAttribute.ctor(string, string[])` instead.

## Strict mappings by default

Starting with v4.0 Mapperly enables strict mappings by default with a severity of `Warning`.
Expand Down
1 change: 0 additions & 1 deletion src/Riok.Mapperly.Abstractions/MapPropertyAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ public MapPropertyAttribute(string source, string[] target)
/// </summary>
/// <param name="source">The path of the source property. The use of `nameof()` is encouraged.</param>
/// <param name="target">The path of the target property. The use of `nameof()` is encouraged.</param>
[Obsolete("Use MapPropertyAttribute(string[], string) or MapPropertyAttribute(string, string[]) instead.")]
public MapPropertyAttribute(string[] source, string[] target)
{
Source = source;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,6 @@ public sealed class MapPropertyAttribute : System.Attribute
public MapPropertyAttribute(string source, string target) { }
public MapPropertyAttribute(string[] source, string target) { }
public MapPropertyAttribute(string source, string[] target) { }
[System.Obsolete("Use MapPropertyAttribute(string[], string) or MapPropertyAttribute(string, string" +
"[]) instead.")]
public MapPropertyAttribute(string[] source, string[] target) { }
public string? FormatProvider { get; set; }
public System.Collections.Generic.IReadOnlyCollection<string> Source { get; }
Expand Down
94 changes: 94 additions & 0 deletions test/Riok.Mapperly.Tests/Mapping/ObjectPropertyNestedTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
using Riok.Mapperly.Diagnostics;

namespace Riok.Mapperly.Tests.Mapping;

public class ObjectPropertyNestedTest
{
[Fact]
public void ManualNestedToNestedProperty()
{
var source = TestSourceBuilder.MapperWithBodyAndTypes(
"""
[MapProperty(new [] {"Value", "IntValue"}, new [] {"Value", "StringValue"})]
public partial B Map(A source);
""",
"class A { public C Value { get; set; } }",
"class B { public D Value { get; set; } }",
"class C { public int IntValue { get; set; } }",
"class D { public string StringValue { get; set; } }"
);

TestHelper
.GenerateMapper(source)
.Should()
.HaveSingleMethodBody(
"""
var target = new global::B();
target.Value.StringValue = source.Value.IntValue.ToString();
return target;
"""
);
}

[Fact]
public void ManualNullableNestedToNullableNestedProperty()
{
var source = TestSourceBuilder.MapperWithBodyAndTypes(
"""
[MapProperty(new [] {"Value", "IntValue"}, new [] {"Value", "StringValue"})]
public partial B Map(A source);
""",
"class A { public C? Value { get; set; } }",
"class B { public D? Value { get; set; } }",
"class C { public int IntValue { get; set; } }",
"class D { public string StringValue { get; set; } }"
);

TestHelper
.GenerateMapper(source)
.Should()
.HaveSingleMethodBody(
"""
var target = new global::B();
if (source.Value != null)
{
target.Value ??= new global::D();
target.Value.StringValue = source.Value.IntValue.ToString();
}
return target;
"""
);
}

[Fact]
public void ManualNestedToInitOnlyNestedPropertyShouldDiagnostic()
{
var source = TestSourceBuilder.MapperWithBodyAndTypes(
"""
[MapProperty(new [] {"Value", "IntValue"}, new [] {"Value", "StringValue"})]
public partial B Map(A source);
""",
"class A { public C Value { get; set; } }",
"class B { public D Value { get; set; } }",
"class C { public int IntValue { get; init; } }",
"class D { public string StringValue { get; init; } }"
);

TestHelper
.GenerateMapper(source, TestHelperOptions.AllowDiagnostics)
.Should()
.HaveDiagnostic(
DiagnosticDescriptors.SourceMemberNotMapped,
"The member Value on the mapping source type A is not mapped to any member on the mapping target type B"
)
.HaveDiagnostic(
DiagnosticDescriptors.SourceMemberNotFound,
"The member Value on the mapping target type B was not found on the mapping source type A"
)
.HaveDiagnostic(
DiagnosticDescriptors.CannotMapToInitOnlyMemberPath,
"Cannot map from A.Value.IntValue to init only member path B.Value.StringValue"
)
.HaveAssertedAllDiagnostics();
}
}

0 comments on commit 042ca8d

Please sign in to comment.