public async Task InputEvents_Exception_Logged() { const string message = "--message--"; var tcs = new TaskCompletionSource <int>(); int exceptionCount = 0; using var api = new StubbedNativeCalls { ReadConsoleInputConsoleInputHandleInt32 = (handle, size) => throw new Exception(message) }; using var sut = new ConControls.ConsoleApi.ConsoleController(api); using var logger = new TestLogger(CheckInputLogForException); api.StdInEvent.Set(); (await Task.WhenAny(tcs.Task, Task.Delay(2000))) .Should() .Be(tcs.Task, "event should be processed in less than 2 seconds!"); void CheckInputLogForException(string msg) { if (!msg.Contains(message)) { return; } if (Interlocked.Increment(ref exceptionCount) == 2) { tcs.SetResult(0); } } } }
public async Task InputEvents_InvalidRecordType_Logged() { var record = new INPUT_RECORD { EventType = (InputEventType)0xFFFF }; var records = new[] { record }; var tcs = new TaskCompletionSource <int>(); using var api = new StubbedNativeCalls(); api.ReadConsoleInputConsoleInputHandleInt32 = (handle, size) => { handle.Should().Be(api.StdIn); return(records); }; using var sut = new ConControls.ConsoleApi.ConsoleController(api); using var logger = new TestLogger(CheckInputLogForRecord); api.StdInEvent.Set(); (await Task.WhenAny(tcs.Task, Task.Delay(2000))) .Should() .Be(tcs.Task, "event should be processed in less than 2 seconds!"); void CheckInputLogForRecord(string msg) { if (msg.Contains("Unkown input record type ")) { tcs.SetResult(0); } } }
public void ActiveScreen_CorrectBehaviour() { var api = new StubbedNativeCalls(); var sut = new ConControls.ConsoleApi.ConsoleController(api); sut.ActiveScreen.Should().BeTrue(); bool set = false; ConsoleOutputHandle currentHandle = api.ScreenHandle; api.SetActiveConsoleScreenBufferConsoleOutputHandle = SetSuccess; sut.ActiveScreen = true; set.Should().BeFalse(); sut.ActiveScreen.Should().BeTrue(); sut.ActiveScreen = false; set.Should().BeTrue(); sut.ActiveScreen.Should().BeFalse(); currentHandle.Should().Be(api.StdOut); set = false; sut.ActiveScreen = false; set.Should().BeFalse(); sut.ActiveScreen.Should().BeFalse(); api.SetActiveConsoleScreenBufferConsoleOutputHandle = SetFail; sut.ActiveScreen = true; set.Should().BeTrue(); sut.ActiveScreen.Should().BeFalse(); api.SetActiveConsoleScreenBufferConsoleOutputHandle = SetSuccess; sut.ActiveScreen = true; sut.ActiveScreen.Should().BeTrue(); currentHandle.Should().Be(api.ScreenHandle); set = false; api.SetActiveConsoleScreenBufferConsoleOutputHandle = SetFail; sut.ActiveScreen = false; set.Should().BeTrue(); sut.ActiveScreen.Should().BeTrue(); bool SetFail(ConsoleOutputHandle handle) { set = true; currentHandle = handle; return(false); } bool SetSuccess(ConsoleOutputHandle handle) { set = true; currentHandle = handle; return(true); } }
public async Task ThreadManagement_ThreadStartedAndStoppedCorrectly() { TaskCompletionSource <int> startTaskSource = new TaskCompletionSource <int>(); TaskCompletionSource <int> endTaskSource = new TaskCompletionSource <int>(); bool threadStartLogged = false, threadEndLogged = false; using var logger = new TestLogger(CheckLog); using var api = new StubbedNativeCalls(); var sut = new ConControls.ConsoleApi.ConsoleController(api); (await Task.WhenAny(startTaskSource.Task, Task.Delay(2000))) .Should() .Be(startTaskSource.Task, "Thread should be started in less than 2 seconds!"); threadStartLogged.Should().BeTrue(); sut.Dispose(); (await Task.WhenAny(endTaskSource.Task, Task.Delay(2000))) .Should() .Be(endTaskSource.Task, "Thread should be stopped in less than 2 seconds!"); threadEndLogged.Should().BeTrue(); sut.Dispose(); // should not fail void CheckLog(string msg) { if (msg.Contains("Starting thread.")) { threadStartLogged = true; startTaskSource.SetResult(0); } if (msg.Contains("Stopping thread")) { threadEndLogged = true; endTaskSource.SetResult(0); } } }
public void ConstructAndDispose_BufferAndModeSetCorrectly() { const ConsoleInputModes originalInputMode = ConsoleInputModes.EnableInsertMode | ConsoleInputModes.EnableAutoPosition; const string originalTitle = "original console title string"; bool inputSet = false, outputSet = false, outputModeSet = false, titleGet = false; bool inputReset = false, outputReset = false, titleSet = false; using var api = new StubbedNativeCalls { GetConsoleTitle = () => { titleGet = true; return(originalTitle); }, SetConsoleTitleString = t => { t.Should().Be(originalTitle); titleSet = true; } }; api.GetConsoleModeConsoleInputHandle = handle => { inputSet.Should().BeFalse(); handle.Should().Be(api.StdIn); return(originalInputMode); }; api.SetActiveConsoleScreenBufferConsoleOutputHandle = handle => { if (!outputSet) { handle.Should().Be(api.ScreenHandle); outputReset.Should().BeFalse(); outputSet = true; return(true); } outputReset.Should().BeFalse(); handle.Should().Be(api.StdOut); outputReset = true; return(true); }; api.SetConsoleModeConsoleInputHandleConsoleInputModes = (handle, mode) => { handle.Should().Be(api.StdIn); if (!inputSet) { mode.Should() .Be(ConsoleInputModes.EnableWindowInput | ConsoleInputModes.EnableMouseInput | ConsoleInputModes.EnableExtendedFlags); inputSet = true; return; } mode.Should().Be(originalInputMode); inputReset.Should().BeFalse(); inputReset = true; }; api.SetConsoleModeConsoleOutputHandleConsoleOutputModes = (handle, mode) => { handle.Should().Be(api.ScreenHandle); outputModeSet.Should().BeFalse(); mode.Should().Be(ConsoleOutputModes.None); outputModeSet = true; }; using var sut = new ConControls.ConsoleApi.ConsoleController(api); inputSet.Should().BeTrue(); outputSet.Should().BeTrue(); outputModeSet.Should().BeTrue(); titleGet.Should().BeTrue(); sut.Dispose(); inputReset.Should().BeTrue(); outputReset.Should().BeTrue(); titleSet.Should().BeTrue(); }
public async Task InputEvents_AllKindsOfEvents_EventsFired() { var keyRecord = new INPUT_RECORD { EventType = InputEventType.Key, Event = new INPUT_RECORD.EVENTUNION { KeyEvent = new KEY_EVENT_RECORD { ControlKeys = ControlKeyStates.LEFT_ALT_PRESSED, KeyDown = 12, RepeatCount = 23, UnicodeChar = 'x', VirtualKeyCode = VirtualKey.Accept, VirtualScanCode = 42 } } }; var mouseRecord = new INPUT_RECORD { EventType = InputEventType.Mouse, Event = new INPUT_RECORD.EVENTUNION { MouseEvent = new MOUSE_EVENT_RECORD { ControlKeys = ControlKeyStates.LEFT_ALT_PRESSED, EventFlags = MouseEventFlags.DoubleClick, ButtonState = MouseButtonStates.FourthButtonPressed, MousePosition = new COORD(23, 42), Scroll = 17 } } }; var sizeRecord = new INPUT_RECORD { EventType = InputEventType.WindowBufferSize, Event = new INPUT_RECORD.EVENTUNION { SizeEvent = new WINDOW_BUFFER_SIZE_RECORD { Size = new COORD(23, 42) } } }; var menuRecord = new INPUT_RECORD { EventType = InputEventType.Menu, Event = new INPUT_RECORD.EVENTUNION { MenuEvent = new MENU_EVENT_RECORD { CommandId = 123 } } }; var focusRecord = new INPUT_RECORD { EventType = InputEventType.Focus, Event = new INPUT_RECORD.EVENTUNION { FocusEvent = new FOCUS_EVENT_RECORD { SetFocus = 123 } } }; var records = new[] { keyRecord, mouseRecord, sizeRecord, menuRecord, focusRecord }; var keyTcs = new TaskCompletionSource <int>(); var mouseTcs = new TaskCompletionSource <int>(); var sizeTcs = new TaskCompletionSource <int>(); var menuTcs = new TaskCompletionSource <int>(); var focusTcs = new TaskCompletionSource <int>(); using var api = new StubbedNativeCalls(); api.ReadConsoleInputConsoleInputHandleInt32 = (handle, size) => { handle.Should().Be(api.StdIn); return(records); }; api.GetConsoleScreenBufferInfoConsoleOutputHandle = handle => { handle.Should().Be(api.ScreenHandle); return(new CONSOLE_SCREEN_BUFFER_INFOEX { Window = new SMALL_RECT(1, 2, 4, 6), BufferSize = sizeRecord.Event.SizeEvent.Size }); }; using var sut = new ConControls.ConsoleApi.ConsoleController(api); sut.KeyEvent += (sender, e) => { e.KeyDown.Should().Be(keyRecord.Event.KeyEvent.KeyDown != 0); e.UnicodeChar.Should().Be(keyRecord.Event.KeyEvent.UnicodeChar); e.RepeatCount.Should().Be(keyRecord.Event.KeyEvent.RepeatCount); e.VirtualKeyCode.Should().Be(keyRecord.Event.KeyEvent.VirtualKeyCode); e.VirtualScanCode.Should().Be(keyRecord.Event.KeyEvent.VirtualScanCode); e.ControlKeys.Should().Be(keyRecord.Event.KeyEvent.ControlKeys); keyTcs.SetResult(0); }; sut.MouseEvent += (sender, e) => { e.ButtonState.Should().Be(mouseRecord.Event.MouseEvent.ButtonState); e.EventFlags.Should().Be(mouseRecord.Event.MouseEvent.EventFlags); e.MousePosition.X.Should().Be(mouseRecord.Event.MouseEvent.MousePosition.X); e.MousePosition.Y.Should().Be(mouseRecord.Event.MouseEvent.MousePosition.Y); e.Scroll.Should().Be(mouseRecord.Event.MouseEvent.Scroll); e.ControlKeys.Should().Be(mouseRecord.Event.MouseEvent.ControlKeys); mouseTcs.SetResult(0); }; sut.SizeEvent += (sender, e) => { if (e.WindowArea == new Rectangle(1, 2, 3, 4) && e.BufferSize.Width == sizeRecord.Event.SizeEvent.Size.X && e.BufferSize.Height == sizeRecord.Event.SizeEvent.Size.Y) { sizeTcs.TrySetResult(0); } }; sut.MenuEvent += (sender, e) => { e.CommandId.Should().Be(menuRecord.Event.MenuEvent.CommandId); menuTcs.SetResult(0); }; sut.FocusEvent += (sender, e) => { e.SetFocus.Should().Be(focusRecord.Event.FocusEvent.SetFocus != 0); focusTcs.SetResult(0); }; var allTasks = Task.WhenAll(new Task[] { keyTcs.Task, mouseTcs.Task, sizeTcs.Task, menuTcs.Task, focusTcs.Task }); api.StdInEvent.Set(); //await allTasks; (await Task.WhenAny(allTasks, Task.Delay(2000))) .Should() .Be(allTasks, "events should be processed in less than 2 seconds!"); }