diff --git a/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Binding.cs b/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Binding.cs index d4e14d00b8..6b4a6f89df 100644 --- a/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Binding.cs +++ b/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Binding.cs @@ -11,6 +11,7 @@ using Avalonia.Logging; using Avalonia.Platform; using Avalonia.Threading; using Avalonia.UnitTests; +using Avalonia.Utilities; using Microsoft.Reactive.Testing; using Moq; using Xunit; @@ -785,7 +786,7 @@ namespace Avalonia.Base.UnitTests target.Bind(Class1.DoubleValueProperty, new Binding(nameof(source.Value), BindingMode.TwoWay) { Source = source }); - Assert.False(source.SetterCalled); + Assert.False(source.ValueSetterCalled); } [Fact] @@ -796,7 +797,7 @@ namespace Avalonia.Base.UnitTests target.Bind(Class1.DoubleValueProperty, new Binding("[0]", BindingMode.TwoWay) { Source = source }); - Assert.False(source.SetterCalled); + Assert.False(source.ValueSetterCalled); } [Fact] @@ -838,7 +839,7 @@ namespace Avalonia.Base.UnitTests target.Bind(Class1.DoubleValueProperty, new Binding(nameof(source.Value), BindingMode.TwoWay) { Source = source }); - Assert.False(source.SetterCalled); + Assert.False(source.ValueSetterCalled); } [Fact] @@ -850,7 +851,36 @@ namespace Avalonia.Base.UnitTests target.Bind(Class1.DoubleValueProperty, new Binding("[0]", BindingMode.TwoWay) { Source = source }); - Assert.False(source.SetterCalled); + Assert.False(source.ValueSetterCalled); + } + + + [Fact] + public void Disposing_a_TwoWay_Binding_Should_Set_Default_Value_On_Binding_Target_But_Not_On_Source() + { + var target = new Class3(); + + // Create a source class which has a Value set to -1 and a Minimum set to -2 + var source = new TestTwoWayBindingViewModel() { Value = -1, Minimum = -2 }; + + // Reset the setter counter + source.ResetSetterCalled(); + + // 1. bind the minimum + var disposable_1 = target.Bind(Class3.MinimumProperty, new Binding("Minimum", BindingMode.TwoWay) { Source = source }); + // 2. Bind the value + var disposable_2 = target.Bind(Class3.ValueProperty, new Binding("Value", BindingMode.TwoWay) { Source = source }); + + // Dispose the minimum binding + disposable_1.Dispose(); + // Dispose the value binding + disposable_2.Dispose(); + + + // The value setter should be called here as we have disposed minimum fist and the default value of minimum is 0, so this should be changed. + Assert.True(source.ValueSetterCalled); + // The minimum value should not be changed in the source. + Assert.False(source.MinimumSetterCalled); } /// @@ -888,6 +918,56 @@ namespace Avalonia.Base.UnitTests AvaloniaProperty.Register("Bar", "bardefault"); } + private class Class3 : AvaloniaObject + { + static Class3() + { + MinimumProperty.Changed.Subscribe(x => OnMinimumChanged(x)); + } + + private static void OnMinimumChanged(AvaloniaPropertyChangedEventArgs e) + { + if (e.Sender is Class3 s) + { + s.SetValue(ValueProperty, MathUtilities.Clamp(s.Value, e.NewValue.Value, double.PositiveInfinity)); + } + } + + /// + /// Defines the property. + /// + public static readonly StyledProperty ValueProperty = + AvaloniaProperty.Register(nameof(Value), 0); + + /// + /// Gets or sets the Value property + /// + public double Value + { + get { return GetValue(ValueProperty); } + set { SetValue(ValueProperty, value); } + } + + + /// + /// Defines the property. + /// + public static readonly StyledProperty MinimumProperty = + AvaloniaProperty.Register(nameof(Minimum), 0); + + /// + /// Gets or sets the minimum property + /// + public double Minimum + { + get { return GetValue(MinimumProperty); } + set { SetValue(MinimumProperty, value); } + } + + + } + + private class TestOneTimeBinding : IBinding { private IObservable _source; @@ -952,7 +1032,18 @@ namespace Avalonia.Base.UnitTests set { _value = value; - SetterCalled = true; + ValueSetterCalled = true; + } + } + + private double _minimum; + public double Minimum + { + get => _minimum; + set + { + _minimum = value; + MinimumSetterCalled = true; } } @@ -962,15 +1053,17 @@ namespace Avalonia.Base.UnitTests set { _value = value; - SetterCalled = true; + ValueSetterCalled = true; } } - public bool SetterCalled { get; private set; } + public bool ValueSetterCalled { get; private set; } + public bool MinimumSetterCalled { get; private set; } public void ResetSetterCalled() { - SetterCalled = false; + ValueSetterCalled = false; + MinimumSetterCalled = false; } } }