Browse Source

Added IndeiBase

And use it as base class for test data that implements
INotifyDataErrorInfo. Removed IndeiValidatorTests as its been
superceeded by IndeiValidationPluginTests.
pull/691/head
Steven Kirk 10 years ago
parent
commit
4ffae3eb55
  1. 25
      tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_DataValidation.cs
  2. 32
      tests/Avalonia.Markup.UnitTests/Data/IndeiBase.cs
  3. 117
      tests/Avalonia.Markup.UnitTests/Data/IndeiValidatorTests.cs
  4. 26
      tests/Avalonia.Markup.UnitTests/Data/Plugins/IndeiValidationPluginTests.cs

25
tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_DataValidation.cs

@ -55,7 +55,7 @@ namespace Avalonia.Markup.UnitTests.Data
observer.Subscribe(_ => { }); observer.Subscribe(_ => { });
Assert.Equal(0, data.PropertyChangedSubscriptionCount); Assert.Equal(0, data.ErrorsChangedSubscriptionCount);
} }
[Fact] [Fact]
@ -65,9 +65,9 @@ namespace Avalonia.Markup.UnitTests.Data
var observer = new ExpressionObserver(data, nameof(data.MustBePositive), true); var observer = new ExpressionObserver(data, nameof(data.MustBePositive), true);
var sub = observer.Subscribe(_ => { }); var sub = observer.Subscribe(_ => { });
Assert.Equal(1, data.PropertyChangedSubscriptionCount); Assert.Equal(1, data.ErrorsChangedSubscriptionCount);
sub.Dispose(); sub.Dispose();
Assert.Equal(0, data.PropertyChangedSubscriptionCount); Assert.Equal(0, data.ErrorsChangedSubscriptionCount);
} }
[Fact] [Fact]
@ -126,11 +126,10 @@ namespace Avalonia.Markup.UnitTests.Data
} }
} }
private class IndeiTest : NotifyingBase, INotifyDataErrorInfo private class IndeiTest : IndeiBase
{ {
private int _mustBePositive; private int _mustBePositive;
private Dictionary<string, IList<string>> _errors = new Dictionary<string, IList<string>>(); private Dictionary<string, IList<string>> _errors = new Dictionary<string, IList<string>>();
private EventHandler<DataErrorsChangedEventArgs> _errorsChanged;
public int MustBePositive public int MustBePositive
{ {
@ -143,27 +142,19 @@ namespace Avalonia.Markup.UnitTests.Data
if (value >= 0) if (value >= 0)
{ {
_errors.Remove(nameof(MustBePositive)); _errors.Remove(nameof(MustBePositive));
_errorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(nameof(MustBePositive))); RaiseErrorsChanged(nameof(MustBePositive));
} }
else else
{ {
_errors[nameof(MustBePositive)] = new[] { "Must be positive" }; _errors[nameof(MustBePositive)] = new[] { "Must be positive" };
_errorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(nameof(MustBePositive))); RaiseErrorsChanged(nameof(MustBePositive));
} }
} }
} }
public bool HasErrors => _mustBePositive >= 0; public override bool HasErrors => _mustBePositive >= 0;
public int ErrorsChangedSubscriptionCount { get; private set; } public override IEnumerable GetErrors(string propertyName)
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged
{
add { _errorsChanged += value; ++ErrorsChangedSubscriptionCount; }
remove { _errorsChanged -= value; --ErrorsChangedSubscriptionCount; }
}
public IEnumerable GetErrors(string propertyName)
{ {
IList<string> result; IList<string> result;
_errors.TryGetValue(propertyName, out result); _errors.TryGetValue(propertyName, out result);

32
tests/Avalonia.Markup.UnitTests/Data/IndeiBase.cs

@ -0,0 +1,32 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Collections;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Avalonia.UnitTests;
namespace Avalonia.Markup.UnitTests.Data
{
internal abstract class IndeiBase : NotifyingBase, INotifyDataErrorInfo
{
private EventHandler<DataErrorsChangedEventArgs> _errorsChanged;
public abstract bool HasErrors { get; }
public int ErrorsChangedSubscriptionCount { get; private set; }
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged
{
add { _errorsChanged += value; ++ErrorsChangedSubscriptionCount; }
remove { _errorsChanged -= value; --ErrorsChangedSubscriptionCount; }
}
public abstract IEnumerable GetErrors(string propertyName);
protected void RaiseErrorsChanged([CallerMemberName] string propertyName = "")
{
_errorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
}
}
}

117
tests/Avalonia.Markup.UnitTests/Data/IndeiValidatorTests.cs

@ -1,117 +0,0 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Avalonia.Data;
using Avalonia.Markup.Data.Plugins;
using Avalonia.UnitTests;
using Xunit;
namespace Avalonia.Markup.UnitTests.Data
{
public class IndeiValidatorTests
{
[Fact]
public void Setting_Non_Validating_Does_Not_Trigger_Validation()
{
var inpcAccessorPlugin = new InpcPropertyAccessorPlugin();
var validatorPlugin = new IndeiValidationPlugin();
var data = new Data();
var accessor = inpcAccessorPlugin.Start(new WeakReference(data), nameof(data.NonValidated));
var validator = validatorPlugin.Start(new WeakReference(data), nameof(data.NonValidated), accessor);
var results = new List<object>();
validator.Subscribe(x => results.Add(x));
validator.SetValue(5, BindingPriority.LocalValue);
Assert.Equal(
new[]
{
new BindingNotification(0),
new BindingNotification(5),
}, results);
}
[Fact]
public void Setting_Validating_Property_To_Valid_Value_Returns_Successful_BindingNotification()
{
var inpcAccessorPlugin = new InpcPropertyAccessorPlugin();
var validatorPlugin = new IndeiValidationPlugin();
var data = new Data { MustBePositive = 1 };
var accessor = inpcAccessorPlugin.Start(new WeakReference(data), nameof(data.MustBePositive));
var validator = validatorPlugin.Start(new WeakReference(data), nameof(data.MustBePositive), accessor);
var results = new List<object>();
validator.Subscribe(x => results.Add(x));
validator.SetValue(5, BindingPriority.LocalValue);
Assert.Equal(
new[]
{
new BindingNotification(1),
new BindingNotification(5),
}, results);
}
[Fact]
public void Setting_Validating_Property_To_Invalid_Value_Returns_DataValidationError()
{
var inpcAccessorPlugin = new InpcPropertyAccessorPlugin();
var validatorPlugin = new IndeiValidationPlugin();
var data = new Data { MustBePositive = 1 };
var accessor = inpcAccessorPlugin.Start(new WeakReference(data), nameof(data.MustBePositive));
var validator = validatorPlugin.Start(new WeakReference(data), nameof(data.MustBePositive), accessor);
var results = new List<object>();
validator.Subscribe(x => results.Add(x));
validator.SetValue(-5, BindingPriority.LocalValue);
Assert.Equal(
new[]
{
new BindingNotification(1),
new BindingNotification(new Exception("MustBePositive must be positive"), BindingErrorType.DataValidationError, -5),
}, results);
}
public class Data : NotifyingBase, INotifyDataErrorInfo
{
private int nonValidated;
public int NonValidated
{
get { return nonValidated; }
set { nonValidated = value; RaisePropertyChanged(); }
}
private int mustBePositive;
public int MustBePositive
{
get { return mustBePositive; }
set { mustBePositive = value; RaisePropertyChanged(); }
}
public bool HasErrors => MustBePositive > 0;
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
private void NotifyErrorsChanged([CallerMemberName] string propertyName = "")
{
ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
}
public IEnumerable GetErrors(string propertyName)
{
if (propertyName == nameof(MustBePositive) && MustBePositive <= 0)
{
yield return $"{nameof(MustBePositive)} must be positive";
}
}
}
}
}

26
tests/Avalonia.Markup.UnitTests/Data/Plugins/IndeiValidationPluginTests.cs

@ -4,11 +4,9 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Reactive.Linq; using System.Reactive.Linq;
using Avalonia.Data; using Avalonia.Data;
using Avalonia.Markup.Data.Plugins; using Avalonia.Markup.Data.Plugins;
using Avalonia.UnitTests;
using Xunit; using Xunit;
namespace Avalonia.Markup.UnitTests.Data.Plugins namespace Avalonia.Markup.UnitTests.Data.Plugins
@ -59,22 +57,20 @@ namespace Avalonia.Markup.UnitTests.Data.Plugins
var accessor = inpcAccessorPlugin.Start(new WeakReference(data), nameof(data.Value)); var accessor = inpcAccessorPlugin.Start(new WeakReference(data), nameof(data.Value));
var validator = validatorPlugin.Start(new WeakReference(data), nameof(data.Value), accessor); var validator = validatorPlugin.Start(new WeakReference(data), nameof(data.Value), accessor);
Assert.Equal(0, data.SubscriptionCount); Assert.Equal(0, data.ErrorsChangedSubscriptionCount);
var sub = validator.Subscribe(_ => { }); var sub = validator.Subscribe(_ => { });
Assert.Equal(1, data.SubscriptionCount); Assert.Equal(1, data.ErrorsChangedSubscriptionCount);
sub.Dispose(); sub.Dispose();
Assert.Equal(0, data.SubscriptionCount); Assert.Equal(0, data.ErrorsChangedSubscriptionCount);
} }
public class Data : NotifyingBase, INotifyDataErrorInfo internal class Data : IndeiBase
{ {
private int _value; private int _value;
private int _maximum; private int _maximum;
private string _error; private string _error;
private EventHandler<DataErrorsChangedEventArgs> _errorsChanged;
public bool HasErrors => _error != null; public override bool HasErrors => _error != null;
public int SubscriptionCount { get; private set; }
public int Value public int Value
{ {
@ -97,13 +93,7 @@ namespace Avalonia.Markup.UnitTests.Data.Plugins
} }
} }
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged public override IEnumerable GetErrors(string propertyName)
{
add { _errorsChanged += value; ++SubscriptionCount; }
remove { _errorsChanged -= value; --SubscriptionCount; }
}
public IEnumerable GetErrors(string propertyName)
{ {
if (propertyName == nameof(Value) && _error != null) if (propertyName == nameof(Value) && _error != null)
{ {
@ -120,7 +110,7 @@ namespace Avalonia.Markup.UnitTests.Data.Plugins
if (_error != null) if (_error != null)
{ {
_error = null; _error = null;
_errorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(nameof(Value))); RaiseErrorsChanged(nameof(Value));
} }
} }
else else
@ -128,7 +118,7 @@ namespace Avalonia.Markup.UnitTests.Data.Plugins
if (_error == null) if (_error == null)
{ {
_error = "Must be less than Maximum"; _error = "Must be less than Maximum";
_errorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(nameof(Value))); RaiseErrorsChanged(nameof(Value));
} }
} }
} }

Loading…
Cancel
Save