Skip to content

Commit 9f198d6

Browse files
authored
Inline configured mapping plans (#33)
* Organising mapping plan tests * Support for inline configuration when creating an overwrite mapping plan * Support for inline configuration when creating an object creation mapping plan * Support for inline configuration of merge mapping plans * Test coverage for mapping plan caching with inline-configured member filters * Differentiating configured data sources by rule set / Support for inline-configured GetPlansFor plan creation * Adding SimpleMappingContext / Test coverage for mapping plan configuration errors
1 parent aff3ad0 commit 9f198d6

18 files changed

+629
-245
lines changed

AgileMapper.UnitTests/AgileMapper.UnitTests.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@
9898
<Compile Include="Configuration\Inline\WhenIgnoringMembersInline.cs" />
9999
<Compile Include="Configuration\Inline\WhenIgnoringMembersInlineIncorrectly.cs" />
100100
<Compile Include="Configuration\Inline\WhenMappingToNullInline.cs" />
101+
<Compile Include="Configuration\Inline\WhenViewingMappingPlans.cs" />
102+
<Compile Include="Configuration\WhenViewingMappingPlans.cs" />
101103
<Compile Include="Extensions\WhenEquatingExpressions.cs" />
102104
<Compile Include="MapperCloning\WhenCloningConstructorDataSources.cs" />
103105
<Compile Include="MapperCloning\WhenCloningMemberIgnores.cs" />
@@ -115,6 +117,7 @@
115117
<Compile Include="Dictionaries\Configuration\WhenConfiguringTargetDictionaryMapping.cs" />
116118
<Compile Include="Dictionaries\WhenCreatingRootDictionaryMembers.cs" />
117119
<Compile Include="MapperCloning\WhenCloningObjectFactories.cs" />
120+
<Compile Include="MappingExtensions.cs" />
118121
<Compile Include="SimpleTypeConversion\WhenConvertingToCharacters.cs" />
119122
<Compile Include="Structs\Configuration\WhenConfiguringStructCreationCallbacks.cs" />
120123
<Compile Include="Structs\Configuration\WhenConfiguringStructDataSources.cs" />
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
namespace AgileObjects.AgileMapper.UnitTests.Configuration.Inline
2+
{
3+
using AgileMapper.Configuration;
4+
using Shouldly;
5+
using TestClasses;
6+
using Xunit;
7+
8+
public class WhenViewingMappingPlans
9+
{
10+
[Fact]
11+
public void ShouldApplyAnExpressionConfiguredInline()
12+
{
13+
using (var mapper = Mapper.CreateNew())
14+
{
15+
string plan = mapper
16+
.GetPlanFor<Person>()
17+
.Over<PersonViewModel>(cfg => cfg
18+
.Map((p, pvm) => p.Title + " " + p.Name)
19+
.To(pvm => pvm.Name));
20+
21+
plan.ShouldContain("pToPvmData.Target.Name = sourcePerson.Title + \" \" + sourcePerson.Name");
22+
23+
var result = mapper
24+
.Map(new Person { Title = Title.Count, Name = "Dooko" })
25+
.Over(new PersonViewModel());
26+
27+
result.Name.ShouldBe("Count Dooko");
28+
}
29+
}
30+
31+
[Fact]
32+
public void ShouldApplyAnIgnoredMemberConfiguredInline()
33+
{
34+
using (var mapper = Mapper.CreateNew())
35+
{
36+
string plan = mapper
37+
.GetPlanFor<Person>()
38+
.ToANew<PersonViewModel>(cfg => cfg
39+
.Ignore(pvm => pvm.AddressLine1));
40+
41+
plan.ShouldContain("// AddressLine1 is ignored");
42+
43+
var result = mapper
44+
.Map(new Customer { Name = "Luke", Address = new Address { Line1 = "Far, Far Away" } })
45+
.ToANew<PersonViewModel>();
46+
47+
result.Name.ShouldBe("Luke");
48+
result.AddressLine1.ShouldBeNull();
49+
}
50+
}
51+
52+
[Fact]
53+
public void ShouldCombineApiAndInlineConfiguration()
54+
{
55+
using (var mapper = Mapper.CreateNew())
56+
{
57+
mapper.WhenMapping
58+
.From<Customer>()
59+
.OnTo<CustomerViewModel>()
60+
.Map((c, cvm) => c.Title + " " + c.Name)
61+
.To(cvm => cvm.Name);
62+
63+
string plan = mapper
64+
.GetPlanFor<Customer>()
65+
.OnTo<CustomerViewModel>(cfg => cfg
66+
.Ignore(cvm => cvm.AddressLine1));
67+
68+
plan.ShouldContain("cToCvmData.Target.Name = sourceCustomer.Title + \" \" + sourceCustomer.Name");
69+
plan.ShouldContain("// AddressLine1 is ignored");
70+
71+
var result = mapper
72+
.Map(new Customer
73+
{
74+
Title = Title.Dr,
75+
Name = "Vader",
76+
Address = new Address { Line1 = "Far, Far Away" }
77+
})
78+
.OnTo(new CustomerViewModel());
79+
80+
result.Name.ShouldBe("Dr Vader");
81+
result.AddressLine1.ShouldBeNull();
82+
}
83+
}
84+
85+
[Fact]
86+
public void ShouldApplyMemberFilterExpressionsConfiguredInline()
87+
{
88+
using (var mapper = Mapper.CreateNew())
89+
{
90+
string plan = mapper
91+
.GetPlanFor<Address>()
92+
.ToANew<Address>(cfg => cfg
93+
.IgnoreTargetMembersWhere(m => m.IsPropertyMatching(p => p.Name == "Line2")));
94+
95+
plan.ShouldContain("m.IsPropertyMatching(p => p.Name == \"Line2\")");
96+
97+
var result = mapper
98+
.Clone(new Customer { Address = new Address { Line1 = "1", Line2 = "2" } });
99+
100+
result.Address.ShouldNotBeNull();
101+
result.Address.Line1.ShouldBe("1");
102+
result.Address.Line2.ShouldBeNull();
103+
}
104+
}
105+
106+
[Fact]
107+
public void ShouldApplyInlinePlansConfigurationToAllRuleSets()
108+
{
109+
using (var mapper = Mapper.CreateNew())
110+
{
111+
string plan = mapper
112+
.GetPlansFor<Product>()
113+
.To<ProductDto>(cfg => cfg
114+
.Map((p, dto) => p.ProductId + " DTO")
115+
.To(dto => dto.ProductId));
116+
117+
plan.ShouldContain("ProductId + \" DTO\"");
118+
119+
var source = new Product { ProductId = "BOOM" };
120+
121+
var createResult = mapper.Map(source).ToANew<ProductDto>();
122+
var updateResult = mapper.Map(source).Over(new ProductDto { ProductId = "ID!" });
123+
var mergeResult = mapper.Map(source).OnTo(new ProductDto());
124+
125+
createResult.ProductId.ShouldBe("BOOM DTO");
126+
updateResult.ProductId.ShouldBe("BOOM DTO");
127+
mergeResult.ProductId.ShouldBe("BOOM DTO");
128+
}
129+
}
130+
131+
[Fact]
132+
public void ShouldErrorIfConflictingDataSourcesConfiguredInline()
133+
{
134+
using (var mapper = Mapper.CreateNew())
135+
{
136+
var configEx = Should.Throw<MappingConfigurationException>(() =>
137+
{
138+
mapper
139+
.GetPlansFor<Product>()
140+
.To<ProductDto>(cfg => cfg
141+
.Map((p, dto) => p.ProductId + " DTO")
142+
.To(dto => dto.ProductId)
143+
.And
144+
.Map((p, dto) => p.ProductId + " DTO!")
145+
.To(dto => dto.ProductId));
146+
});
147+
148+
configEx.Message.ShouldContain("already has a configured data source");
149+
}
150+
}
151+
152+
[Fact]
153+
public void ShouldErrorIfDuplicateIgnoredMembersConfiguredInline()
154+
{
155+
using (var mapper = Mapper.CreateNew())
156+
{
157+
var configEx = Should.Throw<MappingConfigurationException>(() =>
158+
{
159+
mapper.WhenMapping
160+
.From<Product>().To<ProductDto>()
161+
.Ignore(dto => dto.ProductId);
162+
163+
mapper
164+
.GetPlanFor<Product>()
165+
.ToANew<ProductDto>(cfg => cfg
166+
.Ignore(dto => dto.ProductId));
167+
});
168+
169+
configEx.Message.ShouldContain("has already been ignored");
170+
}
171+
}
172+
}
173+
}

AgileMapper.UnitTests/Configuration/WhenConfiguringDataSources.cs

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -874,11 +874,38 @@ public void ShouldRestrictConfigurationApplicationByMappingRuleSet()
874874

875875
var source = new PublicProperty<int> { Value = 64738 };
876876

877-
var toNewResult = mapper.Map(source).ToANew<PublicProperty<long>>();
878-
var overwriteResult = mapper.Map(source).Over(new PublicProperty<long>());
877+
var createResult = mapper.Map(source).ToANew<PublicProperty<long>>();
878+
var updateResult = mapper.Map(source).Over(new PublicProperty<long>());
879879

880-
toNewResult.Value.ShouldBe(9999);
881-
overwriteResult.Value.ShouldBe(source.Value);
880+
createResult.Value.ShouldBe(9999);
881+
updateResult.Value.ShouldBe(source.Value);
882+
}
883+
}
884+
885+
[Fact]
886+
public void ShouldDifferentiateConfigurationByMappingRuleSet()
887+
{
888+
using (var mapper = Mapper.CreateNew())
889+
{
890+
mapper.WhenMapping
891+
.From<PublicProperty<int>>()
892+
.ToANew<PublicProperty<long>>()
893+
.Map(999)
894+
.To(x => x.Value);
895+
896+
mapper.WhenMapping
897+
.From<PublicProperty<int>>()
898+
.Over<PublicProperty<long>>()
899+
.Map(999)
900+
.To(x => x.Value);
901+
902+
var source = new PublicProperty<int> { Value = 6478 };
903+
904+
var createResult = mapper.Map(source).ToANew<PublicProperty<long>>();
905+
var updateResult = mapper.Map(source).Over(new PublicProperty<long>());
906+
907+
createResult.Value.ShouldBe(999);
908+
updateResult.Value.ShouldBe(999);
882909
}
883910
}
884911

0 commit comments

Comments
 (0)