198 lines
5.8 KiB
Python
198 lines
5.8 KiB
Python
from decimal import Decimal
|
|
|
|
import pytest
|
|
from rich.style import Style
|
|
|
|
from textual.color import Color
|
|
from textual.css.errors import StyleValueError
|
|
from textual.css.scalar import Scalar, Unit
|
|
from textual.css.styles import RenderStyles, Styles
|
|
from textual.dom import DOMNode
|
|
from textual.widget import Widget
|
|
|
|
|
|
def test_styles_reset():
|
|
styles = Styles()
|
|
styles.text_style = "not bold"
|
|
assert styles.text_style == Style(bold=False)
|
|
styles.reset()
|
|
assert styles.text_style is Style.null()
|
|
|
|
|
|
def test_has_rule():
|
|
styles = Styles()
|
|
assert not styles.has_rule("text_style")
|
|
styles.text_style = "bold"
|
|
assert styles.has_rule("text_style")
|
|
styles.text_style = None
|
|
assert not styles.has_rule("text_style")
|
|
|
|
|
|
def test_clear_rule():
|
|
styles = Styles()
|
|
styles.text_style = "bold"
|
|
assert styles.has_rule("text_style")
|
|
styles.clear_rule("text_style")
|
|
assert not styles.has_rule("text_style")
|
|
|
|
|
|
def test_get_rules():
|
|
styles = Styles()
|
|
# Empty rules at start
|
|
assert styles.get_rules() == {}
|
|
styles.text_style = "bold"
|
|
assert styles.get_rules() == {"text_style": Style.parse("bold")}
|
|
styles.display = "none"
|
|
assert styles.get_rules() == {
|
|
"text_style": Style.parse("bold"),
|
|
"display": "none",
|
|
}
|
|
|
|
|
|
def test_set_rule():
|
|
styles = Styles()
|
|
assert styles.get_rules() == {}
|
|
styles.set_rule("text_style", Style.parse("bold"))
|
|
assert styles.get_rules() == {"text_style": Style.parse("bold")}
|
|
|
|
|
|
def test_reset():
|
|
styles = Styles()
|
|
assert styles.get_rules() == {}
|
|
styles.set_rule("text_style", Style.parse("bold"))
|
|
assert styles.get_rules() == {"text_style": Style.parse("bold")}
|
|
styles.reset()
|
|
assert styles.get_rules() == {}
|
|
|
|
|
|
def test_merge():
|
|
styles = Styles()
|
|
styles.set_rule("text_style", Style.parse("bold"))
|
|
styles2 = Styles()
|
|
styles2.set_rule("display", "none")
|
|
styles.merge(styles2)
|
|
assert styles.get_rules() == {
|
|
"text_style": Style.parse("bold"),
|
|
"display": "none",
|
|
}
|
|
|
|
|
|
def test_merge_rules():
|
|
styles = Styles()
|
|
styles.set_rule("text_style", Style.parse("bold"))
|
|
styles.merge_rules({"display": "none"})
|
|
assert styles.get_rules() == {
|
|
"text_style": Style.parse("bold"),
|
|
"display": "none",
|
|
}
|
|
|
|
|
|
def test_render_styles_border():
|
|
base = Styles()
|
|
inline = Styles()
|
|
styles_view = RenderStyles(None, base, inline)
|
|
|
|
base.border_top = ("heavy", "red")
|
|
# Base has border-top: heavy red
|
|
assert styles_view.border_top == ("heavy", Color.parse("red"))
|
|
|
|
inline.border_left = ("rounded", "green")
|
|
# Base has border-top heavy red, inline has border-left: rounded green
|
|
assert styles_view.border_top == ("heavy", Color.parse("red"))
|
|
assert styles_view.border_left == ("rounded", Color.parse("green"))
|
|
assert styles_view.border == (
|
|
("heavy", Color.parse("red")),
|
|
("", Color(0, 255, 0)),
|
|
("", Color(0, 255, 0)),
|
|
("rounded", Color.parse("green")),
|
|
)
|
|
|
|
|
|
def test_get_opacity_default():
|
|
styles = RenderStyles(DOMNode(), Styles(), Styles())
|
|
assert styles.text_opacity == 1.0
|
|
|
|
|
|
def test_styles_css_property():
|
|
css = "opacity: 50%; text-opacity: 20%; background: green; color: red; tint: dodgerblue 20%;"
|
|
styles = Styles().parse(css, path="")
|
|
assert styles.css == (
|
|
"background: #008000;\n"
|
|
"color: #FF0000;\n"
|
|
"opacity: 0.5;\n"
|
|
"text-opacity: 0.2;\n"
|
|
"tint: rgba(30,144,255,0.2);"
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"set_value, expected",
|
|
[
|
|
[0.2, 0.2],
|
|
[-0.4, 0.0],
|
|
[5.8, 1.0],
|
|
["25%", 0.25],
|
|
["-10%", 0.0],
|
|
["120%", 1.0],
|
|
],
|
|
)
|
|
def test_opacity_set_then_get(set_value, expected):
|
|
styles = RenderStyles(DOMNode(), Styles(), Styles())
|
|
styles.text_opacity = set_value
|
|
assert styles.text_opacity == expected
|
|
|
|
|
|
def test_opacity_set_invalid_type_error():
|
|
styles = RenderStyles(DOMNode(), Styles(), Styles())
|
|
with pytest.raises(StyleValueError):
|
|
styles.text_opacity = "invalid value"
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"size_dimension_input,size_dimension_expected_output",
|
|
[
|
|
# fmt: off
|
|
[None, None],
|
|
[1, Scalar(1, Unit.CELLS, Unit.WIDTH)],
|
|
[1.0, Scalar(1.0, Unit.CELLS, Unit.WIDTH)],
|
|
[1.2, Scalar(1.2, Unit.CELLS, Unit.WIDTH)],
|
|
[1.2e3, Scalar(1200.0, Unit.CELLS, Unit.WIDTH)],
|
|
["20", Scalar(20, Unit.CELLS, Unit.WIDTH)],
|
|
["1.4", Scalar(1.4, Unit.CELLS, Unit.WIDTH)],
|
|
[Scalar(100, Unit.CELLS, Unit.WIDTH), Scalar(100, Unit.CELLS, Unit.WIDTH)],
|
|
[Scalar(10.3, Unit.CELLS, Unit.WIDTH), Scalar(10.3, Unit.CELLS, Unit.WIDTH)],
|
|
[Scalar(10.4, Unit.CELLS, Unit.HEIGHT), Scalar(10.4, Unit.CELLS, Unit.HEIGHT)],
|
|
[Scalar(10.5, Unit.PERCENT, Unit.WIDTH), Scalar(10.5, Unit.WIDTH, Unit.WIDTH)],
|
|
[Scalar(10.6, Unit.PERCENT, Unit.PERCENT), Scalar(10.6, Unit.WIDTH, Unit.WIDTH)],
|
|
[Scalar(10.7, Unit.HEIGHT, Unit.PERCENT), Scalar(10.7, Unit.HEIGHT, Unit.PERCENT)],
|
|
# percentage values are normalised to floats and get the WIDTH "percent_unit":
|
|
[Scalar(11, Unit.PERCENT, Unit.HEIGHT), Scalar(11.0, Unit.WIDTH, Unit.WIDTH)],
|
|
# fmt: on
|
|
],
|
|
)
|
|
def test_widget_style_size_can_accept_various_data_types_and_normalize_them(
|
|
size_dimension_input, size_dimension_expected_output
|
|
):
|
|
widget = Widget()
|
|
|
|
widget.styles.width = size_dimension_input
|
|
assert widget.styles.width == size_dimension_expected_output
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"size_dimension_input",
|
|
[
|
|
"a",
|
|
"1.4e3",
|
|
3.14j,
|
|
Decimal("3.14"),
|
|
list(),
|
|
tuple(),
|
|
dict(),
|
|
],
|
|
)
|
|
def test_widget_style_size_fails_if_data_type_is_not_supported(size_dimension_input):
|
|
widget = Widget()
|
|
|
|
with pytest.raises(StyleValueError):
|
|
widget.styles.width = size_dimension_input
|