File: test_input_mouse.py

package info (click to toggle)
textual 2.1.2-1.1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 55,080 kB
  • sloc: python: 85,423; lisp: 1,669; makefile: 101
file content (79 lines) | stat: -rw-r--r-- 2,722 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
from __future__ import annotations

import pytest

from textual.app import App, ComposeResult
from textual.geometry import Offset
from textual.widgets import Input

# A string containing only single-width characters
TEXT_SINGLE = "That gum you like is going to come back in style"

# A string containing only double-width characters
TEXT_DOUBLE = "こんにちは"

# A string containing both single and double-width characters
TEXT_MIXED = "aこんbcにdちeは"


class InputApp(App[None]):
    def __init__(self, text):
        super().__init__()
        self._text = text

    def compose(self) -> ComposeResult:
        yield Input(self._text)


@pytest.mark.parametrize(
    "text, click_at, should_land",
    (
        # Single-width characters
        (TEXT_SINGLE, 0, 0),
        (TEXT_SINGLE, 1, 1),
        (TEXT_SINGLE, 10, 10),
        (TEXT_SINGLE, len(TEXT_SINGLE) - 1, len(TEXT_SINGLE) - 1),
        (TEXT_SINGLE, len(TEXT_SINGLE), len(TEXT_SINGLE)),
        (TEXT_SINGLE, len(TEXT_SINGLE) + 10, len(TEXT_SINGLE)),
        # Double-width characters
        (TEXT_DOUBLE, 0, 0),
        (TEXT_DOUBLE, 1, 0),
        (TEXT_DOUBLE, 2, 1),
        (TEXT_DOUBLE, 3, 1),
        (TEXT_DOUBLE, 4, 2),
        (TEXT_DOUBLE, 5, 2),
        (TEXT_DOUBLE, (len(TEXT_DOUBLE) * 2) - 1, len(TEXT_DOUBLE) - 1),
        (TEXT_DOUBLE, len(TEXT_DOUBLE) * 2, len(TEXT_DOUBLE)),
        (TEXT_DOUBLE, len(TEXT_DOUBLE) * 10, len(TEXT_DOUBLE)),
        # Mixed-width characters
        (TEXT_MIXED, 0, 0),
        (TEXT_MIXED, 1, 1),
        (TEXT_MIXED, 2, 1),
        (TEXT_MIXED, 3, 2),
        (TEXT_MIXED, 4, 2),
        (TEXT_MIXED, 5, 3),
        (TEXT_MIXED, 13, 9),
        (TEXT_MIXED, 14, 9),
        (TEXT_MIXED, 15, 10),
        (TEXT_MIXED, 60, 10),
    ),
)
async def test_mouse_clicks_within(text, click_at, should_land):
    """Mouse clicks should result in the cursor going to the right place."""
    async with InputApp(text).run_test() as pilot:
        # Note the offsets to take into account the decoration around an
        # Input.
        await pilot.click(Input, Offset(click_at + 3, 1))
        await pilot.pause()
        assert pilot.app.query_one(Input).cursor_position == should_land


async def test_mouse_click_outwith_moves_cursor_to_nearest_cell():
    """Mouse clicks in the padding or border area should move the cursor as this makes
    dragging and selecting text easier."""
    async with InputApp(TEXT_SINGLE).run_test() as pilot:
        pilot.app.query_one(Input).cursor_position = 3
        assert pilot.app.query_one(Input).cursor_position == 3
        await pilot.click(Input, Offset(0, 0))
        await pilot.pause()
        assert pilot.app.query_one(Input).cursor_position == 0