TextBoxTests_DataValidation.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  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.ComponentModel;
  7. using System.Linq;
  8. using Avalonia.Controls.Presenters;
  9. using Avalonia.Controls.Templates;
  10. using Avalonia.Data;
  11. using Avalonia.Markup.Xaml.Data;
  12. using Avalonia.Platform;
  13. using Avalonia.UnitTests;
  14. using Moq;
  15. using Xunit;
  16. namespace Avalonia.Controls.UnitTests
  17. {
  18. public class TextBoxTests_DataValidation
  19. {
  20. [Fact]
  21. public void Setter_Exceptions_Should_Set_Error_Pseudoclass()
  22. {
  23. using (UnitTestApplication.Start(Services))
  24. {
  25. var target = new TextBox
  26. {
  27. DataContext = new ExceptionTest(),
  28. [!TextBox.TextProperty] = new Binding(nameof(ExceptionTest.LessThan10), BindingMode.TwoWay),
  29. Template = CreateTemplate(),
  30. };
  31. target.ApplyTemplate();
  32. Assert.False(target.Classes.Contains(":error"));
  33. target.Text = "20";
  34. Assert.True(target.Classes.Contains(":error"));
  35. target.Text = "1";
  36. Assert.False(target.Classes.Contains(":error"));
  37. }
  38. }
  39. [Fact]
  40. public void Setter_Exceptions_Should_Set_DataValidationErrors()
  41. {
  42. using (UnitTestApplication.Start(Services))
  43. {
  44. var target = new TextBox
  45. {
  46. DataContext = new ExceptionTest(),
  47. [!TextBox.TextProperty] = new Binding(nameof(ExceptionTest.LessThan10), BindingMode.TwoWay),
  48. Template = CreateTemplate(),
  49. };
  50. target.ApplyTemplate();
  51. Assert.Null(target.DataValidationErrors);
  52. target.Text = "20";
  53. Assert.Equal(1, target.DataValidationErrors.Count());
  54. Assert.IsType<InvalidOperationException>(target.DataValidationErrors.Single());
  55. target.Text = "1";
  56. Assert.Null(target.DataValidationErrors);
  57. }
  58. }
  59. private static TestServices Services => TestServices.MockThreadingInterface.With(
  60. standardCursorFactory: Mock.Of<IStandardCursorFactory>());
  61. private IControlTemplate CreateTemplate()
  62. {
  63. return new FuncControlTemplate<TextBox>(control =>
  64. new TextPresenter
  65. {
  66. Name = "PART_TextPresenter",
  67. [!!TextPresenter.TextProperty] = new Binding
  68. {
  69. Path = "Text",
  70. Mode = BindingMode.TwoWay,
  71. Priority = BindingPriority.TemplatedParent,
  72. RelativeSource = new RelativeSource(RelativeSourceMode.TemplatedParent),
  73. },
  74. });
  75. }
  76. private class ExceptionTest
  77. {
  78. private int _lessThan10;
  79. public int LessThan10
  80. {
  81. get { return _lessThan10; }
  82. set
  83. {
  84. if (value < 10)
  85. {
  86. _lessThan10 = value;
  87. }
  88. else
  89. {
  90. throw new InvalidOperationException("More than 10.");
  91. }
  92. }
  93. }
  94. }
  95. private class IndeiTest : INotifyDataErrorInfo
  96. {
  97. private int _lessThan10;
  98. private Dictionary<string, IList<string>> _errors = new Dictionary<string, IList<string>>();
  99. public int LessThan10
  100. {
  101. get { return _lessThan10; }
  102. set
  103. {
  104. if (value < 10)
  105. {
  106. _lessThan10 = value;
  107. _errors.Remove(nameof(LessThan10));
  108. ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(nameof(LessThan10)));
  109. }
  110. else
  111. {
  112. _errors[nameof(LessThan10)] = new[] { "More than 10" };
  113. ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(nameof(LessThan10)));
  114. }
  115. }
  116. }
  117. public bool HasErrors => _lessThan10 >= 10;
  118. public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
  119. public IEnumerable GetErrors(string propertyName)
  120. {
  121. IList<string> result;
  122. _errors.TryGetValue(propertyName, out result);
  123. return result;
  124. }
  125. }
  126. }
  127. }