From 53b9d24644c1beedc6962e24a2072ea4cee1625c Mon Sep 17 00:00:00 2001 From: donandren Date: Sun, 26 Feb 2017 21:27:44 +0200 Subject: [PATCH] another test for #855 and #824 using setter which behind scenes is using weakobservable --- .../Primitives/RangeBaseTests.cs | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/tests/Avalonia.Controls.UnitTests/Primitives/RangeBaseTests.cs b/tests/Avalonia.Controls.UnitTests/Primitives/RangeBaseTests.cs index 9bccb1986d4..9d48680c0b1 100644 --- a/tests/Avalonia.Controls.UnitTests/Primitives/RangeBaseTests.cs +++ b/tests/Avalonia.Controls.UnitTests/Primitives/RangeBaseTests.cs @@ -7,6 +7,7 @@ using Avalonia.Controls.Templates; using Avalonia.Data; using Avalonia.Markup.Xaml.Data; +using Avalonia.Styling; using Xunit; namespace Avalonia.Controls.UnitTests.Primitives @@ -141,6 +142,72 @@ public void SetValue_Should_Not_Cause_StackOverflow() Assert.Equal(expected, track.Value); } + [Fact] + public void SetValue_Using_Setter_Should_Not_Cause_StackOverflow() + { + var viewModel = new TestStackOverflowViewModel() + { + Value = 50 + }; + + Track track = null; + + var target = new TestRange() + { + Template = new FuncControlTemplate(c => + { + track = new Track() + { + Width = 100, + Orientation = Orientation.Horizontal, + [~~Track.MinimumProperty] = c[~~RangeBase.MinimumProperty], + [~~Track.MaximumProperty] = c[~~RangeBase.MaximumProperty], + //use setter binding instead to be closer to real world scenario + //as setter is using weakobservable + //[~~Track.ValueProperty] = c[~~RangeBase.ValueProperty], + Name = "PART_Track", + Thumb = new Thumb() + }; + + var s = new Setter() + { + Property = Track.ValueProperty, + Value = new Binding("Value") + { + RelativeSource = new RelativeSource(RelativeSourceMode.TemplatedParent), + Priority = BindingPriority.TemplatedParent, + Mode = BindingMode.TwoWay + } + }; + + s.Apply(null, track, null); + return track; + }), + Minimum = 0, + Maximum = 100, + DataContext = viewModel + }; + + target.Bind(TestRange.ValueProperty, new Binding("Value") { Mode = BindingMode.TwoWay }); + + target.ApplyTemplate(); + track.Measure(new Size(100, 0)); + track.Arrange(new Rect(0, 0, 100, 0)); + + Assert.Equal(1, viewModel.SetterInvokedCount); + + //here in real life stack overflow exception is thrown issue #855 and #824 + target.Value = 51.001; + + Assert.Equal(2, viewModel.SetterInvokedCount); + + double expected = 51; + + Assert.Equal(expected, viewModel.Value); + Assert.Equal(expected, target.Value); + Assert.Equal(expected, track.Value); + } + private class TestRange : RangeBase { }