Test terminal restoration in ppaged() after pager exits.
(outsim_app, monkeypatch, has_tcsetpgrp)
| 3290 | @pytest.mark.skipif(sys.platform.startswith("win"), reason="termios is not available on Windows") |
| 3291 | @pytest.mark.parametrize("has_tcsetpgrp", [True, False]) |
| 3292 | def test_ppaged_terminal_restoration(outsim_app, monkeypatch, has_tcsetpgrp) -> None: |
| 3293 | """Test terminal restoration in ppaged() after pager exits.""" |
| 3294 | # Make it look like we're in a terminal |
| 3295 | stdin_mock = mock.MagicMock() |
| 3296 | stdin_mock.isatty.return_value = True |
| 3297 | stdin_mock.fileno.return_value = 0 |
| 3298 | monkeypatch.setattr(outsim_app, "stdin", stdin_mock) |
| 3299 | |
| 3300 | stdout_mock = mock.MagicMock() |
| 3301 | stdout_mock.isatty.return_value = True |
| 3302 | monkeypatch.setattr(outsim_app, "stdout", stdout_mock) |
| 3303 | |
| 3304 | if not sys.platform.startswith("win") and os.environ.get("TERM") is None: |
| 3305 | monkeypatch.setenv("TERM", "simulated") |
| 3306 | |
| 3307 | # Mock termios and signal since they are imported within the method |
| 3308 | termios_mock = mock.MagicMock() |
| 3309 | # The error attribute needs to be the actual exception for isinstance checks |
| 3310 | import termios |
| 3311 | |
| 3312 | termios_mock.error = termios.error |
| 3313 | monkeypatch.setitem(sys.modules, "termios", termios_mock) |
| 3314 | |
| 3315 | signal_mock = mock.MagicMock() |
| 3316 | monkeypatch.setitem(sys.modules, "signal", signal_mock) |
| 3317 | |
| 3318 | # Mock os.tcsetpgrp and os.getpgrp |
| 3319 | if has_tcsetpgrp: |
| 3320 | monkeypatch.setattr(os, "tcsetpgrp", mock.Mock(), raising=False) |
| 3321 | monkeypatch.setattr(os, "getpgrp", mock.Mock(return_value=123), raising=False) |
| 3322 | else: |
| 3323 | monkeypatch.delattr(os, "tcsetpgrp", raising=False) |
| 3324 | |
| 3325 | # Mock subprocess.Popen |
| 3326 | popen_mock = mock.MagicMock(name="Popen") |
| 3327 | monkeypatch.setattr("subprocess.Popen", popen_mock) |
| 3328 | |
| 3329 | # Set initial termios settings so the logic will run |
| 3330 | dummy_settings = ["dummy settings"] |
| 3331 | outsim_app._initial_termios_settings = dummy_settings |
| 3332 | |
| 3333 | # Call ppaged |
| 3334 | outsim_app.ppaged("Test") |
| 3335 | |
| 3336 | # Verify restoration logic |
| 3337 | if has_tcsetpgrp: |
| 3338 | os.tcsetpgrp.assert_called_once_with(0, 123) |
| 3339 | signal_mock.signal.assert_any_call(signal_mock.SIGTTOU, signal_mock.SIG_IGN) |
| 3340 | |
| 3341 | termios_mock.tcsetattr.assert_called_once_with(0, termios_mock.TCSANOW, dummy_settings) |
| 3342 | |
| 3343 | |
| 3344 | @pytest.mark.skipif(sys.platform.startswith("win"), reason="termios is not available on Windows") |