From 8ec5a4aafb964de82cd23dbdd025c9cf2bff08ce Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 11 May 2023 13:38:52 +0200 Subject: [PATCH 1/2] Detect inherited properties in ObservableValidator generator --- ...ObservableValidatorValidateAllPropertiesGenerator.Execute.cs | 2 +- .../Messaging/IMessengerRegisterAllGenerator.Execute.cs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservableValidatorValidateAllPropertiesGenerator.Execute.cs b/src/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservableValidatorValidateAllPropertiesGenerator.Execute.cs index 3ff64228b..c8e097135 100644 --- a/src/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservableValidatorValidateAllPropertiesGenerator.Execute.cs +++ b/src/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservableValidatorValidateAllPropertiesGenerator.Execute.cs @@ -42,7 +42,7 @@ public static ValidationInfo GetInfo(INamedTypeSymbol typeSymbol) { using ImmutableArrayBuilder propertyNames = ImmutableArrayBuilder.Rent(); - foreach (ISymbol memberSymbol in typeSymbol.GetMembers()) + foreach (ISymbol memberSymbol in typeSymbol.GetAllMembers()) { if (memberSymbol is { IsStatic: true } or not (IPropertySymbol { IsIndexer: false } or IFieldSymbol)) { diff --git a/src/CommunityToolkit.Mvvm.SourceGenerators/Messaging/IMessengerRegisterAllGenerator.Execute.cs b/src/CommunityToolkit.Mvvm.SourceGenerators/Messaging/IMessengerRegisterAllGenerator.Execute.cs index 516a3bd2d..8b36b73af 100644 --- a/src/CommunityToolkit.Mvvm.SourceGenerators/Messaging/IMessengerRegisterAllGenerator.Execute.cs +++ b/src/CommunityToolkit.Mvvm.SourceGenerators/Messaging/IMessengerRegisterAllGenerator.Execute.cs @@ -4,7 +4,6 @@ using System.Collections.Immutable; using System.Linq; -using CommunityToolkit.Mvvm.SourceGenerators.ComponentModel.Models; using CommunityToolkit.Mvvm.SourceGenerators.Extensions; using CommunityToolkit.Mvvm.SourceGenerators.Helpers; using CommunityToolkit.Mvvm.SourceGenerators.Messaging.Models; From a7c198acabb15134b118ed350d3c87a10bfdcb36 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 11 May 2023 14:10:48 +0200 Subject: [PATCH 2/2] Add unit test for validating inherited properties --- .../Test_ObservableValidator.cs | 61 ++++++++++++++++++- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/tests/CommunityToolkit.Mvvm.UnitTests/Test_ObservableValidator.cs b/tests/CommunityToolkit.Mvvm.UnitTests/Test_ObservableValidator.cs index b686d2192..af4b9f4be 100644 --- a/tests/CommunityToolkit.Mvvm.UnitTests/Test_ObservableValidator.cs +++ b/tests/CommunityToolkit.Mvvm.UnitTests/Test_ObservableValidator.cs @@ -491,7 +491,7 @@ public void Test_ObservableRecipient_ValidationOnNonValidatableProperties(Type t { ObservableValidatorBase viewmodel = (ObservableValidatorBase)Activator.CreateInstance(type)!; - viewmodel.ValidateAll(); + viewmodel.ValidateAllProperties(); } // See: https://github.com/CommunityToolkit/WindowsCommunityToolkit/issues/4272 @@ -565,6 +565,50 @@ public void Test_ObservableValidator_WithGenericTypeParameters() Assert.IsFalse(model.HasErrors); } + // See https://github.com/CommunityToolkit/dotnet/issues/691 + [TestMethod] + public void Test_ObservableValidator_ValidateAllProperties_IncludeInheritedProperties() + { + DerivedModelWithValidatableProperties model = new(); + List events = new(); + + model.ErrorsChanged += (s, e) => events.Add(e); + + model.ValidateAllProperties(); + + Assert.IsTrue(model.HasErrors); + Assert.IsTrue(events.Count == 2); + + Assert.IsTrue(events.Any(e => e.PropertyName == nameof(DerivedModelWithValidatableProperties.Name))); + Assert.IsTrue(events.Any(e => e.PropertyName == nameof(DerivedModelWithValidatableProperties.Number))); + + events.Clear(); + + model.Number = 42; + + model.ValidateAllProperties(); + + Assert.IsTrue(model.HasErrors); + Assert.IsTrue(events.Count == 2); + + Assert.IsTrue(events.Any(e => e.PropertyName == nameof(DerivedModelWithValidatableProperties.Name))); + Assert.IsTrue(events.Any(e => e.PropertyName == nameof(DerivedModelWithValidatableProperties.Number))); + + Assert.AreEqual(1, model.GetErrors(nameof(DerivedModelWithValidatableProperties.Name)).Count()); + Assert.AreEqual(0, model.GetErrors(nameof(DerivedModelWithValidatableProperties.Number)).Count()); + + events.Clear(); + + model.Name = "Bob"; + model.Number = 80; + + model.ValidateAllProperties(); + + Assert.IsFalse(model.HasErrors); + Assert.IsTrue(events.Count == 1); + + Assert.IsTrue(events.Any(e => e.PropertyName == nameof(DerivedModelWithValidatableProperties.Name))); } + public class Person : ObservableValidator { private string? name; @@ -786,9 +830,9 @@ public class ObservableValidatorBase : ObservableValidator { public int? MyDummyInt { get; set; } = 0; - public void ValidateAll() + public new void ValidateAllProperties() { - ValidateAllProperties(); + base.ValidateAllProperties(); } } @@ -824,6 +868,17 @@ public abstract class AbstractModelWithValidatableProperty : ObservableValidator public string? Name { get; set; } } + public class DerivedModelWithValidatableProperties : AbstractModelWithValidatableProperty + { + [Range(10, 1000)] + public int Number { get; set; } + + public new void ValidateAllProperties() + { + base.ValidateAllProperties(); + } + } + public class GenericPerson : ObservableValidator { [Required]