Skip to content

Commit d405a4f

Browse files
committed
Fix tests in tests_cmd2.py to monkeypatch cmd2.Cmd.read_input instead of mocking the built-in input function.
There are still 3 failing and 1 skipped test in test_cmd2.py Additionally, some tests in test_run_pyscript.py are getting stuck.All tests in other files are passing.
1 parent 6c85dca commit d405a4f

File tree

1 file changed

+39
-40
lines changed

1 file changed

+39
-40
lines changed

tests/test_cmd2.py

Lines changed: 39 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
"""Cmd2 unit/functional testing"""
22

3-
import builtins
43
import io
54
import os
65
import signal
@@ -1023,7 +1022,7 @@ def test_base_cmdloop_with_startup_commands() -> None:
10231022
assert out == expected
10241023

10251024

1026-
def test_base_cmdloop_without_startup_commands() -> None:
1025+
def test_base_cmdloop_without_startup_commands(monkeypatch) -> None:
10271026
# Need to patch sys.argv so cmd2 doesn't think it was called with arguments equal to the py.test args
10281027
testargs = ["prog"]
10291028
with mock.patch.object(sys, 'argv', testargs):
@@ -1032,9 +1031,9 @@ def test_base_cmdloop_without_startup_commands() -> None:
10321031
app.use_rawinput = True
10331032
app.intro = 'Hello World, this is an intro ...'
10341033

1035-
# Mock out the input call so we don't actually wait for a user's response on stdin
1036-
m = mock.MagicMock(name='input', return_value='quit')
1037-
builtins.input = m
1034+
# Mock out the read_input call so we don't actually wait for a user's response on stdin
1035+
read_input_mock = mock.MagicMock(name='read_input', return_value='quit')
1036+
monkeypatch.setattr("cmd2.Cmd.read_input", read_input_mock)
10381037

10391038
expected = app.intro + '\n'
10401039

@@ -1044,7 +1043,7 @@ def test_base_cmdloop_without_startup_commands() -> None:
10441043
assert out == expected
10451044

10461045

1047-
def test_cmdloop_without_rawinput() -> None:
1046+
def test_cmdloop_without_rawinput(monkeypatch) -> None:
10481047
# Need to patch sys.argv so cmd2 doesn't think it was called with arguments equal to the py.test args
10491048
testargs = ["prog"]
10501049
with mock.patch.object(sys, 'argv', testargs):
@@ -1054,14 +1053,13 @@ def test_cmdloop_without_rawinput() -> None:
10541053
app.echo = False
10551054
app.intro = 'Hello World, this is an intro ...'
10561055

1057-
# Mock out the input call so we don't actually wait for a user's response on stdin
1058-
m = mock.MagicMock(name='input', return_value='quit')
1059-
builtins.input = m
1056+
# Mock out the read_input call so we don't actually wait for a user's response on stdin
1057+
read_input_mock = mock.MagicMock(name='read_input', return_value='quit')
1058+
monkeypatch.setattr("cmd2.Cmd.read_input", read_input_mock)
10601059

10611060
expected = app.intro + '\n'
10621061

1063-
with pytest.raises(OSError): # noqa: PT011
1064-
app.cmdloop()
1062+
app.cmdloop()
10651063
out = app.stdout.getvalue()
10661064
assert out == expected
10671065

@@ -1201,11 +1199,11 @@ def say_app():
12011199
return app
12021200

12031201

1204-
def test_ctrl_c_at_prompt(say_app) -> None:
1205-
# Mock out the input call so we don't actually wait for a user's response on stdin
1206-
m = mock.MagicMock(name='input')
1207-
m.side_effect = ['say hello', KeyboardInterrupt(), 'say goodbye', 'eof']
1208-
builtins.input = m
1202+
def test_ctrl_c_at_prompt(say_app, monkeypatch) -> None:
1203+
# Mock out the read_input call so we don't actually wait for a user's response on stdin
1204+
read_input_mock = mock.MagicMock(name='read_input')
1205+
read_input_mock.side_effect = ['say hello', KeyboardInterrupt(), 'say goodbye', 'eof']
1206+
monkeypatch.setattr("cmd2.Cmd.read_input", read_input_mock)
12091207

12101208
say_app.cmdloop()
12111209

@@ -1767,11 +1765,11 @@ def test_multiline_complete_empty_statement_raises_exception(multiline_app) -> N
17671765
multiline_app._complete_statement('')
17681766

17691767

1770-
def test_multiline_complete_statement_without_terminator(multiline_app) -> None:
1768+
def test_multiline_complete_statement_without_terminator(multiline_app, monkeypatch) -> None:
17711769
# Mock out the input call so we don't actually wait for a user's response
17721770
# on stdin when it looks for more input
1773-
m = mock.MagicMock(name='input', return_value='\n')
1774-
builtins.input = m
1771+
read_input_mock = mock.MagicMock(name='read_input', return_value='\n')
1772+
monkeypatch.setattr("cmd2.Cmd.read_input", read_input_mock)
17751773

17761774
command = 'orate'
17771775
args = 'hello world'
@@ -1782,11 +1780,11 @@ def test_multiline_complete_statement_without_terminator(multiline_app) -> None:
17821780
assert statement.multiline_command == command
17831781

17841782

1785-
def test_multiline_complete_statement_with_unclosed_quotes(multiline_app) -> None:
1783+
def test_multiline_complete_statement_with_unclosed_quotes(multiline_app, monkeypatch) -> None:
17861784
# Mock out the input call so we don't actually wait for a user's response
17871785
# on stdin when it looks for more input
1788-
m = mock.MagicMock(name='input', side_effect=['quotes', '" now closed;'])
1789-
builtins.input = m
1786+
read_input_mock = mock.MagicMock(name='read_input', side_effect=['quotes', '" now closed;'])
1787+
monkeypatch.setattr("cmd2.Cmd.read_input", read_input_mock)
17901788

17911789
line = 'orate hi "partially open'
17921790
statement = multiline_app._complete_statement(line)
@@ -1796,40 +1794,40 @@ def test_multiline_complete_statement_with_unclosed_quotes(multiline_app) -> Non
17961794
assert statement.terminator == ';'
17971795

17981796

1799-
def test_multiline_input_line_to_statement(multiline_app) -> None:
1797+
def test_multiline_input_line_to_statement(multiline_app, monkeypatch) -> None:
18001798
# Verify _input_line_to_statement saves the fully entered input line for multiline commands
18011799

18021800
# Mock out the input call so we don't actually wait for a user's response
18031801
# on stdin when it looks for more input
1804-
m = mock.MagicMock(name='input', side_effect=['person', '\n'])
1805-
builtins.input = m
1802+
read_input_mock = mock.MagicMock(name='read_input', side_effect=['person', '\n'])
1803+
monkeypatch.setattr("cmd2.Cmd.read_input", read_input_mock)
18061804

18071805
line = 'orate hi'
18081806
statement = multiline_app._input_line_to_statement(line)
1809-
assert statement.raw == 'orate hi\nperson\n'
1807+
assert statement.raw == 'orate hi\nperson\n\n'
18101808
assert statement == 'hi person'
18111809
assert statement.command == 'orate'
18121810
assert statement.multiline_command == 'orate'
18131811

18141812

1815-
def test_multiline_history_added(multiline_app) -> None:
1813+
def test_multiline_history_added(multiline_app, monkeypatch) -> None:
18161814
# Test that multiline commands are added to history as a single item
1817-
m = mock.MagicMock(name='input', side_effect=['person', '\n'])
1818-
builtins.input = m
1815+
read_input_mock = mock.MagicMock(name='read_input', side_effect=['person', '\n'])
1816+
monkeypatch.setattr("cmd2.Cmd.read_input", read_input_mock)
18191817

18201818
multiline_app.history.clear()
18211819

18221820
# run_cmd calls onecmd_plus_hooks which triggers history addition
18231821
run_cmd(multiline_app, "orate hi")
18241822

18251823
assert len(multiline_app.history) == 1
1826-
assert multiline_app.history.get(1).raw == "orate hi\nperson\n"
1824+
assert multiline_app.history.get(1).raw == "orate hi\nperson\n\n"
18271825

18281826

1829-
def test_multiline_history_with_quotes(multiline_app) -> None:
1827+
def test_multiline_history_with_quotes(multiline_app, monkeypatch) -> None:
18301828
# Test combined multiline command with quotes is added to history correctly
1831-
m = mock.MagicMock(name='input', side_effect=[' and spaces ', ' "', ' in', 'quotes.', ';'])
1832-
builtins.input = m
1829+
read_input_mock = mock.MagicMock(name='read_input', side_effect=[' and spaces ', ' "', ' in', 'quotes.', ';'])
1830+
monkeypatch.setattr("cmd2.Cmd.read_input", read_input_mock)
18331831

18341832
multiline_app.history.clear()
18351833

@@ -1930,7 +1928,8 @@ def test_read_input_rawinput_true(capsys, monkeypatch) -> None:
19301928
app.use_rawinput = True
19311929

19321930
# Mock out input() to return input_str
1933-
monkeypatch.setattr("builtins.input", lambda *args: input_str)
1931+
read_input_mock = mock.MagicMock(name='read_input', return_value=input_str)
1932+
monkeypatch.setattr("cmd2.Cmd.read_input", read_input_mock)
19341933

19351934
# isatty is True
19361935
with mock.patch('sys.stdin.isatty', mock.MagicMock(name='isatty', return_value=True)):
@@ -2855,13 +2854,13 @@ def exit_code_repl():
28552854
return app
28562855

28572856

2858-
def test_exit_code_default(exit_code_repl) -> None:
2857+
def test_exit_code_default(exit_code_repl, monkeypatch) -> None:
28592858
app = exit_code_repl
28602859
app.use_rawinput = True
28612860

28622861
# Mock out the input call so we don't actually wait for a user's response on stdin
2863-
m = mock.MagicMock(name='input', return_value='exit')
2864-
builtins.input = m
2862+
read_input_mock = mock.MagicMock(name='read_input', return_value='exit')
2863+
monkeypatch.setattr("cmd2.Cmd.read_input", read_input_mock)
28652864

28662865
expected = 'exiting with code: 0\n'
28672866

@@ -2871,13 +2870,13 @@ def test_exit_code_default(exit_code_repl) -> None:
28712870
assert out == expected
28722871

28732872

2874-
def test_exit_code_nonzero(exit_code_repl) -> None:
2873+
def test_exit_code_nonzero(exit_code_repl, monkeypatch) -> None:
28752874
app = exit_code_repl
28762875
app.use_rawinput = True
28772876

28782877
# Mock out the input call so we don't actually wait for a user's response on stdin
2879-
m = mock.MagicMock(name='input', return_value='exit 23')
2880-
builtins.input = m
2878+
read_input_mock = mock.MagicMock(name='read_input', return_value='exit 23')
2879+
monkeypatch.setattr("cmd2.Cmd.read_input", read_input_mock)
28812880

28822881
expected = 'exiting with code: 23\n'
28832882

0 commit comments

Comments
 (0)