[widget] Better tests for types of values we handle or not in style's size

This commit is contained in:
Olivier Philippon
2022-04-27 11:23:07 +01:00
parent 9d1f9da641
commit f7e72ed945
3 changed files with 58 additions and 30 deletions

View File

@@ -115,12 +115,12 @@ class ScalarProperty:
): ):
raise StyleValueError("'auto' not allowed here") raise StyleValueError("'auto' not allowed here")
if new_value.unit != Unit.AUTO: if new_value is not None and new_value.unit != Unit.AUTO:
if new_value is not None and new_value.unit not in self.units: if new_value.unit not in self.units:
raise StyleValueError( raise StyleValueError(
f"{self.name} units must be one of {friendly_list(get_symbols(self.units))}" f"{self.name} units must be one of {friendly_list(get_symbols(self.units))}"
) )
if new_value is not None and new_value.is_percent: if new_value.is_percent:
new_value = Scalar( new_value = Scalar(
float(new_value.value), self.percent_unit, Unit.WIDTH float(new_value.value), self.percent_unit, Unit.WIDTH
) )

View File

@@ -1,11 +1,15 @@
from decimal import Decimal
import pytest import pytest
from rich.style import Style from rich.style import Style
from textual.color import Color from textual.color import Color
from textual.css.errors import StyleTypeError from textual.css.errors import StyleTypeError, StyleValueError
from textual.css.scalar import Scalar, Unit
from textual.css.styles import Styles, RenderStyles from textual.css.styles import Styles, RenderStyles
from textual.dom import DOMNode from textual.dom import DOMNode
from textual.widget import Widget
def test_styles_reset(): def test_styles_reset():
@@ -131,3 +135,53 @@ def test_opacity_set_invalid_type_error():
styles = RenderStyles(DOMNode(), Styles(), Styles()) styles = RenderStyles(DOMNode(), Styles(), Styles())
with pytest.raises(StyleTypeError): with pytest.raises(StyleTypeError):
styles.opacity = "invalid value" styles.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

View File

@@ -32,29 +32,3 @@ def test_widget_set_visible_invalid_string():
widget.visible = "nope! no widget for me!" widget.visible = "nope! no widget for me!"
assert widget.visible assert widget.visible
@pytest.mark.parametrize(
"size_input, expectation",
[
(None, does_not_raise()),
(10, does_not_raise()),
(10.0, does_not_raise()),
(10.2, does_not_raise()),
(Scalar(100, Unit.CELLS, Unit.WIDTH), does_not_raise()),
(Scalar(10.2, Unit.CELLS, Unit.WIDTH), does_not_raise()),
("10", does_not_raise()),
# And now for some common types we don't handle...
("a", pytest.raises(StyleValueError)),
(list(), pytest.raises(StyleValueError)),
(tuple(), pytest.raises(StyleValueError)),
(dict(), pytest.raises(StyleValueError)),
(3.14j, pytest.raises(StyleValueError)),
(Decimal("3.14"), pytest.raises(StyleValueError)),
],
)
def test_widget_style_size_can_accept_various_data_types(size_input, expectation):
widget = Widget()
with expectation:
widget.styles.width = size_input