using Blacklight.Core.Keyboard; namespace Blacklight.Core.UnitTests.Keyboard { public class KeyboardRoutingTests : UnitTestSharp.TestFixture { public class RecordingGamepad : IKeyboardConsumer { public bool Consumes; public int KeyDownCount = 0; public int KeyUpCount = 0; public KeyCode LastKeyCode; public KeyState LastHeld; public RecordingGamepad(bool consumes) { Consumes = consumes; } public bool KeyDown(KeyCode keyCode, KeyState held) { KeyDownCount++; LastKeyCode = keyCode; LastHeld = held; return Consumes; } public bool KeyUp(KeyCode keyCode) { KeyUpCount++; LastKeyCode = keyCode; return Consumes; } } public class RecordingText : ITextConsumer { public bool Consumes; public int KeyCommandCount = 0; public KeyInput LastKeyInput; public int TextInputCount = 0; public string LastText; public RecordingText(bool consumes) { Consumes = consumes; } public bool KeyCommand(KeyInput input) { KeyCommandCount++; LastKeyInput = input; return Consumes; } public void TextInput(string text) { TextInputCount++; LastText = text; } } public class KeyDownTests : UnitTestSharp.TestFixture { public void NoTextConsumer_GoesToTheGamepad() { var gamepad = new RecordingGamepad(consumes: true); Check(KeyboardRouting.KeyDown(gamepad, text: null, new KeyInput { KeyCode = KeyCode.W }, default)); CheckEqual(KeyCode.W, gamepad.LastKeyCode); } public void NoTextConsumer_ReturnsWhatTheGamepadReturns() { var gamepad = new RecordingGamepad(consumes: false); CheckFalse( KeyboardRouting.KeyDown(gamepad, text: null, new KeyInput { KeyCode = KeyCode.W }, default)); } public void TextConsumerTakingIt_KeepsItFromTheGamepad() { var gamepad = new RecordingGamepad(consumes: true); var text = new RecordingText(consumes: true); Check(KeyboardRouting.KeyDown(gamepad, text, new KeyInput { KeyCode = KeyCode.W }, default)); CheckEqual(0, gamepad.KeyDownCount); } public void TextConsumerDecliningIt_FallsThroughToTheGamepad() { var gamepad = new RecordingGamepad(consumes: true); var text = new RecordingText(consumes: false); Check(KeyboardRouting.KeyDown(gamepad, text, new KeyInput { KeyCode = KeyCode.W }, default)); CheckEqual(1, gamepad.KeyDownCount); } public void TextConsumerDecliningIt_ReturnsWhatTheGamepadReturns() { var gamepad = new RecordingGamepad(consumes: false); var text = new RecordingText(consumes: false); CheckFalse(KeyboardRouting.KeyDown(gamepad, text, new KeyInput { KeyCode = KeyCode.W }, default)); } public void TextConsumer_GetsTheWholeKeyInput() { var gamepad = new RecordingGamepad(consumes: false); var text = new RecordingText(consumes: true); var input = new KeyInput { KeyCode = KeyCode.W, LayoutCode = KeyCode.Z, Modifiers = KeyModifiers.Control | KeyModifiers.Shift, IsRepeat = true, }; KeyboardRouting.KeyDown(gamepad, text, input, default); CheckEqual(KeyCode.W, text.LastKeyInput.KeyCode); CheckEqual(KeyCode.Z, text.LastKeyInput.LayoutCode.Value); CheckEqual(KeyModifiers.Control | KeyModifiers.Shift, text.LastKeyInput.Modifiers); Check(text.LastKeyInput.IsRepeat); } public void Gamepad_GetsOnlyTheKeyCode() { var gamepad = new RecordingGamepad(consumes: false); var input = new KeyInput { KeyCode = KeyCode.W, LayoutCode = KeyCode.Z }; KeyboardRouting.KeyDown(gamepad, text: null, input, default); CheckEqual(KeyCode.W, gamepad.LastKeyCode); } public void Gamepad_GetsTheHeldState() { var gamepad = new RecordingGamepad(consumes: false); KeyState held = new KeyState(KeyCode.W, KeyCode.ShiftLeft); KeyboardRouting.KeyDown(gamepad, text: null, new KeyInput { KeyCode = KeyCode.W }, held); CheckEqual(held, gamepad.LastHeld); } } public class KeyUpTests : UnitTestSharp.TestFixture { public void GoesToTheGamepad() { var gamepad = new RecordingGamepad(consumes: true); Check(KeyboardRouting.KeyUp(gamepad, KeyCode.W)); CheckEqual(KeyCode.W, gamepad.LastKeyCode); } public void ReturnsWhatTheGamepadReturns() { var gamepad = new RecordingGamepad(consumes: false); CheckFalse(KeyboardRouting.KeyUp(gamepad, KeyCode.W)); } } public class TextInputTests : UnitTestSharp.TestFixture { public void NoTextConsumer_IsDropped() { KeyboardRouting.TextInput(text: null, committed: "abc"); } public void GoesToTheTextConsumer() { var text = new RecordingText(consumes: false); KeyboardRouting.TextInput(text, committed: "abc"); CheckEqual("abc", text.LastText); CheckEqual(1, text.TextInputCount); } public void SurrogatePair_ArrivesInOneCall() { var text = new RecordingText(consumes: false); string surrogatePair = char.ConvertFromUtf32(0x20BB7); KeyboardRouting.TextInput(text, committed: surrogatePair); CheckEqual(surrogatePair, text.LastText); CheckEqual(1, text.TextInputCount); } public void DoesNotTouchTheKeyCommandPath() { var text = new RecordingText(consumes: true); KeyboardRouting.TextInput(text, committed: "abc"); CheckEqual(0, text.KeyCommandCount); } } } }