IndeiValidationPluginTests.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. // Copyright (c) The Avalonia Project. All rights reserved.
  2. // Licensed under the MIT license. See licence.md file in the project root for full license information.
  3. using System;
  4. using System.Collections;
  5. using System.Collections.Generic;
  6. using System.Reactive.Linq;
  7. using Avalonia.Data;
  8. using Avalonia.Data.Core.Plugins;
  9. using Xunit;
  10. namespace Avalonia.Base.UnitTests.Data.Core.Plugins
  11. {
  12. public class IndeiValidationPluginTests
  13. {
  14. [Fact]
  15. public void Produces_BindingNotifications()
  16. {
  17. var inpcAccessorPlugin = new InpcPropertyAccessorPlugin();
  18. var validatorPlugin = new IndeiValidationPlugin();
  19. var data = new Data { Maximum = 5 };
  20. var accessor = inpcAccessorPlugin.Start(new WeakReference(data), nameof(data.Value));
  21. var validator = validatorPlugin.Start(new WeakReference(data), nameof(data.Value), accessor);
  22. var result = new List<object>();
  23. validator.Subscribe(x => result.Add(x));
  24. validator.SetValue(5, BindingPriority.LocalValue);
  25. validator.SetValue(6, BindingPriority.LocalValue);
  26. data.Maximum = 10;
  27. data.Maximum = 5;
  28. Assert.Equal(new[]
  29. {
  30. new BindingNotification(0),
  31. new BindingNotification(5),
  32. // Value is first signalled without an error as validation hasn't been updated.
  33. new BindingNotification(6),
  34. // Then the ErrorsChanged event is fired.
  35. new BindingNotification(new Exception("Must be less than Maximum"), BindingErrorType.DataValidationError, 6),
  36. // Maximum is changed to 10 so value is now valid.
  37. new BindingNotification(6),
  38. // And Maximum is changed back to 5.
  39. new BindingNotification(new Exception("Must be less than Maximum"), BindingErrorType.DataValidationError, 6),
  40. }, result);
  41. }
  42. [Fact]
  43. public void Subscribes_And_Unsubscribes()
  44. {
  45. var inpcAccessorPlugin = new InpcPropertyAccessorPlugin();
  46. var validatorPlugin = new IndeiValidationPlugin();
  47. var data = new Data { Maximum = 5 };
  48. var accessor = inpcAccessorPlugin.Start(new WeakReference(data), nameof(data.Value));
  49. var validator = validatorPlugin.Start(new WeakReference(data), nameof(data.Value), accessor);
  50. Assert.Equal(0, data.ErrorsChangedSubscriptionCount);
  51. var sub = validator.Subscribe(_ => { });
  52. Assert.Equal(1, data.ErrorsChangedSubscriptionCount);
  53. sub.Dispose();
  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. }