diff --git a/tests/test_url_copy.py b/tests/test_url_copy.py index 1f6a24d2..e01bfbf6 100644 --- a/tests/test_url_copy.py +++ b/tests/test_url_copy.py @@ -3,6 +3,7 @@ from __future__ import annotations import io +from typing import cast import pytest from rich.console import Console @@ -15,6 +16,18 @@ def _console() -> Console: return Console(file=io.StringIO(), force_terminal=True, width=80) +def _output(console: Console) -> str: + """Everything a ``_console()`` was asked to print. + + Rich declares ``Console.file`` as ``IO[str]``, which has no ``getvalue``, + so reading the buffer straight off the console is a type error (`ty`). The + cast narrows it back to the ``StringIO`` ``_console`` put there -- the same + idiom ``tests/test_output.py`` uses at its 23 read sites. Wrapped in a + helper here only because this file reads the buffer from several tests. + """ + return cast(io.StringIO, console.file).getvalue() + + class _Recorder: def __init__(self) -> None: self.copied: list[str] = [] @@ -50,7 +63,13 @@ def test_detect_clipboard_linux_prefers_wl_copy(monkeypatch: pytest.MonkeyPatch) assert detect_clipboard() is not None -def test_disabled_without_backend() -> None: +def test_disabled_without_backend(monkeypatch: pytest.MonkeyPatch) -> None: + # `copier=None` means "detect one", NOT "there is none" (_url_copy.py:123), + # so the no-backend case has to be staged by making detection fail. Without + # this the test passes only on a machine with no clipboard command -- i.e. + # a bare CI container -- and fails for every developer on macOS (`pbcopy` + # is always there), Windows, WSL, or a Linux desktop. + monkeypatch.setattr(_url_copy, "detect_clipboard", lambda: None) wait = CopyableUrlWait(_console(), copier=None, interactive=True) assert wait.enabled is False @@ -64,14 +83,16 @@ def test_on_prompt_prints_hint_when_enabled() -> None: console = _console() wait = CopyableUrlWait(console, copier=_Recorder(), interactive=True) wait.on_prompt("https://example.com/x") - assert "Press c to copy the link" in console.file.getvalue() + assert "Press c to copy the link" in _output(console) -def test_on_prompt_silent_when_disabled() -> None: +def test_on_prompt_silent_when_disabled(monkeypatch: pytest.MonkeyPatch) -> None: + # Same staging as test_disabled_without_backend: no detectable backend. + monkeypatch.setattr(_url_copy, "detect_clipboard", lambda: None) console = _console() wait = CopyableUrlWait(console, copier=None, interactive=True) wait.on_prompt("https://example.com/x") - assert console.file.getvalue() == "" + assert _output(console) == "" def test_wait_copies_on_c_keypress(monkeypatch: pytest.MonkeyPatch) -> None: @@ -83,7 +104,7 @@ def test_wait_copies_on_c_keypress(monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr(wait, "_read_key", lambda _timeout: next(keys, None)) wait.wait(0.01) assert rec.copied == ["https://example.com/x"] - assert "Copied to clipboard" in console.file.getvalue() + assert "Copied to clipboard" in _output(console) def test_wait_copies_only_once(monkeypatch: pytest.MonkeyPatch) -> None: