Skip to content

Commit

Permalink
another failing test for issue AvaloniaUI#855 and AvaloniaUI#824
Browse files Browse the repository at this point in the history
  • Loading branch information
donandren committed Feb 26, 2017
1 parent 220a987 commit 3729b97
Showing 1 changed file with 89 additions and 0 deletions.
89 changes: 89 additions & 0 deletions tests/Avalonia.Controls.UnitTests/Primitives/RangeBaseTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -87,8 +91,93 @@ public void Properties_Should_Not_Accept_Nan_And_Inifinity()
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)));
}
}
}
}
}
}

0 comments on commit 3729b97

Please sign in to comment.