From d234c54343b0dce3fa5e10a77106aa0704c2cb96 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Sun, 3 Apr 2022 21:30:51 +0100 Subject: [PATCH] test fixes --- src/textual/color.py | 13 ++++--------- src/textual/css/parse.py | 2 +- src/textual/css/styles.py | 2 +- src/textual/css/tokenizer.py | 10 +++++++++- src/textual/design.py | 1 + tests/css/test_styles.py | 27 --------------------------- tests/test_color.py | 26 ++++++++++++++++++++++++++ 7 files changed, 42 insertions(+), 39 deletions(-) diff --git a/src/textual/color.py b/src/textual/color.py index 7499bcdab..fd3b2fd39 100644 --- a/src/textual/color.py +++ b/src/textual/color.py @@ -118,7 +118,7 @@ class Color(NamedTuple): ) @property - def saturate(self) -> Color: + def clamped(self) -> Color: """Get a color with all components saturated to maximum and minimum values.""" r, g, b, a = self _clamp = clamp @@ -161,11 +161,6 @@ class Color(NamedTuple): brightness = (299 * r + 587 * g + 114 * b) / 1000 return brightness - @property - def is_transparent(self) -> bool: - """Check if the color is transparent (alpha == 0).""" - return self.a == 0 - @property def hex(self) -> str: """The color in CSS hex form, with 6 digits for RGB, and 8 digits for RGBA. @@ -267,7 +262,7 @@ class Color(NamedTuple): r, g, b = [int(pair, 16) for pair in split_pairs3(rgb_hex)] color = cls(r, g, b, 1.0) elif rgba_hex is not None: - r, g, b, a = [int(pair, 16) for pair in split_pairs3(rgba_hex)] + r, g, b, a = [int(pair, 16) for pair in split_pairs4(rgba_hex)] color = cls(r, g, b, a / 255.0) elif rgb is not None: r, g, b = [clamp(int(float(value)), 0, 255) for value in rgb.split(",")] @@ -297,7 +292,7 @@ class Color(NamedTuple): """ h, l, s = self.hls color = self.from_hls(h, l - amount, s) - return color.saturate + return color.clamped def lighten(self, amount: float) -> Color: """Lighten the color by a given amount. @@ -308,7 +303,7 @@ class Color(NamedTuple): Returns: Color: New color. """ - return self.darken(-amount).saturate + return self.darken(-amount).clamped def get_contrast_text(self, alpha=0.95) -> Color: """Get a light or dark color that best contrasts this color, for use with text. diff --git a/src/textual/css/parse.py b/src/textual/css/parse.py index 76e7a7325..6450ff76d 100644 --- a/src/textual/css/parse.py +++ b/src/textual/css/parse.py @@ -261,7 +261,7 @@ def substitute_references( elif token.name == "variable_ref": ref_name = token.value[1:] if ref_name in variables: - variable_tokens = variables[variable_name] + variable_tokens = variables.setdefault(variable_name, []) reference_tokens = variables[ref_name] variable_tokens.extend(reference_tokens) ref_location = token.location diff --git a/src/textual/css/styles.py b/src/textual/css/styles.py index 0c07489b3..0ff7939cd 100644 --- a/src/textual/css/styles.py +++ b/src/textual/css/styles.py @@ -142,7 +142,7 @@ class StylesBase(ABC): text = StyleProperty() color = ColorProperty(Color(255, 255, 255)) - background = ColorProperty(Color(255, 255, 255)) + background = ColorProperty(Color(0, 0, 0)) text_style = StyleFlagsProperty() opacity = FractionalProperty() diff --git a/src/textual/css/tokenizer.py b/src/textual/css/tokenizer.py index 4fcb94264..5bd042fe9 100644 --- a/src/textual/css/tokenizer.py +++ b/src/textual/css/tokenizer.py @@ -110,9 +110,17 @@ class Tokenizer: for name, value in zip(expect.names, iter_groups): if value is not None: break + else: + # For MyPy's benefiy + raise AssertionError("can't reach here") token = Token( - name, value, self.path, self.code, (line_no, col_no), referenced_by=None + name, + value, + self.path, + self.code, + (line_no, col_no), + referenced_by=None, ) col_no += len(value) if col_no >= len(line): diff --git a/src/textual/design.py b/src/textual/design.py index b25855af0..25ffeb06b 100644 --- a/src/textual/design.py +++ b/src/textual/design.py @@ -86,6 +86,7 @@ class ColorSystem: @property def shades(self) -> Iterable[str]: + """The names of the colors and derived shades.""" for color in self.COLOR_NAMES: yield f"{color}-darken2" yield f"{color}-darken1" diff --git a/tests/css/test_styles.py b/tests/css/test_styles.py index 58af80860..039d5745f 100644 --- a/tests/css/test_styles.py +++ b/tests/css/test_styles.py @@ -84,33 +84,6 @@ def test_merge_rules(): } -def test_render_styles_text(): - """Test inline styles override base styles""" - base = Styles() - inline = Styles() - styles_view = RenderStyles(None, base, inline) - - # Both styles are empty - assert styles_view.text == Style() - - # Base is bold blue - base.color = "blue" - base.text_style = "bold" - assert styles_view.text == Style.parse("bold blue") - - # Base is bold blue, inline is red - inline.color = "red" - assert styles_view.text == Style.parse("bold red") - - # Base is bold yellow, inline is red - base.color = "yellow" - assert styles_view.text == Style.parse("bold red") - - # Base is bold blue - inline.color = None - assert styles_view.text == Style.parse("bold yellow") - - def test_render_styles_border(): base = Styles() inline = Styles() diff --git a/tests/test_color.py b/tests/test_color.py index 1361043fc..ac09625c4 100644 --- a/tests/test_color.py +++ b/tests/test_color.py @@ -1,6 +1,8 @@ import pytest from rich.color import Color as RichColor +from rich.text import Text + from textual.color import Color, ColorPair @@ -28,6 +30,21 @@ def test_parse(text, expected): def test_rich_color(): """Check conversion to Rich color.""" assert Color(10, 20, 30, 1.0).rich_color == RichColor.from_rgb(10, 20, 30) + assert Color.from_rich_color(RichColor.from_rgb(10, 20, 30)) == Color( + 10, 20, 30, 1.0 + ) + + +def test_rich_color_rich_output(): + assert isinstance(Color(10, 20, 30).__rich__(), Text) + + +def test_normalized(): + assert Color(255, 128, 64).normalized == pytest.approx((1.0, 128 / 255, 64 / 255)) + + +def test_clamped(): + assert Color(300, 100, -20, 1.5).clamped == Color(255, 100, 0, 1.0) def test_css(): @@ -50,3 +67,12 @@ def test_colorpair_style(): str(ColorPair(Color.parse("rgba(0,0,0,0.5)"), Color.parse("#ffffff")).style) == "#7f7f7f on #ffffff" ) + + +def test_hls(): + + red = Color(200, 20, 32) + print(red.hls) + assert red.hls == pytest.approx( + (0.9888888888888889, 0.43137254901960786, 0.818181818181818) + )