IndeiValidationPluginTests.cs 4.2 KB

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