IndeiValidationPluginTests.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using Avalonia.Data;
  5. using Avalonia.Data.Core.Plugins;
  6. using Avalonia.Threading;
  7. using Xunit;
  8. namespace Avalonia.Base.UnitTests.Data.Core.Plugins
  9. {
  10. public class IndeiValidationPluginTests
  11. {
  12. [Fact]
  13. public void Produces_BindingNotifications()
  14. {
  15. var inpcAccessorPlugin = new InpcPropertyAccessorPlugin();
  16. var validatorPlugin = new IndeiValidationPlugin();
  17. var data = new Data { Maximum = 5 };
  18. var accessor = inpcAccessorPlugin.Start(new WeakReference<object>(data), nameof(data.Value));
  19. var validator = validatorPlugin.Start(new WeakReference<object>(data), nameof(data.Value), accessor);
  20. var result = new List<object>();
  21. validator.Subscribe(x => result.Add(x));
  22. validator.SetValue(5, BindingPriority.LocalValue);
  23. validator.SetValue(6, BindingPriority.LocalValue);
  24. data.Maximum = 10;
  25. data.Maximum = 5;
  26. Assert.Equal(new[]
  27. {
  28. new BindingNotification(0),
  29. new BindingNotification(5),
  30. // Value is first signalled without an error as validation hasn't been updated.
  31. new BindingNotification(6),
  32. // Then the ErrorsChanged event is fired.
  33. new BindingNotification(new DataValidationException("Must be less than Maximum"), BindingErrorType.DataValidationError, 6),
  34. // Maximum is changed to 10 so value is now valid.
  35. new BindingNotification(6),
  36. // And Maximum is changed back to 5.
  37. new BindingNotification(new DataValidationException("Must be less than Maximum"), BindingErrorType.DataValidationError, 6),
  38. }, result);
  39. }
  40. [Fact]
  41. public void Subscribes_And_Unsubscribes()
  42. {
  43. var inpcAccessorPlugin = new InpcPropertyAccessorPlugin();
  44. var validatorPlugin = new IndeiValidationPlugin();
  45. var data = new Data { Maximum = 5 };
  46. var accessor = inpcAccessorPlugin.Start(new WeakReference<object>(data), nameof(data.Value));
  47. var validator = validatorPlugin.Start(new WeakReference<object>(data), nameof(data.Value), accessor);
  48. Assert.Equal(0, data.ErrorsChangedSubscriptionCount);
  49. validator.Subscribe(_ => { });
  50. Assert.Equal(1, data.ErrorsChangedSubscriptionCount);
  51. validator.Unsubscribe();
  52. // Forces WeakEvent compact
  53. Dispatcher.UIThread.RunJobs();
  54. Assert.Equal(0, data.ErrorsChangedSubscriptionCount);
  55. }
  56. internal class Data : IndeiBase
  57. {
  58. private int _value;
  59. private int _maximum;
  60. private string _error;
  61. public override bool HasErrors => _error != null;
  62. public int Value
  63. {
  64. get { return _value; }
  65. set
  66. {
  67. _value = value;
  68. RaisePropertyChanged();
  69. UpdateError();
  70. }
  71. }
  72. public int Maximum
  73. {
  74. get { return _maximum; }
  75. set
  76. {
  77. _maximum = value;
  78. UpdateError();
  79. }
  80. }
  81. public override IEnumerable GetErrors(string propertyName)
  82. {
  83. if (propertyName == nameof(Value) && _error != null)
  84. {
  85. return new[] { _error };
  86. }
  87. return null;
  88. }
  89. private void UpdateError()
  90. {
  91. if (_value <= _maximum)
  92. {
  93. if (_error != null)
  94. {
  95. _error = null;
  96. RaiseErrorsChanged(nameof(Value));
  97. }
  98. }
  99. else
  100. {
  101. if (_error == null)
  102. {
  103. _error = "Must be less than Maximum";
  104. RaiseErrorsChanged(nameof(Value));
  105. }
  106. }
  107. }
  108. }
  109. }
  110. }