@@ -1610,3 +1610,43 @@ def test_prompt_after_help(self):
16101610 # Extra stuff (newline and `exit` rewrites) are necessary
16111611 # because of how run_repl works.
16121612 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