Files
Terminal.Gui/UnitTests/ContextMenuTests.cs
2022-07-04 11:22:27 -04:00

684 lines
19 KiB
C#

using System.Globalization;
using System.Threading;
using Xunit;
using Xunit.Abstractions;
using GraphViewTests = Terminal.Gui.Views.GraphViewTests;
namespace Terminal.Gui.Core {
public class ContextMenuTests {
readonly ITestOutputHelper output;
public ContextMenuTests (ITestOutputHelper output)
{
this.output = output;
}
[Fact]
[AutoInitShutdown]
public void ContextMenu_Constructors ()
{
var cm = new ContextMenu ();
Assert.Equal (new Point (0, 0), cm.Position);
Assert.Empty (cm.MenuItems.Children);
Assert.Null (cm.Host);
cm.Position = new Point (20, 10);
cm.MenuItems = new MenuBarItem (new MenuItem [] {
new MenuItem ("First", "", null)
});
Assert.Equal (new Point (20, 10), cm.Position);
Assert.Single (cm.MenuItems.Children);
cm = new ContextMenu (5, 10,
new MenuBarItem (new MenuItem [] {
new MenuItem ("One", "", null),
new MenuItem ("Two", "", null)
})
);
Assert.Equal (new Point (5, 10), cm.Position);
Assert.Equal (2, cm.MenuItems.Children.Length);
Assert.Null (cm.Host);
cm = new ContextMenu (new View () { X = 5, Y = 10 },
new MenuBarItem (new MenuItem [] {
new MenuItem ("One", "", null),
new MenuItem ("Two", "", null)
})
);
Assert.Equal (new Point (5, 10), cm.Position);
Assert.Equal (2, cm.MenuItems.Children.Length);
Assert.NotNull (cm.Host);
}
[Fact]
[AutoInitShutdown]
public void Show_Hide_IsShow ()
{
var cm = new ContextMenu (10, 5,
new MenuBarItem (new MenuItem [] {
new MenuItem ("One", "", null),
new MenuItem ("Two", "", null)
})
);
cm.Show ();
Assert.True (ContextMenu.IsShow);
Application.Begin (Application.Top);
var expected = @"
┌──────┐
│ One │
│ Two │
└──────┘
";
GraphViewTests.AssertDriverContentsAre (expected, output);
cm.Hide ();
Assert.False (ContextMenu.IsShow);
Application.Refresh ();
expected = "";
GraphViewTests.AssertDriverContentsAre (expected, output);
}
[Fact]
[AutoInitShutdown]
public void Position_Changing ()
{
var cm = new ContextMenu (10, 5,
new MenuBarItem (new MenuItem [] {
new MenuItem ("One", "", null),
new MenuItem ("Two", "", null)
})
);
cm.Show ();
Application.Begin (Application.Top);
var expected = @"
┌──────┐
│ One │
│ Two │
└──────┘
";
GraphViewTests.AssertDriverContentsAre (expected, output);
cm.Position = new Point (5, 10);
cm.Show ();
Application.Refresh ();
expected = @"
┌──────┐
│ One │
│ Two │
└──────┘
";
GraphViewTests.AssertDriverContentsAre (expected, output);
}
[Fact]
[AutoInitShutdown]
public void MenuItens_Changing ()
{
var cm = new ContextMenu (10, 5,
new MenuBarItem (new MenuItem [] {
new MenuItem ("One", "", null),
new MenuItem ("Two", "", null)
})
);
cm.Show ();
Application.Begin (Application.Top);
var expected = @"
┌──────┐
│ One │
│ Two │
└──────┘
";
GraphViewTests.AssertDriverContentsAre (expected, output);
cm.MenuItems = new MenuBarItem (new MenuItem [] {
new MenuItem ("First", "", null),
new MenuItem ("Second", "", null),
new MenuItem ("Third", "", null)
});
cm.Show ();
Application.Refresh ();
expected = @"
┌─────────┐
│ First │
│ Second │
│ Third │
└─────────┘
";
GraphViewTests.AssertDriverContentsAre (expected, output);
}
[Fact, AutoInitShutdown]
public void Key_Changing ()
{
var lbl = new Label ("Original");
var cm = new ContextMenu ();
lbl.KeyPress += (e) => {
if (e.KeyEvent.Key == cm.Key) {
lbl.Text = "Replaced";
e.Handled = true;
}
};
var top = Application.Top;
top.Add (lbl);
Application.Begin (top);
Assert.True (lbl.ProcessKey (new KeyEvent (cm.Key, new KeyModifiers ())));
Assert.Equal ("Replaced", lbl.Text);
lbl.Text = "Original";
cm.Key = Key.Space | Key.CtrlMask;
Assert.True (lbl.ProcessKey (new KeyEvent (cm.Key, new KeyModifiers ())));
Assert.Equal ("Replaced", lbl.Text);
}
[Fact, AutoInitShutdown]
public void MouseFlags_Changing ()
{
var lbl = new Label ("Original");
var cm = new ContextMenu ();
lbl.MouseClick += (e) => {
if (e.MouseEvent.Flags == cm.MouseFlags) {
lbl.Text = "Replaced";
e.Handled = true;
}
};
var top = Application.Top;
top.Add (lbl);
Application.Begin (top);
Assert.True (lbl.OnMouseEvent (new MouseEvent () { Flags = cm.MouseFlags }));
Assert.Equal ("Replaced", lbl.Text);
lbl.Text = "Original";
cm.MouseFlags = MouseFlags.Button2Clicked;
Assert.True (lbl.OnMouseEvent (new MouseEvent () { Flags = cm.MouseFlags }));
Assert.Equal ("Replaced", lbl.Text);
}
[Fact, AutoInitShutdown]
public void KeyChanged_Event ()
{
var oldKey = Key.Null;
var cm = new ContextMenu ();
cm.KeyChanged += (e) => oldKey = e;
cm.Key = Key.Space | Key.CtrlMask;
Assert.Equal (Key.Space | Key.CtrlMask, cm.Key);
Assert.Equal (Key.F10 | Key.ShiftMask, oldKey);
}
[Fact, AutoInitShutdown]
public void MouseFlagsChanged_Event ()
{
var oldMouseFlags = new MouseFlags ();
var cm = new ContextMenu ();
cm.MouseFlagsChanged += (e) => oldMouseFlags = e;
cm.MouseFlags = MouseFlags.Button2Clicked;
Assert.Equal (MouseFlags.Button2Clicked, cm.MouseFlags);
Assert.Equal (MouseFlags.Button3Clicked, oldMouseFlags);
}
[Fact, AutoInitShutdown]
public void Show_Ensures_Display_Inside_The_Container_But_Preserves_Position ()
{
var cm = new ContextMenu (80, 25,
new MenuBarItem (new MenuItem [] {
new MenuItem ("One", "", null),
new MenuItem ("Two", "", null)
})
);
Assert.Equal (new Point (80, 25), cm.Position);
cm.Show ();
Assert.Equal (new Point (80, 25), cm.Position);
Application.Begin (Application.Top);
var expected = @"
┌──────┐
│ One │
│ Two │
└──────┘
";
var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output);
Assert.Equal (new Rect (72, 21, 80, 4), pos);
cm.Hide ();
Assert.Equal (new Point (80, 25), cm.Position);
}
[Fact, AutoInitShutdown]
public void Show_Ensures_Display_Inside_The_Container_Without_Overlap_The_Host ()
{
var view = new View ("View") {
X = Pos.AnchorEnd (10),
Y = Pos.AnchorEnd (1),
Width = 10,
Height = 1
};
var cm = new ContextMenu (view,
new MenuBarItem (new MenuItem [] {
new MenuItem ("One", "", null),
new MenuItem ("Two", "", null)
})
);
Application.Top.Add (view);
Application.Begin (Application.Top);
Assert.Equal (new Rect (70, 24, 10, 1), view.Frame);
Assert.Equal (new Point (0, 0), cm.Position);
cm.Show ();
Assert.Equal (new Point (70, 24), cm.Position);
Application.Top.Redraw (Application.Top.Bounds);
var expected = @"
┌──────┐
│ One │
│ Two │
└──────┘
View
";
var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output);
Assert.Equal (new Rect (70, 20, 78, 5), pos);
cm.Hide ();
Assert.Equal (new Point (70, 24), cm.Position);
}
[Fact, AutoInitShutdown]
public void Show_Display_Below_The_Bottom_Host_If_Has_Enough_Space ()
{
var view = new View ("View") { X = 10, Y = 5, Width = 10, Height = 1 };
var cm = new ContextMenu (view,
new MenuBarItem (new MenuItem [] {
new MenuItem ("One", "", null),
new MenuItem ("Two", "", null)
})
);
Application.Top.Add (view);
Application.Begin (Application.Top);
Assert.Equal (new Point (10, 5), cm.Position);
cm.Show ();
Application.Top.Redraw (Application.Top.Bounds);
Assert.Equal (new Point (10, 5), cm.Position);
var expected = @"
View
┌──────┐
│ One │
│ Two │
└──────┘
";
var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output);
Assert.Equal (new Rect (10, 5, 18, 5), pos);
cm.Hide ();
Assert.Equal (new Point (10, 5), cm.Position);
cm.Host.X = 5;
cm.Host.Y = 10;
cm.Host.Height = 3;
cm.Show ();
Application.Top.Redraw (Application.Top.Bounds);
Assert.Equal (new Point (5, 12), cm.Position);
expected = @"
View
┌──────┐
│ One │
│ Two │
└──────┘
";
pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output);
Assert.Equal (new Rect (5, 10, 13, 7), pos);
cm.Hide ();
Assert.Equal (new Point (5, 12), cm.Position);
}
[Fact, AutoInitShutdown]
public void Show_Display_At_Zero_If_The_Toplevel_Width_Is_Less_Than_The_Menu_Width ()
{
var cm = new ContextMenu (0, 0,
new MenuBarItem (new MenuItem [] {
new MenuItem ("One", "", null),
new MenuItem ("Two", "", null)
})
);
Assert.Equal (new Point (0, 0), cm.Position);
cm.Show ();
Assert.Equal (new Point (0, 0), cm.Position);
Application.Begin (Application.Top);
((FakeDriver)Application.Driver).SetBufferSize (5, 25);
var expected = @"
┌────
│ One
│ Two
└────
";
var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output);
Assert.Equal (new Rect (0, 1, 5, 4), pos);
cm.Hide ();
Assert.Equal (new Point (0, 0), cm.Position);
}
[Fact, AutoInitShutdown]
public void Show_Display_At_Zero_If_The_Toplevel_Height_Is_Less_Than_The_Menu_Height ()
{
var cm = new ContextMenu (0, 0,
new MenuBarItem (new MenuItem [] {
new MenuItem ("One", "", null),
new MenuItem ("Two", "", null)
})
);
Assert.Equal (new Point (0, 0), cm.Position);
cm.Show ();
Assert.Equal (new Point (0, 0), cm.Position);
Application.Begin (Application.Top);
((FakeDriver)Application.Driver).SetBufferSize (80, 4);
var expected = @"
┌──────┐
│ One │
│ Two │
";
var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output);
Assert.Equal (new Rect (0, 1, 8, 3), pos);
cm.Hide ();
Assert.Equal (new Point (0, 0), cm.Position);
}
[Fact, AutoInitShutdown]
public void Hide_Is_Invoke_At_Container_Closing ()
{
var cm = new ContextMenu (80, 25,
new MenuBarItem (new MenuItem [] {
new MenuItem ("One", "", null),
new MenuItem ("Two", "", null)
})
);
var top = Application.Top;
Application.Begin (top);
top.Running = true;
Assert.False (ContextMenu.IsShow);
cm.Show ();
Assert.True (ContextMenu.IsShow);
top.RequestStop ();
Assert.False (ContextMenu.IsShow);
}
[Fact, AutoInitShutdown]
public void ForceMinimumPosToZero_True_False ()
{
var cm = new ContextMenu (-1, -2,
new MenuBarItem (new MenuItem [] {
new MenuItem ("One", "", null),
new MenuItem ("Two", "", null)
})
);
Assert.Equal (new Point (-1, -2), cm.Position);
cm.Show ();
Assert.Equal (new Point (-1, -2), cm.Position);
Application.Begin (Application.Top);
var expected = @"
┌──────┐
│ One │
│ Two │
└──────┘
";
var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output);
Assert.Equal (new Rect (0, 1, 8, 4), pos);
cm.ForceMinimumPosToZero = false;
cm.Show ();
Assert.Equal (new Point (-1, -2), cm.Position);
Application.Refresh ();
expected = @"
One │
Two │
──────┘
";
pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output);
Assert.Equal (new Rect (1, 0, 7, 3), pos);
}
[Fact, AutoInitShutdown]
public void ContextMenu_Is_Closed_If_Another_MenuBar_Is_Open_Or_Vice_Versa ()
{
var cm = new ContextMenu (10, 5,
new MenuBarItem (new MenuItem [] {
new MenuItem ("One", "", null),
new MenuItem ("Two", "", null)
})
);
var menu = new MenuBar (new MenuBarItem [] {
new MenuBarItem ("File", "", null),
new MenuBarItem ("Edit", "", null)
});
Application.Top.Add (menu);
Assert.Null (Application.mouseGrabView);
cm.Show ();
Assert.True (ContextMenu.IsShow);
Assert.Equal (cm.MenuBar, Application.mouseGrabView);
Assert.False (menu.IsMenuOpen);
Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F9, new KeyModifiers ())));
Assert.False (ContextMenu.IsShow);
Assert.Equal (menu, Application.mouseGrabView);
Assert.True (menu.IsMenuOpen);
cm.Show ();
Assert.True (ContextMenu.IsShow);
Assert.Equal (cm.MenuBar, Application.mouseGrabView);
Assert.False (menu.IsMenuOpen);
Assert.False (menu.OnKeyDown (new KeyEvent (Key.Null, new KeyModifiers () { Alt = true })));
Assert.True (menu.OnKeyUp (new KeyEvent (Key.Null, new KeyModifiers () { Alt = true })));
Assert.False (ContextMenu.IsShow);
Assert.Equal (menu, Application.mouseGrabView);
Assert.True (menu.IsMenuOpen);
cm.Show ();
Assert.True (ContextMenu.IsShow);
Assert.Equal (cm.MenuBar, Application.mouseGrabView);
Assert.False (menu.IsMenuOpen);
Assert.False (menu.MouseEvent (new MouseEvent () { X = 1, Flags = MouseFlags.ReportMousePosition, View = menu }));
Assert.True (ContextMenu.IsShow);
Assert.Equal (cm.MenuBar, Application.mouseGrabView);
Assert.False (menu.IsMenuOpen);
Assert.True (menu.MouseEvent (new MouseEvent () { X = 1, Flags = MouseFlags.Button1Clicked, View = menu }));
Assert.False (ContextMenu.IsShow);
Assert.Equal (menu, Application.mouseGrabView);
Assert.True (menu.IsMenuOpen);
}
[Fact, AutoInitShutdown]
public void ContextMenu_On_Toplevel_With_A_MenuBar_TextField_StatusBar ()
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo ("en-US");
var menu = new MenuBar (new MenuBarItem [] {
new MenuBarItem ("File", "", null),
new MenuBarItem ("Edit", "", null)
});
var label = new Label ("Label:") {
X = 2,
Y = 3
};
var tf = new TextField ("TextField") {
X = Pos.Right (label) + 1,
Y = Pos.Top (label),
Width = 20
};
var statusBar = new StatusBar (new StatusItem [] {
new StatusItem(Key.F1, "~F1~ Help", null),
new StatusItem(Key.CtrlMask | Key.Q, "~^Q~ Quit", null)
});
Application.Top.Add (menu, label, tf, statusBar);
Application.Begin (Application.Top);
((FakeDriver)Application.Driver).SetBufferSize (45, 17);
Assert.Equal (new Rect (9, 3, 20, 1), tf.Frame);
Assert.True (tf.HasFocus);
tf.ContextMenu.Show ();
Assert.True (ContextMenu.IsShow);
Assert.Equal (new Point (9, 3), tf.ContextMenu.Position);
Application.Top.Redraw (Application.Top.Bounds);
var expected = @"
File Edit
Label: TextField
┌───────────────────────────┐
│ Select All Ctrl+T │
│ Delete All Ctrl+Shift+D │
│ Copy Ctrl+C │
│ Cut Ctrl+X │
│ Paste Ctrl+V │
│ Undo Ctrl+Z │
│ Redo Ctrl+Y │
└───────────────────────────┘
F1 Help │ ^Q Quit
";
var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output);
Assert.Equal (new Rect (2, 0, 38, 17), pos);
}
[Fact, AutoInitShutdown]
public void ContextMenu_On_Toplevel_With_A_MenuBar_Window_TextField_StatusBar ()
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo ("en-US");
var menu = new MenuBar (new MenuBarItem [] {
new MenuBarItem ("File", "", null),
new MenuBarItem ("Edit", "", null)
});
var label = new Label ("Label:") {
X = 2,
Y = 3
};
var tf = new TextField ("TextField") {
X = Pos.Right (label) + 1,
Y = Pos.Top (label),
Width = 20
};
var win = new Window ("Window");
win.Add (label, tf);
var statusBar = new StatusBar (new StatusItem [] {
new StatusItem(Key.F1, "~F1~ Help", null),
new StatusItem(Key.CtrlMask | Key.Q, "~^Q~ Quit", null)
});
Application.Top.Add (menu, win, statusBar);
Application.Begin (Application.Top);
((FakeDriver)Application.Driver).SetBufferSize (44, 17);
Assert.Equal (new Rect (9, 3, 20, 1), tf.Frame);
Assert.True (tf.HasFocus);
tf.ContextMenu.Show ();
Assert.True (ContextMenu.IsShow);
Assert.Equal (new Point (10, 5), tf.ContextMenu.Position);
Application.Top.Redraw (Application.Top.Bounds);
var expected = @"
File Edit
┌ Window ──────────────────────────────────┐
│ │
│ │
│ │
│ Label: TextField │
│ ┌───────────────────────────┐ │
│ │ Select All Ctrl+T │ │
│ │ Delete All Ctrl+Shift+D │ │
│ │ Copy Ctrl+C │ │
│ │ Cut Ctrl+X │ │
│ │ Paste Ctrl+V │ │
│ │ Undo Ctrl+Z │ │
│ │ Redo Ctrl+Y │ │
│ └───────────────────────────┘ │
└──────────────────────────────────────────┘
F1 Help │ ^Q Quit
";
var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output);
Assert.Equal (new Rect (2, 0, 44, 17), pos);
}
}
}