csharpc-sharpdotnetxamlavaloniauicross-platformcross-platform-xamlavaloniaguimulti-platformuser-interfacedotnetcore
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
5.1 KiB
150 lines
5.1 KiB
using System;
|
|
using Avalonia.Animation;
|
|
using Avalonia.Controls;
|
|
using Avalonia.Styling;
|
|
using Avalonia.Threading;
|
|
using Avalonia.UnitTests;
|
|
using Xunit;
|
|
|
|
namespace Avalonia.LeakTests
|
|
{
|
|
public class TransitionTests : ScopedTestBase
|
|
{
|
|
[Fact]
|
|
public void Transition_On_StyledProperty_Is_Freed()
|
|
{
|
|
var clock = new MockGlobalClock();
|
|
|
|
using (UnitTestApplication.Start(TestServices.StyledWindow.With(globalClock: clock)))
|
|
{
|
|
WeakReference Run()
|
|
{
|
|
var opacityTransition = new DoubleTransition { Duration = TimeSpan.FromSeconds(1), Property = Border.OpacityProperty, };
|
|
|
|
var border = new Border { Transitions = new Transitions() { opacityTransition } };
|
|
var window = new Window();
|
|
window.Content = border;
|
|
window.Show();
|
|
|
|
border.Opacity = 0;
|
|
|
|
clock.Pulse(TimeSpan.FromSeconds(0));
|
|
clock.Pulse(TimeSpan.FromSeconds(0.5));
|
|
|
|
Assert.Equal(0.5, border.Opacity);
|
|
|
|
var transitionInstance = border.TryGetTransitionInstance(opacityTransition);
|
|
Assert.NotNull(transitionInstance);
|
|
|
|
clock.Pulse(TimeSpan.FromSeconds(1));
|
|
|
|
Assert.Equal(0, border.Opacity);
|
|
|
|
window.Close();
|
|
|
|
return new WeakReference(transitionInstance);
|
|
}
|
|
|
|
var weakTransitionInstance = Run();
|
|
Assert.True(weakTransitionInstance.IsAlive);
|
|
|
|
CollectGarbage();
|
|
|
|
Assert.False(weakTransitionInstance.IsAlive);
|
|
}
|
|
}
|
|
|
|
[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) }
|
|
};
|
|
|
|
WeakReference Run()
|
|
{
|
|
var button = new Button() { Theme = controlTheme };
|
|
var window = new Window();
|
|
window.Content = button;
|
|
window.Show();
|
|
window.Content = null;
|
|
window.Close();
|
|
|
|
return new WeakReference(button);
|
|
}
|
|
|
|
var weakButton = Run();
|
|
Assert.True(weakButton.IsAlive);
|
|
|
|
CollectGarbage();
|
|
|
|
Assert.False(weakButton.IsAlive);
|
|
}
|
|
}
|
|
|
|
[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) }
|
|
};
|
|
|
|
WeakReference Run()
|
|
{
|
|
var window = new Window();
|
|
window.Show();
|
|
var button = new Button() { Theme = controlTheme };
|
|
window.Content = new UserControl
|
|
{
|
|
Content = button,
|
|
// When invisible, Button won't be attached to the visual tree
|
|
IsVisible = false
|
|
};
|
|
window.Content = null;
|
|
window.Close();
|
|
|
|
return new WeakReference(button);
|
|
}
|
|
|
|
var weakButton = Run();
|
|
Assert.True(weakButton.IsAlive);
|
|
|
|
CollectGarbage();
|
|
|
|
Assert.False(weakButton.IsAlive);
|
|
}
|
|
}
|
|
|
|
private static void CollectGarbage()
|
|
{
|
|
// Process all Loaded events to free control reference(s)
|
|
Dispatcher.UIThread.RunJobs(DispatcherPriority.Loaded);
|
|
GC.Collect();
|
|
}
|
|
}
|
|
}
|
|
|