Browse Source

Fix ContextMenu tests

pull/6059/head
Max Katz 5 years ago
parent
commit
18812a217f
  1. 15
      src/Avalonia.Controls/ContextMenu.cs
  2. 88
      tests/Avalonia.Controls.UnitTests/ContextMenuTests.cs

15
src/Avalonia.Controls/ContextMenu.cs

@ -224,6 +224,7 @@ namespace Avalonia.Controls
if (e.OldValue is ContextMenu oldMenu)
{
control.ContextRequested -= ControlContextRequested;
control.DetachedFromVisualTree -= ControlDetachedFromVisualTree;
oldMenu._attachedControls?.Remove(control);
((ISetLogicalParent?)oldMenu._popup)?.SetParent(null);
}
@ -233,6 +234,7 @@ namespace Avalonia.Controls
newMenu._attachedControls ??= new List<Control>();
newMenu._attachedControls.Add(control);
control.ContextRequested += ControlContextRequested;
control.DetachedFromVisualTree += ControlDetachedFromVisualTree;
}
}
@ -410,9 +412,9 @@ namespace Avalonia.Controls
private static void ControlContextRequested(object sender, ContextRequestedEventArgs e)
{
var control = (Control)sender;
if (!e.Handled
if (sender is Control control
&& control.ContextMenu is ContextMenu contextMenu
&& !e.Handled
&& !contextMenu.CancelOpening())
{
contextMenu.Open(control, e.Source as Control ?? control);
@ -420,6 +422,15 @@ namespace Avalonia.Controls
}
}
private static void ControlDetachedFromVisualTree(object sender, VisualTreeAttachmentEventArgs e)
{
if (sender is Control control
&& control.ContextMenu is ContextMenu contextMenu)
{
contextMenu.Close();
}
}
private bool CancelClosing()
{
var eventArgs = new CancelEventArgs();

88
tests/Avalonia.Controls.UnitTests/ContextMenuTests.cs

@ -6,6 +6,8 @@ using Avalonia.Markup.Xaml;
using Avalonia.Platform;
using Avalonia.Rendering;
using Avalonia.UnitTests;
using Avalonia.VisualTree;
using Moq;
using Xunit;
@ -128,12 +130,10 @@ namespace Avalonia.Controls.UnitTests
{
using (Application())
{
var renderer = new Mock<IRenderer>();
var platform = AvaloniaLocator.Current.GetService<IWindowingPlatform>();
var windowImpl = Mock.Get(platform.CreateWindow());
windowImpl.Setup(x => x.CreateRenderer(It.IsAny<IRenderRoot>())).Returns(renderer.Object);
popupImpl.Setup(x => x.Show(true)).Verifiable();
popupImpl.Setup(x => x.Hide()).Verifiable();
var window = new Window(windowImpl.Object);
var window = PreparedWindow();
window.Width = 100;
window.Height = 100;
@ -160,12 +160,15 @@ namespace Avalonia.Controls.UnitTests
button.ContextMenu = c;
c.Open(button);
var e = CreatePointerPressedEventArgs(window, new Point(90, 90));
var overlay = LightDismissOverlayLayer.GetLightDismissOverlayLayer(window);
overlay.RaiseEvent(e);
_mouse.Down(overlay, MouseButton.Left, new Point(90, 90));
_mouse.Up(button, MouseButton.Left, new Point(90, 90));
Assert.Equal(1, tracker);
Assert.True(c.IsOpen);
popupImpl.Verify(x => x.Hide(), Times.Never);
popupImpl.Verify(x => x.Show(true), Times.Exactly(1));
}
}
@ -174,12 +177,10 @@ namespace Avalonia.Controls.UnitTests
{
using (Application())
{
var renderer = new Mock<IRenderer>();
var platform = AvaloniaLocator.Current.GetService<IWindowingPlatform>();
var windowImpl = Mock.Get(platform.CreateWindow());
windowImpl.Setup(x => x.CreateRenderer(It.IsAny<IRenderRoot>())).Returns(renderer.Object);
popupImpl.Setup(x => x.Show(true)).Verifiable();
popupImpl.Setup(x => x.Hide()).Verifiable();
var window = new Window(windowImpl.Object);
var window = PreparedWindow();
window.Width = 100;
window.Height = 100;
@ -199,11 +200,13 @@ namespace Avalonia.Controls.UnitTests
c.PlacementMode = PlacementMode.Bottom;
c.Open(button);
var e = CreatePointerPressedEventArgs(window, new Point(90, 90));
var overlay = LightDismissOverlayLayer.GetLightDismissOverlayLayer(window);
overlay.RaiseEvent(e);
_mouse.Down(overlay, MouseButton.Left, new Point(90, 90));
_mouse.Up(button, MouseButton.Left, new Point(90, 90));
Assert.False(c.IsOpen);
popupImpl.Verify(x => x.Hide(), Times.Exactly(1));
popupImpl.Verify(x => x.Show(true), Times.Exactly(1));
}
}
@ -221,15 +224,17 @@ namespace Avalonia.Controls.UnitTests
ContextMenu = sut
};
var window = new Window {Content = target};
var window = PreparedWindow(target);
window.ApplyTemplate();
window.Presenter.ApplyTemplate();
var overlay = LightDismissOverlayLayer.GetLightDismissOverlayLayer(window);
_mouse.Click(target, MouseButton.Right);
Assert.True(sut.IsOpen);
_mouse.Click(target);
_mouse.Down(overlay);
_mouse.Up(target);
Assert.False(sut.IsOpen);
popupImpl.Verify(x => x.Show(true), Times.Once);
@ -251,15 +256,16 @@ namespace Avalonia.Controls.UnitTests
ContextMenu = sut
};
var window = new Window {Content = target};
var window = PreparedWindow(target);
window.ApplyTemplate();
window.Presenter.ApplyTemplate();
var overlay = LightDismissOverlayLayer.GetLightDismissOverlayLayer(window);
_mouse.Click(target, MouseButton.Right);
Assert.True(sut.IsOpen);
_mouse.Click(target, MouseButton.Right);
_mouse.Down(overlay, MouseButton.Right);
_mouse.Up(target, MouseButton.Right);
Assert.True(sut.IsOpen);
popupImpl.Verify(x => x.Hide(), Times.Once);
@ -293,12 +299,10 @@ namespace Avalonia.Controls.UnitTests
Assert.True(sut.IsOpen);
_mouse.Click(target2, MouseButton.Left);
Assert.False(sut.IsOpen);
sp.Children.Remove(target1);
Assert.False(sut.IsOpen);
_mouse.Click(target2, MouseButton.Right);
Assert.True(sut.IsOpen);
@ -439,17 +443,20 @@ namespace Avalonia.Controls.UnitTests
{
ContextMenu = sut
};
var window = new Window {Content = target};
window.ApplyTemplate();
var window = PreparedWindow(target);
var overlay = LightDismissOverlayLayer.GetLightDismissOverlayLayer(window);
sut.ContextMenuClosing += (c, e) => { eventCalled = true; e.Cancel = true; };
window.Show();
_mouse.Click(target, MouseButton.Right);
Assert.True(sut.IsOpen);
_mouse.Click(target, MouseButton.Right);
_mouse.Down(overlay, MouseButton.Right);
_mouse.Up(target, MouseButton.Right);
Assert.True(eventCalled);
Assert.True(sut.IsOpen);
@ -459,6 +466,18 @@ namespace Avalonia.Controls.UnitTests
}
}
private Window PreparedWindow(object content = null)
{
var renderer = new Mock<IRenderer>();
var platform = AvaloniaLocator.Current.GetService<IWindowingPlatform>();
var windowImpl = Mock.Get(platform.CreateWindow());
windowImpl.Setup(x => x.CreateRenderer(It.IsAny<IRenderRoot>())).Returns(renderer.Object);
var w = new Window(windowImpl.Object) { Content = content };
w.ApplyTemplate();
return w;
}
private IDisposable Application()
{
var screen = new PixelRect(new PixelPoint(), new PixelSize(100, 100));
@ -480,18 +499,5 @@ namespace Avalonia.Controls.UnitTests
return UnitTestApplication.Start(services);
}
private PointerPressedEventArgs CreatePointerPressedEventArgs(Window source, Point p)
{
var pointer = new Pointer(Pointer.GetNextFreeId(), PointerType.Mouse, true);
return new PointerPressedEventArgs(
source,
pointer,
source,
p,
0,
new PointerPointProperties(RawInputModifiers.None, PointerUpdateKind.LeftButtonPressed),
KeyModifiers.None);
}
}
}

Loading…
Cancel
Save