Skip to content

Commit 4248cf6

Browse files
committed
Added more unit tests for ValidateAllProperties fallback
1 parent fef65a5 commit 4248cf6

File tree

1 file changed

+94
-0
lines changed

1 file changed

+94
-0
lines changed

UnitTests/UnitTests.Shared/Mvvm/Test_ObservableValidator.cs

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.ComponentModel;
88
using System.ComponentModel.DataAnnotations;
99
using System.Linq;
10+
using System.Reflection;
1011
using System.Text.RegularExpressions;
1112
using Microsoft.Toolkit.Mvvm.ComponentModel;
1213
using Microsoft.VisualStudio.TestTools.UnitTesting;
@@ -335,6 +336,54 @@ public void Test_ObservableValidator_ValidateAllProperties()
335336
model.Age = -10;
336337

337338
model.ValidateAllProperties();
339+
340+
Assert.IsTrue(model.HasErrors);
341+
Assert.IsTrue(events.Count == 1);
342+
Assert.IsTrue(events.Any(e => e.PropertyName == nameof(Person.Age)));
343+
}
344+
345+
[TestCategory("Mvvm")]
346+
[TestMethod]
347+
public void Test_ObservableValidator_ValidateAllProperties_WithFallback()
348+
{
349+
var model = new PersonWithDeferredValidation();
350+
var events = new List<DataErrorsChangedEventArgs>();
351+
352+
MethodInfo[] staticMethods = typeof(ObservableValidator).GetMethods(BindingFlags.Static | BindingFlags.NonPublic);
353+
MethodInfo validationMethod = staticMethods.Single(static m => m.Name.Contains("GetValidationActionFallback"));
354+
Func<Type, Action<object>> validationFunc = (Func<Type, Action<object>>)validationMethod.CreateDelegate(typeof(Func<Type, Action<object>>));
355+
Action<object> validationAction = validationFunc(model.GetType());
356+
357+
model.ErrorsChanged += (s, e) => events.Add(e);
358+
359+
validationAction(model);
360+
361+
Assert.IsTrue(model.HasErrors);
362+
Assert.IsTrue(events.Count == 2);
363+
364+
// Note: we can't use an index here because the order used to return properties
365+
// from reflection APIs is an implementation detail and might change at any time.
366+
Assert.IsTrue(events.Any(e => e.PropertyName == nameof(Person.Name)));
367+
Assert.IsTrue(events.Any(e => e.PropertyName == nameof(Person.Age)));
368+
369+
events.Clear();
370+
371+
model.Name = "James";
372+
model.Age = 42;
373+
374+
validationAction(model);
375+
376+
Assert.IsFalse(model.HasErrors);
377+
Assert.IsTrue(events.Count == 2);
378+
Assert.IsTrue(events.Any(e => e.PropertyName == nameof(Person.Name)));
379+
Assert.IsTrue(events.Any(e => e.PropertyName == nameof(Person.Age)));
380+
381+
events.Clear();
382+
383+
model.Age = -10;
384+
385+
validationAction(model);
386+
338387
Assert.IsTrue(model.HasErrors);
339388
Assert.IsTrue(events.Count == 1);
340389
Assert.IsTrue(events.Any(e => e.PropertyName == nameof(Person.Age)));
@@ -414,6 +463,34 @@ public void Test_ObservableValidator_ValidationWithFormattedDisplayName()
414463
Assert.AreEqual(allErrors[1].ErrorMessage, $"SECOND: {nameof(ValidationWithDisplayName.AnotherRequiredField)}.");
415464
}
416465

466+
// See: https://github.com/CommunityToolkit/WindowsCommunityToolkit/issues/4272
467+
[TestCategory("Mvvm")]
468+
[TestMethod]
469+
[DataRow(typeof(MyBase))]
470+
[DataRow(typeof(MyDerived2))]
471+
public void Test_ObservableRecipient_ValidationOnNonValidatableProperties(Type type)
472+
{
473+
MyBase viewmodel = (MyBase)Activator.CreateInstance(type);
474+
475+
viewmodel.ValidateAll();
476+
}
477+
478+
// See: https://github.com/CommunityToolkit/WindowsCommunityToolkit/issues/4272
479+
[TestCategory("Mvvm")]
480+
[TestMethod]
481+
[DataRow(typeof(MyBase))]
482+
[DataRow(typeof(MyDerived2))]
483+
public void Test_ObservableRecipient_ValidationOnNonValidatableProperties_WithFallback(Type type)
484+
{
485+
MyBase viewmodel = (MyBase)Activator.CreateInstance(type);
486+
487+
MethodInfo[] staticMethods = typeof(ObservableValidator).GetMethods(BindingFlags.Static | BindingFlags.NonPublic);
488+
MethodInfo validationMethod = staticMethods.Single(static m => m.Name.Contains("GetValidationActionFallback"));
489+
Func<Type, Action<object>> validationFunc = (Func<Type, Action<object>>)validationMethod.CreateDelegate(typeof(Func<Type, Action<object>>));
490+
491+
validationFunc(viewmodel.GetType())(viewmodel);
492+
}
493+
417494
public class Person : ObservableValidator
418495
{
419496
private string name;
@@ -631,5 +708,22 @@ public string AnotherRequiredField
631708
set => SetProperty(ref this.anotherRequiredField, value, true);
632709
}
633710
}
711+
712+
public class MyBase : ObservableValidator
713+
{
714+
public int? MyDummyInt { get; set; } = 0;
715+
716+
public void ValidateAll()
717+
{
718+
ValidateAllProperties();
719+
}
720+
}
721+
722+
public class MyDerived2 : MyBase
723+
{
724+
public string Name { get; set; }
725+
726+
public int SomeRandomproperty { get; set; }
727+
}
634728
}
635729
}

0 commit comments

Comments
 (0)