Add sensible error to query

This commit is contained in:
Will McGugan
2022-10-23 09:52:31 +01:00
parent 610dfee843
commit 6f602f02c0
3 changed files with 36 additions and 6 deletions

View File

@@ -28,7 +28,8 @@ class CalculatorApp(App):
"plus_minus_sign": "plus-minus", "plus_minus_sign": "plus-minus",
"percent_sign": "percent", "percent_sign": "percent",
"equals_sign": "equals", "equals_sign": "equals",
"enter": "equals", "minus": "minus",
"plus": "plus",
} }
def watch_numbers(self, value: str) -> None: def watch_numbers(self, value: str) -> None:
@@ -80,7 +81,6 @@ class CalculatorApp(App):
self.query_one(f"#{button_id}", Button).press() self.query_one(f"#{button_id}", Button).press()
except NoMatches: except NoMatches:
pass pass
self.set_focus(None)
key = event.key key = event.key
if key.isdecimal(): if key.isdecimal():
@@ -89,6 +89,8 @@ class CalculatorApp(App):
press("c") press("c")
press("ac") press("ac")
else: else:
button_id = self.NAME_MAP.get(key)
if button_id is not None:
press(self.NAME_MAP.get(key, key)) press(self.NAME_MAP.get(key, key))
def on_button_pressed(self, event: Button.Pressed) -> None: def on_button_pressed(self, event: Button.Pressed) -> None:

View File

@@ -20,7 +20,7 @@ from typing import cast, Generic, TYPE_CHECKING, Iterator, TypeVar, overload
import rich.repr import rich.repr
from .errors import DeclarationError from .errors import DeclarationError, TokenError
from .match import match from .match import match
from .model import SelectorSet from .model import SelectorSet
from .parse import parse_declarations, parse_selectors from .parse import parse_declarations, parse_selectors
@@ -34,6 +34,10 @@ class QueryError(Exception):
"""Base class for a query related error.""" """Base class for a query related error."""
class InvalidQueryFormat(QueryError):
"""Query did not parse correctly."""
class NoMatches(QueryError): class NoMatches(QueryError):
"""No nodes matched the query.""" """No nodes matched the query."""
@@ -72,9 +76,17 @@ class DOMQuery(Generic[QueryType]):
parent._excludes.copy() if parent else [] parent._excludes.copy() if parent else []
) )
if filter is not None: if filter is not None:
try:
self._filters.append(parse_selectors(filter)) self._filters.append(parse_selectors(filter))
except TokenError:
# TODO: More helpful errors
raise InvalidQueryFormat(f"Unable to parse filter {filter!r} as query")
if exclude is not None: if exclude is not None:
try:
self._excludes.append(parse_selectors(exclude)) self._excludes.append(parse_selectors(exclude))
except TokenError:
raise InvalidQueryFormat(f"Unable to parse filter {filter!r} as query")
@property @property
def node(self) -> DOMNode: def node(self) -> DOMNode:

View File

@@ -1,4 +1,7 @@
import pytest
from textual.widget import Widget from textual.widget import Widget
from textual.css.query import InvalidQueryFormat
def test_query(): def test_query():
@@ -78,3 +81,16 @@ def test_query():
assert list(app.query("#widget1, #widget2")) == [widget1, widget2] assert list(app.query("#widget1, #widget2")) == [widget1, widget2]
assert list(app.query("#widget1 , #widget2")) == [widget1, widget2] assert list(app.query("#widget1 , #widget2")) == [widget1, widget2]
assert list(app.query("#widget1, #widget2, App")) == [app, widget1, widget2] assert list(app.query("#widget1, #widget2, App")) == [app, widget1, widget2]
def test_invalid_query():
class App(Widget):
pass
app = App()
with pytest.raises(InvalidQueryFormat):
app.query("#3")
with pytest.raises(InvalidQueryFormat):
app.query("#foo").exclude("#2")