Files

214 lines
6.0 KiB
C#

using System.Reflection;
using Avalonia.Controls;
using Avalonia.Threading;
using Shouldly;
using Xunit;
using AtomUIWindow = AtomUI.Desktop.Controls.Window;
namespace AtomUI.Desktop.Controls.Tests.TreeView;
public class TreeViewPinnedOpenTests
{
static TreeViewPinnedOpenTests()
{
AvaloniaTestApp.EnsureInitialized();
}
[Fact]
public void Pinned_FloatableTreeView_Opens_And_Rejects_Normal_Close()
{
var flyout = CreateFlyout();
var tree = CreateTree(flyout);
var window = CreateWindow(tree);
try
{
window.Show();
Dispatcher.UIThread.RunJobs();
SetPopupPinnedOpen(tree, true);
Dispatcher.UIThread.RunJobs();
flyout.IsPopupPinnedOpen.ShouldBeTrue();
flyout.IsOpen.ShouldBeTrue();
flyout.Popup.ShouldBeOfType<Popup>().IsPopupPinnedOpen.ShouldBeTrue();
tree.Close();
Dispatcher.UIThread.RunJobs();
flyout.IsOpen.ShouldBeTrue();
flyout.Popup.IsOpen.ShouldBeTrue();
}
finally
{
SetPopupPinnedOpenIfAvailable(tree, false);
flyout.Hide();
window.Close();
Dispatcher.UIThread.RunJobs();
}
}
[Fact]
public void Pinned_FloatableTreeView_Replacement_Closes_Old_And_Opens_New_Flyout()
{
var oldFlyout = CreateFlyout();
var newFlyout = CreateFlyout();
var tree = CreateTree(oldFlyout);
var window = CreateWindow(tree);
try
{
window.Show();
Dispatcher.UIThread.RunJobs();
SetPopupPinnedOpen(tree, true);
Dispatcher.UIThread.RunJobs();
oldFlyout.IsOpen.ShouldBeTrue();
tree.TreeViewFlyout = newFlyout;
Dispatcher.UIThread.RunJobs();
oldFlyout.IsPopupPinnedOpen.ShouldBeFalse();
oldFlyout.IsOpen.ShouldBeFalse();
oldFlyout.Popup.IsOpen.ShouldBeFalse();
newFlyout.IsPopupPinnedOpen.ShouldBeTrue();
newFlyout.IsOpen.ShouldBeTrue();
}
finally
{
SetPopupPinnedOpenIfAvailable(tree, false);
oldFlyout.Hide();
newFlyout.Hide();
window.Close();
Dispatcher.UIThread.RunJobs();
}
}
[Fact]
public void Pinned_FloatableTreeView_Detach_ForceCloses_And_Reattach_Reopens_Flyout()
{
var flyout = CreateFlyout();
var tree = CreateTree(flyout);
var window = CreateWindow(tree);
try
{
window.Show();
Dispatcher.UIThread.RunJobs();
SetPopupPinnedOpen(tree, true);
Dispatcher.UIThread.RunJobs();
flyout.IsOpen.ShouldBeTrue();
window.Content = new Border();
Dispatcher.UIThread.RunJobs();
flyout.IsPopupPinnedOpen.ShouldBeFalse();
flyout.IsOpen.ShouldBeFalse();
flyout.Popup.IsOpen.ShouldBeFalse();
window.Content = tree;
Dispatcher.UIThread.RunJobs();
flyout.IsPopupPinnedOpen.ShouldBeTrue();
flyout.IsOpen.ShouldBeTrue();
}
finally
{
SetPopupPinnedOpenIfAvailable(tree, false);
flyout.Hide();
window.Close();
Dispatcher.UIThread.RunJobs();
}
}
[Fact]
public void Unpinned_FloatableTreeView_Does_Not_Repin_The_Flyout_When_It_Reopens()
{
var flyout = CreateFlyout();
var tree = CreateTree(flyout);
var window = CreateWindow(tree);
try
{
window.Show();
Dispatcher.UIThread.RunJobs();
SetPopupPinnedOpen(tree, true);
Dispatcher.UIThread.RunJobs();
flyout.IsOpen.ShouldBeTrue();
SetPopupPinnedOpen(tree, false);
Dispatcher.UIThread.RunJobs();
flyout.IsPopupPinnedOpen.ShouldBeFalse();
flyout.IsOpen.ShouldBeTrue();
flyout.Hide();
Dispatcher.UIThread.RunJobs();
flyout.IsOpen.ShouldBeFalse();
flyout.ShowAt(tree);
Dispatcher.UIThread.RunJobs();
flyout.IsPopupPinnedOpen.ShouldBeFalse();
flyout.Hide();
Dispatcher.UIThread.RunJobs();
flyout.IsOpen.ShouldBeFalse();
}
finally
{
SetPopupPinnedOpenIfAvailable(tree, false);
flyout.CloseForLifecycle();
window.Close();
Dispatcher.UIThread.RunJobs();
}
}
private static FloatableTreeView CreateTree(TreeViewFlyout flyout)
{
var tree = new FloatableTreeView
{
Width = 180,
Height = 120,
TreeViewFlyout = flyout,
IsMotionEnabled = false
};
tree.Items.Add(new TreeItemNode { Header = "Anchor" });
return tree;
}
private static TreeViewFlyout CreateFlyout()
{
var flyout = new TreeViewFlyout
{
IsMotionEnabled = false,
ShouldUseOverlayPopup = true
};
flyout.Items.Add(new TreeItemNode { Header = "Child" });
return flyout;
}
private static AtomUIWindow CreateWindow(Control content)
{
return new AtomUIWindow
{
Width = 360,
Height = 260,
Content = content
};
}
private static void SetPopupPinnedOpen(object target, bool value)
{
var property = target.GetType().GetProperty(
"IsPopupPinnedOpen",
BindingFlags.Instance | BindingFlags.NonPublic);
property.ShouldNotBeNull($"{target.GetType().Name} must own the internal popup pin contract.")
.SetValue(target, value);
}
private static void SetPopupPinnedOpenIfAvailable(object target, bool value)
{
target.GetType()
.GetProperty("IsPopupPinnedOpen", BindingFlags.Instance | BindingFlags.NonPublic)?
.SetValue(target, value);
}
}