Skip to content

Commit 66ee923

Browse files
committed
Added UnmappedPropertiesAttribute to declare multiple unmapped properties at once.
1 parent 63f1f67 commit 66ee923

File tree

4 files changed

+91
-3
lines changed

4 files changed

+91
-3
lines changed

src/Analyzers/MappingAnalyzer.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ private void OnMethodDeclaration(SyntaxNodeAnalysisContext context)
5959
.Select(a => (string) a.ConstructorArguments[0].Value)
6060
.ToList();
6161

62+
excludedPropertyNames.AddRange(method.GetAttributes()
63+
.Where(a => a.AttributeClass.Name == "UnmappedPropertiesAttribute")
64+
.SelectMany(a => a.ConstructorArguments[0].Values.Select(v => (string) v.Value)));
65+
6266
var unmappedPropertyNames = mappingTargetProperties
6367
.Except(mappedProperties, new RootPropertyEqualityComparer())
6468
.Select(p => p.Name)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace ManualMappingGuard
5+
{
6+
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
7+
public class UnmappedPropertiesAttribute : Attribute
8+
{
9+
public IReadOnlyCollection<string> PropertyNames { get; }
10+
11+
public UnmappedPropertiesAttribute(params string[] propertyNames)
12+
{
13+
PropertyNames = propertyNames ?? throw new ArgumentNullException(nameof(propertyNames));
14+
}
15+
}
16+
}

src/Tests/Analyzers/MappingAnalyzerTests.cs

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ public Person Map()
138138
}
139139

140140
[Test]
141-
public async Task UnmappedProperty_Excluded_DoesNotReportMissingProperty()
141+
public async Task UnmappedProperty_ExcludedSingle_DoesNotReportMissingProperty()
142142
{
143143
var diagnostics = await Analyze(@"
144144
public class Person
@@ -157,7 +157,26 @@ public class Person
157157
}
158158

159159
[Test]
160-
public async Task UnmappedProperty_MultipleExcluded_DoesNotReportMissingProperties()
160+
public async Task UnmappedProperty_ExcludedMultiple_DoesNotReportMissingProperty()
161+
{
162+
var diagnostics = await Analyze(@"
163+
public class Person
164+
{
165+
public int Id { get; set; }
166+
public string FirstName { get; set; }
167+
public string LastName { get; set; }
168+
}
169+
170+
[MappingMethod]
171+
[UnmappedProperties(nameof(Person.Id))]
172+
public Person Map() => new Person { FirstName = ""Test"" };
173+
");
174+
175+
AssertUnmappedProperties(diagnostics, "LastName");
176+
}
177+
178+
[Test]
179+
public async Task UnmappedProperty_MultipleExcludedIndividually_DoesNotReportMissingProperties()
161180
{
162181
var diagnostics = await Analyze(@"
163182
public class Person
@@ -179,7 +198,28 @@ public class Person
179198
}
180199

181200
[Test]
182-
public async Task NonExistingExcludedProperty_DoesNotFail()
201+
public async Task UnmappedProperty_MultipleExcludedAtOnce_DoesNotReportMissingProperties()
202+
{
203+
var diagnostics = await Analyze(@"
204+
public class Person
205+
{
206+
public const string IdPropertyName = ""Id"";
207+
208+
public int Id { get; set; }
209+
public string FirstName { get; set; }
210+
public string LastName { get; set; }
211+
}
212+
213+
[MappingMethod]
214+
[UnmappedProperties(Person.IdPropertyName, ""LastName"")]
215+
public Person Map() => new Person { FirstName = ""Test"" };
216+
");
217+
218+
AssertNoUnmappedProperties(diagnostics);
219+
}
220+
221+
[Test]
222+
public async Task NonExistingExcludedProperty_Single_DoesNotFail()
183223
{
184224
var diagnostics = await Analyze(@"
185225
public class Person { }
@@ -192,6 +232,20 @@ public class Person { }
192232
Assert.That(diagnostics, Is.Empty);
193233
}
194234

235+
[Test]
236+
public async Task NonExistingExcludedProperty_Multiple_DoesNotFail()
237+
{
238+
var diagnostics = await Analyze(@"
239+
public class Person { }
240+
241+
[MappingMethod]
242+
[UnmappedProperties(""NotExisting1"", ""NonExisting2"")]
243+
public Person Map() => new Person();
244+
");
245+
246+
Assert.That(diagnostics, Is.Empty);
247+
}
248+
195249
private void AssertMissingMappingTargetType(ImmutableArray<Diagnostic> diagnostics)
196250
{
197251
var expectedMessages = new[]
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using NUnit.Framework;
2+
3+
namespace ManualMappingGuard.Core
4+
{
5+
[TestFixture]
6+
public class UnmappedPropertiesAttributeTests
7+
{
8+
[Test]
9+
public void NullPropertyNames_ThrowsException()
10+
{
11+
Assert.That(() => new UnmappedPropertiesAttribute((string[]) null!), Throws.ArgumentNullException);
12+
}
13+
}
14+
}

0 commit comments

Comments
 (0)