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 126 127 128
|
from __future__ import annotations
from typing import Any
from textual import on
from textual.app import App, ComposeResult
from textual.widgets import Tree
class TreeApp(App[None]):
"""Test tree app."""
def __init__(self, disabled: bool, *args: Any, **kwargs: Any) -> None:
super().__init__(*args, **kwargs)
self.disabled = disabled
self.messages: list[tuple[str, str]] = []
def compose(self) -> ComposeResult:
"""Compose the child widgets."""
yield Tree("Root", disabled=self.disabled, id="test-tree")
def on_mount(self) -> None:
self.query_one(Tree).root.add("Child")
self.query_one(Tree).focus()
def record(
self,
event: (
Tree.NodeSelected[None]
| Tree.NodeExpanded[None]
| Tree.NodeCollapsed[None]
| Tree.NodeHighlighted[None]
),
) -> None:
self.messages.append(
(event.__class__.__name__, event.node.tree.id or "Unknown")
)
@on(Tree.NodeSelected)
def node_selected(self, event: Tree.NodeSelected[None]) -> None:
self.record(event)
@on(Tree.NodeExpanded)
def node_expanded(self, event: Tree.NodeExpanded[None]) -> None:
self.record(event)
@on(Tree.NodeCollapsed)
def node_collapsed(self, event: Tree.NodeCollapsed[None]) -> None:
self.record(event)
@on(Tree.NodeHighlighted)
def node_highlighted(self, event: Tree.NodeHighlighted[None]) -> None:
self.record(event)
async def test_creating_disabled_tree():
"""Mounting a disabled `Tree` should result in the base `Widget`
having a `disabled` property equal to `True`"""
app = TreeApp(disabled=True)
async with app.run_test() as pilot:
tree = app.query_one(Tree)
assert not tree.focusable
assert tree.disabled
assert tree.cursor_line == 0
await pilot.click("#test-tree")
await pilot.pause()
await pilot.press("down")
await pilot.pause()
assert tree.cursor_line == 0
async def test_creating_enabled_tree():
"""Mounting an enabled `Tree` should result in the base `Widget`
having a `disabled` property equal to `False`"""
app = TreeApp(disabled=False)
async with app.run_test() as pilot:
tree = app.query_one(Tree)
assert tree.focusable
assert not tree.disabled
assert tree.cursor_line == 0
await pilot.click("#test-tree")
await pilot.pause()
await pilot.press("down")
await pilot.pause()
assert tree.cursor_line == 1
async def test_disabled_tree_node_selected_message() -> None:
"""Clicking the root node disclosure triangle on a disabled tree
should result in no messages being emitted."""
app = TreeApp(disabled=True)
async with app.run_test() as pilot:
tree = app.query_one(Tree)
# try clicking on a disabled tree
await pilot.click("#test-tree")
await pilot.pause()
assert pilot.app.messages == [("NodeHighlighted", "test-tree")]
# make sure messages DO flow after enabling a disabled tree
tree.disabled = False
await pilot.click("#test-tree")
await pilot.pause()
print(pilot.app.messages)
assert pilot.app.messages == [
("NodeHighlighted", "test-tree"),
("NodeExpanded", "test-tree"),
]
async def test_enabled_tree_node_selected_message() -> None:
"""Clicking the root node disclosure triangle on an enabled tree
should result in an `NodeExpanded` message being emitted."""
app = TreeApp(disabled=False)
async with app.run_test() as pilot:
tree = app.query_one(Tree)
# try clicking on an enabled tree
await pilot.click("#test-tree")
await pilot.pause()
print(pilot.app.messages)
assert pilot.app.messages == [
("NodeHighlighted", "test-tree"),
("NodeExpanded", "test-tree"),
]
tree.disabled = True
# make sure messages DO NOT flow after disabling an enabled tree
app.messages = []
await pilot.click("#test-tree")
await pilot.pause()
assert not pilot.app.messages
|