Skip to content

Commit 3191845

Browse files
committed
Improve diagnostics, add unit tests
1 parent 171b89b commit 3191845

File tree

4 files changed

+73
-4
lines changed

4 files changed

+73
-4
lines changed

CommunityToolkit.Mvvm.SourceGenerators/AnalyzerReleases.Shipped.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,4 @@ MVVMTK0022 | CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator
3232
MVVMTK0023 | CommunityToolkit.Mvvm.SourceGenerators.ICommandGenerator | Error | See https://aka.ms/mvvmtoolkit/error
3333
MVVMTK0024 | CommunityToolkit.Mvvm.SourceGenerators.ICommandGenerator | Error | See https://aka.ms/mvvmtoolkit/error
3434
MVVMTK0025 | CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator | Error | See https://aka.ms/mvvmtoolkit/error
35+
MVVMTK0026 | CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator | Error | See https://aka.ms/mvvmtoolkit/error

CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservablePropertyGenerator.Execute.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ internal static class Execute
152152
}
153153
}
154154

155-
// Log the diagnostics if needed
155+
// Log the diagnostic for missing ObservableValidator, if needed
156156
if (hasAnyValidationAttributes &&
157157
!fieldSymbol.ContainingType.InheritsFromFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.ObservableValidator"))
158158
{
@@ -164,6 +164,16 @@ internal static class Execute
164164
forwardedAttributes.Count);
165165
}
166166

167+
// Log the diagnostic for missing validation attributes, if any
168+
if (alsoValidateProperty && !hasAnyValidationAttributes)
169+
{
170+
builder.Add(
171+
MissingValidationAttributesForAlsoValidatePropertyError,
172+
fieldSymbol,
173+
fieldSymbol.ContainingType,
174+
fieldSymbol.Name);
175+
}
176+
167177
diagnostics = builder.ToImmutable();
168178

169179
return new(

CommunityToolkit.Mvvm.SourceGenerators/Diagnostics/DiagnosticDescriptors.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,22 @@ internal static class DiagnosticDescriptors
409409
category: typeof(ObservablePropertyGenerator).FullName,
410410
defaultSeverity: DiagnosticSeverity.Error,
411411
isEnabledByDefault: true,
412-
description: "Cannot apply [AlsoValidateProperty] to field that are declared in a type that doesn't inherit from ObservableValidator.",
412+
description: "Cannot apply [AlsoValidateProperty] to fields that are declared in a type that doesn't inherit from ObservableValidator.",
413+
helpLinkUri: "https://aka.ms/mvvmtoolkit");
414+
415+
/// <summary>
416+
/// Gets a <see cref="DiagnosticDescriptor"/> indicating when the target field uses [AlsoValidateProperty] but has no validation attributes.
417+
/// <para>
418+
/// Format: <c>"The field {0}.{1} cannot be annotated with [AlsoValidateProperty], as it doesn't have any validation attributes to use during validation"</c>.
419+
/// </para>
420+
/// </summary>
421+
public static readonly DiagnosticDescriptor MissingValidationAttributesForAlsoValidatePropertyError = new DiagnosticDescriptor(
422+
id: "MVVMTK0026",
423+
title: "Missing validation attributes",
424+
messageFormat: "The field {0}.{1} cannot be annotated with [AlsoValidateProperty], as it doesn't have any validation attributes to use during validation",
425+
category: typeof(ObservablePropertyGenerator).FullName,
426+
defaultSeverity: DiagnosticSeverity.Error,
427+
isEnabledByDefault: true,
428+
description: "Cannot apply [AlsoValidateProperty] to fields that don't have any validation attributes to use during validation.",
413429
helpLinkUri: "https://aka.ms/mvvmtoolkit");
414430
}

tests/CommunityToolkit.Mvvm.SourceGenerators.UnitTests/Test_SourceGeneratorsDiagnostics.cs

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ public partial class SampleViewModel
192192
}
193193

194194
[TestMethod]
195-
public void MissingObservableValidatorInheritanceError()
195+
public void MissingObservableValidatorInheritanceForValidationAttributeError()
196196
{
197197
string source = @"
198198
using System.ComponentModel.DataAnnotations;
@@ -1188,6 +1188,48 @@ public partial class MyViewModel : ObservableObject
11881188
VerifyGeneratedDiagnostics<ObservablePropertyGenerator>(source, "MVVMTK0024");
11891189
}
11901190

1191+
[TestMethod]
1192+
public void MissingObservableValidatorInheritanceForAlsoValidatePropertyError()
1193+
{
1194+
string source = @"
1195+
using System.ComponentModel.DataAnnotations;
1196+
using CommunityToolkit.Mvvm.ComponentModel;
1197+
1198+
namespace MyApp
1199+
{
1200+
[INotifyPropertyChanged]
1201+
public partial class SampleViewModel
1202+
{
1203+
[ObservableProperty]
1204+
[Required]
1205+
[AlsoValidateProperty]
1206+
private string name;
1207+
}
1208+
}";
1209+
1210+
VerifyGeneratedDiagnostics<ObservablePropertyGenerator>(source, "MVVMTK0006", "MVVMTK0025");
1211+
}
1212+
1213+
[TestMethod]
1214+
public void MissingValidationAttributesForAlsoValidatePropertyError()
1215+
{
1216+
string source = @"
1217+
using System.ComponentModel.DataAnnotations;
1218+
using CommunityToolkit.Mvvm.ComponentModel;
1219+
1220+
namespace MyApp
1221+
{
1222+
public partial class SampleViewModel : ObservableValidator
1223+
{
1224+
[ObservableProperty]
1225+
[AlsoValidateProperty]
1226+
private string name;
1227+
}
1228+
}";
1229+
1230+
VerifyGeneratedDiagnostics<ObservablePropertyGenerator>(source, "MVVMTK0026");
1231+
}
1232+
11911233
/// <summary>
11921234
/// Verifies the output of a source generator.
11931235
/// </summary>
@@ -1232,7 +1274,7 @@ from assembly in AppDomain.CurrentDomain.GetAssemblies()
12321274

12331275
HashSet<string> resultingIds = diagnostics.Select(diagnostic => diagnostic.Id).ToHashSet();
12341276

1235-
Assert.IsTrue(resultingIds.SetEquals(diagnosticsIds));
1277+
CollectionAssert.AreEquivalent(diagnosticsIds, resultingIds.ToArray());
12361278

12371279
GC.KeepAlive(observableObjectType);
12381280
GC.KeepAlive(validationAttributeType);

0 commit comments

Comments
 (0)