123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307 |
- using System;
- using Xunit;
- using Xunit.Abstractions;
- using System.Text;
- namespace Terminal.Gui.ViewTests;
- public class HotKeyTests {
- readonly ITestOutputHelper _output;
- public HotKeyTests (ITestOutputHelper output)
- {
- this._output = output;
- }
- [Fact]
- public void Defaults ()
- {
- var view = new View ();
- Assert.Equal (string.Empty, view.Title);
- Assert.Equal (KeyCode.Null, view.HotKey);
- // Verify key bindings were set
- var commands = view.KeyBindings.GetCommands (KeyCode.Null);
- Assert.Empty (commands);
- }
- [Theory]
- [InlineData (KeyCode.A)]
- [InlineData ((KeyCode)'a')]
- [InlineData (KeyCode.A | KeyCode.ShiftMask)]
- [InlineData (KeyCode.D1)]
- [InlineData (KeyCode.D1 | KeyCode.ShiftMask)]
- [InlineData ((KeyCode)'!')]
- [InlineData ((KeyCode)'х')] // Cyrillic x
- [InlineData ((KeyCode)'你')] // Chinese ni
- [InlineData ((KeyCode)'ö')] // German o umlaut
- [InlineData (KeyCode.Null)]
- public void Set_Sets_WithValidKey (KeyCode key)
- {
- var view = new View ();
- view.HotKey = key;
- Assert.Equal (key, view.HotKey);
- }
- [Theory]
- [InlineData (KeyCode.A)]
- [InlineData (KeyCode.A | KeyCode.ShiftMask)]
- [InlineData (KeyCode.D1)]
- [InlineData (KeyCode.D1 | KeyCode.ShiftMask)] // '!'
- [InlineData ((KeyCode)'х')] // Cyrillic x
- [InlineData ((KeyCode)'你')] // Chinese ni
- [InlineData ((KeyCode)'ö')] // German o umlaut
- public void Set_SetsKeyBindings (Key key)
- {
- var view = new View ();
- view.HotKey = key;
- Assert.Equal (string.Empty, view.Title);
- Assert.Equal (key, view.HotKey);
- // Verify key bindings were set
- // As passed
- var commands = view.KeyBindings.GetCommands (key);
- Assert.Contains (Command.Accept, commands);
- var baseKey = key.NoShift;
- // If A...Z, with and without shift
- if (baseKey.IsKeyCodeAtoZ) {
- commands = view.KeyBindings.GetCommands (key.WithShift);
- Assert.Contains (Command.Accept, commands);
- commands = view.KeyBindings.GetCommands (key.NoShift);
- Assert.Contains (Command.Accept, commands);
- commands = view.KeyBindings.GetCommands (key.WithAlt);
- Assert.Contains (Command.Accept, commands);
- commands = view.KeyBindings.GetCommands (key.NoShift.WithAlt);
- Assert.Contains (Command.Accept, commands);
- } else {
- // Non A..Z keys should not have shift bindings
- if (key.IsShift) {
- commands = view.KeyBindings.GetCommands (key.NoShift);
- Assert.Empty (commands);
- } else {
- commands = view.KeyBindings.GetCommands (key.WithShift);
- Assert.Empty (commands);
- }
- }
- }
- [Fact]
- public void Set_RemovesOldKeyBindings ()
- {
- var view = new View ();
- view.HotKey = KeyCode.A;
- Assert.Equal (string.Empty, view.Title);
- Assert.Equal (KeyCode.A, view.HotKey);
- // Verify key bindings were set
- var commands = view.KeyBindings.GetCommands (KeyCode.A);
- Assert.Contains (Command.Accept, commands);
- commands = view.KeyBindings.GetCommands (KeyCode.A | KeyCode.ShiftMask);
- Assert.Contains (Command.Accept, commands);
- commands = view.KeyBindings.GetCommands (KeyCode.A | KeyCode.AltMask);
- Assert.Contains (Command.Accept, commands);
- commands = view.KeyBindings.GetCommands (KeyCode.A | KeyCode.ShiftMask | KeyCode.AltMask);
- Assert.Contains (Command.Accept, commands);
- // Now set again
- view.HotKey = KeyCode.B;
- Assert.Equal (string.Empty, view.Title);
- Assert.Equal (KeyCode.B, view.HotKey);
- commands = view.KeyBindings.GetCommands (KeyCode.A);
- Assert.DoesNotContain (Command.Accept, commands);
- commands = view.KeyBindings.GetCommands (KeyCode.A | KeyCode.ShiftMask);
- Assert.DoesNotContain (Command.Accept, commands);
- commands = view.KeyBindings.GetCommands (KeyCode.A | KeyCode.AltMask);
- Assert.DoesNotContain (Command.Accept, commands);
- commands = view.KeyBindings.GetCommands (KeyCode.A | KeyCode.ShiftMask | KeyCode.AltMask);
- Assert.DoesNotContain (Command.Accept, commands);
- }
- [Fact]
- public void Set_Throws_If_Modifiers_Are_Included ()
- {
- var view = new View ();
- // A..Z must be naked (Alt is assumed)
- view.HotKey = KeyCode.A | KeyCode.AltMask;
- Assert.Throws<ArgumentException> (() => view.HotKey = KeyCode.A | KeyCode.CtrlMask);
- Assert.Throws<ArgumentException> (() => view.HotKey = KeyCode.A | KeyCode.ShiftMask | KeyCode.AltMask | KeyCode.CtrlMask);
- // All others must not have Ctrl (Alt is assumed)
- view.HotKey = KeyCode.D1 | KeyCode.AltMask;
- Assert.Throws<ArgumentException> (() => view.HotKey = KeyCode.D1 | KeyCode.CtrlMask);
- Assert.Throws<ArgumentException> (() => view.HotKey = KeyCode.D1 | KeyCode.ShiftMask | KeyCode.AltMask | KeyCode.CtrlMask);
- // Shift is ok (e.g. this is '!')
- view.HotKey = KeyCode.D1 | KeyCode.ShiftMask;
- }
- [Theory]
- [InlineData (KeyCode.A)]
- [InlineData (KeyCode.A | KeyCode.ShiftMask)]
- [InlineData (KeyCode.D1)]
- [InlineData (KeyCode.D1 | KeyCode.ShiftMask)] // '!'
- [InlineData ((KeyCode)'х')] // Cyrillic x
- [InlineData ((KeyCode)'你')] // Chinese ni
- public void AddKeyBindingsForHotKey_Sets (KeyCode key)
- {
- var view = new View ();
- view.HotKey = KeyCode.Z;
- Assert.Equal (string.Empty, view.Title);
- Assert.Equal (KeyCode.Z, view.HotKey);
- view.AddKeyBindingsForHotKey (KeyCode.Null, key);
- // Verify key bindings were set
- // As passed
- var commands = view.KeyBindings.GetCommands (key);
- Assert.Contains (Command.Accept, commands);
- commands = view.KeyBindings.GetCommands (key | KeyCode.AltMask);
- Assert.Contains (Command.Accept, commands);
- var baseKey = key & ~KeyCode.ShiftMask;
- // If A...Z, with and without shift
- if (baseKey is >= KeyCode.A and <= KeyCode.Z) {
- commands = view.KeyBindings.GetCommands (key | KeyCode.ShiftMask);
- Assert.Contains (Command.Accept, commands);
- commands = view.KeyBindings.GetCommands (key & ~KeyCode.ShiftMask);
- Assert.Contains (Command.Accept, commands);
- commands = view.KeyBindings.GetCommands (key | KeyCode.AltMask);
- Assert.Contains (Command.Accept, commands);
- commands = view.KeyBindings.GetCommands (key & ~KeyCode.ShiftMask | KeyCode.AltMask);
- Assert.Contains (Command.Accept, commands);
- } else {
- // Non A..Z keys should not have shift bindings
- if (key.HasFlag (KeyCode.ShiftMask)) {
- commands = view.KeyBindings.GetCommands (key & ~KeyCode.ShiftMask);
- Assert.Empty (commands);
- } else {
- commands = view.KeyBindings.GetCommands (key | KeyCode.ShiftMask);
- Assert.Empty (commands);
- }
- }
- }
- [Theory]
- [InlineData (KeyCode.Delete)]
- [InlineData (KeyCode.Backspace)]
- [InlineData (KeyCode.Tab)]
- [InlineData (KeyCode.Enter)]
- [InlineData (KeyCode.Esc)]
- [InlineData (KeyCode.Space)]
- [InlineData (KeyCode.CursorLeft)]
- [InlineData (KeyCode.F1)]
- [InlineData (KeyCode.Null | KeyCode.ShiftMask)]
- public void Set_Throws_With_Invalid_Key (KeyCode key)
- {
- var view = new View ();
- Assert.Throws<ArgumentException> (() => view.HotKey = key);
- }
- [Theory]
- [InlineData ("Test", KeyCode.T)]
- [InlineData ("^Test", KeyCode.T)]
- [InlineData ("T^est", KeyCode.E)]
- [InlineData ("Te^st", KeyCode.S)]
- [InlineData ("Tes^t", KeyCode.T)]
- [InlineData ("other", KeyCode.Null)]
- [InlineData ("oTher", KeyCode.T)]
- [InlineData ("^Öther", (KeyCode)'Ö')]
- [InlineData ("^öther", (KeyCode)'ö')]
- // BUGBUG: '!' should be supported. Line 968 of TextFormatter filters on char.IsLetterOrDigit
- //[InlineData ("Test^!", (Key)'!')]
- public void Text_Change_Sets_HotKey (string text, KeyCode expectedHotKey)
- {
- var view = new View () {
- HotKeySpecifier = new Rune ('^'),
- Text = "^Hello"
- };
- Assert.Equal (KeyCode.H, view.HotKey);
-
- view.Text = text;
- Assert.Equal (expectedHotKey, view.HotKey);
- }
- [Theory]
- [InlineData("^Test")]
- public void Text_Empty_Sets_HotKey_To_Null (string text)
- {
- var view = new View () {
- HotKeySpecifier = (Rune)'^',
- Text = text
- };
- Assert.Equal (text, view.Text);
- Assert.Equal (KeyCode.T, view.HotKey);
- view.Text = string.Empty;
- Assert.Equal ("", view.Text);
- Assert.Equal (KeyCode.Null, view.HotKey);
- }
- [Theory]
- [InlineData (KeyCode.Null, true)] // non-shift
- [InlineData (KeyCode.ShiftMask, true)]
- [InlineData (KeyCode.AltMask, true)]
- [InlineData (KeyCode.ShiftMask | KeyCode.AltMask, true)]
- [InlineData (KeyCode.CtrlMask, false)]
- [InlineData (KeyCode.ShiftMask | KeyCode.CtrlMask, false)]
- public void KeyPress_Runs_Default_HotKey_Command (KeyCode mask, bool expected)
- {
- var view = new View () {
- HotKeySpecifier = (Rune)'^',
- Text = "^Test"
- };
- view.CanFocus = true;
- Assert.False (view.HasFocus);
- view.NewKeyDownEvent (new (KeyCode.T | mask));
- Assert.Equal (expected, view.HasFocus);
- }
- [Fact]
- public void ProcessKeyDown_Invokes_HotKey_Command_With_SuperView ()
- {
- var view = new View () {
- HotKeySpecifier = (Rune)'^',
- Text = "^Test"
- };
- var superView = new View ();
- superView.Add (view);
- view.CanFocus = true;
- Assert.False (view.HasFocus);
- var ke = new Key (KeyCode.T);
- superView.NewKeyDownEvent (ke);
- Assert.True (view.HasFocus);
- }
- [Fact]
- public void ProcessKeyDown_Ignores_KeyBindings_Out_Of_Scope_SuperView ()
- {
- var view = new View ();
- view.KeyBindings.Add (KeyCode.A, Command.Default);
- view.InvokingKeyBindings += (s, e) => {
- Assert.Fail ();
- };
-
- var superView = new View ();
- superView.Add (view);
- var ke = new Key (KeyCode.A);
- superView.NewKeyDownEvent (ke);
- }
- }
|