Improve error message when layout doesnt exist, add tests for parsing layout from CSS

This commit is contained in:
Darren Burns
2022-01-21 14:14:40 +00:00
parent 9c2a125c24
commit d04c66291b
3 changed files with 39 additions and 9 deletions

View File

@@ -6,19 +6,19 @@ import rich.repr
from rich.color import Color
from rich.style import Style
from ._error_tools import friendly_list
from .constants import VALID_BORDER, VALID_EDGE, VALID_DISPLAY, VALID_VISIBILITY
from .errors import DeclarationError
from ._error_tools import friendly_list
from .._duration import _duration_as_seconds
from .._easing import EASING
from ..geometry import Spacing, SpacingDimensions
from .model import Declaration
from .scalar import Scalar, ScalarOffset, Unit, ScalarError
from .styles import DockGroup, Styles
from .types import Edge, Display, Visibility
from .tokenize import Token
from .transition import Transition
from ..layouts.factory import get_layout
from .types import Edge, Display, Visibility
from .._duration import _duration_as_seconds
from .._easing import EASING
from ..geometry import Spacing, SpacingDimensions
from ..layouts.factory import get_layout, LayoutName, MissingLayout, LAYOUT_MAP
class StylesBuilder:
@@ -60,7 +60,7 @@ class StylesBuilder:
self.styles.important.add(rule_name)
try:
process_method(declaration.name, tokens, important)
except DeclarationError as error:
except DeclarationError:
raise
except Exception as error:
self.error(declaration.name, declaration.token, str(error))
@@ -289,7 +289,16 @@ class StylesBuilder:
if len(tokens) != 1:
self.error(name, tokens[0], "unexpected tokens in declaration")
else:
self.styles._rule_layout = get_layout(tokens[0].value)
value = tokens[0].value
layout_name = cast(LayoutName, value)
try:
self.styles._rule_layout = get_layout(layout_name)
except MissingLayout:
self.error(
name,
tokens[0],
f"invalid value for layout (received {value!r}, expected {friendly_list(LAYOUT_MAP.keys())})",
)
def process_text(self, name: str, tokens: list[Token], important: bool) -> None:
style_definition = " ".join(token.value for token in tokens)

View File

@@ -28,5 +28,5 @@ def get_layout(name: LayoutName) -> Layout:
layout_class = LAYOUT_MAP.get(name)
if layout_class is None:
raise MissingLayout("no layout called {name!r}")
raise MissingLayout(f"no layout called {name!r}, valid layouts")
return layout_class()

View File

@@ -4,6 +4,27 @@ from rich.color import Color, ColorType
from textual.css.scalar import Scalar, Unit
from textual.css.stylesheet import Stylesheet, StylesheetParseError
from textual.css.transition import Transition
from textual.layouts.dock import DockLayout
class TestParseLayout:
def test_valid_layout_name(self):
css = "#some-widget { layout: dock; }"
stylesheet = Stylesheet()
stylesheet.parse(css)
styles = stylesheet.rules[0].styles
assert isinstance(styles.layout, DockLayout)
def test_invalid_layout_name(self):
css = "#some-widget { layout: invalidlayout; }"
stylesheet = Stylesheet()
with pytest.raises(StylesheetParseError) as ex:
stylesheet.parse(css)
assert ex.value.errors is not None
class TestParseText: