public void FrameCharSets_SetOnlyOnChange() { var api = new StubbedNativeCalls(); var graphicsProvider = new StubbedGraphicsProvider(); bool graphicsRequested = false; graphicsProvider.ProvideConsoleOutputHandleINativeCallsSizeFrameCharSets = (handle, calls, arg3, arg4) => { graphicsRequested = true; return(graphicsProvider.Graphics); }; using var sut = new ConControls.Controls.ConsoleWindow(api, new StubbedConsoleController(), graphicsProvider); sut.FrameCharSets.Should().BeOfType <FrameCharSets>(); var fremeCharSets = new FrameCharSets(); graphicsRequested = false; sut.FrameCharSets = fremeCharSets; graphicsRequested.Should().BeTrue(); sut.FrameCharSets.Should().BeSameAs(fremeCharSets); graphicsRequested = false; sut.FrameCharSets = fremeCharSets; graphicsRequested.Should().BeFalse(); sut.FrameCharSets = new FrameCharSets(); graphicsRequested.Should().BeTrue(); sut.Invoking(s => s.FrameCharSets = null !).Should().Throw <ArgumentNullException>(); }
public void Title_GetAndSetProperly() { string title = string.Empty; var api = new StubbedNativeCalls { GetConsoleTitle = () => title, SetConsoleTitleString = s => title = s }; using var controller = new StubbedConsoleController(); var graphicsProvider = new StubbedGraphicsProvider(); using var sut = new ConControls.Controls.ConsoleWindow(api, controller, graphicsProvider); sut.Title.Should().Be(string.Empty); sut.Title = "hello"; title.Should().Be("hello"); sut.Title.Should().Be("hello"); sut.Title = "world"; title.Should().Be("world"); sut.Title.Should().Be("world"); sut.Title = null !; title.Should().BeEmpty(); sut.Title.Should().BeEmpty(); }
public void ControlManagement_ControlAreaChanged_Redrawn() { var api = new StubbedNativeCalls(); using var controller = new StubbedConsoleController(); var graphicsProvider = new StubbedGraphicsProvider(); bool provided = false; graphicsProvider.ProvideConsoleOutputHandleINativeCallsSizeFrameCharSets = (handle, calls, arg3, arg4) => { provided = true; return(graphicsProvider.Graphics); }; using var sut = new ConControls.Controls.ConsoleWindow(api, controller, graphicsProvider); using var c = new Panel(sut) { Area = (5, 5, 10, 10).Rect(), Parent = sut }; provided = false; c.Area = (4, 4, 6, 6).Rect(); provided.Should().BeTrue(); sut.Controls.Remove(c); provided = false; c.Area = (1, 2, 3, 4).Rect(); provided.Should().BeFalse(); } }
public void DefaultCursorSize_SetAndDrawn() { const int originalCursorSize = 17; const int alternativeCursorSize = 23; var api = new StubbedNativeCalls { GetCursorInfoConsoleOutputHandle = handle => (true, originalCursorSize, Point.Empty) }; using var controller = new StubbedConsoleController(); bool graphicsProvided = false; var graphicsProvider = new StubbedGraphicsProvider(); graphicsProvider.ProvideConsoleOutputHandleINativeCallsSizeFrameCharSets = (handle, calls, arg3, arg4) => { graphicsProvided = true; return(graphicsProvider.Graphics); }; using var sut = new ConControls.Controls.ConsoleWindow(api, controller, graphicsProvider); var suti = (IControlContainer)sut; sut.DefaultCursorSize.Should().Be(originalCursorSize); suti.CursorSize.Should().Be(originalCursorSize); graphicsProvided = false; suti.CursorSize = alternativeCursorSize; graphicsProvided.Should().BeTrue(); sut.DefaultCursorSize.Should().Be(alternativeCursorSize); graphicsProvided = false; suti.CursorSize = null; graphicsProvided.Should().BeFalse(); sut.DefaultCursorSize.Should().Be(alternativeCursorSize); }
public void FocusNext_Cousins_CorrectOrder() { using var consoleController = new StubbedConsoleController(); using var api = new StubbedNativeCalls(); var graphicsProvider = new StubbedGraphicsProvider(); using var sut = new ConControls.Controls.ConsoleWindow(api, consoleController, graphicsProvider); var c0 = new Panel(sut) { Parent = sut }; var f00 = new ConControls.Controls.TextBlock(sut) { Parent = c0 }; var c1 = new Panel(sut) { Parent = sut }; var f10 = new ConControls.Controls.TextBlock(sut) { Parent = c1 }; sut.FocusedControl.Should().BeNull(); sut.FocusNext().Should().Be(f00); sut.FocusNext().Should().Be(f10); sut.FocusNext().Should().Be(f00); sut.FocusNext().Should().Be(f10); }
public void KeyEvent_Handled_Ignored() { using var consoleController = new StubbedConsoleController(); using var api = new StubbedNativeCalls(); var graphicsProvider = new StubbedGraphicsProvider(); using var sut = new ConControls.Controls.ConsoleWindow(api, consoleController, graphicsProvider); bool raised = false; sut.KeyEvent += (sender, e) => { sender.Should().Be(sut); raised = true; e.Handled = true; }; _ = new StubbedTextControl(sut); consoleController.KeyEventEvent(consoleController, new ConsoleKeyEventArgs(new KEY_EVENT_RECORD { ControlKeys = ControlKeyStates.None, KeyDown = 1, VirtualKeyCode = VirtualKey.Tab })); raised.Should().BeTrue(); sut.FocusedControl.Should().BeNull(); }
public void DefaultForegroundColor_SetAndDrawn() { const ConsoleColor color = ConsoleColor.DarkMagenta; var api = new StubbedNativeCalls(); using var controller = new StubbedConsoleController(); bool graphicsProvided = false; var graphicsProvider = new StubbedGraphicsProvider(); graphicsProvider.ProvideConsoleOutputHandleINativeCallsSizeFrameCharSets = (handle, calls, arg3, arg4) => { graphicsProvided = true; return(graphicsProvider.Graphics); }; using var sut = new ConControls.Controls.ConsoleWindow(api, controller, graphicsProvider); var suti = (IControlContainer)sut; sut.DefaultForegroundColor.Should().Be(ConsoleColor.Gray); suti.ForegroundColor.Should().Be(ConsoleColor.Gray); graphicsProvided = false; suti.ForegroundColor = color; graphicsProvided.Should().BeTrue(); sut.DefaultForegroundColor.Should().Be(color); graphicsProvided = false; suti.ForegroundColor = null; graphicsProvided.Should().BeFalse(); sut.DefaultForegroundColor.Should().Be(color); }
public void KeyEvent_SwitchBuffersKey_BuffersSwitched() { bool active = true; using var consoleController = new StubbedConsoleController { ActiveScreenGet = () => active, ActiveScreenSetBoolean = b => active = b }; using var api = new StubbedNativeCalls(); var graphicsProvider = new StubbedGraphicsProvider(); using var sut = new ConControls.Controls.ConsoleWindow(api, consoleController, graphicsProvider) { SwitchConsoleBuffersKey = ConControls.Controls.KeyCombination.F11 }; var e = new ConsoleKeyEventArgs(new KEY_EVENT_RECORD { KeyDown = 1, VirtualKeyCode = VirtualKey.F11 }); consoleController.KeyEventEvent(consoleController, e); active.Should().BeFalse(); consoleController.KeyEventEvent(consoleController, e); active.Should().BeTrue(); consoleController.KeyEventEvent(consoleController, e); active.Should().BeFalse(); }
public void FocusNext_Empty_Null() { using var consoleController = new StubbedConsoleController(); using var api = new StubbedNativeCalls(); var graphicsProvider = new StubbedGraphicsProvider(); using var sut = new ConControls.Controls.ConsoleWindow(api, consoleController, graphicsProvider); sut.FocusedControl.Should().BeNull(); sut.FocusNext().Should().BeNull(); sut.FocusNext().Should().BeNull(); }
public void PointToConsole_Identity() { var consoleListener = new StubbedConsoleController(); using var api = new StubbedNativeCalls(); var graphicsProvider = new StubbedGraphicsProvider(); using var sut = new ConControls.Controls.ConsoleWindow(api, consoleListener, graphicsProvider); Point p = new Point(12, 34); sut.PointToConsole(p).Should().Be(p); }
public void Size_Get_BufferSize() { var consoleListener = new StubbedConsoleController(); var windowSize = new Size(12, 34); using var api = new StubbedNativeCalls { GetConsoleScreenBufferInfoConsoleOutputHandle = handle => new CONSOLE_SCREEN_BUFFER_INFOEX { Window = new SMALL_RECT(1, 2, 3, 4), BufferSize = new COORD(windowSize) } }; var graphicsProvider = new StubbedGraphicsProvider(); using var sut = new ConControls.Controls.ConsoleWindow(api, consoleListener, graphicsProvider); sut.Size.Should().Be(windowSize); }
public void FocusedControl_NonFocussableControl_InvalidOperationException() { var api = new StubbedNativeCalls(); using var controller = new StubbedConsoleController(); var graphicsProvider = new StubbedGraphicsProvider(); using var sut = new ConControls.Controls.ConsoleWindow(api, controller, graphicsProvider); using var c = new Panel(sut) { Parent = sut }; sut.Invoking(s => s.FocusedControl = c).Should().Throw <InvalidOperationException>(); }
static void PerformSizeTest(Size original, Size target, Size maximum, Size expectedTempWindowSize, Size expectedFinalWindowSize) { Size currentWindowSize = original, currentBufferSize = original; int windowSet = 0; using var api = new StubbedNativeCalls(); var controller = new StubbedConsoleController(); var graphicsProvider = new StubbedGraphicsProvider(); using var sut = new ConControls.Controls.ConsoleWindow(api, controller, graphicsProvider); api.GetConsoleScreenBufferInfoConsoleOutputHandle = handle => { handle.Should().Be(controller.OutputHandle); return(new CONSOLE_SCREEN_BUFFER_INFOEX { Window = new SMALL_RECT(currentWindowSize), BufferSize = new COORD(currentBufferSize), MaximumWindowSize = new COORD(maximum) }); }; api.SetConsoleWindowSizeConsoleOutputHandleSize = (handle, size) => { handle.Should().Be(controller.OutputHandle); currentWindowSize = size; if (windowSet == 0) { size.Should().Be(expectedTempWindowSize); windowSet = 1; return; } size.Should().Be(expectedFinalWindowSize); windowSet.Should().Be(1); windowSet = 2; }; api.SetConsoleScreenBufferSizeConsoleOutputHandleSize = (handle, size) => { handle.Should().Be(controller.OutputHandle); size.Should().Be(target); currentBufferSize = size; }; sut.Size.Should().Be(original); sut.Size = target; currentBufferSize.Should().Be(target); currentWindowSize.Should().Be(expectedFinalWindowSize); }
public void ControlManagement_CursorUpdate_Updated() { bool cursorVisible = false; int cursorSize = 0; Point cursorPosition = Point.Empty; var api = new StubbedNativeCalls { SetCursorInfoConsoleOutputHandleBooleanInt32Point = (handle, visible, size, position) => { cursorVisible = visible; cursorSize = size; cursorPosition = position; } }; using var controller = new StubbedConsoleController(); var graphicsProvider = new StubbedGraphicsProvider(); var textController = new StubbedConsoleTextController { BufferLineCountGet = () => 20, MaxLineLengthGet = () => 20, EndCaretGet = () => (20, 20).Pt(), GetLineLengthInt32 = l => 20 }; using var sut = new ConControls.Controls.ConsoleWindow(api, controller, graphicsProvider); using var c = new ConControls.Controls.TextBlock(sut, textController) { Area = (5, 5, 10, 10).Rect(), Parent = sut, CursorSize = 12, CursorVisible = false, CursorPosition = (1, 2).Pt() }; sut.FocusedControl = c; cursorVisible.Should().BeFalse(); cursorSize.Should().Be(12); cursorPosition.Should().Be((6, 7).Pt()); c.CursorPosition = (5, 6).Pt(); cursorPosition.Should().Be((10, 11).Pt()); c.CursorVisible = true; cursorVisible.Should().BeTrue(); c.CursorSize = 23; cursorSize.Should().Be(23); }
public void KeyEvent_UnhandledKeyUp_Ignored() { using var consoleController = new StubbedConsoleController(); using var api = new StubbedNativeCalls(); var graphicsProvider = new StubbedGraphicsProvider(); using var sut = new ConControls.Controls.ConsoleWindow(api, consoleController, graphicsProvider); _ = new StubbedTextControl(sut); consoleController.KeyEventEvent(consoleController, new ConsoleKeyEventArgs(new KEY_EVENT_RECORD { ControlKeys = ControlKeyStates.None, KeyDown = 0, VirtualKeyCode = VirtualKey.Tab })); sut.FocusedControl.Should().BeNull(); }
public void FocusNext_SingleThenDisabled_Null() { using var consoleController = new StubbedConsoleController(); using var api = new StubbedNativeCalls(); var graphicsProvider = new StubbedGraphicsProvider(); using var sut = new ConControls.Controls.ConsoleWindow(api, consoleController, graphicsProvider); var f0 = new ConControls.Controls.TextBlock(sut) { Parent = sut }; sut.FocusedControl.Should().BeNull(); sut.FocusNext().Should().Be(f0); f0.Enabled = false; sut.FocusNext().Should().BeNull(); }
public void MouseEvents_MouseEventRaisedWithCorrectValues() { const ControlKeyStates controlKeys = ControlKeyStates.LEFT_ALT_PRESSED | ControlKeyStates.CAPSLOCK_ON; const int scroll = 123; const MouseButtonStates buttons = MouseButtonStates.LeftButtonPressed; Point position = (3, 7).Pt(); const MouseEventFlags kind = MouseEventFlags.Wheeled; var api = new StubbedNativeCalls(); using var controller = new StubbedConsoleController(); var graphicsProvider = new StubbedGraphicsProvider(); var args = new ConsoleMouseEventArgs(new MOUSE_EVENT_RECORD { ButtonState = buttons, ControlKeys = controlKeys, EventFlags = kind, MousePosition = new COORD(position), Scroll = scroll }); using var sut = new ConControls.Controls.ConsoleWindow(api, controller, graphicsProvider); bool raised = false; sut.MouseEvent += OnMouse; controller.MouseEventEvent(controller, args); raised.Should().BeTrue(); raised = false; sut.MouseEvent -= OnMouse; controller.MouseEventEvent(controller, args); raised.Should().BeFalse(); void OnMouse(object sender, MouseEventArgs e) { sender.Should().Be(sut); e.ControlKeys.Should().Be(controlKeys); e.Scroll.Should().Be(scroll); e.ButtonState.Should().Be(buttons); e.Position.Should().Be(position); e.Kind.Should().Be(kind); raised = true; } }
public void KeyEvent_CloseWindowKey_WindowClosed() { using var consoleController = new StubbedConsoleController(); using var api = new StubbedNativeCalls(); var graphicsProvider = new StubbedGraphicsProvider(); using var sut = new ConControls.Controls.ConsoleWindow(api, consoleController, graphicsProvider) { CloseWindowKey = ConControls.Controls.KeyCombination.AltF4 }; consoleController.KeyEventEvent(consoleController, new ConsoleKeyEventArgs(new KEY_EVENT_RECORD { ControlKeys = ControlKeyStates.LEFT_ALT_PRESSED, KeyDown = 1, VirtualKeyCode = VirtualKey.F4 })); sut.IsDisposed.Should().BeTrue(); }
public void Draw_NotDrawnWhenInhibited() { var api = new StubbedNativeCalls(); using var controller = new StubbedConsoleController(); var graphicsProvider = new StubbedGraphicsProvider(); bool provided = false; graphicsProvider.ProvideConsoleOutputHandleINativeCallsSizeFrameCharSets = (handle, calls, arg3, arg4) => { provided = true; return(graphicsProvider.Graphics); }; using var sut = new ConControls.Controls.ConsoleWindow(api, controller, graphicsProvider); provided = false; using (sut.DeferDrawing()) { sut.Invalidate(); provided.Should().BeFalse(); } provided.Should().BeTrue(); }
public void SizeEvents_AreaChangedRaised() { var api = new StubbedNativeCalls(); using var controller = new StubbedConsoleController(); var graphicsProvider = new StubbedGraphicsProvider(); using var sut = new ConControls.Controls.ConsoleWindow(api, controller, graphicsProvider); bool raised = false; sut.AreaChanged += OnAreaChanged; controller.SizeEventEvent(controller, new ConsoleSizeEventArgs(Rectangle.Empty, Size.Empty)); raised.Should().BeTrue(); raised = false; sut.AreaChanged -= OnAreaChanged; controller.SizeEventEvent(controller, new ConsoleSizeEventArgs(Rectangle.Empty, Size.Empty)); raised.Should().BeFalse(); void OnAreaChanged(object sender, EventArgs e) { sender.Should().Be(sut); raised = true; } }
public void FocusPrevious_Single_Focused() { using var consoleController = new StubbedConsoleController(); using var api = new StubbedNativeCalls(); var graphicsProvider = new StubbedGraphicsProvider(); using var sut = new ConControls.Controls.ConsoleWindow(api, consoleController, graphicsProvider); var c0 = new Panel(sut) { Parent = sut }; var f00 = new ConControls.Controls.TextBlock(sut) { Parent = c0 }; sut.Controls.Add(new Panel(sut)); sut.FocusedControl.Should().BeNull(); sut.FocusPrevious().Should().Be(f00); sut.FocusPrevious().Should().Be(f00); sut.FocusPrevious().Should().Be(f00); }
public void KeyEvent_ShiftTab_FocusChanged() { using var consoleController = new StubbedConsoleController(); using var api = new StubbedNativeCalls(); var graphicsProvider = new StubbedGraphicsProvider(); using var sut = new ConControls.Controls.ConsoleWindow(api, consoleController, graphicsProvider); var t1 = new ConControls.Controls.TextBlock(sut) { Parent = sut }; var t2 = new ConControls.Controls.TextBlock(sut) { Parent = sut }; var eventArgs = new ConsoleKeyEventArgs(new KEY_EVENT_RECORD { ControlKeys = ControlKeyStates.SCROLLLOCK_ON | ControlKeyStates.SHIFT_PRESSED, KeyDown = 1, VirtualKeyCode = VirtualKey.Tab }); consoleController.KeyEventEvent(consoleController, eventArgs); sut.FocusedControl.Should().Be(t2); consoleController.KeyEventEvent(consoleController, eventArgs); sut.FocusedControl.Should().Be(t1); consoleController.KeyEventEvent(consoleController, eventArgs); sut.FocusedControl.Should().Be(t2); consoleController.KeyEventEvent(consoleController, eventArgs); sut.FocusedControl.Should().Be(t1); }
public void FocusNext_MultipleTabOrder_CorrectSequence() { using var consoleController = new StubbedConsoleController(); using var api = new StubbedNativeCalls(); var graphicsProvider = new StubbedGraphicsProvider(); using var sut = new ConControls.Controls.ConsoleWindow(api, consoleController, graphicsProvider); var c0 = new Panel(sut) { TabOrder = 10 }; var f00 = new ConControls.Controls.TextBlock(sut) { TabOrder = 20 }; var f01 = new ConControls.Controls.TextBlock(sut) { TabOrder = 10 }; var c02 = new Panel(sut) { TabOrder = 15 }; var f020 = new ConControls.Controls.TextBlock(sut); var c021 = new ConControls.Controls.TextBlock(sut) { Enabled = false }; var c1 = new Panel(sut) { TabOrder = 5 }; var f10 = new ConControls.Controls.TextBlock(sut); var f100 = new ConControls.Controls.TextBlock(sut) { TabOrder = 10 }; var f101 = new ConControls.Controls.TextBlock(sut) { TabOrder = 10 }; sut.Controls.AddRange(c0, c1); c0.Controls.AddRange(f00, f01, c02); c02.Controls.AddRange(f020, c021); c1.Controls.Add(f10); f10.Controls.AddRange(f100, f101); sut.FocusedControl.Should().BeNull(); sut.FocusNext().Should().Be(f10); sut.FocusNext().Should().Be(f100); sut.FocusNext().Should().Be(f101); sut.FocusNext().Should().Be(f01); sut.FocusNext().Should().Be(f020); sut.FocusNext().Should().Be(f00); sut.FocusNext().Should().Be(f10); sut.FocusNext().Should().Be(f100); sut.FocusNext().Should().Be(f101); sut.FocusNext().Should().Be(f01); sut.FocusNext().Should().Be(f020); sut.FocusNext().Should().Be(f00); }
public void Constructor_WindowInitialized() { bool cursorSet = false, cursorReset = false; bool disposing = false, controllerDisposed = false; using var consoleController = new StubbedConsoleController { Dispose = () => controllerDisposed = true }; const int originalCursorSize = 10; Size windowSize = new Size(12, 42); using var api = new StubbedNativeCalls { GetConsoleScreenBufferInfoConsoleOutputHandle = handle => { handle.Should().Be(consoleController.OutputHandle); return(new CONSOLE_SCREEN_BUFFER_INFOEX { BufferSize = new COORD(windowSize) }); }, GetCursorInfoConsoleOutputHandle = handle => { handle.Should().Be(consoleController.OutputHandle); return(true, originalCursorSize, Point.Empty); }, SetCursorInfoConsoleOutputHandleBooleanInt32Point = (handle, visible, size, position) => { handle.Should().Be(consoleController.OutputHandle); if (disposing) { cursorSet.Should().BeTrue(); cursorReset.Should().BeFalse(); visible.Should().BeTrue(); size.Should().Be(originalCursorSize); position.Should().Be(Point.Empty); cursorReset = true; return; } visible.Should().BeFalse(); size.Should().Be(originalCursorSize); position.Should().Be(Point.Empty); cursorSet = true; } }; bool drawn = false; var graphics = new StubIConsoleGraphics { DrawBackgroundConsoleColorRectangle = (color, rectangle) => { drawn.Should().BeFalse(); color.Should().Be(ConsoleColor.Black); rectangle.Should().Be(new Rectangle(Point.Empty, windowSize)); drawn = true; } }; var graphicsProvider = new StubbedGraphicsProvider { ProvideConsoleOutputHandleINativeCallsSizeFrameCharSets = (handle, consoleApi, size, frameCharSets) => { handle.Should().Be(consoleController.OutputHandle); consoleApi.Should().Be(api); size.Should().Be(windowSize); frameCharSets.Should().BeOfType <FrameCharSets>(); return(graphics); } }; using var sut = new ConControls.Controls.ConsoleWindow(api, consoleController, graphicsProvider); consoleController.FocusEventEvent.Should().NotBeNull(); consoleController.KeyEventEvent.Should().NotBeNull(); consoleController.MenuEventEvent.Should().NotBeNull(); consoleController.MouseEventEvent.Should().NotBeNull(); consoleController.SizeEventEvent.Should().NotBeNull(); sut.Controls.Should().NotBeNull(); cursorSet.Should().BeTrue(); drawn.Should().BeTrue(); controllerDisposed.Should().BeFalse(); disposing = true; sut.Dispose(); consoleController.FocusEventEvent.Should().BeNull(); consoleController.KeyEventEvent.Should().BeNull(); consoleController.MenuEventEvent.Should().BeNull(); consoleController.MouseEventEvent.Should().BeNull(); consoleController.SizeEventEvent.Should().BeNull(); cursorReset.Should().BeTrue(); controllerDisposed.Should().BeTrue(); } }
public void FocusPrevious_MultipleTabOrder_CorrectSequence() { using var consoleController = new StubbedConsoleController(); using var api = new StubbedNativeCalls(); var graphicsProvider = new StubbedGraphicsProvider(); using var sut = new ConControls.Controls.ConsoleWindow(api, consoleController, graphicsProvider); var c0 = new Panel(sut) { Parent = sut, TabOrder = 10 }; var f00 = new ConControls.Controls.TextBlock(sut) { Parent = c0, TabOrder = 20 }; var f01 = new ConControls.Controls.TextBlock(sut) { Parent = c0, TabOrder = 10 }; var c02 = new Panel(sut) { Parent = c0, TabOrder = 15 }; var f020 = new ConControls.Controls.TextBlock(sut) { Parent = c02 }; c02.Controls.Add(new ConControls.Controls.TextBlock(sut) { Enabled = false }); var c1 = new Panel(sut) { Parent = sut, TabOrder = 5 }; var f10 = new ConControls.Controls.TextBlock(sut) { Parent = c1 }; var f100 = new ConControls.Controls.TextBlock(sut) { Parent = f10, TabOrder = 10 }; var f101 = new ConControls.Controls.TextBlock(sut) { Parent = f10, TabOrder = 10 }; sut.FocusedControl.Should().BeNull(); sut.FocusPrevious().Should().Be(f00); sut.FocusPrevious().Should().Be(f020); sut.FocusPrevious().Should().Be(f01); sut.FocusPrevious().Should().Be(f101); sut.FocusPrevious().Should().Be(f100); sut.FocusPrevious().Should().Be(f10); sut.FocusPrevious().Should().Be(f00); sut.FocusPrevious().Should().Be(f020); sut.FocusPrevious().Should().Be(f01); sut.FocusPrevious().Should().Be(f101); sut.FocusPrevious().Should().Be(f100); sut.FocusPrevious().Should().Be(f10); }