Files
textual/tests/test_color.py
Will McGugan f3ff9c61c7 color tests
2022-04-06 11:59:58 +01:00

158 lines
4.6 KiB
Python

import pytest
from rich.color import Color as RichColor
from rich.text import Text
from textual.color import Color, ColorPair, Lab, lab_to_rgb, rgb_to_lab
@pytest.mark.parametrize(
"text,expected",
[
("#000000", Color(0, 0, 0, 1.0)),
("#ffffff", Color(255, 255, 255, 1.0)),
("#FFFFFF", Color(255, 255, 255, 1.0)),
("#020304ff", Color(2, 3, 4, 1.0)),
("#02030400", Color(2, 3, 4, 0.0)),
("#0203040f", Color(2, 3, 4, 0.058823529411764705)),
("rgb(0,0,0)", Color(0, 0, 0, 1.0)),
("rgb(255,255,255)", Color(255, 255, 255, 1.0)),
("rgba(255,255,255,1)", Color(255, 255, 255, 1.0)),
("rgb(2,3,4)", Color(2, 3, 4, 1.0)),
("rgba(2,3,4,1.0)", Color(2, 3, 4, 1.0)),
("rgba(2,3,4,0.058823529411764705)", Color(2, 3, 4, 0.058823529411764705)),
],
)
def test_parse(text, expected):
assert Color.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():
"""Check conversion to CSS style"""
assert Color(10, 20, 30, 1.0).css == "rgb(10,20,30)"
assert Color(10, 20, 30, 0.5).css == "rgba(10,20,30,0.5)"
def test_colorpair_style():
"""Test conversion of colorpair to style."""
# Black on white
assert (
str(ColorPair(Color.parse("#000000"), Color.parse("#ffffff")).style)
== "#000000 on #ffffff"
)
# 50% black on white
assert (
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)
)
assert Color.from_hls(
0.9888888888888889, 0.43137254901960786, 0.818181818181818
).normalized == pytest.approx(red.normalized, rel=1e-5)
def test_color_brightness():
assert Color(255, 255, 255).brightness == 1
assert Color(0, 0, 0).brightness == 0
assert Color(127, 127, 127).brightness == pytest.approx(0.49803921568627446)
assert Color(255, 127, 64).brightness == pytest.approx(0.6199607843137255)
def test_color_hex():
assert Color(255, 0, 127).hex == "#FF007F"
assert Color(255, 0, 127, 0.5).hex == "#FF007F7F"
def test_color_css():
assert Color(255, 0, 127).css == "rgb(255,0,127)"
assert Color(255, 0, 127, 0.5).css == "rgba(255,0,127,0.5)"
def test_color_with_alpha():
assert Color(255, 50, 100).with_alpha(0.25) == Color(255, 50, 100, 0.25)
def test_color_blend():
assert Color(0, 0, 0).blend(Color(255, 255, 255), 0) == Color(0, 0, 0)
assert Color(0, 0, 0).blend(Color(255, 255, 255), 1.0) == Color(255, 255, 255)
assert Color(0, 0, 0).blend(Color(255, 255, 255), 0.5) == Color(127, 127, 127)
# Computed with http://www.easyrgb.com/en/convert.php,
# (r, g, b) values in sRGB to (L*, a*, b*) values in CIE-L*ab.
RGB_LAB_DATA = [
(10, 23, 73, 10.245, 15.913, -32.672),
(200, 34, 123, 45.438, 67.750, -8.008),
(0, 0, 0, 0, 0, 0),
(255, 255, 255, 100, 0, 0),
]
@pytest.mark.parametrize(
"r, g, b, L_, a_, b_",
RGB_LAB_DATA,
)
def test_rgb_to_lab(r, g, b, L_, a_, b_):
"""Test conversion from the RGB color space to CIE-L*ab."""
rgb = Color(r, g, b)
lab = rgb_to_lab(rgb)
assert lab.L == pytest.approx(L_, abs=0.1)
assert lab.a == pytest.approx(a_, abs=0.1)
assert lab.b == pytest.approx(b_, abs=0.1)
@pytest.mark.parametrize(
"r, g, b, L_, a_, b_",
RGB_LAB_DATA,
)
def test_lab_to_rgb(r, g, b, L_, a_, b_):
"""Test conversion from the CIE-L*ab color space to RGB."""
lab = Lab(L_, a_, b_)
rgb = lab_to_rgb(lab)
assert rgb.r == pytest.approx(r, abs=1)
assert rgb.g == pytest.approx(g, abs=1)
assert rgb.b == pytest.approx(b, abs=1)
def test_rgb_lab_rgb_roundtrip():
"""Test RGB -> CIE-L*ab -> RGB color conversion roundtripping."""
for r in range(0, 256, 4):
for g in range(0, 256, 4):
for b in range(0, 256, 4):
c_ = lab_to_rgb(rgb_to_lab(Color(r, g, b)))
assert c_.r == pytest.approx(r, abs=1)
assert c_.g == pytest.approx(g, abs=1)
assert c_.b == pytest.approx(b, abs=1)