|
|
@@ -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));
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|