From f1ca851833840138fcb7a49559134fa95d827a21 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Tue, 6 Oct 2015 20:21:19 +0200 Subject: [PATCH] Fix setting expression value on broken chain. Closes #254. --- .../Binding/PropertyAccessorNode.cs | 2 + .../ExpressionObserverTests_SetValue.cs | 80 +++++++++++++++++++ .../Perspex.Markup.UnitTests.csproj | 1 + 3 files changed, 83 insertions(+) create mode 100644 tests/Perspex.Markup.UnitTests/Binding/ExpressionObserverTests_SetValue.cs diff --git a/src/Markup/Perspex.Markup/Binding/PropertyAccessorNode.cs b/src/Markup/Perspex.Markup/Binding/PropertyAccessorNode.cs index 1015bcfa0a..b4efbc324c 100644 --- a/src/Markup/Perspex.Markup/Binding/PropertyAccessorNode.cs +++ b/src/Markup/Perspex.Markup/Binding/PropertyAccessorNode.cs @@ -81,6 +81,8 @@ namespace Perspex.Markup.Binding { inpc.PropertyChanged -= PropertyChanged; } + + _propertyInfo = null; } private static PropertyInfo FindProperty(object target, string propertyName) diff --git a/tests/Perspex.Markup.UnitTests/Binding/ExpressionObserverTests_SetValue.cs b/tests/Perspex.Markup.UnitTests/Binding/ExpressionObserverTests_SetValue.cs new file mode 100644 index 0000000000..7be47702b8 --- /dev/null +++ b/tests/Perspex.Markup.UnitTests/Binding/ExpressionObserverTests_SetValue.cs @@ -0,0 +1,80 @@ +// Copyright (c) The Perspex 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.Generic; +using System.Reactive.Linq; +using Perspex.Markup.Binding; +using Xunit; + +namespace Perspex.Markup.UnitTests.Binding +{ + public class ExpressionObserverTests_SetValue + { + [Fact] + public void Should_Set_Simple_Property_Value() + { + var data = new { Foo = "foo" }; + var target = new ExpressionObserver(data, "Foo"); + + target.SetValue("bar"); + + Assert.Equal("foo", data.Foo); + } + + [Fact] + public void Should_Set_Value_On_Simple_Property_Chain() + { + var data = new Class1 { Foo = new Class2 { Bar = "bar" } }; + var target = new ExpressionObserver(data, "Foo.Bar"); + + target.SetValue("foo"); + + Assert.Equal("foo", data.Foo.Bar); + } + + [Fact] + public void Should_Not_Try_To_Set_Value_On_Broken_Chain() + { + var data = new Class1 { Foo = new Class2 { Bar = "bar" } }; + var target = new ExpressionObserver(data, "Foo.Bar"); + + // Ensure the ExpressionObserver's subscriptions are kept active. + target.OfType().Subscribe(x => { }); + + data.Foo = null; + + Assert.False(target.SetValue("foo")); + } + + private class Class1 : NotifyingBase + { + private Class2 _foo; + + public Class2 Foo + { + get { return _foo; } + set + { + _foo = value; + RaisePropertyChanged(nameof(Foo)); + } + } + } + + private class Class2 : NotifyingBase + { + private string _bar; + + public string Bar + { + get { return _bar; } + set + { + _bar = value; + RaisePropertyChanged(nameof(Bar)); + } + } + } + } +} diff --git a/tests/Perspex.Markup.UnitTests/Perspex.Markup.UnitTests.csproj b/tests/Perspex.Markup.UnitTests/Perspex.Markup.UnitTests.csproj index 36ff242096..71cc52aef1 100644 --- a/tests/Perspex.Markup.UnitTests/Perspex.Markup.UnitTests.csproj +++ b/tests/Perspex.Markup.UnitTests/Perspex.Markup.UnitTests.csproj @@ -74,6 +74,7 @@ +