mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
111 lines
3.1 KiB
Python
111 lines
3.1 KiB
Python
import pytest
|
|
|
|
from textual.app import App, ComposeResult
|
|
from textual.signal import Signal, SignalError
|
|
from textual.widgets import Label
|
|
|
|
|
|
async def test_signal():
|
|
"""Test signal subscribe"""
|
|
called = 0
|
|
|
|
class TestLabel(Label):
|
|
def on_mount(self) -> None:
|
|
def signal_result(_):
|
|
nonlocal called
|
|
called += 1
|
|
|
|
assert isinstance(self.app, TestApp)
|
|
self.app.test_signal.subscribe(self, signal_result)
|
|
|
|
class TestApp(App):
|
|
BINDINGS = [("space", "signal")]
|
|
|
|
def __init__(self) -> None:
|
|
self.test_signal: Signal[str] = Signal(self, "coffee ready")
|
|
super().__init__()
|
|
|
|
def compose(self) -> ComposeResult:
|
|
yield TestLabel()
|
|
|
|
def action_signal(self) -> None:
|
|
self.test_signal.publish("foo")
|
|
|
|
app = TestApp()
|
|
async with app.run_test() as pilot:
|
|
# Check default called is 0
|
|
assert called == 0
|
|
# Action should publish signal
|
|
await pilot.press("space")
|
|
assert called == 1
|
|
# Check a second time
|
|
await pilot.press("space")
|
|
assert called == 2
|
|
# Removed the owner object
|
|
await app.query_one(TestLabel).remove()
|
|
# Check nothing is called
|
|
await pilot.press("space")
|
|
assert called == 2
|
|
# Add a new test label
|
|
await app.mount(TestLabel())
|
|
# Check callback again
|
|
await pilot.press("space")
|
|
assert called == 3
|
|
# Unsubscribe
|
|
app.test_signal.unsubscribe(app.query_one(TestLabel))
|
|
# Check nothing to update
|
|
await pilot.press("space")
|
|
assert called == 3
|
|
|
|
|
|
def test_signal_errors():
|
|
"""Check exceptions raised by Signal class."""
|
|
app = App()
|
|
test_signal = Signal(app, "test")
|
|
label = Label()
|
|
# Check subscribing a non-running widget is an error
|
|
with pytest.raises(SignalError):
|
|
test_signal.subscribe(label, lambda _: None)
|
|
|
|
|
|
def test_repr():
|
|
"""Check the repr doesn't break."""
|
|
app = App()
|
|
test_signal = Signal(app, "test")
|
|
assert isinstance(repr(test_signal), str)
|
|
|
|
|
|
async def test_signal_parameters():
|
|
str_result: str | None = None
|
|
int_result: int | None = None
|
|
|
|
class TestApp(App):
|
|
BINDINGS = [("space", "signal")]
|
|
|
|
def __init__(self) -> None:
|
|
self.str_signal: Signal[str] = Signal(self, "str")
|
|
self.int_signal: Signal[int] = Signal(self, "int")
|
|
super().__init__()
|
|
|
|
def action_signal(self) -> None:
|
|
self.str_signal.publish("foo")
|
|
self.int_signal.publish(3)
|
|
|
|
def on_mount(self) -> None:
|
|
def on_str(my_str):
|
|
nonlocal str_result
|
|
str_result = my_str
|
|
|
|
def on_int(my_int):
|
|
nonlocal int_result
|
|
int_result = my_int
|
|
|
|
self.str_signal.subscribe(self, on_str)
|
|
self.int_signal.subscribe(self, on_int)
|
|
|
|
app = TestApp()
|
|
async with app.run_test() as pilot:
|
|
await pilot.press("space")
|
|
assert str_result == "foo"
|
|
assert int_result == 3
|