Browse Source

Make failing tests pass.

To do this needed to change behavior a little in that now binding errors update the target. Previously in the case of a binding error at the first node in the binding chain, we were converting the `BindingNotification` to `UnsetValue` which had the effect of updating the target value. Now we're passing the `BindingNotification` back, we need to make sure this happens. I believe this is the right thing to do as the behavior should be the same no matter where in the binding chain the error occurs. Data validation errors continue to not update the target.
Steven Kirk 8 years ago
parent
commit
8743ce95bd

+ 2 - 6
src/Avalonia.Base/AvaloniaObject.cs

@@ -665,14 +665,10 @@ namespace Avalonia
             if (notification != null)
             {
                 notification.LogIfError(this, property);
-
-                if (notification.HasValue)
-                {
-                    value = notification.Value;
-                }
+                value = notification.Value;
             }
 
-            if (notification == null || notification.HasValue)
+            if (notification == null || notification.ErrorType == BindingErrorType.Error || notification.HasValue)
             {
                 var metadata = (IDirectPropertyMetadata)property.GetMetadata(GetType());
                 var accessor = (IDirectPropertyAccessor)GetRegistered(property);

+ 1 - 1
src/Avalonia.Base/PriorityBindingEntry.cs

@@ -98,7 +98,7 @@ namespace Avalonia
 
             if (notification != null)
             {
-                if (notification.HasValue)
+                if (notification.HasValue || notification.ErrorType == BindingErrorType.Error)
                 {
                     Value = notification.Value;
                     _owner.Changed(this);

+ 2 - 2
tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Binding.cs

@@ -314,7 +314,7 @@ namespace Avalonia.Base.UnitTests
                 new InvalidOperationException("Foo"),
                 BindingErrorType.Error));
 
-            Assert.Equal(6.7, target.GetValue(Class1.QuxProperty));
+            Assert.Equal(5.6, target.GetValue(Class1.QuxProperty));
         }
 
         [Fact]
@@ -359,7 +359,7 @@ namespace Avalonia.Base.UnitTests
                     new InvalidOperationException("Foo"),
                     BindingErrorType.Error));
 
-                Assert.Equal(6.7, target.GetValue(Class1.QuxProperty));
+                Assert.Equal(5.6, target.GetValue(Class1.QuxProperty));
                 Assert.True(called);
             }
         }

+ 2 - 2
tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Direct.cs

@@ -352,14 +352,14 @@ namespace Avalonia.Base.UnitTests
         }
 
         [Fact]
-        public void BindingError_Does_Not_Cause_Target_Update()
+        public void DataValidationError_Does_Not_Cause_Target_Update()
         {
             var target = new Class1();
             var source = new Subject<object>();
 
             target.Bind(Class1.FooProperty, source);
             source.OnNext("initial");
-            source.OnNext(new BindingNotification(new InvalidOperationException("Foo"), BindingErrorType.Error));
+            source.OnNext(new BindingNotification(new InvalidOperationException("Foo"), BindingErrorType.DataValidationError));
 
             Assert.Equal("initial", target.GetValue(Class1.FooProperty));
         }

+ 2 - 2
tests/Avalonia.Markup.Xaml.UnitTests/Data/BindingTests.cs

@@ -302,12 +302,12 @@ namespace Avalonia.Markup.Xaml.UnitTests.Data
 
             // Bind Foo and Bar to the VM.
             target.Bind(OldDataContextTest.FooProperty, fooBinding);
-            //target.Bind(OldDataContextTest.BarProperty, barBinding);
+            target.Bind(OldDataContextTest.BarProperty, barBinding);
             target.DataContext = vm;
 
             // Make sure the control's Foo and Bar properties are read from the VM
             Assert.Equal(1, target.GetValue(OldDataContextTest.FooProperty));
-            //Assert.Equal(2, target.GetValue(OldDataContextTest.BarProperty));
+            Assert.Equal(2, target.GetValue(OldDataContextTest.BarProperty));
 
             // Set DataContext to null.
             target.DataContext = null;