DataAnnotationsValidationPluginTests.cs 4.4 KB

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