File: test_widget_mounting.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 (125 lines) | stat: -rw-r--r-- 4,855 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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import pytest

from textual.app import App
from textual.css.query import TooManyMatches
from textual.widget import MountError, Widget, WidgetError
from textual.widgets import Static


class SelfOwn(Widget):
    """Test a widget that tries to own itself."""

    def __init__(self) -> None:
        super().__init__(self)


async def test_mount_via_app() -> None:
    """Perform mount tests via the app."""

    # Make a background set of widgets.
    widgets = [Static(id=f"starter-{n}") for n in range(10)]

    async with App[None]().run_test() as pilot:
        with pytest.raises(WidgetError):
            await pilot.app.mount(SelfOwn())

    async with App().run_test() as pilot:
        # Mount the first one and make sure it's there.
        await pilot.app.mount(widgets[0])
        assert len(pilot.app.screen._nodes) == 1
        assert pilot.app.screen._nodes[0] == widgets[0]

        # Mount the next 2 widgets via mount.
        await pilot.app.mount(*widgets[1:3])
        assert list(pilot.app.screen._nodes) == widgets[0:3]

        # Finally mount the rest of the widgets via mount_all.
        await pilot.app.mount_all(widgets[3:])
        assert list(pilot.app.screen._nodes) == widgets

    async with App().run_test() as pilot:
        # Mount a widget before -1, which is "before the end".
        penultimate = Static(id="penultimate")
        await pilot.app.mount_all(widgets)
        await pilot.app.mount(penultimate, before=-1)
        assert pilot.app.screen._nodes[-2] == penultimate

    async with App().run_test() as pilot:
        # Mount a widget after -1, which is "at the end".
        ultimate = Static(id="ultimate")
        await pilot.app.mount_all(widgets)
        await pilot.app.mount(ultimate, after=-1)
        assert pilot.app.screen._nodes[-1] == ultimate

    async with App().run_test() as pilot:
        # Mount a widget before -2, which is "before the penultimate".
        penpenultimate = Static(id="penpenultimate")
        await pilot.app.mount_all(widgets)
        await pilot.app.mount(penpenultimate, before=-2)
        assert pilot.app.screen._nodes[-3] == penpenultimate

    async with App().run_test() as pilot:
        # Mount a widget after -2, which is "before the end".
        penultimate = Static(id="penultimate")
        await pilot.app.mount_all(widgets)
        await pilot.app.mount(penultimate, after=-2)
        assert pilot.app.screen._nodes[-2] == penultimate

    async with App().run_test() as pilot:
        # Mount a widget before 0, which is "at the start".
        start = Static(id="start")
        await pilot.app.mount_all(widgets)
        await pilot.app.mount(start, before=0)
        assert pilot.app.screen._nodes[0] == start

    async with App().run_test() as pilot:
        # Mount a widget after 0. You get the idea...
        second = Static(id="second")
        await pilot.app.mount_all(widgets)
        await pilot.app.mount(second, after=0)
        assert pilot.app.screen._nodes[1] == second

    async with App().run_test() as pilot:
        # Mount a widget relative to another via query.
        queue_jumper = Static(id="queue-jumper")
        await pilot.app.mount_all(widgets)
        await pilot.app.mount(queue_jumper, after="#starter-5")
        assert pilot.app.screen._nodes[6] == queue_jumper

    async with App().run_test() as pilot:
        # Mount a widget relative to another via query.
        queue_jumper = Static(id="queue-jumper")
        await pilot.app.mount_all(widgets)
        await pilot.app.mount(queue_jumper, after=widgets[5])
        assert pilot.app.screen._nodes[6] == queue_jumper

    async with App().run_test() as pilot:
        # Make sure we get told off for trying to before and after.
        await pilot.app.mount_all(widgets)
        with pytest.raises(MountError):
            await pilot.app.mount(Static(), before=2, after=2)

    async with App().run_test() as pilot:
        # Make sure we get told off trying to mount relative to something
        # that isn't actually in the DOM.
        await pilot.app.mount_all(widgets)
        with pytest.raises(MountError):
            await pilot.app.mount(Static(), before=Static())
        with pytest.raises(MountError):
            await pilot.app.mount(Static(), after=Static())

    async with App().run_test() as pilot:
        # Make sure we get an error if we try and mount with a selector that
        # results in more than one hit.
        await pilot.app.mount_all(widgets)
        with pytest.raises(TooManyMatches):
            await pilot.app.mount(Static(), before="Static")


async def test_mount_error() -> None:
    """Mounting a widget on an un-mounted widget should raise an error."""
    app = App()
    async with app.run_test():
        with pytest.raises(MountError):
            widget = Widget()
            widget.mount(Static())