2222 MOVE_UP ,
2323 MOVE_DOWN ,
2424 ERASE_IN_LINE ,
25+ INPUT_RECORD ,
26+ ConsoleEvent ,
27+ KeyEvent ,
28+ Char ,
29+ KEY_EVENT
2530 )
2631except ImportError :
2732 pass
2833
2934
35+ def make_input_record (character : str , repeat_count : int = 1 , virtual_keycode : int = 0 ):
36+ assert len (character ) == 1
37+
38+ rec = INPUT_RECORD ()
39+ rec .EventType = KEY_EVENT
40+ rec .Event = ConsoleEvent ()
41+ rec .Event .KeyEvent = KeyEvent ()
42+
43+ rec .Event .KeyEvent .bKeyDown = True
44+ rec .Event .KeyEvent .wRepeatCount = repeat_count
45+ rec .Event .KeyEvent .wVirtualKeyCode = virtual_keycode # Only used for special keys (see VK_MAP in windows_console.py)
46+ rec .Event .KeyEvent .wVirtualScanCode = 0 # Not used by WindowsConsole
47+ rec .Event .KeyEvent .uChar = Char ()
48+ rec .Event .KeyEvent .uChar .UnicodeChar = character
49+ rec .Event .KeyEvent .dwControlKeyState = False
50+ return rec
51+
52+
3053class WindowsConsoleTests (TestCase ):
31- def console (self , events , ** kwargs ) -> Console :
54+ def console (self , events , mock_input_record = False , ** kwargs ) -> Console :
3255 console = WindowsConsole ()
33- console .get_event = MagicMock (side_effect = events )
56+ if mock_input_record :
57+ # Mock the lower level _read_input method instead of get_event
58+ console ._read_input = MagicMock (side_effect = events )
59+ else :
60+ console .get_event = MagicMock (side_effect = events )
3461 console ._scroll = MagicMock ()
3562 console ._hide_cursor = MagicMock ()
3663 console ._show_cursor = MagicMock ()
@@ -49,6 +76,9 @@ def console(self, events, **kwargs) -> Console:
4976 def handle_events (self , events : Iterable [Event ], ** kwargs ):
5077 return handle_all_events (events , partial (self .console , ** kwargs ))
5178
79+ def handle_input_records (self , input_records : Iterable [INPUT_RECORD ], ** kwargs ):
80+ return handle_all_events (input_records , partial (self .console , mock_input_record = True , ** kwargs ))
81+
5282 def handle_events_narrow (self , events ):
5383 return self .handle_events (events , width = 5 )
5484
@@ -58,6 +88,21 @@ def handle_events_short(self, events):
5888 def handle_events_height_3 (self , events ):
5989 return self .handle_events (events , height = 3 )
6090
91+ def test_key_records_no_repeat (self ):
92+ input_records = [make_input_record (c ) for c in "12+34" ]
93+ _ , con = self .handle_input_records (input_records )
94+ expected_calls = [call (c .encode ()) for c in "12+34" ]
95+ con .out .write .assert_has_calls (expected_calls )
96+ con .restore ()
97+
98+ def test_key_records_with_repeat (self ):
99+ input_records = [make_input_record (c , 2 ) for c in "12+34" ]
100+ input_records .append (make_input_record ("5" , 3 ))
101+ _ , con = self .handle_input_records (input_records )
102+ expected_calls = [call (c .encode ()) for c in "1122++3344555" ]
103+ con .out .write .assert_has_calls (expected_calls )
104+ con .restore ()
105+
61106 def test_simple_addition (self ):
62107 code = "12+34"
63108 events = code_to_events (code )
0 commit comments