123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441 |
- using Xunit.Abstractions;
- namespace Terminal.Gui.ApplicationTests;
- public class KeyboardTests
- {
- private readonly ITestOutputHelper _output;
- public KeyboardTests (ITestOutputHelper output)
- {
- _output = output;
- #if DEBUG_IDISPOSABLE
- Responder.Instances.Clear ();
- RunState.Instances.Clear ();
- #endif
- }
- [Fact]
- public void AlternateForwardKey_AlternateBackwardKey_Tests ()
- {
- Application.Init (new FakeDriver ());
- Toplevel top = Application.Top;
- var w1 = new Window ();
- var v1 = new TextField ();
- var v2 = new TextView ();
- w1.Add (v1, v2);
- var w2 = new Window ();
- var v3 = new CheckBox ();
- var v4 = new Button ();
- w2.Add (v3, v4);
- top.Add (w1, w2);
- Application.Iteration += (s, a) =>
- {
- Assert.True (v1.HasFocus);
- // Using default keys.
- top.NewKeyDownEvent (Key.Tab.WithCtrl);
- Assert.True (v2.HasFocus);
- top.NewKeyDownEvent (Key.Tab.WithCtrl);
- Assert.True (v3.HasFocus);
- top.NewKeyDownEvent (Key.Tab.WithCtrl);
- Assert.True (v4.HasFocus);
- top.NewKeyDownEvent (Key.Tab.WithCtrl);
- Assert.True (v1.HasFocus);
- top.NewKeyDownEvent (Key.Tab.WithShift.WithCtrl);
- Assert.True (v4.HasFocus);
- top.NewKeyDownEvent (Key.Tab.WithShift.WithCtrl);
- Assert.True (v3.HasFocus);
- top.NewKeyDownEvent (Key.Tab.WithShift.WithCtrl);
- Assert.True (v2.HasFocus);
- top.NewKeyDownEvent (Key.Tab.WithShift.WithCtrl);
- Assert.True (v1.HasFocus);
- top.NewKeyDownEvent (Key.PageDown.WithCtrl);
- Assert.True (v2.HasFocus);
- top.NewKeyDownEvent (Key.PageDown.WithCtrl);
- Assert.True (v3.HasFocus);
- top.NewKeyDownEvent (Key.PageDown.WithCtrl);
- Assert.True (v4.HasFocus);
- top.NewKeyDownEvent (Key.PageDown.WithCtrl);
- Assert.True (v1.HasFocus);
- top.NewKeyDownEvent (Key.PageUp.WithCtrl);
- Assert.True (v4.HasFocus);
- top.NewKeyDownEvent (Key.PageUp.WithCtrl);
- Assert.True (v3.HasFocus);
- top.NewKeyDownEvent (Key.PageUp.WithCtrl);
- Assert.True (v2.HasFocus);
- top.NewKeyDownEvent (Key.PageUp.WithCtrl);
- Assert.True (v1.HasFocus);
- // Using another's alternate keys.
- Application.AlternateForwardKey = Key.F7;
- Application.AlternateBackwardKey = Key.F6;
- top.NewKeyDownEvent (Key.F7);
- Assert.True (v2.HasFocus);
- top.NewKeyDownEvent (Key.F7);
- Assert.True (v3.HasFocus);
- top.NewKeyDownEvent (Key.F7);
- Assert.True (v4.HasFocus);
- top.NewKeyDownEvent (Key.F7);
- Assert.True (v1.HasFocus);
- top.NewKeyDownEvent (Key.F6);
- Assert.True (v4.HasFocus);
- top.NewKeyDownEvent (Key.F6);
- Assert.True (v3.HasFocus);
- top.NewKeyDownEvent (Key.F6);
- Assert.True (v2.HasFocus);
- top.NewKeyDownEvent (Key.F6);
- Assert.True (v1.HasFocus);
- Application.RequestStop ();
- };
- Application.Run (top);
- // Replacing the defaults keys to avoid errors on others unit tests that are using it.
- Application.AlternateForwardKey = Key.PageDown.WithCtrl;
- Application.AlternateBackwardKey = Key.PageUp.WithCtrl;
- Application.QuitKey = Key.Q.WithCtrl;
- Assert.Equal (KeyCode.PageDown | KeyCode.CtrlMask, Application.AlternateForwardKey.KeyCode);
- Assert.Equal (KeyCode.PageUp | KeyCode.CtrlMask, Application.AlternateBackwardKey.KeyCode);
- Assert.Equal (KeyCode.Q | KeyCode.CtrlMask, Application.QuitKey.KeyCode);
- // Shutdown must be called to safely clean up Application if Init has been called
- Application.Shutdown ();
- }
- [Fact]
- [AutoInitShutdown]
- public void EnsuresTopOnFront_CanFocus_False_By_Keyboard ()
- {
- Toplevel top = Application.Top;
- var win = new Window
- {
- Title = "win",
- X = 0,
- Y = 0,
- Width = 20,
- Height = 10
- };
- var tf = new TextField { Width = 10 };
- win.Add (tf);
- var win2 = new Window
- {
- Title = "win2",
- X = 22,
- Y = 0,
- Width = 20,
- Height = 10
- };
- var tf2 = new TextField { Width = 10 };
- win2.Add (tf2);
- top.Add (win, win2);
- Application.Begin (top);
- Assert.True (win.CanFocus);
- Assert.True (win.HasFocus);
- Assert.True (win2.CanFocus);
- Assert.False (win2.HasFocus);
- Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title);
- win.CanFocus = false;
- Assert.False (win.CanFocus);
- Assert.False (win.HasFocus);
- Assert.True (win2.CanFocus);
- Assert.True (win2.HasFocus);
- Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title);
- top.NewKeyDownEvent (Key.Tab.WithCtrl);
- Assert.True (win2.CanFocus);
- Assert.False (win.HasFocus);
- Assert.True (win2.CanFocus);
- Assert.True (win2.HasFocus);
- Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title);
- top.NewKeyDownEvent (Key.Tab.WithCtrl);
- Assert.False (win.CanFocus);
- Assert.False (win.HasFocus);
- Assert.True (win2.CanFocus);
- Assert.True (win2.HasFocus);
- Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title);
- }
- [Fact]
- [AutoInitShutdown]
- public void EnsuresTopOnFront_CanFocus_True_By_Keyboard_ ()
- {
- Toplevel top = Application.Top;
- var win = new Window
- {
- Title = "win",
- X = 0,
- Y = 0,
- Width = 20,
- Height = 10
- };
- var tf = new TextField { Width = 10 };
- win.Add (tf);
- var win2 = new Window
- {
- Title = "win2",
- X = 22,
- Y = 0,
- Width = 20,
- Height = 10
- };
- var tf2 = new TextField { Width = 10 };
- win2.Add (tf2);
- top.Add (win, win2);
- Application.Begin (top);
- Assert.True (win.CanFocus);
- Assert.True (win.HasFocus);
- Assert.True (win2.CanFocus);
- Assert.False (win2.HasFocus);
- Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title);
- top.NewKeyDownEvent (Key.Tab.WithCtrl);
- Assert.True (win.CanFocus);
- Assert.False (win.HasFocus);
- Assert.True (win2.CanFocus);
- Assert.True (win2.HasFocus);
- Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title);
- top.NewKeyDownEvent (Key.Tab.WithCtrl);
- Assert.True (win.CanFocus);
- Assert.True (win.HasFocus);
- Assert.True (win2.CanFocus);
- Assert.False (win2.HasFocus);
- Assert.Equal ("win", ((Window)top.Subviews [top.Subviews.Count - 1]).Title);
- }
- [Fact]
- public void KeyUp_Event ()
- {
- Application.Init (new FakeDriver ());
- // Setup some fake keypresses (This)
- var input = "Tests";
- // Put a control-q in at the end
- FakeConsole.MockKeyPresses.Push (new ConsoleKeyInfo ('Q', ConsoleKey.Q, false, false, true));
- foreach (char c in input.Reverse ())
- {
- if (char.IsLetter (c))
- {
- FakeConsole.MockKeyPresses.Push (
- new ConsoleKeyInfo (
- c,
- (ConsoleKey)char.ToUpper (c),
- char.IsUpper (c),
- false,
- false
- )
- );
- }
- else
- {
- FakeConsole.MockKeyPresses.Push (
- new ConsoleKeyInfo (
- c,
- (ConsoleKey)c,
- false,
- false,
- false
- )
- );
- }
- }
- int stackSize = FakeConsole.MockKeyPresses.Count;
- var iterations = 0;
- Application.Iteration += (s, a) =>
- {
- iterations++;
- // Stop if we run out of control...
- if (iterations > 10)
- {
- Application.RequestStop ();
- }
- };
- var keyUps = 0;
- var output = string.Empty;
- Application.Top.KeyUp += (sender, args) =>
- {
- if (args.KeyCode != (KeyCode.CtrlMask | KeyCode.Q))
- {
- output += args.AsRune;
- }
- keyUps++;
- };
- Application.Run (Application.Top);
- // Input string should match output
- Assert.Equal (input, output);
- // # of key up events should match stack size
- //Assert.Equal (stackSize, keyUps);
- // We can't use numbers variables on the left side of an Assert.Equal/NotEqual,
- // it must be literal (Linux only).
- Assert.Equal (6, keyUps);
- // # of key up events should match # of iterations
- Assert.Equal (stackSize, iterations);
- Application.Shutdown ();
- Assert.Null (Application.Current);
- Assert.Null (Application.Top);
- Assert.Null (Application.MainLoop);
- Assert.Null (Application.Driver);
- }
- [Fact]
- [AutoInitShutdown]
- public void OnKeyDown_Application_KeyBinding ()
- {
- var view = new ScopedKeyBindingView ();
- var invoked = false;
- view.InvokingKeyBindings += (s, e) => invoked = true;
- Application.Top.Add (view);
- Application.Begin (Application.Top);
- Application.OnKeyDown (Key.A);
- Assert.True (invoked);
- Assert.True (view.ApplicationCommand);
- invoked = false;
- view.ApplicationCommand = false;
- view.KeyBindings.Remove (KeyCode.A);
- Application.OnKeyDown (Key.A); // old
- Assert.False (invoked);
- Assert.False (view.ApplicationCommand);
- view.KeyBindings.Add (Key.A.WithCtrl, KeyBindingScope.Application, Command.Save);
- Application.OnKeyDown (Key.A); // old
- Assert.False (invoked);
- Assert.False (view.ApplicationCommand);
- Application.OnKeyDown (Key.A.WithCtrl); // new
- Assert.True (invoked);
- Assert.True (view.ApplicationCommand);
- invoked = false;
- Application.OnKeyDown (Key.H);
- Assert.True (invoked);
- invoked = false;
- Assert.False (view.HasFocus);
- Application.OnKeyDown (Key.F);
- Assert.False (invoked);
- Assert.True (view.ApplicationCommand);
- Assert.True (view.HotKeyCommand);
- Assert.False (view.FocusedCommand);
- }
- [Fact]
- [AutoInitShutdown]
- public void OnKeyDown_Application_KeyBinding_Negative ()
- {
- var view = new ScopedKeyBindingView ();
- var invoked = false;
- view.InvokingKeyBindings += (s, e) => invoked = true;
- Application.Top.Add (view);
- Application.Begin (Application.Top);
- Application.OnKeyDown (Key.A.WithCtrl);
- Assert.False (invoked);
- Assert.False (view.ApplicationCommand);
- Assert.False (view.HotKeyCommand);
- Assert.False (view.FocusedCommand);
- invoked = false;
- Assert.False (view.HasFocus);
- Application.OnKeyDown (Key.Z);
- Assert.False (invoked);
- Assert.False (view.ApplicationCommand);
- Assert.False (view.HotKeyCommand);
- Assert.False (view.FocusedCommand);
- }
- [Fact]
- [AutoInitShutdown]
- public void QuitKey_Getter_Setter ()
- {
- Toplevel top = Application.Top;
- var isQuiting = false;
- top.Closing += (s, e) =>
- {
- isQuiting = true;
- e.Cancel = true;
- };
- Application.Begin (top);
- top.Running = true;
- Assert.Equal (KeyCode.Q | KeyCode.CtrlMask, Application.QuitKey.KeyCode);
- Application.Driver.SendKeys ('Q', ConsoleKey.Q, false, false, true);
- Assert.True (isQuiting);
- isQuiting = false;
- Application.OnKeyDown (Key.Q.WithCtrl);
- Assert.True (isQuiting);
- isQuiting = false;
- Application.QuitKey = Key.C.WithCtrl;
- Application.Driver.SendKeys ('Q', ConsoleKey.Q, false, false, true);
- Assert.False (isQuiting);
- Application.OnKeyDown (Key.Q.WithCtrl);
- Assert.False (isQuiting);
- Application.OnKeyDown (Application.QuitKey);
- Assert.True (isQuiting);
- // Reset the QuitKey to avoid throws errors on another tests
- Application.QuitKey = Key.Q.WithCtrl;
- }
- // test Application key Bindings
- public class ScopedKeyBindingView : View
- {
- public ScopedKeyBindingView ()
- {
- AddCommand (Command.Save, () => ApplicationCommand = true);
- AddCommand (Command.HotKey, () => HotKeyCommand = true);
- AddCommand (Command.Left, () => FocusedCommand = true);
- KeyBindings.Add (Key.A, KeyBindingScope.Application, Command.Save);
- HotKey = KeyCode.H;
- KeyBindings.Add (Key.F, KeyBindingScope.Focused, Command.Left);
- }
- public bool ApplicationCommand { get; set; }
- public bool FocusedCommand { get; set; }
- public bool HotKeyCommand { get; set; }
- }
- }
|