@@ -1610,3 +1610,43 @@ def test_prompt_after_help(self):
1610
1610
# Extra stuff (newline and `exit` rewrites) are necessary
1611
1611
# because of how run_repl works.
1612
1612
self .assertNotIn (">>> \n >>> >>>" , cleaned_output )
1613
+
1614
+ class TestPyReplCtrlD (TestCase ):
1615
+ def prepare_reader (self , events ):
1616
+ console = FakeConsole (events )
1617
+ config = ReadlineConfig (readline_completer = None )
1618
+ reader = ReadlineAlikeReader (console = console , config = config )
1619
+ return reader
1620
+
1621
+ def test_ctrl_d_empty_buffer (self ):
1622
+ """Test that pressing Ctrl+D on empty buffer exits the program"""
1623
+ events = [
1624
+ Event (evt = "key" , data = "\x04 " , raw = bytearray (b"\x04 " )), # Ctrl+D
1625
+ ]
1626
+ reader = self .prepare_reader (events )
1627
+ with self .assertRaises (EOFError ):
1628
+ multiline_input (reader )
1629
+
1630
+ def test_ctrl_d_multiline_mode (self ):
1631
+ """Test that pressing Ctrl+D in multiline mode exits multiline mode"""
1632
+ events = itertools .chain (
1633
+ code_to_events ("def f():\n " ), # Enter multiline mode
1634
+ [
1635
+ Event (evt = "key" , data = "\x04 " , raw = bytearray (b"\x04 " )), # Ctrl+D
1636
+ ],
1637
+ )
1638
+ reader = self .prepare_reader (events )
1639
+ output = multiline_input (reader )
1640
+ self .assertEqual (output , "def f():\n " ) # Should return current input
1641
+
1642
+ def test_ctrl_d_single_line (self ):
1643
+ """Test that pressing Ctrl+D in single line mode deletes current character"""
1644
+ events = itertools .chain (
1645
+ code_to_events ("hello" ),
1646
+ [Event (evt = "key" , data = "left" , raw = bytearray (b"\x1b OD" ))], # move left
1647
+ [Event (evt = "key" , data = "\x04 " , raw = bytearray (b"\x04 " ))], # Ctrl+D
1648
+ code_to_events ("\n " ),
1649
+ )
1650
+ reader = self .prepare_reader (events )
1651
+ output = multiline_input (reader )
1652
+ self .assertEqual (output , "hell" ) # Should delete the last character
0 commit comments