Browse Source

Update ListBoxTests

Now ListBox is virtualized it needs more setup for unit testing.
Steven Kirk 9 years ago
parent
commit
2d5a41a729

+ 80 - 54
tests/Avalonia.Controls.UnitTests/ListBoxTests.cs

@@ -7,6 +7,7 @@ using Avalonia.Controls.Templates;
 using Avalonia.Input;
 using Avalonia.LogicalTree;
 using Avalonia.Styling;
+using Avalonia.UnitTests;
 using Avalonia.VisualTree;
 using Xunit;
 
@@ -20,18 +21,13 @@ namespace Avalonia.Controls.UnitTests
             var target = new ListBox
             {
                 Template = CreateListBoxTemplate(),
+                Items = new[] { "Foo" },
                 ItemTemplate = new FuncDataTemplate<string>(_ => new Canvas()),
             };
 
-            target.Items = new[] { "Foo" };
-            target.ApplyTemplate();
-            target.Presenter.ApplyTemplate();
+            Prepare(target);
 
             var container = (ListBoxItem)target.Presenter.Panel.Children[0];
-            container.Template = ListBoxItemTemplate();
-            container.ApplyTemplate();
-            ((ContentPresenter)container.Presenter).UpdateChild();
-
             Assert.IsType<Canvas>(container.Presenter.Child);
         }
 
@@ -43,7 +39,7 @@ namespace Avalonia.Controls.UnitTests
                 Template = CreateListBoxTemplate(),
             };
 
-            ApplyTemplate(target);
+            Prepare(target);
 
             Assert.IsType<ItemsPresenter>(target.Presenter);
         }
@@ -51,78 +47,85 @@ namespace Avalonia.Controls.UnitTests
         [Fact]
         public void ListBoxItem_Containers_Should_Be_Generated()
         {
-            var items = new[] { "Foo", "Bar", "Baz " };
-            var target = new ListBox
+            using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface))
             {
-                Template = CreateListBoxTemplate(),
-                Items = items,
-            };
+                var items = new[] { "Foo", "Bar", "Baz " };
+                var target = new ListBox
+                {
+                    Template = CreateListBoxTemplate(),
+                    Items = items,
+                };
 
-            ApplyTemplate(target);
+                Prepare(target);
 
-            var text = target.Presenter.Panel.Children
-                .OfType<ListBoxItem>()
-                .Do(x => x.Template = ListBoxItemTemplate())
-                .Do(x => { x.ApplyTemplate(); ((ContentPresenter)x.Presenter).UpdateChild(); })
-                .Select(x => x.Presenter.Child)
-                .OfType<TextBlock>()
-                .Select(x => x.Text)
-                .ToList();
+                var text = target.Presenter.Panel.Children
+                    .OfType<ListBoxItem>()
+                    .Select(x => x.Presenter.Child)
+                    .OfType<TextBlock>()
+                    .Select(x => x.Text)
+                    .ToList();
 
-            Assert.Equal(items, text);
+                Assert.Equal(items, text);
+            }
         }
 
         [Fact]
         public void LogicalChildren_Should_Be_Set_For_DataTemplate_Generated_Items()
         {
-            var target = new ListBox
+            using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface))
             {
-                Template = CreateListBoxTemplate(),
-                Items = new[] { "Foo", "Bar", "Baz " },
-            };
+                var target = new ListBox
+                {
+                    Template = CreateListBoxTemplate(),
+                    Items = new[] { "Foo", "Bar", "Baz " },
+                };
 
-            ApplyTemplate(target);
+                Prepare(target);
 
-            Assert.Equal(3, target.GetLogicalChildren().Count());
+                Assert.Equal(3, target.GetLogicalChildren().Count());
 
-            foreach (var child in target.GetLogicalChildren())
-            {
-                Assert.IsType<ListBoxItem>(child);
+                foreach (var child in target.GetLogicalChildren())
+                {
+                    Assert.IsType<ListBoxItem>(child);
+                }
             }
         }
 
         [Fact]
         public void DataContexts_Should_Be_Correctly_Set()
         {
-            var items = new object[]
+            using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface))
             {
-                "Foo",
-                new Item("Bar"),
-                new TextBlock { Text = "Baz" },
-                new ListBoxItem { Content = "Qux" },
-            };
+                var items = new object[]
+                {
+                    "Foo",
+                    new Item("Bar"),
+                    new TextBlock { Text = "Baz" },
+                    new ListBoxItem { Content = "Qux" },
+                };
 
-            var target = new ListBox
-            {
-                Template = CreateListBoxTemplate(),
-                DataContext = "Base",
-                DataTemplates = new DataTemplates
+                var target = new ListBox
+                {
+                    Template = CreateListBoxTemplate(),
+                    DataContext = "Base",
+                    DataTemplates = new DataTemplates
                 {
                     new FuncDataTemplate<Item>(x => new Button { Content = x })
                 },
-                Items = items,
-            };
+                    Items = items,
+                };
 
-            ApplyTemplate(target);
+                Prepare(target);
 
-            var dataContexts = target.Presenter.Panel.Children
-                .Cast<Control>()
-                .Select(x => x.DataContext)
-                .ToList();
+                var dataContexts = target.Presenter.Panel.Children
+                    .Cast<Control>()
+                    .Select(x => x.DataContext)
+                    .ToList();
 
-            Assert.Equal(
-                new object[] { items[0], items[1], "Base", "Base" },
-                dataContexts);
+                Assert.Equal(
+                    new object[] { items[0], items[1], "Base", "Base" },
+                    dataContexts);
+            }
         }
 
         private FuncControlTemplate CreateListBoxTemplate()
@@ -136,6 +139,7 @@ namespace Avalonia.Controls.UnitTests
                     {
                         Name = "PART_ItemsPresenter",
                         [~ItemsPresenter.ItemsProperty] = parent.GetObservable(ItemsControl.ItemsProperty),
+                        [~ItemsPresenter.ItemsPanelProperty] = parent.GetObservable(ItemsControl.ItemsPanelProperty),
                     }
                 });
         }
@@ -159,7 +163,7 @@ namespace Avalonia.Controls.UnitTests
             };
         }
 
-        private void ApplyTemplate(ListBox target)
+        private void Prepare(ListBox target)
         {
             // Apply the template to the ListBox itself.
             target.ApplyTemplate();
@@ -173,6 +177,28 @@ namespace Avalonia.Controls.UnitTests
 
             // Now the ItemsPresenter should be reigstered, so apply its template.
             target.Presenter.ApplyTemplate();
+
+            // Because ListBox items are virtualized we need to do a layout to make them appear.
+            target.Measure(new Size(100, 100));
+            target.Arrange(new Rect(0, 0, 100, 100));
+
+            // Now set and apply the item templates.
+            foreach (ListBoxItem item in target.Presenter.Panel.Children)
+            {
+                item.Template = ListBoxItemTemplate();
+                item.ApplyTemplate();
+                item.Presenter.ApplyTemplate();
+                ((ContentPresenter)item.Presenter).UpdateChild();
+            }
+
+            // The items were created before the template was applied, so now we need to go back
+            // and re-arrange everything.
+            foreach (IControl i in target.GetSelfAndVisualDescendents())
+            {
+                i.InvalidateArrange();
+            }
+
+            target.Arrange(new Rect(0, 0, 100, 100));
         }
 
         private class Item

+ 3 - 0
tests/Avalonia.UnitTests/TestServices.cs

@@ -27,6 +27,9 @@ namespace Avalonia.UnitTests
             threadingInterface: Mock.Of<IPlatformThreadingInterface>(x => x.CurrentThreadIsLoopThread == true),
             windowingPlatform: new MockWindowingPlatform());
 
+        public static readonly TestServices MockPlatformRenderInterface = new TestServices(
+            renderInterface: CreateRenderInterfaceMock());
+
         public static readonly TestServices MockPlatformWrapper = new TestServices(
             platformWrapper: Mock.Of<IPclPlatformWrapper>());