Skip to content

Commit

Permalink
issue AvaloniaUI#855 unit test
Browse files Browse the repository at this point in the history
  • Loading branch information
donandren committed Feb 26, 2017
1 parent 008cec2 commit 220a987
Showing 1 changed file with 70 additions and 1 deletion.
71 changes: 70 additions & 1 deletion tests/Avalonia.Controls.UnitTests/ListBoxTests_Single.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
// 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.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Templates;
using Avalonia.Data;
using Avalonia.Input;
using Avalonia.LogicalTree;
using Avalonia.Markup.Xaml.Data;
using Avalonia.Styling;
using Avalonia.VisualTree;
using Xunit;
Expand Down Expand Up @@ -199,6 +203,71 @@ public void Setting_Item_IsSelected_Sets_ListBox_Selection()
Assert.Equal(1, target.SelectedIndex);
}

[Fact]
public void SelectedItem_Should_Not_Cause_StackOverflow()
{
var viewModel = new TestStackOverflowViewModel()
{
Items = new List<string> { "foo", "bar", "baz" }
};

var target = new ListBox
{
Template = new FuncControlTemplate(CreateListBoxTemplate),
DataContext = viewModel,
Items = viewModel.Items
};

target.Bind(ListBox.SelectedItemProperty,
new Binding("SelectedItem") { Mode = BindingMode.TwoWay });

Assert.Equal(0, viewModel.SetterInvokedCount);

//here in real life stack overflow exception is thrown issue #855
target.SelectedItem = viewModel.Items[2];

Assert.Equal(viewModel.Items[1], target.SelectedItem);
Assert.Equal(1, viewModel.SetterInvokedCount);
}

private class TestStackOverflowViewModel : INotifyPropertyChanged
{
public List<string> Items { get; set; }

public int SetterInvokedCount { get; private set; }

public const int MaxInvokedCount = 1000;

private string _selectedItem;

public event PropertyChangedEventHandler PropertyChanged;

public string SelectedItem
{
get { return _selectedItem; }
set
{
if (_selectedItem != value)
{
SetterInvokedCount++;

int index = Items.IndexOf(value);

if (MaxInvokedCount > SetterInvokedCount && index > 0)
{
_selectedItem = Items[index - 1];
}
else
{
_selectedItem = value;
}

PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedItem)));
}
}
}
}

private Control CreateListBoxTemplate(ITemplatedControl parent)
{
return new ScrollViewer
Expand Down Expand Up @@ -237,4 +306,4 @@ private void ApplyTemplate(ListBox target)
target.Presenter.ApplyTemplate();
}
}
}
}

0 comments on commit 220a987

Please sign in to comment.