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