| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321 |
- // Copyright (c) The Perspex Project. All rights reserved.
- // Licensed under the MIT license. See licence.md file in the project root for full license information.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using JetBrains.dotMemoryUnit;
- using Perspex.Controls;
- using Perspex.Controls.Primitives;
- using Perspex.Controls.Templates;
- using Perspex.VisualTree;
- using Xunit;
- using Xunit.Abstractions;
- namespace Perspex.LeakTests
- {
- [DotMemoryUnit(FailIfRunWithoutSupport = false)]
- public class ControlTests
- {
- public ControlTests(ITestOutputHelper atr)
- {
- TestApp.Initialize();
- DotMemoryUnitTestOutput.SetOutputMethod(atr.WriteLine);
- }
- [Fact]
- public void Canvas_Is_Freed()
- {
- Func<Window> run = () =>
- {
- var window = new Window
- {
- Content = new Canvas()
- };
- // Do a layout and make sure that Canvas gets added to visual tree.
- window.LayoutManager.ExecuteLayoutPass();
- Assert.IsType<Canvas>(window.Presenter.Child);
- // Clear the content and ensure the Canvas is removed.
- window.Content = null;
- window.LayoutManager.ExecuteLayoutPass();
- Assert.Null(window.Presenter.Child);
- return window;
- };
- var result = run();
- dotMemory.Check(memory =>
- Assert.Equal(0, memory.GetObjects(where => where.Type.Is<Canvas>()).ObjectsCount));
- }
- [Fact]
- public void Named_Canvas_Is_Freed()
- {
- Func<Window> run = () =>
- {
- var window = new Window
- {
- Content = new Canvas
- {
- Name = "foo"
- }
- };
- // Do a layout and make sure that Canvas gets added to visual tree.
- window.LayoutManager.ExecuteLayoutPass();
- Assert.IsType<Canvas>(window.Find<Canvas>("foo"));
- Assert.IsType<Canvas>(window.Presenter.Child);
- // Clear the content and ensure the Canvas is removed.
- window.Content = null;
- window.LayoutManager.ExecuteLayoutPass();
- Assert.Null(window.Presenter.Child);
- return window;
- };
- var result = run();
- dotMemory.Check(memory =>
- Assert.Equal(0, memory.GetObjects(where => where.Type.Is<Canvas>()).ObjectsCount));
- }
- [Fact]
- public void Templated_Child_Is_Freed_When_Template_Cleared()
- {
- Func<Window> run = () =>
- {
- var window = new Window
- {
- Content = new TestTemplatedControl()
- };
- // Do a layout and make sure that the control gets added to visual tree and its
- // template applied.
- window.LayoutManager.ExecuteLayoutPass();
- Assert.IsType<TestTemplatedControl>(window.Presenter.Child);
- Assert.IsType<Canvas>(window.Presenter.Child.GetVisualChildren().SingleOrDefault());
- // Clear the template and ensure the control template gets removed
- ((TestTemplatedControl)window.Content).Template = null;
- window.LayoutManager.ExecuteLayoutPass();
- Assert.Equal(0, window.Presenter.Child.GetVisualChildren().Count());
- return window;
- };
- var result = run();
- dotMemory.Check(memory =>
- Assert.Equal(0, memory.GetObjects(where => where.Type.Is<Canvas>()).ObjectsCount));
- }
- [Fact]
- public void ScrollViewer_With_Content_Is_Freed()
- {
- Func<Window> run = () =>
- {
- var window = new Window
- {
- Content = new ScrollViewer
- {
- Content = new Canvas()
- }
- };
- // Do a layout and make sure that ScrollViewer gets added to visual tree and its
- // template applied.
- window.LayoutManager.ExecuteLayoutPass();
- Assert.IsType<ScrollViewer>(window.Presenter.Child);
- Assert.IsType<Canvas>(((ScrollViewer)window.Presenter.Child).Presenter.Child);
- // Clear the content and ensure the ScrollViewer is removed.
- window.Content = null;
- window.LayoutManager.ExecuteLayoutPass();
- Assert.Null(window.Presenter.Child);
- return window;
- };
- var result = run();
- dotMemory.Check(memory =>
- Assert.Equal(0, memory.GetObjects(where => where.Type.Is<TextBox>()).ObjectsCount));
- dotMemory.Check(memory =>
- Assert.Equal(0, memory.GetObjects(where => where.Type.Is<Canvas>()).ObjectsCount));
- }
- [Fact]
- public void TextBox_Is_Freed()
- {
- Func<Window> run = () =>
- {
- var window = new Window
- {
- Content = new TextBox()
- };
- // Do a layout and make sure that TextBox gets added to visual tree and its
- // template applied.
- window.LayoutManager.ExecuteLayoutPass();
- Assert.IsType<TextBox>(window.Presenter.Child);
- Assert.NotEqual(0, window.Presenter.Child.GetVisualChildren().Count());
- // Clear the content and ensure the TextBox is removed.
- window.Content = null;
- window.LayoutManager.ExecuteLayoutPass();
- Assert.Null(window.Presenter.Child);
- return window;
- };
- var result = run();
- dotMemory.Check(memory =>
- Assert.Equal(0, memory.GetObjects(where => where.Type.Is<TextBox>()).ObjectsCount));
- }
- [Fact]
- public void TextBox_With_Xaml_Binding_Is_Freed()
- {
- Func<Window> run = () =>
- {
- var window = new Window
- {
- DataContext = new Node { Name = "foo" },
- Content = new TextBox()
- };
- var binding = new Perspex.Markup.Xaml.Data.Binding
- {
- Path = "Name"
- };
- var textBox = (TextBox)window.Content;
- textBox.Bind(TextBox.TextProperty, binding);
- // Do a layout and make sure that TextBox gets added to visual tree and its
- // Text property set.
- window.LayoutManager.ExecuteLayoutPass();
- Assert.IsType<TextBox>(window.Presenter.Child);
- Assert.Equal("foo", ((TextBox)window.Presenter.Child).Text);
- // Clear the content and DataContext and ensure the TextBox is removed.
- window.Content = null;
- window.DataContext = null;
- window.LayoutManager.ExecuteLayoutPass();
- Assert.Null(window.Presenter.Child);
- return window;
- };
- var result = run();
- dotMemory.Check(memory =>
- Assert.Equal(0, memory.GetObjects(where => where.Type.Is<TextBox>()).ObjectsCount));
- dotMemory.Check(memory =>
- Assert.Equal(0, memory.GetObjects(where => where.Type.Is<Node>()).ObjectsCount));
- }
- [Fact]
- public void TextBox_ScrollViewer_Is_Freed_When_Template_Cleared()
- {
- Func<Window> run = () =>
- {
- var window = new Window
- {
- Content = new TextBox()
- };
- // Do a layout and make sure that TextBox gets added to visual tree and its
- // template applied.
- window.LayoutManager.ExecuteLayoutPass();
- Assert.IsType<TextBox>(window.Presenter.Child);
- Assert.NotEqual(0, window.Presenter.Child.GetVisualChildren().Count());
- // Clear the template and ensure the TextBox template gets removed
- ((TextBox)window.Content).Template = null;
- window.LayoutManager.ExecuteLayoutPass();
- Assert.Equal(0, window.Presenter.Child.GetVisualChildren().Count());
- return window;
- };
- var result = run();
- dotMemory.Check(memory =>
- Assert.Equal(0, memory.GetObjects(where => where.Type.Is<ScrollViewer>()).ObjectsCount));
- }
- [Fact]
- public void TreeView_Is_Freed()
- {
- Func<Window> run = () =>
- {
- var nodes = new[]
- {
- new Node
- {
- Children = new[] { new Node() },
- }
- };
- TreeView target;
- var window = new Window
- {
- Content = target = new TreeView
- {
- DataTemplates = new DataTemplates
- {
- new FuncTreeDataTemplate<Node>(
- x => new TextBlock { Text = x.Name },
- x => x.Children)
- },
- Items = nodes
- }
- };
- // Do a layout and make sure that TreeViewItems get realized.
- window.LayoutManager.ExecuteLayoutPass();
- Assert.Equal(1, target.ItemContainerGenerator.Containers.Count());
- // Clear the content and ensure the TreeView is removed.
- window.Content = null;
- window.LayoutManager.ExecuteLayoutPass();
- Assert.Null(window.Presenter.Child);
- return window;
- };
- var result = run();
- dotMemory.Check(memory =>
- Assert.Equal(0, memory.GetObjects(where => where.Type.Is<TreeView>()).ObjectsCount));
- }
- private class TestTemplatedControl : TemplatedControl
- {
- public static readonly StyledProperty<int> IsCanvasVisibleProperty =
- PerspexProperty.Register<TestTemplatedControl, int>("IsCanvasVisible");
- public TestTemplatedControl()
- {
- Template = new FuncControlTemplate<TestTemplatedControl>(parent =>
- new Canvas
- {
- [~IsVisibleProperty] = parent[~IsCanvasVisibleProperty]
- });
- }
- }
- private class Node
- {
- public string Name { get; set; }
- public IEnumerable<Node> Children { get; set; }
- }
- }
- }
|