csharpc-sharpdotnetxamlavaloniauicross-platformcross-platform-xamlavaloniaguimulti-platformuser-interfacedotnetcore
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
4.4 KiB
128 lines
4.4 KiB
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using Avalonia.Data;
|
|
using Avalonia.Data.Core.Plugins;
|
|
using Avalonia.Threading;
|
|
using Xunit;
|
|
|
|
namespace Avalonia.Base.UnitTests.Data.Core.Plugins
|
|
{
|
|
public class IndeiValidationPluginTests
|
|
{
|
|
[Fact]
|
|
public void Produces_BindingNotifications()
|
|
{
|
|
var inpcAccessorPlugin = new InpcPropertyAccessorPlugin();
|
|
var validatorPlugin = new IndeiValidationPlugin();
|
|
var data = new Data { Maximum = 5 };
|
|
var accessor = inpcAccessorPlugin.Start(new WeakReference<object?>(data), nameof(data.Value));
|
|
Assert.NotNull(accessor);
|
|
var validator = validatorPlugin.Start(new WeakReference<object?>(data), nameof(data.Value), accessor);
|
|
var result = new List<object?>();
|
|
|
|
validator.Subscribe(x => result.Add(x));
|
|
validator.SetValue(5, BindingPriority.LocalValue);
|
|
validator.SetValue(6, BindingPriority.LocalValue);
|
|
data.Maximum = 10;
|
|
data.Maximum = 5;
|
|
|
|
Assert.Equal(new[]
|
|
{
|
|
new BindingNotification(0),
|
|
new BindingNotification(5),
|
|
|
|
// Value is first signalled without an error as validation hasn't been updated.
|
|
new BindingNotification(6),
|
|
|
|
// Then the ErrorsChanged event is fired.
|
|
new BindingNotification(new DataValidationException("Must be less than Maximum"), BindingErrorType.DataValidationError, 6),
|
|
|
|
// Maximum is changed to 10 so value is now valid.
|
|
new BindingNotification(6),
|
|
|
|
// And Maximum is changed back to 5.
|
|
new BindingNotification(new DataValidationException("Must be less than Maximum"), BindingErrorType.DataValidationError, 6),
|
|
}, result);
|
|
}
|
|
|
|
[Fact]
|
|
public void Subscribes_And_Unsubscribes()
|
|
{
|
|
var inpcAccessorPlugin = new InpcPropertyAccessorPlugin();
|
|
var validatorPlugin = new IndeiValidationPlugin();
|
|
var data = new Data { Maximum = 5 };
|
|
var accessor = inpcAccessorPlugin.Start(new WeakReference<object?>(data), nameof(data.Value));
|
|
Assert.NotNull(accessor);
|
|
var validator = validatorPlugin.Start(new WeakReference<object?>(data), nameof(data.Value), accessor);
|
|
|
|
Assert.Equal(0, data.ErrorsChangedSubscriptionCount);
|
|
validator.Subscribe(_ => { });
|
|
Assert.Equal(1, data.ErrorsChangedSubscriptionCount);
|
|
validator.Unsubscribe();
|
|
// Forces WeakEvent compact
|
|
Dispatcher.UIThread.RunJobs(null, TestContext.Current.CancellationToken);
|
|
Assert.Equal(0, data.ErrorsChangedSubscriptionCount);
|
|
}
|
|
|
|
internal class Data : IndeiBase
|
|
{
|
|
private int _value;
|
|
private int _maximum;
|
|
private string? _error;
|
|
|
|
public override bool HasErrors => _error != null;
|
|
|
|
public int Value
|
|
{
|
|
get { return _value; }
|
|
set
|
|
{
|
|
_value = value;
|
|
RaisePropertyChanged();
|
|
UpdateError();
|
|
}
|
|
}
|
|
|
|
public int Maximum
|
|
{
|
|
get { return _maximum; }
|
|
set
|
|
{
|
|
_maximum = value;
|
|
UpdateError();
|
|
}
|
|
}
|
|
|
|
public override IEnumerable GetErrors(string? propertyName)
|
|
{
|
|
if (propertyName == nameof(Value) && _error != null)
|
|
{
|
|
return new[] { _error };
|
|
}
|
|
|
|
return Array.Empty<string?>();
|
|
}
|
|
|
|
private void UpdateError()
|
|
{
|
|
if (_value <= _maximum)
|
|
{
|
|
if (_error != null)
|
|
{
|
|
_error = null;
|
|
RaiseErrorsChanged(nameof(Value));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (_error == null)
|
|
{
|
|
_error = "Must be less than Maximum";
|
|
RaiseErrorsChanged(nameof(Value));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|