diff options
Diffstat (limited to 'packages/meshbay-cli/tests/test_interactive.py')
| -rw-r--r-- | packages/meshbay-cli/tests/test_interactive.py | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/packages/meshbay-cli/tests/test_interactive.py b/packages/meshbay-cli/tests/test_interactive.py index fa7e96c..5b9d9b0 100644 --- a/packages/meshbay-cli/tests/test_interactive.py +++ b/packages/meshbay-cli/tests/test_interactive.py @@ -208,6 +208,17 @@ async def test_delete_removes_what_is_yours_and_asks_first(world): assert any("select them on the right" in n.message for n in app._notifications) +async def _right_click(pilot, widget, offset=(0, 0)) -> None: + """Through App.on_event, as the terminal driver sends it; the pilot's own + clicks skip it.""" + from textual import events + from textual.pilot import _get_mouse_message_arguments + args = _get_mouse_message_arguments(widget, offset, button=3) + for cls in (events.MouseDown, events.MouseUp): + pilot.app.post_message(cls(**args)) + await pilot.pause() + + def _log_text(screen) -> str: from textual.widgets import RichLog return "\n".join("".join(seg.text for seg in strip) @@ -285,3 +296,71 @@ async def test_the_interactive_chat_joins_talks_leaves_and_comes_back(world, mon await _until(pilot, lambda: isinstance(app.screen, ChatGroupsScreen)) await pilot.press("q") assert app.return_code in (0, None) + + +async def test_a_right_click_copies_from_the_chat_and_pastes_into_the_line(world, monkeypatch): + """The selection, else the line under the pointer; pasted as one line.""" + from meshbay_cli.tui import clipboard + from meshbay_cli.tui.chat import ChatGroupsScreen, ChatInput, ChatLog, ChatRoomScreen + hub, node, _ = world + written, held = [], {"text": None} + + async def write_text(text): + written.append(text) + return True + + async def read_text(): + return held["text"] + monkeypatch.setattr(clipboard, "write_text", write_text) + monkeypatch.setattr(clipboard, "read_text", read_text) + node.say("earlier, from bob") + assert await asyncio.to_thread(cli.main, ["--hub", "https://hub.test", "-u", USERNAME, + "--password", PASSPHRASE, "login"]) == 0 + + app = MeshBayApp(context.Context(cli.build_parser().parse_args( + ["--hub", "https://hub.test"])), ChatGroupsScreen) + async with app.run_test(size=(120, 30)) as pilot: + await _until(pilot, lambda: isinstance(app.screen, ChatGroupsScreen)) + await pilot.pause(0.3) + await pilot.press("enter") + await _until(pilot, lambda: isinstance(app.screen, ChatRoomScreen)) + room = app.screen + log = room.query_one(ChatLog) + await _until(pilot, lambda: "<bob-test> earlier, from bob" in _log_text(room)) + y = next(i for i, line in enumerate(log.lines) if "earlier, from bob" in line.text) + line = log.lines[y].text + + # Nothing selected: the line under the pointer. + await _right_click(pilot, log, (4, y)) + await _until(pilot, lambda: written) + assert written[-1] == line.rstrip() and app.clipboard == written[-1] + assert "<bob-test> earlier, from bob" in written[-1] + + # Selected with the mouse: that text, and only it. + x = line.index("bob-test") + await pilot.mouse_down(log, offset=(1 + x, y)) + await pilot.hover(log, offset=(x + len("bob-test"), y)) + await pilot.mouse_up(log, offset=(x + len("bob-test"), y)) + await pilot.pause(0.1) + assert log.text_selection is not None + await _right_click(pilot, log, (1, y + 3)) + await _until(pilot, lambda: len(written) == 2) + assert written[-1] == "bob-test" + + # Pasted into the line written in, at the cursor, lines side by side. + field = room.query_one(ChatInput) + field.value = "say: " + field.cursor_position = len(field.value) + held["text"] = "first line\nsecond line\n" + await _right_click(pilot, field, (2, 0)) + await _until(pilot, lambda: field.value != "say: ") + assert field.value == "say: first line second line" + + # No tool to read the system clipboard: what was copied here. + held["text"] = None + field.value = "" + await _right_click(pilot, field, (2, 0)) + await _until(pilot, lambda: field.value) + assert field.value == "bob-test" + assert app.screen is room # a right-click left nothing behind + await pilot.press("escape") |