4 changed files with 348 additions and 90 deletions
@ -0,0 +1,245 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using Avalonia.Collections; |
||||
|
using Avalonia.Controls.Selection; |
||||
|
using Avalonia.Controls.Utils; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Avalonia.Controls.UnitTests.Utils |
||||
|
{ |
||||
|
public class SelectedItemsSyncTests |
||||
|
{ |
||||
|
[Fact] |
||||
|
public void Initial_Items_Are_From_Model() |
||||
|
{ |
||||
|
var target = CreateTarget(); |
||||
|
var items = target.SelectedItems; |
||||
|
|
||||
|
Assert.Equal(new[] { "bar", "baz" }, items); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Selecting_On_Model_Adds_Item() |
||||
|
{ |
||||
|
var target = CreateTarget(); |
||||
|
var items = target.SelectedItems; |
||||
|
|
||||
|
target.SelectionModel.Select(0); |
||||
|
|
||||
|
Assert.Equal(new[] { "bar", "baz", "foo" }, items); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Selecting_Duplicate_On_Model_Adds_Item() |
||||
|
{ |
||||
|
var target = CreateTarget(new[] { "foo", "bar", "baz", "foo", "bar", "baz" }); |
||||
|
var items = target.SelectedItems; |
||||
|
|
||||
|
target.SelectionModel.Select(4); |
||||
|
|
||||
|
Assert.Equal(new[] { "bar", "baz", "bar" }, items); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Deselecting_On_Model_Removes_Item() |
||||
|
{ |
||||
|
var target = CreateTarget(); |
||||
|
var items = target.SelectedItems; |
||||
|
|
||||
|
target.SelectionModel.Deselect(1); |
||||
|
|
||||
|
Assert.Equal(new[] { "baz" }, items); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Deselecting_Duplicate_On_Model_Removes_Item() |
||||
|
{ |
||||
|
var target = CreateTarget(new[] { "foo", "bar", "baz", "foo", "bar", "baz" }); |
||||
|
var items = target.SelectedItems; |
||||
|
|
||||
|
target.SelectionModel.Select(4); |
||||
|
target.SelectionModel.Deselect(4); |
||||
|
|
||||
|
Assert.Equal(new[] { "baz", "bar" }, items); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Reassigning_Model_Resets_Items() |
||||
|
{ |
||||
|
var target = CreateTarget(); |
||||
|
var items = target.SelectedItems; |
||||
|
|
||||
|
var newModel = new SelectionModel<string> |
||||
|
{ |
||||
|
Source = (string[])target.SelectionModel.Source, |
||||
|
SingleSelect = false |
||||
|
}; |
||||
|
|
||||
|
newModel.Select(0); |
||||
|
newModel.Select(1); |
||||
|
|
||||
|
target.SelectionModel = newModel; |
||||
|
|
||||
|
Assert.Equal(new[] { "foo", "bar" }, items); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Reassigning_Model_Tracks_New_Model() |
||||
|
{ |
||||
|
var target = CreateTarget(); |
||||
|
var items = target.SelectedItems; |
||||
|
|
||||
|
var newModel = new SelectionModel<string> |
||||
|
{ |
||||
|
Source = (string[])target.SelectionModel.Source, |
||||
|
SingleSelect = false |
||||
|
}; |
||||
|
|
||||
|
target.SelectionModel = newModel; |
||||
|
|
||||
|
newModel.Select(0); |
||||
|
newModel.Select(1); |
||||
|
|
||||
|
Assert.Equal(new[] { "foo", "bar" }, items); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Adding_To_Items_Selects_On_Model() |
||||
|
{ |
||||
|
var target = CreateTarget(); |
||||
|
var items = target.SelectedItems; |
||||
|
|
||||
|
items.Add("foo"); |
||||
|
|
||||
|
Assert.Equal(new[] { 0, 1, 2 }, target.SelectionModel.SelectedIndexes); |
||||
|
Assert.Equal(new[] { "bar", "baz", "foo" }, items); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Removing_From_Items_Deselects_On_Model() |
||||
|
{ |
||||
|
var target = CreateTarget(); |
||||
|
var items = target.SelectedItems; |
||||
|
|
||||
|
items.Remove("baz"); |
||||
|
|
||||
|
Assert.Equal(new[] { 1 }, target.SelectionModel.SelectedIndexes); |
||||
|
Assert.Equal(new[] { "bar" }, items); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Replacing_Item_Updates_Model() |
||||
|
{ |
||||
|
var target = CreateTarget(); |
||||
|
var items = target.SelectedItems; |
||||
|
|
||||
|
items[0] = "foo"; |
||||
|
|
||||
|
Assert.Equal(new[] { 0, 2 }, target.SelectionModel.SelectedIndexes); |
||||
|
Assert.Equal(new[] { "foo", "baz" }, items); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Clearing_Items_Updates_Model() |
||||
|
{ |
||||
|
var target = CreateTarget(); |
||||
|
var items = target.SelectedItems; |
||||
|
|
||||
|
items.Clear(); |
||||
|
|
||||
|
Assert.Empty(target.SelectionModel.SelectedIndexes); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Setting_Items_Updates_Model() |
||||
|
{ |
||||
|
var target = CreateTarget(); |
||||
|
var oldItems = target.SelectedItems; |
||||
|
|
||||
|
var newItems = new AvaloniaList<string> { "foo", "baz" }; |
||||
|
target.SelectedItems = newItems; |
||||
|
|
||||
|
Assert.Equal(new[] { 0, 2 }, target.SelectionModel.SelectedIndexes); |
||||
|
Assert.Same(newItems, target.SelectedItems); |
||||
|
Assert.NotSame(oldItems, target.SelectedItems); |
||||
|
Assert.Equal(new[] { "foo", "baz" }, newItems); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Setting_Items_Subscribes_To_Model() |
||||
|
{ |
||||
|
var target = CreateTarget(); |
||||
|
var items = new AvaloniaList<string> { "foo", "baz" }; |
||||
|
|
||||
|
target.SelectedItems = items; |
||||
|
target.SelectionModel.Select(1); |
||||
|
|
||||
|
Assert.Equal(new[] { "foo", "baz", "bar" }, items); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Setting_Items_To_Null_Creates_Empty_Items() |
||||
|
{ |
||||
|
var target = CreateTarget(); |
||||
|
var oldItems = target.SelectedItems; |
||||
|
|
||||
|
target.SelectedItems = null; |
||||
|
|
||||
|
var newItems = Assert.IsType<AvaloniaList<object>>(target.SelectedItems); |
||||
|
|
||||
|
Assert.NotSame(oldItems, newItems); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Handles_Null_Model_Source() |
||||
|
{ |
||||
|
var model = new SelectionModel<string> { SingleSelect = false }; |
||||
|
model.Select(1); |
||||
|
|
||||
|
var target = new SelectedItemsSync(model); |
||||
|
var items = target.SelectedItems; |
||||
|
|
||||
|
Assert.Empty(items); |
||||
|
|
||||
|
model.Select(2); |
||||
|
model.Source = new[] { "foo", "bar", "baz" }; |
||||
|
|
||||
|
Assert.Equal(new[] { "bar", "baz" }, items); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Does_Not_Accept_Fixed_Size_Items() |
||||
|
{ |
||||
|
var target = CreateTarget(); |
||||
|
|
||||
|
Assert.Throws<NotSupportedException>(() => |
||||
|
target.SelectedItems = new[] { "foo", "bar", "baz" }); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Selected_Items_Can_Be_Set_Before_SelectionModel_Source() |
||||
|
{ |
||||
|
var model = new SelectionModel<string>(); |
||||
|
var target = new SelectedItemsSync(model); |
||||
|
var items = new AvaloniaList<string> { "foo", "bar", "baz" }; |
||||
|
var selectedItems = new AvaloniaList<string> { "bar" }; |
||||
|
|
||||
|
target.SelectedItems = selectedItems; |
||||
|
model.Source = items; |
||||
|
|
||||
|
Assert.Equal(1, model.SelectedIndex); |
||||
|
} |
||||
|
|
||||
|
private static SelectedItemsSync CreateTarget( |
||||
|
IEnumerable<string> items = null) |
||||
|
{ |
||||
|
items ??= new[] { "foo", "bar", "baz" }; |
||||
|
|
||||
|
var model = new SelectionModel<string> { Source = items, SingleSelect = false }; |
||||
|
model.SelectRange(1, 2); |
||||
|
|
||||
|
var target = new SelectedItemsSync(model); |
||||
|
return target; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue