diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-10-15 09:33:28 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-10-15 09:33:28 +0200 |
| commit | 5044bdfdfffceceecc0d92a776983ad361079839 (patch) | |
| tree | 4a80ab66ef53f9ba76cdf8db4276dfc07d0fc1f7 /packages/meshbay-cli/tests/test_clipboard.py | |
| parent | 1e8eae1f3de765fcd8163716de6e5fe5aab5a034 (diff) | |
| download | meshbay-5044bdfdfffceceecc0d92a776983ad361079839.tar.gz | |
feat(cli): help, and right-click copy and paste in the interactive chat
help prints what --help prints; help ACTION, what ACTION --help prints.
In the interactive chat a right-click on the conversation copies the text
selected with the mouse, else the line under the pointer: to the terminal
(OSC 52) and to the platform's clipboard tool. A right-click on the line
written in pastes the system clipboard's text at the cursor, its lines side
by side, read with wl-paste, xclip or xsel, pbpaste or PowerShell, else what
was copied here last. The conversation is selectable with the mouse, which
RichLog alone is not. The deb and rpm packages recommend wl-clipboard or
xclip for the paste.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-cli/tests/test_clipboard.py')
| -rw-r--r-- | packages/meshbay-cli/tests/test_clipboard.py | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/packages/meshbay-cli/tests/test_clipboard.py b/packages/meshbay-cli/tests/test_clipboard.py new file mode 100644 index 0000000..6296317 --- /dev/null +++ b/packages/meshbay-cli/tests/test_clipboard.py @@ -0,0 +1,58 @@ +""" +The chat's clipboard: the platform's tools, run for real, and nothing when none +works. Fake `wl-copy`/`wl-paste` stand in for wl-clipboard, sharing one file. +""" + +import shutil +import sys +import time + +import pytest +from meshbay_cli.tui import clipboard + +pytestmark = pytest.mark.skipif(sys.platform in ("win32", "darwin"), + reason="the Wayland and X11 tools") +# Found before a test leaves only the fake tools on PATH. +CAT, SLEEP = shutil.which("cat"), shutil.which("sleep") + + +@pytest.fixture +def wayland(tmp_path, monkeypatch): + held = tmp_path / "held" + bin_dir = tmp_path / "bin" + bin_dir.mkdir() + for name, body in (("wl-copy", f'{CAT} > "{held}"'), ("wl-paste", f'{CAT} "{held}"')): + tool = bin_dir / name + tool.write_text(f"#!/bin/sh\n{body}\n") + tool.chmod(0o755) + monkeypatch.setenv("PATH", str(bin_dir)) + monkeypatch.setenv("WAYLAND_DISPLAY", "wayland-0") + monkeypatch.delenv("DISPLAY", raising=False) + return held + + +async def test_what_is_copied_is_what_is_pasted(wayland): + assert await clipboard.write_text("héllo — 你好\nsecond") is True + assert wayland.read_text(encoding="utf-8") == "héllo — 你好\nsecond" + assert await clipboard.read_text() == "héllo — 你好\nsecond" + + +async def test_no_tool_is_none_not_an_error(tmp_path, monkeypatch): + monkeypatch.setenv("PATH", str(tmp_path)) + monkeypatch.setenv("WAYLAND_DISPLAY", "wayland-0") + monkeypatch.setenv("DISPLAY", ":0") + assert await clipboard.read_text() is None + assert await clipboard.write_text("x") is False + + +async def test_a_failing_tool_is_skipped(wayland): + (wayland.parent / "bin" / "wl-paste").write_text("#!/bin/sh\nexit 1\n") + assert await clipboard.read_text() is None + + +async def test_a_hanging_tool_is_given_up(wayland, monkeypatch): + (wayland.parent / "bin" / "wl-paste").write_text(f"#!/bin/sh\nexec {SLEEP} 30\n") + monkeypatch.setattr(clipboard, "TIMEOUT", 0.3) + started = time.monotonic() + assert await clipboard.read_text() is None + assert 0.3 <= time.monotonic() - started < 5 |