|
11 | 11 |
|
12 | 12 | from __future__ import annotations |
13 | 13 |
|
14 | | -import pytest |
15 | | - |
16 | 14 | from textual.app import App, ComposeResult |
17 | | -from textual.widgets import Static |
18 | | -from textual.screen import Screen |
19 | 15 | from textual.binding import Binding |
20 | 16 | from textual.containers import Container |
| 17 | +from textual.screen import Screen |
| 18 | +from textual.widget import Widget |
| 19 | +from textual.widgets import Static |
21 | 20 |
|
22 | 21 | ############################################################################## |
23 | 22 | # These are the movement keys within Textual; they kind of have a special |
@@ -574,6 +573,7 @@ def compose(self) -> ComposeResult: |
574 | 573 | def on_mount(self) -> None: |
575 | 574 | self.query_one(PriorityOverlapWidget).focus() |
576 | 575 |
|
| 576 | + |
577 | 577 | class PriorityOverlapApp(AppKeyRecorder): |
578 | 578 | """An application with a priority binding.""" |
579 | 579 |
|
@@ -607,3 +607,40 @@ async def test_overlapping_priority_bindings() -> None: |
607 | 607 | "app_e", |
608 | 608 | "screen_f", |
609 | 609 | ] |
| 610 | + |
| 611 | + |
| 612 | +async def test_skip_action() -> None: |
| 613 | + """Test that a binding may be skipped by an action returning False""" |
| 614 | + |
| 615 | + class Handle(Widget, can_focus=True): |
| 616 | + BINDINGS = [("t", "test('foo')", "Test")] |
| 617 | + |
| 618 | + def action_test(self, text: str) -> None: |
| 619 | + self.app.exit(text) |
| 620 | + |
| 621 | + no_handle_invoked = False |
| 622 | + |
| 623 | + class NoHandle(Widget, can_focus=True): |
| 624 | + BINDINGS = [("t", "test('bar')", "Test")] |
| 625 | + |
| 626 | + def action_test(self, text: str) -> bool: |
| 627 | + nonlocal no_handle_invoked |
| 628 | + no_handle_invoked = True |
| 629 | + return False |
| 630 | + |
| 631 | + class SkipApp(App): |
| 632 | + def compose(self) -> ComposeResult: |
| 633 | + yield Handle(NoHandle()) |
| 634 | + |
| 635 | + def on_mount(self) -> None: |
| 636 | + self.query_one(NoHandle).focus() |
| 637 | + |
| 638 | + async with SkipApp().run_test() as pilot: |
| 639 | + # Check the NoHandle widget has focus |
| 640 | + assert pilot.app.query_one(NoHandle).has_focus |
| 641 | + # Press the "t" key |
| 642 | + await pilot.press("t") |
| 643 | + # Check the action on the no handle widget was called |
| 644 | + assert no_handle_invoked |
| 645 | + # Check the return value, confirming that the action on Handle was called |
| 646 | + assert pilot.app.return_value == "foo" |
0 commit comments