mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
Merge branch 'css' into style-error-improvements
This commit is contained in:
@@ -864,7 +864,7 @@ class TestParseLayout:
|
||||
css = "#some-widget { layout: dock; }"
|
||||
|
||||
stylesheet = Stylesheet()
|
||||
stylesheet.parse(css)
|
||||
stylesheet.add_source(css)
|
||||
|
||||
styles = stylesheet.rules[0].styles
|
||||
assert isinstance(styles.layout, DockLayout)
|
||||
@@ -874,7 +874,8 @@ class TestParseLayout:
|
||||
|
||||
stylesheet = Stylesheet()
|
||||
with pytest.raises(StylesheetParseError) as ex:
|
||||
stylesheet.parse(css)
|
||||
stylesheet.add_source(css)
|
||||
stylesheet.parse()
|
||||
|
||||
assert ex.value.errors is not None
|
||||
|
||||
@@ -886,7 +887,7 @@ class TestParseText:
|
||||
}
|
||||
"""
|
||||
stylesheet = Stylesheet()
|
||||
stylesheet.parse(css)
|
||||
stylesheet.add_source(css)
|
||||
|
||||
styles = stylesheet.rules[0].styles
|
||||
assert styles.color == Color.parse("green")
|
||||
@@ -897,7 +898,7 @@ class TestParseText:
|
||||
}
|
||||
"""
|
||||
stylesheet = Stylesheet()
|
||||
stylesheet.parse(css)
|
||||
stylesheet.add_source(css)
|
||||
|
||||
styles = stylesheet.rules[0].styles
|
||||
assert styles.background == Color.parse("red")
|
||||
@@ -933,7 +934,7 @@ class TestParseOffset:
|
||||
}}
|
||||
"""
|
||||
stylesheet = Stylesheet()
|
||||
stylesheet.parse(css)
|
||||
stylesheet.add_source(css)
|
||||
|
||||
styles = stylesheet.rules[0].styles
|
||||
|
||||
@@ -972,7 +973,7 @@ class TestParseOffset:
|
||||
}}
|
||||
"""
|
||||
stylesheet = Stylesheet()
|
||||
stylesheet.parse(css)
|
||||
stylesheet.add_source(css)
|
||||
|
||||
styles = stylesheet.rules[0].styles
|
||||
|
||||
@@ -1002,7 +1003,7 @@ class TestParseTransition:
|
||||
}}
|
||||
"""
|
||||
stylesheet = Stylesheet()
|
||||
stylesheet.parse(css)
|
||||
stylesheet.add_source(css)
|
||||
|
||||
styles = stylesheet.rules[0].styles
|
||||
|
||||
@@ -1017,7 +1018,7 @@ class TestParseTransition:
|
||||
def test_no_delay_specified(self):
|
||||
css = f"#some-widget {{ transition: offset-x 1 in_out_cubic; }}"
|
||||
stylesheet = Stylesheet()
|
||||
stylesheet.parse(css)
|
||||
stylesheet.add_source(css)
|
||||
|
||||
styles = stylesheet.rules[0].styles
|
||||
|
||||
@@ -1032,9 +1033,11 @@ class TestParseTransition:
|
||||
|
||||
stylesheet = Stylesheet()
|
||||
with pytest.raises(StylesheetParseError) as ex:
|
||||
stylesheet.parse(css)
|
||||
stylesheet.add_source(css)
|
||||
stylesheet.parse()
|
||||
|
||||
stylesheet_errors = stylesheet.rules[0].errors
|
||||
rules = stylesheet._parse_rules(css, "foo")
|
||||
stylesheet_errors = rules[0].errors
|
||||
|
||||
assert len(stylesheet_errors) == 1
|
||||
assert stylesheet_errors[0][0].value == invalid_func_name
|
||||
@@ -1056,7 +1059,7 @@ class TestParseOpacity:
|
||||
def test_opacity_to_styles(self, css_value, styles_value):
|
||||
css = f"#some-widget {{ opacity: {css_value} }}"
|
||||
stylesheet = Stylesheet()
|
||||
stylesheet.parse(css)
|
||||
stylesheet.add_source(css)
|
||||
|
||||
assert stylesheet.rules[0].styles.opacity == styles_value
|
||||
assert not stylesheet.rules[0].errors
|
||||
@@ -1066,15 +1069,17 @@ class TestParseOpacity:
|
||||
stylesheet = Stylesheet()
|
||||
|
||||
with pytest.raises(StylesheetParseError):
|
||||
stylesheet.parse(css)
|
||||
assert stylesheet.rules[0].errors
|
||||
stylesheet.add_source(css)
|
||||
stylesheet.parse()
|
||||
rules = stylesheet._parse_rules(css, "foo")
|
||||
assert rules[0].errors
|
||||
|
||||
|
||||
class TestParseMargin:
|
||||
def test_margin_partial(self):
|
||||
css = "#foo {margin: 1; margin-top: 2; margin-right: 3; margin-bottom: -1;}"
|
||||
stylesheet = Stylesheet()
|
||||
stylesheet.parse(css)
|
||||
stylesheet.add_source(css)
|
||||
assert stylesheet.rules[0].styles.margin == Spacing(2, 3, -1, 1)
|
||||
|
||||
|
||||
@@ -1082,5 +1087,5 @@ class TestParsePadding:
|
||||
def test_padding_partial(self):
|
||||
css = "#foo {padding: 1; padding-top: 2; padding-right: 3; padding-bottom: -1;}"
|
||||
stylesheet = Stylesheet()
|
||||
stylesheet.parse(css)
|
||||
stylesheet.add_source(css)
|
||||
assert stylesheet.rules[0].styles.padding == Spacing(2, 3, -1, 1)
|
||||
|
||||
55
tests/css/test_stylesheet.py
Normal file
55
tests/css/test_stylesheet.py
Normal file
@@ -0,0 +1,55 @@
|
||||
from contextlib import nullcontext as does_not_raise
|
||||
import pytest
|
||||
|
||||
from textual.color import Color
|
||||
from textual.css.stylesheet import Stylesheet, StylesheetParseError
|
||||
from textual.css.tokenizer import TokenizeError
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"css_value,expectation,expected_color",
|
||||
[
|
||||
# Valid values:
|
||||
["transparent", does_not_raise(), Color(0, 0, 0, 0)],
|
||||
["ansi_red", does_not_raise(), Color(128, 0, 0)],
|
||||
["ansi_bright_magenta", does_not_raise(), Color(255, 0, 255)],
|
||||
["red", does_not_raise(), Color(255, 0, 0)],
|
||||
["lime", does_not_raise(), Color(0, 255, 0)],
|
||||
["coral", does_not_raise(), Color(255, 127, 80)],
|
||||
["aqua", does_not_raise(), Color(0, 255, 255)],
|
||||
["deepskyblue", does_not_raise(), Color(0, 191, 255)],
|
||||
["rebeccapurple", does_not_raise(), Color(102, 51, 153)],
|
||||
["#ffcc00", does_not_raise(), Color(255, 204, 0)],
|
||||
["#ffcc0033", does_not_raise(), Color(255, 204, 0, 0.2)],
|
||||
["rgb(200,90,30)", does_not_raise(), Color(200, 90, 30)],
|
||||
["rgba(200,90,30,0.3)", does_not_raise(), Color(200, 90, 30, 0.3)],
|
||||
# Some invalid ones:
|
||||
["coffee", pytest.raises(StylesheetParseError), None], # invalid color name
|
||||
["ansi_dark_cyan", pytest.raises(StylesheetParseError), None],
|
||||
["red 4", pytest.raises(StylesheetParseError), None], # space in it
|
||||
["1", pytest.raises(StylesheetParseError), None], # invalid value
|
||||
["()", pytest.raises(TokenizeError), None], # invalid tokens
|
||||
# TODO: implement hex colors with 3 chars? @link https://devdocs.io/css/color_value
|
||||
["#09f", pytest.raises(TokenizeError), None],
|
||||
# TODO: allow spaces in rgb/rgba expressions?
|
||||
["rgb(200, 90, 30)", pytest.raises(TokenizeError), None],
|
||||
["rgba(200,90,30, 0.4)", pytest.raises(TokenizeError), None],
|
||||
],
|
||||
)
|
||||
def test_color_property_parsing(css_value, expectation, expected_color):
|
||||
stylesheet = Stylesheet()
|
||||
css = """
|
||||
* {
|
||||
background: ${COLOR};
|
||||
}
|
||||
""".replace(
|
||||
"${COLOR}", css_value
|
||||
)
|
||||
|
||||
with expectation:
|
||||
stylesheet.add_source(css)
|
||||
stylesheet.parse()
|
||||
|
||||
if expected_color:
|
||||
css_rule = stylesheet.rules[0]
|
||||
assert css_rule.styles.background == expected_color
|
||||
Reference in New Issue
Block a user