Jelajahi Sumber

Modernized some SelectingItemsControl tests.

And moved some of the tests that were specific to user interaction to `ListBoxTests` as `SelectingItemsControl` doesn't define user interactions.
Steven Kirk 2 tahun lalu
induk
melakukan
e609822311

+ 475 - 0
tests/Avalonia.Controls.UnitTests/ListBoxTests_Multiple.cs

@@ -1,17 +1,22 @@
+using System.Collections.Generic;
 using System.Linq;
 using Avalonia.Controls.Presenters;
 using Avalonia.Controls.Primitives;
 using Avalonia.Controls.Templates;
 using Avalonia.Input;
+using Avalonia.Input.Platform;
 using Avalonia.Styling;
 using Avalonia.UnitTests;
 using Avalonia.VisualTree;
+using Moq;
 using Xunit;
 
 namespace Avalonia.Controls.UnitTests
 {
     public class ListBoxTests_Multiple
     {
+        private MouseTestHelper _helper = new MouseTestHelper();
+
         [Fact]
         public void Focusing_Item_With_Shift_And_Arrow_Key_Should_Add_To_Selection()
         {
@@ -82,6 +87,468 @@ namespace Avalonia.Controls.UnitTests
             Assert.Equal(new[] { "Foo", "Bar" }, target.SelectedItems);
         }
 
+        [Fact]
+        public void Shift_Selecting_From_No_Selection_Selects_From_Start()
+        {
+            using (UnitTestApplication.Start())
+            {
+                var target = new ListBox
+                {
+                    Template = new FuncControlTemplate(CreateListBoxTemplate),
+                    ItemsSource = new[] { "Foo", "Bar", "Baz" },
+                    SelectionMode = SelectionMode.Multiple,
+                    Width = 100,
+                    Height = 100,
+                };
+
+                var root = new TestRoot(target);
+                root.LayoutManager.ExecuteInitialLayoutPass();
+
+                AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
+                _helper.Click(target.Presenter.Panel.Children[2], modifiers: KeyModifiers.Shift);
+
+                Assert.Equal(new[] { "Foo", "Bar", "Baz" }, target.SelectedItems);
+                Assert.Equal(new[] { 0, 1, 2 }, SelectedContainers(target));
+            }
+        }
+
+
+        [Fact]
+        public void Ctrl_Selecting_Raises_SelectionChanged_Events()
+        {
+            using (UnitTestApplication.Start())
+            {
+                var target = new ListBox
+                {
+                    Template = new FuncControlTemplate(CreateListBoxTemplate),
+                    ItemsSource = new[] { "Foo", "Bar", "Baz", "Qux" },
+                    SelectionMode = SelectionMode.Multiple,
+                    Width = 100,
+                    Height = 100,
+                };
+
+                var root = new TestRoot(target);
+                root.LayoutManager.ExecuteInitialLayoutPass();
+
+                AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
+
+                SelectionChangedEventArgs receivedArgs = null;
+
+                target.SelectionChanged += (_, args) => receivedArgs = args;
+
+                void VerifyAdded(string selection)
+                {
+                    Assert.NotNull(receivedArgs);
+                    Assert.Equal(new[] { selection }, receivedArgs.AddedItems);
+                    Assert.Empty(receivedArgs.RemovedItems);
+                }
+
+                void VerifyRemoved(string selection)
+                {
+                    Assert.NotNull(receivedArgs);
+                    Assert.Equal(new[] { selection }, receivedArgs.RemovedItems);
+                    Assert.Empty(receivedArgs.AddedItems);
+                }
+
+                _helper.Click(target.Presenter.Panel.Children[1]);
+
+                VerifyAdded("Bar");
+
+                receivedArgs = null;
+                _helper.Click(target.Presenter.Panel.Children[2], modifiers: KeyModifiers.Control);
+
+                VerifyAdded("Baz");
+
+                receivedArgs = null;
+                _helper.Click(target.Presenter.Panel.Children[3], modifiers: KeyModifiers.Control);
+
+                VerifyAdded("Qux");
+
+                receivedArgs = null;
+                _helper.Click(target.Presenter.Panel.Children[1], modifiers: KeyModifiers.Control);
+
+                VerifyRemoved("Bar");
+            }
+        }
+
+        [Fact]
+        public void Ctrl_Selecting_SelectedItem_With_Multiple_Selection_Active_Sets_SelectedItem_To_Next_Selection()
+        {
+            using (UnitTestApplication.Start())
+            {
+                var target = new ListBox
+                {
+                    Template = new FuncControlTemplate(CreateListBoxTemplate),
+                    ItemsSource = new[] { "Foo", "Bar", "Baz", "Qux" },
+                    SelectionMode = SelectionMode.Multiple,
+                    Width = 100,
+                    Height = 100,
+                };
+
+                var root = new TestRoot(target);
+                root.LayoutManager.ExecuteInitialLayoutPass();
+
+                AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
+                _helper.Click(target.Presenter.Panel.Children[1]);
+                _helper.Click(target.Presenter.Panel.Children[2], modifiers: KeyModifiers.Control);
+                _helper.Click(target.Presenter.Panel.Children[3], modifiers: KeyModifiers.Control);
+
+                Assert.Equal(1, target.SelectedIndex);
+                Assert.Equal("Bar", target.SelectedItem);
+                Assert.Equal(new[] { "Bar", "Baz", "Qux" }, target.SelectedItems);
+
+                _helper.Click(target.Presenter.Panel.Children[1], modifiers: KeyModifiers.Control);
+
+                Assert.Equal(2, target.SelectedIndex);
+                Assert.Equal("Baz", target.SelectedItem);
+                Assert.Equal(new[] { "Baz", "Qux" }, target.SelectedItems);
+            }
+        }
+
+        [Fact]
+        public void Ctrl_Selecting_Non_SelectedItem_With_Multiple_Selection_Active_Leaves_SelectedItem_The_Same()
+        {
+            using (UnitTestApplication.Start())
+            {
+                var target = new ListBox
+                {
+                    Template = new FuncControlTemplate(CreateListBoxTemplate),
+                    ItemsSource = new[] { "Foo", "Bar", "Baz" },
+                    SelectionMode = SelectionMode.Multiple,
+                    Width = 100,
+                    Height = 100,
+                };
+
+                var root = new TestRoot(target);
+                root.LayoutManager.ExecuteInitialLayoutPass();
+
+                AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
+                _helper.Click(target.Presenter.Panel.Children[1]);
+                _helper.Click(target.Presenter.Panel.Children[2], modifiers: KeyModifiers.Control);
+
+                Assert.Equal(1, target.SelectedIndex);
+                Assert.Equal("Bar", target.SelectedItem);
+
+                _helper.Click(target.Presenter.Panel.Children[2], modifiers: KeyModifiers.Control);
+
+                Assert.Equal(1, target.SelectedIndex);
+                Assert.Equal("Bar", target.SelectedItem);
+            }
+        }
+
+        [Fact]
+        public void Should_Ctrl_Select_Correct_Item_When_Duplicate_Items_Are_Present()
+        {
+            using (UnitTestApplication.Start())
+            {
+                var target = new ListBox
+                {
+                    Template = new FuncControlTemplate(CreateListBoxTemplate),
+                    ItemsSource = new[] { "Foo", "Bar", "Baz", "Foo", "Bar", "Baz" },
+                    SelectionMode = SelectionMode.Multiple,
+                    Width = 100,
+                    Height = 100,
+                };
+
+                var root = new TestRoot(target);
+                root.LayoutManager.ExecuteInitialLayoutPass();
+
+                AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
+                _helper.Click(target.Presenter.Panel.Children[3]);
+                _helper.Click(target.Presenter.Panel.Children[4], modifiers: KeyModifiers.Control);
+
+                var panel = target.Presenter.Panel;
+
+                Assert.Equal(new[] { "Foo", "Bar" }, target.SelectedItems);
+                Assert.Equal(new[] { 3, 4 }, SelectedContainers(target));
+            }
+        }
+
+        [Fact]
+        public void Should_Shift_Select_Correct_Item_When_Duplicates_Are_Present()
+        {
+            using (UnitTestApplication.Start())
+            {
+                var target = new ListBox
+                {
+                    Template = new FuncControlTemplate(CreateListBoxTemplate),
+                    ItemsSource = new[] { "Foo", "Bar", "Baz", "Foo", "Bar", "Baz" },
+                    SelectionMode = SelectionMode.Multiple,
+                    Width = 100,
+                    Height = 100,
+                };
+
+                var root = new TestRoot(target);
+                root.LayoutManager.ExecuteInitialLayoutPass();
+
+                AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
+                _helper.Click(target.Presenter.Panel.Children[3]);
+                _helper.Click(target.Presenter.Panel.Children[5], modifiers: KeyModifiers.Shift);
+
+                var panel = target.Presenter.Panel;
+
+                Assert.Equal(new[] { "Foo", "Bar", "Baz" }, target.SelectedItems);
+                Assert.Equal(new[] { 3, 4, 5 }, SelectedContainers(target));
+            }
+        }
+
+        [Fact]
+        public void Can_Shift_Select_All_Items_When_Duplicates_Are_Present()
+        {
+            using (UnitTestApplication.Start())
+            {
+                var target = new ListBox
+                {
+                    Template = new FuncControlTemplate(CreateListBoxTemplate),
+                    ItemsSource = new[] { "Foo", "Bar", "Baz", "Foo", "Bar", "Baz" },
+                    SelectionMode = SelectionMode.Multiple,
+                    Width = 100,
+                    Height = 100,
+                };
+
+                var root = new TestRoot(target);
+                root.LayoutManager.ExecuteInitialLayoutPass();
+
+                AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
+                _helper.Click(target.Presenter.Panel.Children[0]);
+                _helper.Click(target.Presenter.Panel.Children[5], modifiers: KeyModifiers.Shift);
+
+                var panel = target.Presenter.Panel;
+
+                Assert.Equal(new[] { "Foo", "Bar", "Baz", "Foo", "Bar", "Baz" }, target.SelectedItems);
+                Assert.Equal(new[] { 0, 1, 2, 3, 4, 5 }, SelectedContainers(target));
+            }
+        }
+
+        [Fact]
+        public void Shift_Selecting_Raises_SelectionChanged_Events()
+        {
+            using (UnitTestApplication.Start())
+            {
+                var target = new ListBox
+                {
+                    Template = new FuncControlTemplate(CreateListBoxTemplate),
+                    ItemsSource = new[] { "Foo", "Bar", "Baz", "Qux" },
+                    SelectionMode = SelectionMode.Multiple,
+                    Width = 100,
+                    Height = 100,
+                };
+                var root = new TestRoot(target);
+                root.LayoutManager.ExecuteInitialLayoutPass();
+
+                AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
+
+                SelectionChangedEventArgs receivedArgs = null;
+
+                target.SelectionChanged += (_, args) => receivedArgs = args;
+
+                void VerifyAdded(params string[] selection)
+                {
+                    Assert.NotNull(receivedArgs);
+                    Assert.Equal(selection, receivedArgs.AddedItems);
+                    Assert.Empty(receivedArgs.RemovedItems);
+                }
+
+                void VerifyRemoved(string selection)
+                {
+                    Assert.NotNull(receivedArgs);
+                    Assert.Equal(new[] { selection }, receivedArgs.RemovedItems);
+                    Assert.Empty(receivedArgs.AddedItems);
+                }
+
+                _helper.Click(target.Presenter.Panel.Children[1]);
+
+                VerifyAdded("Bar");
+
+                receivedArgs = null;
+                _helper.Click(target.Presenter.Panel.Children[3], modifiers: KeyModifiers.Shift);
+
+                VerifyAdded("Baz", "Qux");
+
+                receivedArgs = null;
+                _helper.Click(target.Presenter.Panel.Children[2], modifiers: KeyModifiers.Shift);
+
+                VerifyRemoved("Qux");
+            }
+        }
+
+        [Fact]
+        public void Duplicate_Items_Are_Added_To_SelectedItems_In_Order()
+        {
+            using (UnitTestApplication.Start())
+            {
+                var target = new ListBox
+                {
+                    Template = new FuncControlTemplate(CreateListBoxTemplate),
+                    ItemsSource = new[] { "Foo", "Bar", "Baz", "Foo", "Bar", "Baz" },
+                    SelectionMode = SelectionMode.Multiple,
+                    Width = 100,
+                    Height = 100,
+                };
+
+                var root = new TestRoot(target);
+                root.LayoutManager.ExecuteInitialLayoutPass();
+
+                AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
+                _helper.Click(target.Presenter.Panel.Children[0]);
+
+                Assert.Equal(new[] { "Foo" }, target.SelectedItems);
+
+                _helper.Click(target.Presenter.Panel.Children[4], modifiers: KeyModifiers.Control);
+
+                Assert.Equal(new[] { "Foo", "Bar" }, target.SelectedItems);
+
+                _helper.Click(target.Presenter.Panel.Children[3], modifiers: KeyModifiers.Control);
+
+                Assert.Equal(new[] { "Foo", "Bar", "Foo" }, target.SelectedItems);
+
+                _helper.Click(target.Presenter.Panel.Children[1], modifiers: KeyModifiers.Control);
+
+                Assert.Equal(new[] { "Foo", "Bar", "Foo", "Bar" }, target.SelectedItems);
+            }
+        }
+
+        [Fact]
+        public void Left_Click_On_SelectedItem_Should_Clear_Existing_Selection()
+        {
+            using (UnitTestApplication.Start())
+            {
+                var target = new ListBox
+                {
+                    Template = new FuncControlTemplate(CreateListBoxTemplate),
+                    ItemsSource = new[] { "Foo", "Bar", "Baz" },
+                    ItemTemplate = new FuncDataTemplate<string>((x, _) => new TextBlock { Width = 20, Height = 10 }),
+                    SelectionMode = SelectionMode.Multiple,
+                    Width = 100,
+                    Height = 100,
+                };
+
+                var root = new TestRoot(target);
+                root.LayoutManager.ExecuteInitialLayoutPass();
+
+                target.SelectAll();
+
+                Assert.Equal(3, target.SelectedItems.Count);
+
+                _helper.Click(target.Presenter.Panel.Children[0]);
+
+                Assert.Equal(1, target.SelectedItems.Count);
+                Assert.Equal(new[] { "Foo", }, target.SelectedItems);
+                Assert.Equal(new[] { 0 }, SelectedContainers(target));
+            }
+        }
+
+        [Fact]
+        public void Right_Click_On_SelectedItem_Should_Not_Clear_Existing_Selection()
+        {
+            using (UnitTestApplication.Start())
+            {
+                var target = new ListBox
+                {
+                    Template = new FuncControlTemplate(CreateListBoxTemplate),
+                    ItemsSource = new[] { "Foo", "Bar", "Baz" },
+                    ItemTemplate = new FuncDataTemplate<string>((x, _) => new TextBlock { Width = 20, Height = 10 }),
+                    SelectionMode = SelectionMode.Multiple,
+                    Width = 100,
+                    Height = 100,
+                };
+
+                var root = new TestRoot(target);
+                root.LayoutManager.ExecuteInitialLayoutPass();
+
+                target.SelectAll();
+
+                Assert.Equal(3, target.SelectedItems.Count);
+
+                _helper.Click(target.Presenter.Panel.Children[0], MouseButton.Right);
+
+                Assert.Equal(3, target.SelectedItems.Count);
+            }
+        }
+
+        [Fact]
+        public void Right_Click_On_UnselectedItem_Should_Clear_Existing_Selection()
+        {
+            using (UnitTestApplication.Start())
+            {
+                var target = new ListBox
+                {
+                    Template = new FuncControlTemplate(CreateListBoxTemplate),
+                    ItemsSource = new[] { "Foo", "Bar", "Baz" },
+                    ItemTemplate = new FuncDataTemplate<string>((x, _) => new TextBlock { Width = 20, Height = 10 }),
+                    SelectionMode = SelectionMode.Multiple,
+                    Width = 100,
+                    Height = 100,
+                };
+
+                var root = new TestRoot(target);
+                root.LayoutManager.ExecuteInitialLayoutPass();
+
+                AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
+                _helper.Click(target.Presenter.Panel.Children[0]);
+                _helper.Click(target.Presenter.Panel.Children[1], modifiers: KeyModifiers.Shift);
+
+                Assert.Equal(2, target.SelectedItems.Count);
+
+                _helper.Click(target.Presenter.Panel.Children[2], MouseButton.Right);
+
+                Assert.Equal(1, target.SelectedItems.Count);
+            }
+        }
+
+        [Fact]
+        public void Shift_Right_Click_Should_Not_Select_Multiple()
+        {
+            using (UnitTestApplication.Start())
+            {
+                var target = new ListBox
+                {
+                    Template = new FuncControlTemplate(CreateListBoxTemplate),
+                    ItemsSource = new[] { "Foo", "Bar", "Baz" },
+                    ItemTemplate = new FuncDataTemplate<string>((x, _) => new TextBlock { Width = 20, Height = 10 }),
+                    SelectionMode = SelectionMode.Multiple,
+                    Width = 100,
+                    Height = 100,
+                };
+
+                var root = new TestRoot(target);
+                root.LayoutManager.ExecuteInitialLayoutPass();
+
+                AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
+
+                _helper.Click(target.Presenter.Panel.Children[0]);
+                _helper.Click(target.Presenter.Panel.Children[2], MouseButton.Right, modifiers: KeyModifiers.Shift);
+
+                Assert.Equal(1, target.SelectedItems.Count);
+            }
+        }
+
+        [Fact]
+        public void Ctrl_Right_Click_Should_Not_Select_Multiple()
+        {
+            using (UnitTestApplication.Start())
+            {
+                var target = new ListBox
+                {
+                    Template = new FuncControlTemplate(CreateListBoxTemplate),
+                    ItemsSource = new[] { "Foo", "Bar", "Baz" },
+                    ItemTemplate = new FuncDataTemplate<string>((x, _) => new TextBlock { Width = 20, Height = 10 }),
+                    SelectionMode = SelectionMode.Multiple,
+                    Width = 100,
+                    Height = 100,
+                };
+
+                var root = new TestRoot(target);
+                root.LayoutManager.ExecuteInitialLayoutPass();
+
+                AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
+
+                _helper.Click(target.Presenter.Panel.Children[0]);
+                _helper.Click(target.Presenter.Panel.Children[2], MouseButton.Right, modifiers: KeyModifiers.Control);
+
+                Assert.Equal(1, target.SelectedItems.Count);
+            }
+        }
         private Control CreateListBoxTemplate(TemplatedControl parent, INameScope scope)
         {
             return new ScrollViewer
@@ -119,5 +586,13 @@ namespace Avalonia.Controls.UnitTests
             // Now the ItemsPresenter should be reigstered, so apply its template.
             ((Control)target.Presenter).ApplyTemplate();
         }
+
+        private static IEnumerable<int> SelectedContainers(SelectingItemsControl target)
+        {
+            return target.Presenter.Panel.Children
+                .Select(x => x.Classes.Contains(":selected") ? target.IndexFromContainer(x) : -1)
+                .Where(x => x != -1);
+        }
+
     }
 }

File diff ditekan karena terlalu besar
+ 135 - 587
tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests_Multiple.cs


Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini