Skip to content

Commit 43fe1bb

Browse files
committed
Add tests
1 parent f2eaddc commit 43fe1bb

2 files changed

Lines changed: 79 additions & 0 deletions

File tree

‎Lib/test/test_pyrepl/test_keymap.py‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ def test_combinations(self):
4848
self.assertEqual(parse_keys("\\C-a\\n\\<up>"), ["\x01", "\n", "up"])
4949
self.assertEqual(parse_keys("\\M-a\\t\\<down>"), ["\033", "a", "\t", "down"])
5050

51+
def test_control_arrow_keys(self):
52+
self.assertEqual(parse_keys("\\C-\\<left>"), ["ctrl left"])
53+
self.assertEqual(parse_keys("\\C-\\<right>"), ["ctrl right"])
54+
self.assertEqual(parse_keys("\\C-\\<up>"), ["ctrl up"])
55+
self.assertEqual(parse_keys("\\C-\\<down>"), ["ctrl down"])
56+
5157
def test_keyspec_errors(self):
5258
cases = [
5359
("\\Ca", "\\C must be followed by `-'"),

‎Lib/test/test_pyrepl/test_pyrepl.py‎

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,79 @@ def test_history_navigation_with_down_arrow(self):
850850
self.assertEqual(output, "1+1")
851851
self.assert_screen_equal(reader, "1+1", clean=True)
852852

853+
def test_history_navigation_with_ctrl_up(self):
854+
# Submit two multiline blocks, then use ctrl+up to jump directly
855+
# to the previous history entry (unlike up which moves line-by-line)
856+
code = "def foo():\nx = 1\n\ndef bar():\ny = 2\n\n"
857+
events = itertools.chain(
858+
code_to_events(code),
859+
[
860+
# Single ctrl+up should recall the entire previous entry
861+
Event(evt="key", data="ctrl up", raw=bytearray(b"\x1b[1;5A")),
862+
Event(evt="key", data="\n", raw=bytearray(b"\n")),
863+
Event(evt="key", data="\n", raw=bytearray(b"\n")),
864+
],
865+
)
866+
867+
reader = self.prepare_reader(events)
868+
869+
output = multiline_input(reader)
870+
self.assertEqual(output, "def foo():\n x = 1\n ")
871+
output = multiline_input(reader)
872+
self.assertEqual(output, "def bar():\n y = 2\n ")
873+
# One ctrl+up jumps straight to previous history item
874+
output = multiline_input(reader)
875+
self.assertEqual(output, "def foo():\n x = 1\n ")
876+
877+
def test_history_navigation_with_ctrl_down(self):
878+
# Submit two multiline entries, ctrl+up twice then ctrl+down once
879+
# With multiline entries, regular down would only move one line,
880+
# but ctrl+down jumps to the next history entry entirely.
881+
code = "def foo():\nx = 1\n\ndef bar():\ny = 2\n\n"
882+
events = itertools.chain(
883+
code_to_events(code),
884+
[
885+
Event(evt="key", data="ctrl up", raw=bytearray(b"\x1b[1;5A")),
886+
Event(evt="key", data="ctrl up", raw=bytearray(b"\x1b[1;5A")),
887+
Event(evt="key", data="ctrl down", raw=bytearray(b"\x1b[1;5B")),
888+
Event(evt="key", data="\n", raw=bytearray(b"\n")),
889+
Event(evt="key", data="\n", raw=bytearray(b"\n")),
890+
],
891+
)
892+
893+
reader = self.prepare_reader(events)
894+
895+
output = multiline_input(reader)
896+
self.assertEqual(output, "def foo():\n x = 1\n ")
897+
output = multiline_input(reader)
898+
self.assertEqual(output, "def bar():\n y = 2\n ")
899+
# ctrl+up twice (to foo), ctrl+down once (back to bar)
900+
output = multiline_input(reader)
901+
self.assertEqual(output, "def bar():\n y = 2\n ")
902+
903+
def test_ctrl_up_at_start_of_history(self):
904+
# Submit a multiline block, then try ctrl+up twice
905+
# (second one should error since we're already at the oldest entry)
906+
code = "def foo():\nx = 1\n\n"
907+
events = itertools.chain(
908+
code_to_events(code),
909+
[
910+
# Already at oldest item; second ctrl+up should error but not crash
911+
Event(evt="key", data="ctrl up", raw=bytearray(b"\x1b[1;5A")),
912+
Event(evt="key", data="ctrl up", raw=bytearray(b"\x1b[1;5A")),
913+
Event(evt="key", data="\n", raw=bytearray(b"\n")),
914+
Event(evt="key", data="\n", raw=bytearray(b"\n")),
915+
],
916+
)
917+
918+
reader = self.prepare_reader(events)
919+
920+
output = multiline_input(reader)
921+
self.assertEqual(output, "def foo():\n x = 1\n ")
922+
# Second ctrl+up at start of history stays on first item
923+
output = multiline_input(reader)
924+
self.assertEqual(output, "def foo():\n x = 1\n ")
925+
853926
def test_history_search(self):
854927
events = itertools.chain(
855928
code_to_events("1+1\n2+2\n3+3\n"),

0 commit comments

Comments
 (0)