DataAnnotationsValidationPluginTests.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel.DataAnnotations;
  4. using System.Linq;
  5. using Avalonia.Data;
  6. using Avalonia.Data.Core.Plugins;
  7. using Avalonia.UnitTests;
  8. using Xunit;
  9. namespace Avalonia.Base.UnitTests.Data.Core.Plugins
  10. {
  11. [InvariantCulture]
  12. public class DataAnnotationsValidationPluginTests
  13. {
  14. [Fact]
  15. public void Should_Match_Property_With_ValidatorAttribute()
  16. {
  17. var target = new DataAnnotationsValidationPlugin();
  18. var data = new Data();
  19. Assert.True(target.Match(new WeakReference<object>(data), nameof(Data.Between5And10)));
  20. }
  21. [Fact]
  22. public void Should_Match_Property_With_Multiple_ValidatorAttributes()
  23. {
  24. var target = new DataAnnotationsValidationPlugin();
  25. var data = new Data();
  26. Assert.True(target.Match(new WeakReference<object>(data), nameof(Data.PhoneNumber)));
  27. }
  28. [Fact]
  29. public void Should_Not_Match_Property_Without_ValidatorAttribute()
  30. {
  31. var target = new DataAnnotationsValidationPlugin();
  32. var data = new Data();
  33. Assert.False(target.Match(new WeakReference<object>(data), nameof(Data.Unvalidated)));
  34. }
  35. [Fact]
  36. public void Produces_Range_BindingNotificationsx()
  37. {
  38. var inpcAccessorPlugin = new InpcPropertyAccessorPlugin();
  39. var validatorPlugin = new DataAnnotationsValidationPlugin();
  40. var data = new Data();
  41. var accessor = inpcAccessorPlugin.Start(new WeakReference<object>(data), nameof(data.Between5And10));
  42. var validator = validatorPlugin.Start(new WeakReference<object>(data), nameof(data.Between5And10), accessor);
  43. var result = new List<object>();
  44. var errmsg = new RangeAttribute(5, 10).FormatErrorMessage(nameof(Data.Between5And10));
  45. validator.Subscribe(x => result.Add(x));
  46. validator.SetValue(3, BindingPriority.LocalValue);
  47. validator.SetValue(7, BindingPriority.LocalValue);
  48. validator.SetValue(11, BindingPriority.LocalValue);
  49. Assert.Equal(new[]
  50. {
  51. new BindingNotification(5),
  52. new BindingNotification(
  53. new DataValidationException(errmsg),
  54. BindingErrorType.DataValidationError,
  55. 3),
  56. new BindingNotification(7),
  57. new BindingNotification(
  58. new DataValidationException(errmsg),
  59. BindingErrorType.DataValidationError,
  60. 11),
  61. }, result);
  62. }
  63. [Fact]
  64. public void Produces_Aggregate_BindingNotificationsx()
  65. {
  66. var inpcAccessorPlugin = new InpcPropertyAccessorPlugin();
  67. var validatorPlugin = new DataAnnotationsValidationPlugin();
  68. var data = new Data();
  69. var accessor = inpcAccessorPlugin.Start(new WeakReference<object>(data), nameof(data.PhoneNumber));
  70. var validator = validatorPlugin.Start(new WeakReference<object>(data), nameof(data.PhoneNumber), accessor);
  71. var result = new List<object>();
  72. validator.Subscribe(x => result.Add(x));
  73. validator.SetValue("123456", BindingPriority.LocalValue);
  74. validator.SetValue("abcdefghijklm", BindingPriority.LocalValue);
  75. Assert.Equal(3, result.Count);
  76. Assert.Equal(new BindingNotification(null), result[0]);
  77. Assert.Equal(new BindingNotification("123456"), result[1]);
  78. var errorResult = (BindingNotification)result[2];
  79. Assert.Equal(BindingErrorType.DataValidationError, errorResult.ErrorType);
  80. Assert.Equal("abcdefghijklm", errorResult.Value);
  81. var exceptions = ((AggregateException)(errorResult.Error)).InnerExceptions;
  82. Assert.True(exceptions.Any(ex =>
  83. ex.Message.Contains("The PhoneNumber field is not a valid phone number.")));
  84. Assert.True(exceptions.Any(ex =>
  85. ex.Message.Contains("The field PhoneNumber must be a string or array type with a maximum length of '10'.")));
  86. }
  87. private class Data
  88. {
  89. [Range(5, 10)]
  90. public int Between5And10 { get; set; } = 5;
  91. public int Unvalidated { get; set; }
  92. [Phone]
  93. [MaxLength(10)]
  94. public string PhoneNumber { get; set; }
  95. }
  96. }
  97. }