using static Terminal.Gui.ConsoleDrivers.ConsoleKeyMapping;
namespace Terminal.Gui.ConsoleDrivers;
public class ConsoleKeyMappingTests
{
#if ENABLE_VK_PACKET_NON_WINDOWS
// This test (and the GetConsoleKeyInfoFromKeyCode API) are bogus. They make no sense outside of
// the context of Windows and knowing they keyboard layout. They should be removed.
[Theory]
[InlineData (KeyCode.A | KeyCode.ShiftMask, ConsoleKey.A, KeyCode.A, 'A')]
[InlineData ((KeyCode)'a', ConsoleKey.A, (KeyCode)'a', 'a')]
[InlineData ((KeyCode)'À' | KeyCode.ShiftMask, ConsoleKey.A, (KeyCode)'À', 'À')]
[InlineData ((KeyCode)'à', ConsoleKey.A, (KeyCode)'à', 'à')]
[InlineData ((KeyCode)'Ü' | KeyCode.ShiftMask, ConsoleKey.U, (KeyCode)'Ü', 'Ü')]
[InlineData ((KeyCode)'ü', ConsoleKey.U, (KeyCode)'ü', 'ü')]
[InlineData ((KeyCode)'Ý' | KeyCode.ShiftMask, ConsoleKey.Y, (KeyCode)'Ý', 'Ý')]
[InlineData ((KeyCode)'ý', ConsoleKey.Y, (KeyCode)'ý', 'ý')]
[InlineData ((KeyCode)'!' | KeyCode.ShiftMask, ConsoleKey.D1, (KeyCode)'!', '!')]
[InlineData (KeyCode.D1 | KeyCode.ShiftMask, ConsoleKey.D1, (KeyCode)'!', '!')]
[InlineData (KeyCode.D1, ConsoleKey.D1, KeyCode.D1, '1')]
[InlineData (
(KeyCode)'/' | KeyCode.ShiftMask,
ConsoleKey.D7,
(KeyCode)'/',
'/'
)] // BUGBUG: This is incorrect for ENG keyboards. Shift-7 should be &.
[InlineData (KeyCode.D7 | KeyCode.ShiftMask, ConsoleKey.D7, (KeyCode)'/', '/')]
[InlineData (KeyCode.D7, ConsoleKey.D7, KeyCode.D7, '7')]
[InlineData ((KeyCode)'{' | KeyCode.AltMask | KeyCode.CtrlMask, ConsoleKey.D7, (KeyCode)'{', '{')]
[InlineData ((KeyCode)'?' | KeyCode.ShiftMask, ConsoleKey.Oem4, (KeyCode)'?', '?')]
[InlineData ((KeyCode)'\'', ConsoleKey.Oem4, (KeyCode)'\'', '\'')]
[InlineData (KeyCode.PageDown | KeyCode.ShiftMask, ConsoleKey.PageDown, KeyCode.Null, '\0')]
[InlineData (KeyCode.PageDown, ConsoleKey.PageDown, KeyCode.Null, '\0')]
[InlineData ((KeyCode)'q', ConsoleKey.Q, (KeyCode)'q', 'q')]
[InlineData (KeyCode.F2, ConsoleKey.F2, KeyCode.Null, '\0')]
[InlineData ((KeyCode)'英', ConsoleKey.None, (KeyCode)'英', '英')]
public void GetConsoleKeyInfoFromKeyCode_Tests (
KeyCode keyCode,
ConsoleKey expectedConsoleKey,
KeyCode expectedKeyCode,
char expectedKeyChar
)
{
var consoleKeyInfo = ConsoleKeyMapping.GetConsoleKeyInfoFromKeyCode (keyCode);
Assert.Equal (consoleKeyInfo.Key, expectedConsoleKey);
Assert.Equal ((char)expectedKeyCode, expectedKeyChar);
Assert.Equal (consoleKeyInfo.KeyChar, expectedKeyChar);
}
static object packetLock = new object ();
///
/// Sometimes when using remote tools EventKeyRecord sends 'virtual keystrokes'.
/// These are indicated with the wVirtualKeyCode of 231 (VK_PACKET). When we see this code
/// then we need to look to the unicode character (UnicodeChar) instead of the key
/// when telling the rest of the framework what button was pressed. For full details
/// see: https://github.com/gui-cs/Terminal.Gui/issues/2008
///
[Theory]
[AutoInitShutdown]
[MemberData (nameof (VKPacket))]
public void TestVKPacket (
uint unicodeCharacter,
bool shift,
bool alt,
bool control,
uint initialVirtualKey,
uint initialScanCode,
KeyCode expectedRemapping,
uint expectedVirtualKey,
uint expectedScanCode
)
{
lock (packetLock)
{
Application._forceFakeConsole = true;
Application.Init ();
ConsoleKeyInfo originalConsoleKeyInfo =
new ConsoleKeyInfo ((char)unicodeCharacter, (ConsoleKey)initialVirtualKey, shift, alt, control);
var encodedChar = ConsoleKeyMapping.EncodeKeyCharForVKPacket (originalConsoleKeyInfo);
ConsoleKeyInfo packetConsoleKeyInfo =
new ConsoleKeyInfo (encodedChar, ConsoleKey.Packet, shift, alt, control);
ConsoleKeyInfo consoleKeyInfo = ConsoleKeyMapping.DecodeVKPacketToKConsoleKeyInfo (packetConsoleKeyInfo);
Assert.Equal (originalConsoleKeyInfo, consoleKeyInfo);
var modifiers = ConsoleKeyMapping.GetModifiers (shift, alt, control);
var scanCode = ConsoleKeyMapping.GetScanCodeFromConsoleKeyInfo (consoleKeyInfo);
Assert.Equal ((uint)consoleKeyInfo.Key, initialVirtualKey);
if (scanCode > 0 && consoleKeyInfo.KeyChar == 0)
{
Assert.Equal (0, (double)consoleKeyInfo.KeyChar);
}
else
{
Assert.Equal (consoleKeyInfo.KeyChar, unicodeCharacter);
}
Assert.Equal ((uint)consoleKeyInfo.Key, expectedVirtualKey);
Assert.Equal (scanCode, initialScanCode);
Assert.Equal (scanCode, expectedScanCode);
var top = Application.Top;
top.KeyDown += (s, e) =>
{
Assert.Equal (Key.ToString (expectedRemapping), Key.ToString (e.KeyCode));
e.Handled = true;
Application.RequestStop ();
};
int iterations = -1;
Application.Iteration += (s, a) =>
{
iterations++;
if (iterations == 0)
{
var keyChar = ConsoleKeyMapping.EncodeKeyCharForVKPacket (consoleKeyInfo);
Application.Driver?.SendKeys (keyChar, ConsoleKey.Packet, shift, alt, control);
}
};
Application.Run ();
Application.Shutdown ();
}
}
public static IEnumerable