Browse Source

another failing test for issue #855 and #824

pull/856/head
donandren 9 years ago
parent
commit
3729b9797f
  1. 89
      tests/Avalonia.Controls.UnitTests/Primitives/RangeBaseTests.cs

89
tests/Avalonia.Controls.UnitTests/Primitives/RangeBaseTests.cs

@ -2,7 +2,11 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.ComponentModel;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Templates;
using Avalonia.Data;
using Avalonia.Markup.Xaml.Data;
using Xunit;
namespace Avalonia.Controls.UnitTests.Primitives
@ -87,8 +91,93 @@ namespace Avalonia.Controls.UnitTests.Primitives
Assert.Throws<ArgumentException>(() => target.Value = double.NegativeInfinity);
}
[Fact]
public void SetValue_Should_Not_Cause_StackOverflow()
{
var viewModel = new TestStackOverflowViewModel()
{
Value = 50
};
Track track = null;
var target = new TestRange()
{
Template = new FuncControlTemplate<RangeBase>(c =>
{
return track = new Track()
{
Width = 100,
Orientation = Orientation.Horizontal,
[~~Track.MinimumProperty] = c[~~RangeBase.MinimumProperty],
[~~Track.MaximumProperty] = c[~~RangeBase.MaximumProperty],
[~~Track.ValueProperty] = c[~~RangeBase.ValueProperty],
Name = "PART_Track",
Thumb = new Thumb()
};
}),
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
{
}
private class TestStackOverflowViewModel : INotifyPropertyChanged
{
public int SetterInvokedCount { get; private set; }
public const int MaxInvokedCount = 1000;
private double _value;
public event PropertyChangedEventHandler PropertyChanged;
public double Value
{
get { return _value; }
set
{
if (_value != value)
{
SetterInvokedCount++;
if (SetterInvokedCount < MaxInvokedCount)
{
_value = (int)value;
if (_value > 75) _value = 75;
if (_value < 25) _value = 25;
}
else
{
_value = value;
}
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Value)));
}
}
}
}
}
}
Loading…
Cancel
Save