Skip to content

Commit 5a1cf12

Browse files
committed
Try to improve testing
1 parent 56f0da4 commit 5a1cf12

File tree

1 file changed

+50
-32
lines changed

1 file changed

+50
-32
lines changed

tests/test_cmd2.py

Lines changed: 50 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,38 +1070,6 @@ def test_cmdloop_without_rawinput() -> None:
10701070

10711071
def test_cmdfinalizations_runs(base_app, monkeypatch) -> None:
10721072
"""Make sure _run_cmdfinalization_hooks is run after each command."""
1073-
termios_settings = [
1074-
27394,
1075-
3,
1076-
19200,
1077-
536872399,
1078-
38400,
1079-
38400,
1080-
[
1081-
b'\x04',
1082-
b'\xff',
1083-
b'\xff',
1084-
b'\x7f',
1085-
b'\x17',
1086-
b'\x15',
1087-
b'\x12',
1088-
b'\x00',
1089-
b'\x03',
1090-
b'\x1c',
1091-
b'\x1a',
1092-
b'\x19',
1093-
b'\x11',
1094-
b'\x13',
1095-
b'\x16',
1096-
b'\x0f',
1097-
b'\x01',
1098-
b'\x00',
1099-
b'\x14',
1100-
b'\x00',
1101-
],
1102-
]
1103-
1104-
base_app._initial_termios_settings = termios_settings
11051073
with (
11061074
mock.patch('sys.stdin.isatty', mock.MagicMock(name='isatty', return_value=True)),
11071075
mock.patch('sys.stdin.fileno', mock.MagicMock(name='fileno', return_value=0)),
@@ -1116,6 +1084,56 @@ def test_cmdfinalizations_runs(base_app, monkeypatch) -> None:
11161084
cmd_fin.assert_called_once()
11171085

11181086

1087+
@pytest.mark.skipif(sys.platform.startswith('win'), reason="termios is not available on Windows")
1088+
@pytest.mark.parametrize(
1089+
('is_tty', 'settings_set', 'raised_exception', 'should_call'),
1090+
[
1091+
(True, True, None, True),
1092+
(True, True, 'termios_error', True),
1093+
(True, True, 'unsupported_operation', True),
1094+
(False, True, None, False),
1095+
(True, False, None, False),
1096+
],
1097+
)
1098+
def test_restore_termios_settings(base_app, monkeypatch, is_tty, settings_set, raised_exception, should_call):
1099+
"""Test that terminal settings are restored after a command and that errors are suppressed."""
1100+
import io
1101+
import termios # Mock termios since it's imported within the method
1102+
1103+
termios_mock = mock.MagicMock()
1104+
# The error attribute needs to be the actual exception for isinstance checks
1105+
termios_mock.error = termios.error
1106+
monkeypatch.setitem(sys.modules, 'termios', termios_mock)
1107+
1108+
# Set the exception to be raised by tcsetattr
1109+
if raised_exception == 'termios_error':
1110+
termios_mock.tcsetattr.side_effect = termios.error("test termios error")
1111+
elif raised_exception == 'unsupported_operation':
1112+
termios_mock.tcsetattr.side_effect = io.UnsupportedOperation("test io error")
1113+
1114+
# Set initial termios settings so the logic will run
1115+
if settings_set:
1116+
termios_settings = ["dummy settings"]
1117+
base_app._initial_termios_settings = termios_settings
1118+
else:
1119+
base_app._initial_termios_settings = None
1120+
termios_settings = None # for the assert
1121+
1122+
# Mock stdin to make it look like a TTY
1123+
monkeypatch.setattr(base_app.stdin, "isatty", lambda: is_tty)
1124+
monkeypatch.setattr(base_app.stdin, "fileno", lambda: 0)
1125+
1126+
# Run a command to trigger _run_cmdfinalization_hooks
1127+
# This should not raise an exception
1128+
base_app.onecmd_plus_hooks('help')
1129+
1130+
# Verify that tcsetattr was called with the correct arguments
1131+
if should_call:
1132+
termios_mock.tcsetattr.assert_called_once_with(0, termios_mock.TCSANOW, termios_settings)
1133+
else:
1134+
termios_mock.tcsetattr.assert_not_called()
1135+
1136+
11191137
def test_sigint_handler(base_app) -> None:
11201138
# No KeyboardInterrupt should be raised when using sigint_protection
11211139
with base_app.sigint_protection:

0 commit comments

Comments
 (0)