Add pytest coverage for CLI and rendering behavior
This commit is contained in:
167
tests/test_pager.py
Normal file
167
tests/test_pager.py
Normal file
@@ -0,0 +1,167 @@
|
||||
"""Tests for pager integration."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import signal
|
||||
import subprocess
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from rp.pager import MousePager, _mouse_capable_less
|
||||
|
||||
|
||||
class TestMouseCapableLess:
|
||||
"""Tests for _mouse_capable_less()."""
|
||||
|
||||
def test_returns_path_when_less_supports_mouse(self) -> None:
|
||||
with patch("rp.pager.shutil.which", return_value="/usr/bin/less"):
|
||||
mock_result = MagicMock()
|
||||
mock_result.stdout = "less 551 (POSIX regular expressions)"
|
||||
mock_result.stderr = ""
|
||||
|
||||
with patch("rp.pager.subprocess.run", return_value=mock_result):
|
||||
assert _mouse_capable_less() == "/usr/bin/less"
|
||||
|
||||
def test_returns_none_when_less_not_found(self) -> None:
|
||||
with patch("rp.pager.shutil.which", return_value=None):
|
||||
assert _mouse_capable_less() is None
|
||||
|
||||
def test_returns_none_when_less_too_old(self) -> None:
|
||||
with patch("rp.pager.shutil.which", return_value="/usr/bin/less"):
|
||||
mock_result = MagicMock()
|
||||
mock_result.stdout = "less 444"
|
||||
mock_result.stderr = ""
|
||||
|
||||
with patch("rp.pager.subprocess.run", return_value=mock_result):
|
||||
assert _mouse_capable_less() is None
|
||||
|
||||
def test_returns_path_when_version_is_in_stderr(self) -> None:
|
||||
with patch("rp.pager.shutil.which", return_value="/usr/bin/less"):
|
||||
mock_result = MagicMock()
|
||||
mock_result.stdout = ""
|
||||
mock_result.stderr = "less 600"
|
||||
|
||||
with patch("rp.pager.subprocess.run", return_value=mock_result):
|
||||
assert _mouse_capable_less() == "/usr/bin/less"
|
||||
|
||||
def test_returns_none_on_timeout(self) -> None:
|
||||
with patch("rp.pager.shutil.which", return_value="/usr/bin/less"):
|
||||
with patch(
|
||||
"rp.pager.subprocess.run",
|
||||
side_effect=subprocess.TimeoutExpired(cmd="less", timeout=5),
|
||||
):
|
||||
assert _mouse_capable_less() is None
|
||||
|
||||
def test_returns_none_on_os_error(self) -> None:
|
||||
with patch("rp.pager.shutil.which", return_value="/usr/bin/less"):
|
||||
with patch("rp.pager.subprocess.run", side_effect=OSError("nope")):
|
||||
assert _mouse_capable_less() is None
|
||||
|
||||
def test_returns_none_when_version_not_parseable(self) -> None:
|
||||
with patch("rp.pager.shutil.which", return_value="/usr/bin/less"):
|
||||
mock_result = MagicMock()
|
||||
mock_result.stdout = "some random output"
|
||||
mock_result.stderr = ""
|
||||
|
||||
with patch("rp.pager.subprocess.run", return_value=mock_result):
|
||||
assert _mouse_capable_less() is None
|
||||
|
||||
def test_boundary_version_543(self) -> None:
|
||||
with patch("rp.pager.shutil.which", return_value="/usr/bin/less"):
|
||||
mock_result = MagicMock()
|
||||
mock_result.stdout = "less 543"
|
||||
mock_result.stderr = ""
|
||||
|
||||
with patch("rp.pager.subprocess.run", return_value=mock_result):
|
||||
assert _mouse_capable_less() == "/usr/bin/less"
|
||||
|
||||
def test_boundary_version_542(self) -> None:
|
||||
with patch("rp.pager.shutil.which", return_value="/usr/bin/less"):
|
||||
mock_result = MagicMock()
|
||||
mock_result.stdout = "less 542"
|
||||
mock_result.stderr = ""
|
||||
|
||||
with patch("rp.pager.subprocess.run", return_value=mock_result):
|
||||
assert _mouse_capable_less() is None
|
||||
|
||||
|
||||
class TestMousePager:
|
||||
"""Tests for MousePager.show()."""
|
||||
|
||||
def test_falls_back_to_system_pager_when_no_less(self) -> None:
|
||||
pager = MousePager()
|
||||
|
||||
with patch("rp.pager._mouse_capable_less", return_value=None):
|
||||
with patch("rp.pager.SystemPager") as mock_system_pager:
|
||||
mock_instance = MagicMock()
|
||||
mock_system_pager.return_value = mock_instance
|
||||
|
||||
pager.show("content")
|
||||
|
||||
mock_instance.show.assert_called_once_with("content")
|
||||
|
||||
def test_uses_less_when_available(self) -> None:
|
||||
pager = MousePager()
|
||||
mock_result = MagicMock()
|
||||
mock_result.returncode = 0
|
||||
|
||||
with patch("rp.pager._mouse_capable_less", return_value="/usr/bin/less"):
|
||||
with patch("rp.pager.subprocess.run", return_value=mock_result) as mock_run:
|
||||
pager.show("hello")
|
||||
|
||||
mock_run.assert_called_once_with(
|
||||
["/usr/bin/less", "-R", "--mouse"],
|
||||
input="hello",
|
||||
text=True,
|
||||
)
|
||||
|
||||
def test_sigint_does_not_trigger_fallback_for_negative_code(self) -> None:
|
||||
pager = MousePager()
|
||||
mock_result = MagicMock()
|
||||
mock_result.returncode = -signal.SIGINT
|
||||
|
||||
with patch("rp.pager._mouse_capable_less", return_value="/usr/bin/less"):
|
||||
with patch("rp.pager.subprocess.run", return_value=mock_result):
|
||||
with patch("rp.pager.SystemPager") as mock_system_pager:
|
||||
pager.show("content")
|
||||
|
||||
mock_system_pager.assert_not_called()
|
||||
|
||||
def test_sigint_does_not_trigger_fallback_for_128_plus_code(self) -> None:
|
||||
pager = MousePager()
|
||||
mock_result = MagicMock()
|
||||
mock_result.returncode = 128 + signal.SIGINT
|
||||
|
||||
with patch("rp.pager._mouse_capable_less", return_value="/usr/bin/less"):
|
||||
with patch("rp.pager.subprocess.run", return_value=mock_result):
|
||||
with patch("rp.pager.SystemPager") as mock_system_pager:
|
||||
pager.show("content")
|
||||
|
||||
mock_system_pager.assert_not_called()
|
||||
|
||||
def test_nonzero_exit_triggers_fallback(self) -> None:
|
||||
pager = MousePager()
|
||||
mock_result = MagicMock()
|
||||
mock_result.returncode = 1
|
||||
|
||||
with patch("rp.pager._mouse_capable_less", return_value="/usr/bin/less"):
|
||||
with patch("rp.pager.subprocess.run", return_value=mock_result):
|
||||
with patch("rp.pager.SystemPager") as mock_system_pager:
|
||||
mock_instance = MagicMock()
|
||||
mock_system_pager.return_value = mock_instance
|
||||
|
||||
pager.show("content")
|
||||
|
||||
mock_instance.show.assert_called_once_with("content")
|
||||
|
||||
def test_oserror_triggers_fallback(self) -> None:
|
||||
pager = MousePager()
|
||||
|
||||
with patch("rp.pager._mouse_capable_less", return_value="/usr/bin/less"):
|
||||
with patch("rp.pager.subprocess.run", side_effect=OSError("fail")):
|
||||
with patch("rp.pager.SystemPager") as mock_system_pager:
|
||||
mock_instance = MagicMock()
|
||||
mock_system_pager.return_value = mock_instance
|
||||
|
||||
pager.show("content")
|
||||
|
||||
mock_instance.show.assert_called_once_with("content")
|
||||
Reference in New Issue
Block a user