Kaynağa Gözat

Added BindingNotification.

This will replace BindingError and IValidationStatus for bindings that want to notify binding/validation errors. Still WIP.
Steven Kirk 9 yıl önce
ebeveyn
işleme
abdbcac79d

+ 1 - 1
src/Avalonia.Base/Avalonia.Base.csproj

@@ -43,7 +43,7 @@
     <Compile Include="..\Shared\SharedAssemblyInfo.cs">
       <Link>Properties\SharedAssemblyInfo.cs</Link>
     </Compile>
-    <Compile Include="Data\BindingError.cs" />
+    <Compile Include="Data\BindingNotification.cs" />
     <Compile Include="Data\IndexerBinding.cs" />
     <Compile Include="Data\IValidationStatus.cs" />
     <Compile Include="Data\ObjectValidationStatus.cs" />

+ 19 - 17
src/Avalonia.Base/AvaloniaObject.cs

@@ -379,12 +379,11 @@ namespace Avalonia
                 }
 
                 subscription = source
-                    .Where(x =>  !(x is IValidationStatus))
                     .Select(x => CastOrDefault(x, property.PropertyType))
                     .Do(_ => { }, () => _directBindings.Remove(subscription))
                     .Subscribe(x => DirectBindingSet(property, x));
                 validationSubcription = source
-                    .OfType<IValidationStatus>()
+                    .OfType<BindingNotification>()
                     .Subscribe(x => DataValidationChanged(property, x));
 
                 _directBindings.Add(subscription);
@@ -487,7 +486,7 @@ namespace Avalonia
         }
 
         /// <inheritdoc/>
-        void IPriorityValueOwner.DataValidationChanged(PriorityValue sender, IValidationStatus status)
+        void IPriorityValueOwner.DataValidationChanged(PriorityValue sender, BindingNotification status)
         {
             var property = sender.Property;
             DataValidationChanged(property, status);
@@ -623,14 +622,14 @@ namespace Avalonia
 
         /// <summary>
         /// Tries to cast a value to a type, taking into account that the value may be a
-        /// <see cref="BindingError"/>.
+        /// <see cref="BindingNotification"/>.
         /// </summary>
         /// <param name="value">The value.</param>
         /// <param name="type">The type.</param>
-        /// <returns>The cast value, or a <see cref="BindingError"/>.</returns>
+        /// <returns>The cast value, or a <see cref="BindingNotification"/>.</returns>
         private static object CastOrDefault(object value, Type type)
         {
-            var error = value as BindingError;
+            var error = value as BindingNotification;
 
             if (error == null)
             {
@@ -674,26 +673,29 @@ namespace Avalonia
         /// <returns></returns>
         private void DirectBindingSet(AvaloniaProperty property, object value)
         {
-            var error = value as BindingError;
+            var notification = value as BindingNotification;
 
-            if (error == null)
+            if (notification == null)
             {
                 SetValue(property, value);
             }
             else
             {
-                if (error.UseFallbackValue)
+                if (notification.HasValue)
                 {
-                    SetValue(property, error.FallbackValue);
+                    SetValue(property, notification.Value);
                 }
 
-                Logger.Error(
-                    LogArea.Binding,
-                    this,
-                    "Error binding to {Target}.{Property}: {Message}",
-                    this,
-                    property,
-                    error.Exception.Message);
+                if (notification.ErrorType == BindingErrorType.Error)
+                {
+                    Logger.Error(
+                        LogArea.Binding,
+                        this,
+                        "Error binding to {Target}.{Property}: {Message}",
+                        this,
+                        property,
+                        notification.Error.Message);
+                }
             }
         }
 

+ 0 - 59
src/Avalonia.Base/Data/BindingError.cs

@@ -1,59 +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;
-
-namespace Avalonia.Data
-{
-    /// <summary>
-    /// Represents a recoverable binding error.
-    /// </summary>
-    /// <remarks>
-    /// When produced by a binding source observable, informs the binding system that an error
-    /// occurred. It can also provide an optional fallback value to be pushed to the binding
-    /// target. 
-    /// 
-    /// Instead of using <see cref="BindingError"/>, one could simply not push a value (in the
-    /// case of a no fallback value) or push a fallback value, but BindingError also causes an
-    /// error to be logged with the correct binding target.
-    /// </remarks>
-    public class BindingError
-    {
-        /// <summary>
-        /// Initializes a new instance of the <see cref="BindingError"/> class.
-        /// </summary>
-        /// <param name="exception">An exception describing the binding error.</param>
-        public BindingError(Exception exception)
-        {
-            Exception = exception;
-        }
-
-        /// <summary>
-        /// Initializes a new instance of the <see cref="BindingError"/> class.
-        /// </summary>
-        /// <param name="exception">An exception describing the binding error.</param>
-        /// <param name="fallbackValue">The fallback value.</param>
-        public BindingError(Exception exception, object fallbackValue)
-        {
-            Exception = exception;
-            FallbackValue = fallbackValue;
-            UseFallbackValue = true;
-        }
-
-        /// <summary>
-        /// Gets the exception describing the binding error.
-        /// </summary>
-        public Exception Exception { get; }
-
-        /// <summary>
-        /// Get the fallback value.
-        /// </summary>
-        public object FallbackValue { get; }
-
-        /// <summary>
-        /// Get a value indicating whether the fallback value should be pushed to the binding
-        /// target.
-        /// </summary>
-        public bool UseFallbackValue { get; }
-    }
-}

+ 169 - 0
src/Avalonia.Base/Data/BindingNotification.cs

@@ -0,0 +1,169 @@
+// 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;
+
+namespace Avalonia.Data
+{
+    /// <summary>
+    /// Defines the types of binding errors for a <see cref="BindingNotification"/>.
+    /// </summary>
+    public enum BindingErrorType
+    {
+        /// <summary>
+        /// There was no error.
+        /// </summary>
+        None,
+
+        /// <summary>
+        /// There was a binding error.
+        /// </summary>
+        Error,
+
+        /// <summary>
+        /// There was a data validation error.
+        /// </summary>
+        DataValidationError,
+    }
+
+    /// <summary>
+    /// Represents a binding notification that can be a valid binding value, or a binding or
+    /// data validation error.
+    /// </summary>
+    public class BindingNotification : IValidationStatus
+    {
+        /// <summary>
+        /// A binding notification representing the null value.
+        /// </summary>
+        public static readonly BindingNotification Null =
+            new BindingNotification(null);
+
+        /// <summary>
+        /// A binding notification representing <see cref="AvaloniaProperty.UnsetValue"/>.
+        /// </summary>
+        public static readonly BindingNotification UnsetValue =
+            new BindingNotification(AvaloniaProperty.UnsetValue);
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="BindingNotification"/> class.
+        /// </summary>
+        /// <param name="value">The binding value.</param>
+        public BindingNotification(object value)
+        {
+            Value = value;
+            HasValue = true;
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="BindingNotification"/> class.
+        /// </summary>
+        /// <param name="error">The binding error.</param>
+        /// <param name="errorType">The type of the binding error.</param>
+        public BindingNotification(Exception error, BindingErrorType errorType)
+        {
+            if (errorType == BindingErrorType.None)
+            {
+                throw new ArgumentException($"'errorType' may not be None");
+            }
+
+            Error = error;
+            ErrorType = errorType;
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="BindingNotification"/> class.
+        /// </summary>
+        /// <param name="error">The binding error.</param>
+        /// <param name="errorType">The type of the binding error.</param>
+        /// <param name="fallbackValue">The fallback value.</param>
+        public BindingNotification(Exception error, BindingErrorType errorType, object fallbackValue)
+            : this(error)
+        {
+            Value = fallbackValue;
+            HasValue = true;
+        }
+
+        /// <summary>
+        /// Gets the value that should be passed to the target when <see cref="HasValue"/>
+        /// is true.
+        /// </summary>
+        public object Value { get; }
+
+        /// <summary>
+        /// Gets a value indicating whether <see cref="Value"/> should be pushed to the target.
+        /// </summary>
+        public bool HasValue { get; }
+
+        /// <summary>
+        /// Gets the error that occurred on the source, if any.
+        /// </summary>
+        public Exception Error { get; }
+
+        /// <summary>
+        /// Gets the type of error that <see cref="Error"/> represents, if any.
+        /// </summary>
+        public BindingErrorType ErrorType { get; }
+
+        bool IValidationStatus.IsValid => ErrorType == BindingErrorType.None;
+
+        public static bool operator ==(BindingNotification a, BindingNotification b)
+        {
+            if (object.ReferenceEquals(a, b))
+            {
+                return true;
+            }
+
+            if ((object)a == null || (object)b == null)
+            {
+                return false;
+            }
+
+            return a.HasValue == b.HasValue &&
+                   a.ErrorType == b.ErrorType &&
+                   (!a.HasValue || object.Equals(a.Value, b.Value)) &&
+                   (a.ErrorType == BindingErrorType.None || object.Equals(a.Error, b.Error));
+        }
+
+        public static bool operator !=(BindingNotification a, BindingNotification b)
+        {
+            return !(a == b);
+        }
+
+        public override bool Equals(object obj)
+        {
+            return Equals(obj as BindingNotification);
+        }
+
+        public bool Equals(BindingNotification other)
+        {
+            return this == other;
+        }
+
+        public override int GetHashCode()
+        {
+            return base.GetHashCode();
+        }
+
+        public BindingNotification WithError(Exception e)
+        {
+            if (e == null)
+            {
+                return this;
+            }
+
+            if (Error != null)
+            {
+                e = new AggregateException(Error, e);
+            }
+
+            if (HasValue)
+            {
+                return new BindingNotification(e, BindingErrorType.Error, Value);
+            }
+            else
+            {
+                return new BindingNotification(e, BindingErrorType.Error, Value);
+            }
+        }
+    }
+}

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

@@ -23,6 +23,6 @@ namespace Avalonia
         /// </summary>
         /// <param name="sender">The source of the change.</param>
         /// <param name="status">The validation status.</param>
-        void DataValidationChanged(PriorityValue sender, IValidationStatus status);
+        void DataValidationChanged(PriorityValue sender, BindingNotification status);
     }
 }

+ 18 - 12
src/Avalonia.Base/PriorityBindingEntry.cs

@@ -93,22 +93,28 @@ namespace Avalonia
 
         private void ValueChanged(object value)
         {
-            var bindingError = value as BindingError;
+            var notification = value as BindingNotification;
 
-            if (bindingError != null)
+            if (notification != null)
             {
-                _owner.Error(this, bindingError);
+                if (notification.ErrorType == BindingErrorType.Error)
+                {
+                    _owner.Error(this, notification);
+                }
+                else if (notification.ErrorType == BindingErrorType.DataValidationError)
+                {
+                    _owner.Validation(this, notification);
+                }
+
+                if (notification.HasValue)
+                {
+                    Value = notification.Value;
+                    _owner.Changed(this);
+                }
             }
-
-            var validationStatus = value as IValidationStatus;
-
-            if (validationStatus != null)
-            {
-                _owner.Validation(this, validationStatus);
-            }
-            else if (bindingError == null || bindingError.UseFallbackValue)
+            else
             {
-                Value = bindingError == null ? value : bindingError.FallbackValue;
+                Value = value;
                 _owner.Changed(this);
             }
         }

+ 2 - 2
src/Avalonia.Base/PriorityLevel.cs

@@ -159,7 +159,7 @@ namespace Avalonia
         /// </summary>
         /// <param name="entry">The entry that completed.</param>
         /// <param name="error">The error.</param>
-        public void Error(PriorityBindingEntry entry, BindingError error)
+        public void Error(PriorityBindingEntry entry, BindingNotification error)
         {
             _owner.LevelError(this, error);
         }
@@ -169,7 +169,7 @@ namespace Avalonia
         /// </summary>
         /// <param name="entry">The entry that completed.</param>
         /// <param name="validationStatus">The validation status.</param>
-        public void Validation(PriorityBindingEntry entry, IValidationStatus validationStatus)
+        public void Validation(PriorityBindingEntry entry, BindingNotification validationStatus)
         {
             _owner.LevelValidation(this, validationStatus);
         }

+ 3 - 3
src/Avalonia.Base/PriorityValue.cs

@@ -184,7 +184,7 @@ namespace Avalonia
         /// </summary>
         /// <param name="priorityLevel">The priority level of the changed entry.</param>
         /// <param name="validationStatus">The validation status.</param>
-        public void LevelValidation(PriorityLevel priorityLevel, IValidationStatus validationStatus)
+        public void LevelValidation(PriorityLevel priorityLevel, BindingNotification validationStatus)
         {
             _owner.DataValidationChanged(this, validationStatus);
         }
@@ -194,7 +194,7 @@ namespace Avalonia
         /// </summary>
         /// <param name="level">The priority level of the changed entry.</param>
         /// <param name="error">The binding error.</param>
-        public void LevelError(PriorityLevel level, BindingError error)
+        public void LevelError(PriorityLevel level, BindingNotification error)
         {
             Logger.Log(
                 LogEventLevel.Error,
@@ -203,7 +203,7 @@ namespace Avalonia
                 "Error binding to {Target}.{Property}: {Message}",
                 _owner,
                 Property,
-                error.Exception.Message);
+                error.Error.Message);
         }
 
         /// <summary>

+ 1 - 1
src/Markup/Avalonia.Markup.Xaml/Templates/MemberSelector.cs

@@ -57,7 +57,7 @@ namespace Avalonia.Markup.Xaml.Templates
             {
                 return null;
             }
-            else if (result is BindingError)
+            else if (result is BindingNotification)
             {
                 return null;
             }

+ 8 - 8
src/Markup/Avalonia.Markup/Data/ExpressionNode.cs

@@ -108,14 +108,14 @@ namespace Avalonia.Markup.Data
         protected virtual void SendValidationStatus(IValidationStatus status)
         {
             //Even if elements only bound to sub-values, send validation changes along so they will be surfaced to the UI level.
-            if (_subject != null)
-            {
-                _subject.OnNext(status);
-            }
-            else
-            {
-                Next?.SendValidationStatus(status);
-            }
+            //if (_subject != null)
+            //{
+            //    _subject.OnNext(status);
+            //}
+            //else
+            //{
+            //    Next?.SendValidationStatus(status);
+            //}
         }
 
         protected virtual void Unsubscribe(object target)

+ 10 - 9
src/Markup/Avalonia.Markup/Data/ExpressionSubject.cs

@@ -126,16 +126,16 @@ namespace Avalonia.Markup.Data
                     converted = TypeUtilities.Default(type);
                     _inner.SetValue(converted, _priority);
                 }
-                else if (converted is BindingError)
+                else if (converted is BindingNotification)
                 {
-                    var error = converted as BindingError;
+                    var error = converted as BindingNotification;
 
                     Logger.Error(
                         LogArea.Binding,
                         this,
                         "Error binding to {Expression}: {Message}",
                         _inner.Expression,
-                        error.Exception.Message);
+                        error.Error.Message);
 
                     if (_fallbackValue != AvaloniaProperty.UnsetValue)
                     {
@@ -174,7 +174,7 @@ namespace Avalonia.Markup.Data
         private object ConvertValue(object value)
         {
             var converted = 
-                value as BindingError ??
+                value as BindingNotification ??
                 value as IValidationStatus ??
                 Converter.Convert(
                     value,
@@ -184,9 +184,9 @@ namespace Avalonia.Markup.Data
 
             if (_fallbackValue != AvaloniaProperty.UnsetValue &&
                 (converted == AvaloniaProperty.UnsetValue ||
-                 converted is BindingError))
+                 converted is BindingNotification))
             {
-                var error = converted as BindingError;
+                var error = converted as BindingNotification;
                 
                 if (TypeUtilities.TryConvert(
                     _targetType, 
@@ -196,14 +196,15 @@ namespace Avalonia.Markup.Data
                 {
                     if (error != null)
                     {
-                        converted = new BindingError(error.Exception, converted);
+                        converted = new BindingNotification(error.Error, BindingErrorType.Error, converted);
                     }
                 }
                 else
                 {
-                    converted = new BindingError(
+                    converted = new BindingNotification(
                         new InvalidCastException(
-                            $"Could not convert FallbackValue '{_fallbackValue}' to '{_targetType}'"));
+                            $"Could not convert FallbackValue '{_fallbackValue}' to '{_targetType}'"),
+                        BindingErrorType.Error);
                 }
             }
 

+ 1 - 1
src/Markup/Avalonia.Markup/Data/Plugins/AvaloniaPropertyAccessorPlugin.cs

@@ -56,7 +56,7 @@ namespace Avalonia.Markup.Data.Plugins
             {
                 var message = $"Could not find AvaloniaProperty '{propertyName}' on '{instance}'";
                 var exception = new MissingMemberException(message);
-                return new PropertyError(new BindingError(exception));
+                return new PropertyError(new BindingNotification(exception, BindingErrorType.Error));
             }
             else
             {

+ 1 - 1
src/Markup/Avalonia.Markup/Data/Plugins/InpcPropertyAccessorPlugin.cs

@@ -61,7 +61,7 @@ namespace Avalonia.Markup.Data.Plugins
             {
                 var message = $"Could not find CLR property '{propertyName}' on '{instance}'";
                 var exception = new MissingMemberException(message);
-                return new PropertyError(new BindingError(exception));
+                return new PropertyError(new BindingNotification(exception, BindingErrorType.Error));
             }
         }
 

+ 2 - 2
src/Markup/Avalonia.Markup/Data/Plugins/PropertyError.cs

@@ -8,13 +8,13 @@ namespace Avalonia.Markup.Data.Plugins
     /// </summary>
     public class PropertyError : IPropertyAccessor
     {
-        private BindingError _error;
+        private BindingNotification _error;
 
         /// <summary>
         /// Initializes a new instance of the <see cref="PropertyError"/> class.
         /// </summary>
         /// <param name="error">The error to report.</param>
-        public PropertyError(BindingError error)
+        public PropertyError(BindingNotification error)
         {
             _error = error;
         }

+ 1 - 1
src/Markup/Avalonia.Markup/DefaultValueConverter.cs

@@ -44,7 +44,7 @@ namespace Avalonia.Markup
             if (value != null)
             {
                 var message = $"Could not convert '{value}' to '{targetType}'";
-                return new BindingError(new InvalidCastException(message));
+                return new BindingNotification(new InvalidCastException(message), BindingErrorType.Error);
             }
 
             return AvaloniaProperty.UnsetValue;

+ 4 - 3
tests/Avalonia.Base.UnitTests/Avalonia.Base.UnitTests.v2.ncrunchproject

@@ -17,10 +17,11 @@
   <DetectStackOverflow>true</DetectStackOverflow>
   <IncludeStaticReferencesInWorkspace>true</IncludeStaticReferencesInWorkspace>
   <DefaultTestTimeout>60000</DefaultTestTimeout>
-  <UseBuildConfiguration />
-  <UseBuildPlatform />
-  <ProxyProcessPath />
+  <UseBuildConfiguration></UseBuildConfiguration>
+  <UseBuildPlatform></UseBuildPlatform>
+  <ProxyProcessPath></ProxyProcessPath>
   <UseCPUArchitecture>AutoDetect</UseCPUArchitecture>
   <MSTestThreadApartmentState>STA</MSTestThreadApartmentState>
   <BuildProcessArchitecture>x86</BuildProcessArchitecture>
+  <HiddenWarnings>LongTestTimesWithoutParallelExecution</HiddenWarnings>
 </ProjectConfiguration>

+ 12 - 5
tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Binding.cs

@@ -273,26 +273,31 @@ namespace Avalonia.Base.UnitTests
 
             target.Bind(Class1.QuxProperty, source);
             source.OnNext(6.7);
-            source.OnNext(new BindingError(new InvalidOperationException("Foo")));
+            source.OnNext(new BindingNotification(
+                new InvalidOperationException("Foo"),
+                BindingErrorType.Error));
 
             Assert.Equal(6.7, target.GetValue(Class1.QuxProperty));
         }
 
         [Fact]
-        public void BindingError_With_FallbackValue_Causes_Target_Update()
+        public void BindingNotification_With_FallbackValue_Causes_Target_Update()
         {
             var target = new Class1();
             var source = new Subject<object>();
 
             target.Bind(Class1.QuxProperty, source);
             source.OnNext(6.7);
-            source.OnNext(new BindingError(new InvalidOperationException("Foo"), 8.9));
+            source.OnNext(new BindingNotification(
+                new InvalidOperationException("Foo"),
+                BindingErrorType.Error,
+                8.9));
 
             Assert.Equal(8.9, target.GetValue(Class1.QuxProperty));
         }
 
         [Fact]
-        public void Bind_Logs_BindingError()
+        public void Bind_Logs_Binding_Error()
         {
             var target = new Class1();
             var source = new Subject<object>();
@@ -313,7 +318,9 @@ namespace Avalonia.Base.UnitTests
             {
                 target.Bind(Class1.QuxProperty, source);
                 source.OnNext(6.7);
-                source.OnNext(new BindingError(new InvalidOperationException("Foo")));
+                source.OnNext(new BindingNotification(
+                    new InvalidOperationException("Foo"),
+                    BindingErrorType.Error));
 
                 Assert.Equal(6.7, target.GetValue(Class1.QuxProperty));
                 Assert.True(called);

+ 6 - 3
tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Direct.cs

@@ -406,7 +406,7 @@ namespace Avalonia.Base.UnitTests
 
             target.Bind(Class1.FooProperty, source);
             source.OnNext("initial");
-            source.OnNext(new BindingError(new InvalidOperationException("Foo")));
+            source.OnNext(new BindingNotification(new InvalidOperationException("Foo"), BindingErrorType.Error));
 
             Assert.Equal("initial", target.GetValue(Class1.FooProperty));
         }
@@ -419,7 +419,10 @@ namespace Avalonia.Base.UnitTests
 
             target.Bind(Class1.FooProperty, source);
             source.OnNext("initial");
-            source.OnNext(new BindingError(new InvalidOperationException("Foo"), "fallback"));
+            source.OnNext(new BindingNotification(
+                new InvalidOperationException("Foo"),
+                BindingErrorType.Error,
+                "fallback"));
 
             Assert.Equal("fallback", target.GetValue(Class1.FooProperty));
         }
@@ -449,7 +452,7 @@ namespace Avalonia.Base.UnitTests
             {
                 target.Bind(Class1.FooProperty, source);
                 source.OnNext("baz");
-                source.OnNext(new BindingError(new InvalidOperationException("Binding Error Message")));
+                source.OnNext(new BindingNotification(new InvalidOperationException("Binding Error Message"), BindingErrorType.Error));
             }
 
             Assert.True(called);

+ 5 - 5
tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Property.cs

@@ -81,11 +81,11 @@ namespace Avalonia.Markup.UnitTests.Data
             var target = new ExpressionObserver(data, "Foo.Bar.Baz");
             var result = await target.Take(1);
 
-            Assert.IsType<BindingError>(result);
+            Assert.IsType<BindingNotification>(result);
 
-            var error = result as BindingError;
-            Assert.IsType<MissingMemberException>(error.Exception);
-            Assert.Equal("Could not find CLR property 'Baz' on '1'", error.Exception.Message);
+            var error = result as BindingNotification;
+            Assert.IsType<MissingMemberException>(error.Error);
+            Assert.Equal("Could not find CLR property 'Baz' on '1'", error.Error.Message);
         }
 
         [Fact]
@@ -216,7 +216,7 @@ namespace Avalonia.Markup.UnitTests.Data
 
             Assert.Equal(3, result.Count);
             Assert.Equal("bar", result[0]);
-            Assert.IsType<BindingError>(result[1]);
+            Assert.IsType<BindingNotification>(result[1]);
             Assert.Equal("baz", result[2]);
 
             sub.Dispose();

+ 1 - 1
tests/Avalonia.Markup.UnitTests/Data/ExpressionSubjectTests.cs

@@ -55,7 +55,7 @@ namespace Avalonia.Markup.UnitTests.Data
             var target = new ExpressionSubject(new ExpressionObserver(data, "StringValue"), typeof(double));
             var result = await target.Take(1);
 
-            Assert.IsType<BindingError>(result);
+            Assert.IsType<BindingNotification>(result);
         }
 
         [Fact]

+ 1 - 1
tests/Avalonia.Markup.UnitTests/DefaultValueConverterTests.cs

@@ -115,7 +115,7 @@ namespace Avalonia.Markup.UnitTests
                 null,
                 CultureInfo.InvariantCulture);
 
-            Assert.IsType<BindingError>(result);
+            Assert.IsType<BindingNotification>(result);
         }
 
         private enum TestEnum