Files
Terminal.Gui/Tests/UnitTestsParallelizable/Drivers/WindowsInputProcessorTests.cs

493 lines
21 KiB
C#

using System.Collections.Concurrent;
using InputRecord = Terminal.Gui.Drivers.WindowsConsole.InputRecord;
using ButtonState = Terminal.Gui.Drivers.WindowsConsole.ButtonState;
using EventFlags = Terminal.Gui.Drivers.WindowsConsole.EventFlags;
using ControlKeyState = Terminal.Gui.Drivers.WindowsConsole.ControlKeyState;
using MouseEventRecord = Terminal.Gui.Drivers.WindowsConsole.MouseEventRecord;
namespace UnitTests_Parallelizable.DriverTests;
public class WindowsInputProcessorTests
{
[Fact]
public void Test_ProcessQueue_CapitalHLowerE ()
{
ConcurrentQueue<InputRecord> queue = new ();
queue.Enqueue (
new ()
{
EventType = WindowsConsole.EventType.Key,
KeyEvent = new ()
{
bKeyDown = true,
UnicodeChar = 'H',
dwControlKeyState = ControlKeyState.CapslockOn,
wVirtualKeyCode = (VK)72,
wVirtualScanCode = 35
}
});
queue.Enqueue (
new ()
{
EventType = WindowsConsole.EventType.Key,
KeyEvent = new ()
{
bKeyDown = false,
UnicodeChar = 'H',
dwControlKeyState = ControlKeyState.CapslockOn,
wVirtualKeyCode = (VK)72,
wVirtualScanCode = 35
}
});
queue.Enqueue (
new ()
{
EventType = WindowsConsole.EventType.Key,
KeyEvent = new ()
{
bKeyDown = true,
UnicodeChar = 'i',
dwControlKeyState = ControlKeyState.NoControlKeyPressed,
wVirtualKeyCode = (VK)73,
wVirtualScanCode = 23
}
});
queue.Enqueue (
new ()
{
EventType = WindowsConsole.EventType.Key,
KeyEvent = new ()
{
bKeyDown = false,
UnicodeChar = 'i',
dwControlKeyState = ControlKeyState.NoControlKeyPressed,
wVirtualKeyCode = (VK)73,
wVirtualScanCode = 23
}
});
var processor = new WindowsInputProcessor (queue);
List<Key> ups = [];
List<Key> downs = [];
processor.KeyUp += (s, e) => { ups.Add (e); };
processor.KeyDown += (s, e) => { downs.Add (e); };
Assert.Empty (ups);
Assert.Empty (downs);
processor.ProcessQueue ();
Assert.Equal (Key.H.WithShift, ups [0]);
Assert.Equal (Key.H.WithShift, downs [0]);
Assert.Equal (Key.I, ups [1]);
Assert.Equal (Key.I, downs [1]);
}
[Fact]
public void Test_ProcessQueue_Mouse_Move ()
{
ConcurrentQueue<InputRecord> queue = new ();
queue.Enqueue (
new ()
{
EventType = WindowsConsole.EventType.Mouse,
MouseEvent = new ()
{
MousePosition = new (32, 31),
ButtonState = ButtonState.NoButtonPressed,
ControlKeyState = ControlKeyState.NoControlKeyPressed,
EventFlags = EventFlags.MouseMoved
}
});
var processor = new WindowsInputProcessor (queue);
List<MouseEventArgs> mouseEvents = [];
processor.MouseEvent += (s, e) => { mouseEvents.Add (e); };
Assert.Empty (mouseEvents);
processor.ProcessQueue ();
MouseEventArgs s = Assert.Single (mouseEvents);
Assert.Equal (MouseFlags.ReportMousePosition, s.Flags);
Assert.Equal (s.ScreenPosition, new (32, 31));
}
[Theory]
[InlineData (ButtonState.Button1Pressed, MouseFlags.Button1Pressed)]
[InlineData (ButtonState.Button2Pressed, MouseFlags.Button2Pressed)]
[InlineData (ButtonState.Button3Pressed, MouseFlags.Button3Pressed)]
[InlineData (ButtonState.Button4Pressed, MouseFlags.Button4Pressed)]
internal void Test_ProcessQueue_Mouse_Pressed (ButtonState state, MouseFlags expectedFlag)
{
ConcurrentQueue<InputRecord> queue = new ();
queue.Enqueue (
new ()
{
EventType = WindowsConsole.EventType.Mouse,
MouseEvent = new ()
{
MousePosition = new (32, 31),
ButtonState = state,
ControlKeyState = ControlKeyState.NoControlKeyPressed,
EventFlags = EventFlags.MouseMoved
}
});
var processor = new WindowsInputProcessor (queue);
List<MouseEventArgs> mouseEvents = [];
processor.MouseEvent += (s, e) => { mouseEvents.Add (e); };
Assert.Empty (mouseEvents);
processor.ProcessQueue ();
MouseEventArgs s = Assert.Single (mouseEvents);
Assert.Equal (s.Flags, MouseFlags.ReportMousePosition | expectedFlag);
Assert.Equal (s.ScreenPosition, new (32, 31));
}
[Theory]
[InlineData (100, MouseFlags.WheeledUp)]
[InlineData (-100, MouseFlags.WheeledDown)]
internal void Test_ProcessQueue_Mouse_Wheel (int wheelValue, MouseFlags expectedFlag)
{
ConcurrentQueue<InputRecord> queue = new ();
queue.Enqueue (
new ()
{
EventType = WindowsConsole.EventType.Mouse,
MouseEvent = new ()
{
MousePosition = new (32, 31),
ButtonState = (ButtonState)wheelValue,
ControlKeyState = ControlKeyState.NoControlKeyPressed,
EventFlags = EventFlags.MouseWheeled
}
});
var processor = new WindowsInputProcessor (queue);
List<MouseEventArgs> mouseEvents = [];
processor.MouseEvent += (s, e) => { mouseEvents.Add (e); };
Assert.Empty (mouseEvents);
processor.ProcessQueue ();
MouseEventArgs s = Assert.Single (mouseEvents);
Assert.Equal (s.Flags, expectedFlag);
Assert.Equal (s.ScreenPosition, new (32, 31));
}
public static IEnumerable<object []> MouseFlagTestData ()
{
yield return
[
new []
{
Tuple.Create (ButtonState.Button1Pressed, EventFlags.NoEvent, ControlKeyState.NoControlKeyPressed, MouseFlags.Button1Pressed),
Tuple.Create (ButtonState.NoButtonPressed, EventFlags.NoEvent, ControlKeyState.NoControlKeyPressed, MouseFlags.Button1Released),
Tuple.Create (ButtonState.NoButtonPressed, EventFlags.NoEvent, ControlKeyState.NoControlKeyPressed, MouseFlags.None)
}
];
yield return
[
new []
{
Tuple.Create (
ButtonState.Button2Pressed,
EventFlags.MouseMoved,
ControlKeyState.NoControlKeyPressed,
MouseFlags.Button2Pressed | MouseFlags.ReportMousePosition),
Tuple.Create (ButtonState.NoButtonPressed, EventFlags.NoEvent, ControlKeyState.NoControlKeyPressed, MouseFlags.Button2Released),
Tuple.Create (ButtonState.NoButtonPressed, EventFlags.NoEvent, ControlKeyState.NoControlKeyPressed, MouseFlags.None)
}
];
yield return
[
new []
{
Tuple.Create (
ButtonState.Button3Pressed,
EventFlags.MouseMoved,
ControlKeyState.NoControlKeyPressed,
MouseFlags.Button3Pressed | MouseFlags.ReportMousePosition),
Tuple.Create (ButtonState.NoButtonPressed, EventFlags.NoEvent, ControlKeyState.NoControlKeyPressed, MouseFlags.Button3Released),
Tuple.Create (ButtonState.NoButtonPressed, EventFlags.NoEvent, ControlKeyState.NoControlKeyPressed, MouseFlags.None)
}
];
yield return
[
new []
{
Tuple.Create (
ButtonState.Button4Pressed,
EventFlags.MouseMoved,
ControlKeyState.NoControlKeyPressed,
MouseFlags.Button4Pressed | MouseFlags.ReportMousePosition),
Tuple.Create (ButtonState.NoButtonPressed, EventFlags.NoEvent, ControlKeyState.NoControlKeyPressed, MouseFlags.Button4Released),
Tuple.Create (ButtonState.NoButtonPressed, EventFlags.MouseMoved, ControlKeyState.NoControlKeyPressed, MouseFlags.ReportMousePosition)
}
];
yield return
[
new []
{
Tuple.Create (
ButtonState.RightmostButtonPressed,
EventFlags.MouseMoved,
ControlKeyState.NoControlKeyPressed,
MouseFlags.Button3Pressed | MouseFlags.ReportMousePosition),
Tuple.Create (ButtonState.NoButtonPressed, EventFlags.NoEvent, ControlKeyState.NoControlKeyPressed, MouseFlags.Button3Released),
Tuple.Create (ButtonState.NoButtonPressed, EventFlags.NoEvent, ControlKeyState.NoControlKeyPressed, MouseFlags.None)
}
];
// Tests for holding down 2 buttons at once and releasing them one after the other
yield return
[
new []
{
Tuple.Create (
ButtonState.Button1Pressed | ButtonState.Button2Pressed,
EventFlags.MouseMoved,
ControlKeyState.NoControlKeyPressed,
MouseFlags.Button1Pressed | MouseFlags.Button2Pressed | MouseFlags.ReportMousePosition),
Tuple.Create (
ButtonState.Button1Pressed,
EventFlags.NoEvent,
ControlKeyState.NoControlKeyPressed,
MouseFlags.Button1Pressed | MouseFlags.Button2Released),
Tuple.Create (ButtonState.NoButtonPressed, EventFlags.NoEvent, ControlKeyState.NoControlKeyPressed, MouseFlags.Button1Released),
Tuple.Create (ButtonState.NoButtonPressed, EventFlags.NoEvent, ControlKeyState.NoControlKeyPressed, MouseFlags.None)
}
];
yield return
[
new []
{
Tuple.Create (
ButtonState.Button3Pressed | ButtonState.Button4Pressed,
EventFlags.MouseMoved,
ControlKeyState.NoControlKeyPressed,
MouseFlags.Button3Pressed | MouseFlags.Button4Pressed | MouseFlags.ReportMousePosition),
Tuple.Create (
ButtonState.Button3Pressed,
EventFlags.NoEvent,
ControlKeyState.NoControlKeyPressed,
MouseFlags.Button3Pressed | MouseFlags.Button4Released),
Tuple.Create (ButtonState.NoButtonPressed, EventFlags.NoEvent, ControlKeyState.NoControlKeyPressed, MouseFlags.Button3Released),
Tuple.Create (ButtonState.NoButtonPressed, EventFlags.NoEvent, ControlKeyState.NoControlKeyPressed, MouseFlags.None)
}
];
// Test for holding down 2 buttons at once and releasing them simultaneously
yield return
[
new []
{
Tuple.Create (
ButtonState.Button1Pressed | ButtonState.Button2Pressed,
EventFlags.MouseMoved,
ControlKeyState.NoControlKeyPressed,
MouseFlags.Button1Pressed | MouseFlags.Button2Pressed | MouseFlags.ReportMousePosition),
Tuple.Create (
ButtonState.NoButtonPressed,
EventFlags.NoEvent,
ControlKeyState.NoControlKeyPressed,
MouseFlags.Button1Released | MouseFlags.Button2Released),
Tuple.Create (ButtonState.NoButtonPressed, EventFlags.NoEvent, ControlKeyState.NoControlKeyPressed, MouseFlags.None)
}
];
// Test that rightmost and button 3 are the same button so 2 states is still only 1 flag
yield return
[
new []
{
Tuple.Create (
ButtonState.Button3Pressed | ButtonState.RightmostButtonPressed,
EventFlags.MouseMoved,
ControlKeyState.NoControlKeyPressed,
MouseFlags.Button3Pressed | MouseFlags.ReportMousePosition),
// Can swap between without raising the released
Tuple.Create (
ButtonState.Button3Pressed,
EventFlags.MouseMoved,
ControlKeyState.NoControlKeyPressed,
MouseFlags.Button3Pressed | MouseFlags.ReportMousePosition),
Tuple.Create (
ButtonState.RightmostButtonPressed,
EventFlags.MouseMoved,
ControlKeyState.NoControlKeyPressed,
MouseFlags.Button3Pressed | MouseFlags.ReportMousePosition),
// Now with neither we get released
Tuple.Create (ButtonState.NoButtonPressed, EventFlags.NoEvent, ControlKeyState.NoControlKeyPressed, MouseFlags.Button3Released),
Tuple.Create (ButtonState.NoButtonPressed, EventFlags.NoEvent, ControlKeyState.NoControlKeyPressed, MouseFlags.None)
}
];
// Test for ControlKeyState buttons pressed and handled
yield return
[
new []
{
Tuple.Create (ButtonState.Button1Pressed, EventFlags.NoEvent, ControlKeyState.LeftAltPressed, MouseFlags.Button1Pressed | MouseFlags.ButtonAlt),
Tuple.Create (
ButtonState.NoButtonPressed,
EventFlags.NoEvent,
ControlKeyState.LeftAltPressed,
MouseFlags.Button1Released | MouseFlags.ButtonAlt),
Tuple.Create (ButtonState.NoButtonPressed, EventFlags.NoEvent, ControlKeyState.LeftAltPressed, MouseFlags.None | MouseFlags.ButtonAlt)
}
];
yield return
[
new []
{
Tuple.Create (
ButtonState.Button1Pressed,
EventFlags.NoEvent,
ControlKeyState.RightAltPressed,
MouseFlags.Button1Pressed | MouseFlags.ButtonAlt),
Tuple.Create (
ButtonState.NoButtonPressed,
EventFlags.NoEvent,
ControlKeyState.RightAltPressed,
MouseFlags.Button1Released | MouseFlags.ButtonAlt),
Tuple.Create (ButtonState.NoButtonPressed, EventFlags.NoEvent, ControlKeyState.RightAltPressed, MouseFlags.None | MouseFlags.ButtonAlt)
}
];
yield return
[
new []
{
Tuple.Create (
ButtonState.Button1Pressed,
EventFlags.NoEvent,
ControlKeyState.LeftControlPressed,
MouseFlags.Button1Pressed | MouseFlags.ButtonCtrl),
Tuple.Create (
ButtonState.NoButtonPressed,
EventFlags.NoEvent,
ControlKeyState.LeftControlPressed,
MouseFlags.Button1Released | MouseFlags.ButtonCtrl),
Tuple.Create (ButtonState.NoButtonPressed, EventFlags.NoEvent, ControlKeyState.LeftControlPressed, MouseFlags.None | MouseFlags.ButtonCtrl)
}
];
yield return
[
new []
{
Tuple.Create (
ButtonState.Button1Pressed,
EventFlags.NoEvent,
ControlKeyState.RightControlPressed,
MouseFlags.Button1Pressed | MouseFlags.ButtonCtrl),
Tuple.Create (
ButtonState.NoButtonPressed,
EventFlags.NoEvent,
ControlKeyState.RightControlPressed,
MouseFlags.Button1Released | MouseFlags.ButtonCtrl),
Tuple.Create (ButtonState.NoButtonPressed, EventFlags.NoEvent, ControlKeyState.RightControlPressed, MouseFlags.None | MouseFlags.ButtonCtrl)
}
];
yield return
[
new []
{
Tuple.Create (ButtonState.Button1Pressed, EventFlags.NoEvent, ControlKeyState.ShiftPressed, MouseFlags.Button1Pressed | MouseFlags.ButtonShift),
Tuple.Create (
ButtonState.NoButtonPressed,
EventFlags.NoEvent,
ControlKeyState.ShiftPressed,
MouseFlags.Button1Released | MouseFlags.ButtonShift),
Tuple.Create (ButtonState.NoButtonPressed, EventFlags.NoEvent, ControlKeyState.ShiftPressed, MouseFlags.None | MouseFlags.ButtonShift)
}
];
// Test for ControlKeyState buttons pressed and not handled
yield return
[
new []
{
Tuple.Create (ButtonState.Button1Pressed, EventFlags.NoEvent, ControlKeyState.CapslockOn, MouseFlags.Button1Pressed),
Tuple.Create (ButtonState.NoButtonPressed, EventFlags.NoEvent, ControlKeyState.CapslockOn, MouseFlags.Button1Released),
Tuple.Create (ButtonState.NoButtonPressed, EventFlags.NoEvent, ControlKeyState.CapslockOn, MouseFlags.None)
}
];
yield return
[
new []
{
Tuple.Create (ButtonState.Button1Pressed, EventFlags.NoEvent, ControlKeyState.EnhancedKey, MouseFlags.Button1Pressed),
Tuple.Create (ButtonState.NoButtonPressed, EventFlags.NoEvent, ControlKeyState.EnhancedKey, MouseFlags.Button1Released),
Tuple.Create (ButtonState.NoButtonPressed, EventFlags.NoEvent, ControlKeyState.EnhancedKey, MouseFlags.None)
}
];
yield return
[
new []
{
Tuple.Create (ButtonState.Button1Pressed, EventFlags.NoEvent, ControlKeyState.NumlockOn, MouseFlags.Button1Pressed),
Tuple.Create (ButtonState.NoButtonPressed, EventFlags.NoEvent, ControlKeyState.NumlockOn, MouseFlags.Button1Released),
Tuple.Create (ButtonState.NoButtonPressed, EventFlags.NoEvent, ControlKeyState.NumlockOn, MouseFlags.None)
}
];
yield return
[
new []
{
Tuple.Create (ButtonState.Button1Pressed, EventFlags.NoEvent, ControlKeyState.ScrolllockOn, MouseFlags.Button1Pressed),
Tuple.Create (ButtonState.NoButtonPressed, EventFlags.NoEvent, ControlKeyState.ScrolllockOn, MouseFlags.Button1Released),
Tuple.Create (ButtonState.NoButtonPressed, EventFlags.NoEvent, ControlKeyState.ScrolllockOn, MouseFlags.None)
}
];
}
[Theory]
[MemberData (nameof (MouseFlagTestData))]
internal void MouseFlags_Should_Map_Correctly (Tuple<ButtonState, EventFlags, ControlKeyState, MouseFlags> [] inputOutputPairs)
{
var processor = new WindowsInputProcessor (new ());
foreach (Tuple<ButtonState, EventFlags, ControlKeyState, MouseFlags> pair in inputOutputPairs)
{
var mockEvent = new MouseEventRecord { ButtonState = pair.Item1, EventFlags = pair.Item2, ControlKeyState = pair.Item3 };
MouseEventArgs result = processor.ToMouseEvent (mockEvent);
Assert.Equal (pair.Item4, result.Flags);
}
}
}