Skip to content

Commit 3615ff3

Browse files
pablogsalambv
authored andcommitted
pythongh-111201: Add more tests to test_pyrepl to cover key translation (python#118705)
Co-authored-by: Łukasz Langa <[email protected]>
1 parent e065d35 commit 3615ff3

File tree

1 file changed

+181
-8
lines changed

1 file changed

+181
-8
lines changed

Lib/test/test_pyrepl.py

Lines changed: 181 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
from _pyrepl.readline import ReadlineAlikeReader, ReadlineConfig
2424
from _pyrepl.simple_interact import _strip_final_indent
2525
from _pyrepl.unix_eventqueue import EventQueue
26-
from _pyrepl.simple_interact import InteractiveColoredConsole
26+
from _pyrepl.input import KeymapTranslator
27+
from _pyrepl.keymap import parse_keys, compile_keymap
2728

2829

2930
def more_lines(unicodetext, namespace=None):
@@ -646,10 +647,10 @@ def test_updown_arrow_with_completion_menu(self):
646647
events = itertools.chain(
647648
code_to_events(code),
648649
[
649-
Event(evt='key', data='up', raw=bytearray(b'\x1bOA')),
650+
Event(evt="key", data="up", raw=bytearray(b"\x1bOA")),
650651
Event(evt="key", data="down", raw=bytearray(b"\x1bOB")),
651652
],
652-
code_to_events("\n")
653+
code_to_events("\n"),
653654
)
654655
reader = self.prepare_reader(events, namespace=namespace)
655656
output = multiline_input(reader, namespace)
@@ -1046,13 +1047,185 @@ def test_setpos_fromxy_in_wrapped_line(self):
10461047
self.assertEqual(reader.pos, 9)
10471048

10481049
def test_up_arrow_after_ctrl_r(self):
1049-
events = iter([
1050-
Event(evt='key', data='\x12', raw=bytearray(b'\x12')),
1051-
Event(evt='key', data='up', raw=bytearray(b'\x1bOA')),
1052-
])
1050+
events = iter(
1051+
[
1052+
Event(evt="key", data="\x12", raw=bytearray(b"\x12")),
1053+
Event(evt="key", data="up", raw=bytearray(b"\x1bOA")),
1054+
]
1055+
)
10531056

10541057
reader, _ = handle_all_events(events)
10551058
self.assert_screen_equals(reader, "")
10561059

1057-
if __name__ == '__main__':
1060+
1061+
class KeymapTranslatorTests(unittest.TestCase):
1062+
def test_push_single_key(self):
1063+
keymap = [("a", "command_a")]
1064+
translator = KeymapTranslator(keymap)
1065+
evt = Event("key", "a")
1066+
translator.push(evt)
1067+
result = translator.get()
1068+
self.assertEqual(result, ("command_a", ["a"]))
1069+
1070+
def test_push_multiple_keys(self):
1071+
keymap = [("ab", "command_ab")]
1072+
translator = KeymapTranslator(keymap)
1073+
evt1 = Event("key", "a")
1074+
evt2 = Event("key", "b")
1075+
translator.push(evt1)
1076+
translator.push(evt2)
1077+
result = translator.get()
1078+
self.assertEqual(result, ("command_ab", ["a", "b"]))
1079+
1080+
def test_push_invalid_key(self):
1081+
keymap = [("a", "command_a")]
1082+
translator = KeymapTranslator(keymap)
1083+
evt = Event("key", "b")
1084+
translator.push(evt)
1085+
result = translator.get()
1086+
self.assertEqual(result, (None, ["b"]))
1087+
1088+
def test_push_invalid_key_with_stack(self):
1089+
keymap = [("ab", "command_ab")]
1090+
translator = KeymapTranslator(keymap)
1091+
evt1 = Event("key", "a")
1092+
evt2 = Event("key", "c")
1093+
translator.push(evt1)
1094+
translator.push(evt2)
1095+
result = translator.get()
1096+
self.assertEqual(result, (None, ["a", "c"]))
1097+
1098+
def test_push_character_key(self):
1099+
keymap = [("a", "command_a")]
1100+
translator = KeymapTranslator(keymap)
1101+
evt = Event("key", "a")
1102+
translator.push(evt)
1103+
result = translator.get()
1104+
self.assertEqual(result, ("command_a", ["a"]))
1105+
1106+
def test_push_character_key_with_stack(self):
1107+
keymap = [("ab", "command_ab")]
1108+
translator = KeymapTranslator(keymap)
1109+
evt1 = Event("key", "a")
1110+
evt2 = Event("key", "b")
1111+
evt3 = Event("key", "c")
1112+
translator.push(evt1)
1113+
translator.push(evt2)
1114+
translator.push(evt3)
1115+
result = translator.get()
1116+
self.assertEqual(result, ("command_ab", ["a", "b"]))
1117+
1118+
def test_push_transition_key(self):
1119+
keymap = [("a", {"b": "command_ab"})]
1120+
translator = KeymapTranslator(keymap)
1121+
evt1 = Event("key", "a")
1122+
evt2 = Event("key", "b")
1123+
translator.push(evt1)
1124+
translator.push(evt2)
1125+
result = translator.get()
1126+
self.assertEqual(result, ("command_ab", ["a", "b"]))
1127+
1128+
def test_push_transition_key_interrupted(self):
1129+
keymap = [("a", {"b": "command_ab"})]
1130+
translator = KeymapTranslator(keymap)
1131+
evt1 = Event("key", "a")
1132+
evt2 = Event("key", "c")
1133+
evt3 = Event("key", "b")
1134+
translator.push(evt1)
1135+
translator.push(evt2)
1136+
translator.push(evt3)
1137+
result = translator.get()
1138+
self.assertEqual(result, (None, ["a", "c"]))
1139+
1140+
def test_push_invalid_key_with_unicode_category(self):
1141+
keymap = [("a", "command_a")]
1142+
translator = KeymapTranslator(keymap)
1143+
evt = Event("key", "\u0003") # Control character
1144+
translator.push(evt)
1145+
result = translator.get()
1146+
self.assertEqual(result, (None, ["\u0003"]))
1147+
1148+
def test_empty(self):
1149+
keymap = [("a", "command_a")]
1150+
translator = KeymapTranslator(keymap)
1151+
self.assertTrue(translator.empty())
1152+
evt = Event("key", "a")
1153+
translator.push(evt)
1154+
self.assertFalse(translator.empty())
1155+
translator.get()
1156+
self.assertTrue(translator.empty())
1157+
1158+
1159+
class TestParseKeys(unittest.TestCase):
1160+
def test_single_character(self):
1161+
self.assertEqual(parse_keys("a"), ["a"])
1162+
self.assertEqual(parse_keys("b"), ["b"])
1163+
self.assertEqual(parse_keys("1"), ["1"])
1164+
1165+
def test_escape_sequences(self):
1166+
self.assertEqual(parse_keys("\\n"), ["\n"])
1167+
self.assertEqual(parse_keys("\\t"), ["\t"])
1168+
self.assertEqual(parse_keys("\\\\"), ["\\"])
1169+
self.assertEqual(parse_keys("\\'"), ["'"])
1170+
self.assertEqual(parse_keys('\\"'), ['"'])
1171+
1172+
def test_control_sequences(self):
1173+
self.assertEqual(parse_keys("\\C-a"), ["\x01"])
1174+
self.assertEqual(parse_keys("\\C-b"), ["\x02"])
1175+
self.assertEqual(parse_keys("\\C-c"), ["\x03"])
1176+
1177+
def test_meta_sequences(self):
1178+
self.assertEqual(parse_keys("\\M-a"), ["\033", "a"])
1179+
self.assertEqual(parse_keys("\\M-b"), ["\033", "b"])
1180+
self.assertEqual(parse_keys("\\M-c"), ["\033", "c"])
1181+
1182+
def test_keynames(self):
1183+
self.assertEqual(parse_keys("\\<up>"), ["up"])
1184+
self.assertEqual(parse_keys("\\<down>"), ["down"])
1185+
self.assertEqual(parse_keys("\\<left>"), ["left"])
1186+
self.assertEqual(parse_keys("\\<right>"), ["right"])
1187+
1188+
def test_combinations(self):
1189+
self.assertEqual(parse_keys("\\C-a\\n\\<up>"), ["\x01", "\n", "up"])
1190+
self.assertEqual(parse_keys("\\M-a\\t\\<down>"), ["\033", "a", "\t", "down"])
1191+
1192+
1193+
class TestCompileKeymap(unittest.TestCase):
1194+
def test_empty_keymap(self):
1195+
keymap = {}
1196+
result = compile_keymap(keymap)
1197+
self.assertEqual(result, {})
1198+
1199+
def test_single_keymap(self):
1200+
keymap = {b"a": "action"}
1201+
result = compile_keymap(keymap)
1202+
self.assertEqual(result, {b"a": "action"})
1203+
1204+
def test_nested_keymap(self):
1205+
keymap = {b"a": {b"b": "action"}}
1206+
result = compile_keymap(keymap)
1207+
self.assertEqual(result, {b"a": {b"b": "action"}})
1208+
1209+
def test_empty_value(self):
1210+
keymap = {b"a": {b"": "action"}}
1211+
result = compile_keymap(keymap)
1212+
self.assertEqual(result, {b"a": {b"": "action"}})
1213+
1214+
def test_multiple_empty_values(self):
1215+
keymap = {b"a": {b"": "action1", b"b": "action2"}}
1216+
result = compile_keymap(keymap)
1217+
self.assertEqual(result, {b"a": {b"": "action1", b"b": "action2"}})
1218+
1219+
def test_multiple_keymaps(self):
1220+
keymap = {b"a": {b"b": "action1", b"c": "action2"}}
1221+
result = compile_keymap(keymap)
1222+
self.assertEqual(result, {b"a": {b"b": "action1", b"c": "action2"}})
1223+
1224+
def test_nested_multiple_keymaps(self):
1225+
keymap = {b"a": {b"b": {b"c": "action"}}}
1226+
result = compile_keymap(keymap)
1227+
self.assertEqual(result, {b"a": {b"b": {b"c": "action"}}})
1228+
1229+
1230+
if __name__ == "__main__":
10581231
unittest.main()

0 commit comments

Comments
 (0)