1
0
Max Katz 1 жил өмнө
parent
commit
db6110804f

+ 92 - 3
tests/Avalonia.LeakTests/TransitionTests.cs

@@ -1,6 +1,8 @@
 using System;
 using Avalonia.Animation;
 using Avalonia.Controls;
+using Avalonia.Data;
+using Avalonia.Styling;
 using Avalonia.UnitTests;
 using JetBrains.dotMemoryUnit;
 using Xunit;
@@ -16,18 +18,18 @@ namespace Avalonia.LeakTests
             DotMemoryUnitTestOutput.SetOutputMethod(atr.WriteLine);
         }
 
-        [Fact(Skip = "TODO: Fix this leak")]
+        [Fact]
         public void Transition_On_StyledProperty_Is_Freed()
         {
             var clock = new MockGlobalClock();
 
-            using (UnitTestApplication.Start(new TestServices(globalClock: clock)))
+            using (UnitTestApplication.Start(TestServices.StyledWindow.With(globalClock: clock)))
             {
                 Func<Border> run = () =>
                 {
                     var border = new Border
                     {
-                        Transitions =
+                        Transitions = new Transitions()
                         {
                             new DoubleTransition
                             {
@@ -36,6 +38,9 @@ namespace Avalonia.LeakTests
                             }
                         }
                     };
+                    var window = new Window();
+                    window.Content = border;
+                    window.Show();
 
                     border.Opacity = 0;
 
@@ -47,6 +52,9 @@ namespace Avalonia.LeakTests
                     clock.Pulse(TimeSpan.FromSeconds(1));
 
                     Assert.Equal(0, border.Opacity);
+
+                    window.Close();
+
                     return border;
                 };
 
@@ -56,5 +64,86 @@ namespace Avalonia.LeakTests
                     Assert.Equal(0, memory.GetObjects(where => where.Type.Is<TransitionInstance>()).ObjectsCount));
             }
         }
+        
+        [Fact]
+        public void Shared_Transition_Collection_Is_Not_Leaking()
+        {
+            var clock = new MockGlobalClock();
+            using (UnitTestApplication.Start(TestServices.StyledWindow.With(globalClock: clock)))
+            {
+                // Our themes do share transition collections, so we need to test this scenario well.
+                var sharedTransitions = new Transitions
+                {
+                    new TransformOperationsTransition
+                    {
+                        Property = Visual.RenderTransformProperty, Duration = TimeSpan.FromSeconds(0.750)
+                    }
+                };
+                var controlTheme = new ControlTheme(typeof(Button))
+                {
+                    BasedOn = Application.Current?.Resources[typeof(Button)] as ControlTheme,
+                    Setters = { new Setter(Animatable.TransitionsProperty, sharedTransitions) }
+                };
+                
+                Func<Window> run = () =>
+                {
+                    var button = new Button() { Theme = controlTheme };
+                    var window = new Window();
+                    window.Content = button;
+                    window.Show();
+                    window.Content = null;
+                    window.Close();
+
+                    return window;
+                };
+
+                var result = run();
+
+                dotMemory.Check(memory =>
+                    Assert.Equal(0, memory.GetObjects(where => where.Type.Is<Button>()).ObjectsCount));
+            }
+        }
+
+        [Fact]
+        public void Lazily_Created_Control_Should_Not_Leak_Transitions()
+        {
+            var clock = new MockGlobalClock();
+            using (UnitTestApplication.Start(TestServices.StyledWindow.With(globalClock: clock)))
+            {
+                var sharedTransitions = new Transitions
+                {
+                    new TransformOperationsTransition
+                    {
+                        Property = Visual.RenderTransformProperty, Duration = TimeSpan.FromSeconds(0.750)
+                    }
+                };
+                var controlTheme = new ControlTheme(typeof(Button))
+                {
+                    BasedOn = Application.Current?.Resources[typeof(Button)] as ControlTheme,
+                    Setters = { new Setter(Animatable.TransitionsProperty, sharedTransitions) }
+                };
+                
+                Func<Window> run = () =>
+                {
+                    var window = new Window();
+                    window.Show();
+                    window.Content = new UserControl
+                    {
+                        Content = new Button() { Theme = controlTheme },
+                        // When invisible, Button won't be attached to the visual tree
+                        IsVisible = false
+                    };
+                    window.Content = null;
+                    window.Close();
+
+                    return window;
+                };
+
+                var result = run();
+
+                dotMemory.Check(memory =>
+                    Assert.Equal(0, memory.GetObjects(where => where.Type.Is<Button>()).ObjectsCount));
+            }
+        }
     }
 }