mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-10-04 06:15:09 +00:00
test(element-style): cover the stateless element_color clamp path (#576)
#569 fixed _normalize_color and #572 covered the resolver path. That test's own docstring notes the resolver "normalizes colour separately from element_color", and the other path had no test: the stateless element_color(), which src.common.sports_card delegates to and which every one of the nine scoreboard plugins takes for each per-element colour it draws. That is the path that regressed. element_color() moved here with the per-element customization framework, the coercion rejected out-of-range components where the reader it replaced clamped them, and a rejection reads as "not configured" -- so one component over 255 painted the element white while the user's colour sat in their config. Every scoreboard's test_element_text_colors.py failed on it, and it took two plugin PRs red on CI to surface. Six cases: clamping, in-range untouched, hex, unparseable fallback, missing element, and agreement with sports_card.coerce_rgb. The last is the point -- the two shared readers disagreed about the same value, so this asserts against coerce_rgb directly rather than restating the arithmetic, and any future move of element_color has to keep them consistent. Verified by mutation: restoring the rejecting coercion fails two of the six, alongside the resolver test from #572. Tests only; no source change. Claude-Session: https://claude.ai/code/session_014RRtqXDCnvnY6EQwhT5CV9 Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -25,6 +25,7 @@ from PIL import ImageFont
|
||||
|
||||
from src.element_style import (
|
||||
alias_keys,
|
||||
element_color,
|
||||
ElementStyleResolver,
|
||||
_load_font_sized,
|
||||
native_bdf_size,
|
||||
@@ -1282,3 +1283,49 @@ class TestAdoptedModes:
|
||||
font = self._live()["score_text"]["properties"]["font"]
|
||||
assert font["x-options"]["maxFixedSize"] == 16
|
||||
assert "null" in font["type"]
|
||||
|
||||
|
||||
class TestElementColorClamps:
|
||||
"""An out-of-range component is clamped, not thrown away.
|
||||
|
||||
#569 fixed this in _normalize_color and #572 covered the resolver path,
|
||||
whose own test notes that "the resolver path normalizes colour separately
|
||||
from element_color". This covers the other one: the stateless element_color()
|
||||
that src.common.sports_card delegates to, which is the path all nine
|
||||
scoreboard plugins take for every per-element colour they draw.
|
||||
|
||||
It regressed once already. element_color() moved here with the per-element
|
||||
customization framework, the coercion rejected out-of-range components where
|
||||
the reader it replaced clamped them, and rejection reads as "not configured"
|
||||
-- so a single component over 255 painted the element white while the user's
|
||||
chosen colour sat in their config. Every scoreboard's
|
||||
test_element_text_colors.py failed on it.
|
||||
"""
|
||||
|
||||
CFG = {"customization": {
|
||||
"rank_text": {"text_color": [999, -5, 20]},
|
||||
"score_text": {"text_color": "#FF0000"},
|
||||
"period_text": {"text_color": [0, 255, 255]},
|
||||
"team_name": {"text_color": "nonsense"},
|
||||
}}
|
||||
|
||||
def test_out_of_range_components_are_clamped(self):
|
||||
assert element_color(self.CFG, "rank_text") == (255, 0, 20)
|
||||
|
||||
def test_in_range_values_are_unchanged(self):
|
||||
assert element_color(self.CFG, "period_text") == (0, 255, 255)
|
||||
|
||||
def test_hex_still_parses(self):
|
||||
assert element_color(self.CFG, "score_text") == (255, 0, 0)
|
||||
|
||||
def test_an_unparseable_value_still_falls_back(self):
|
||||
assert element_color(self.CFG, "team_name") == (255, 255, 255)
|
||||
|
||||
def test_a_missing_element_still_falls_back(self):
|
||||
assert element_color(self.CFG, "detail_text") == (255, 255, 255)
|
||||
|
||||
def test_it_agrees_with_coerce_rgb(self):
|
||||
from src.common.sports_card import coerce_rgb
|
||||
for value in ([999, -5, 20], [300, 300, 300], [-1, -1, -1], [0, 128, 255]):
|
||||
cfg = {"customization": {"rank_text": {"text_color": value}}}
|
||||
assert element_color(cfg, "rank_text") == coerce_rgb(value, (0, 0, 0)), value
|
||||
|
||||
Reference in New Issue
Block a user