Use render instead of render_lines in Opacity, add tests

This commit is contained in:
Darren Burns
2022-02-09 11:33:01 +00:00
parent 3b0cab6f79
commit 7109ec0796
3 changed files with 62 additions and 42 deletions

View File

@@ -1,13 +1,9 @@
import functools
from time import sleep
from rich.color import Color
from rich.console import ConsoleOptions, Console, RenderResult, RenderableType
from rich.live import Live
from rich.panel import Panel
from rich.segment import Segment
from rich.style import Style
from rich.text import Text
from textual.renderables.utilities import blend_colors
@@ -27,26 +23,24 @@ class Opacity:
def __rich_console__(
self, console: Console, options: ConsoleOptions
) -> RenderResult:
lines = console.render_lines(self.renderable, options)
segments = console.render(self.renderable, options)
opacity = self.value
for line in lines:
for segment in line:
style = segment.style
if not style:
yield segment
continue
fg, bg = style.color, style.bgcolor
if fg and fg.triplet and bg and bg.triplet:
yield Segment(
text=segment.text,
style=_get_blended_style_cached(
fg_color=fg, bg_color=bg, opacity=opacity
),
control=segment.control,
)
else:
yield segment
yield ""
for segment in segments:
style = segment.style
if not style:
yield segment
continue
fg, bg = style.color, style.bgcolor
if fg and fg.triplet and bg and bg.triplet:
yield Segment(
text=segment.text,
style=_get_blended_style_cached(
fg_color=fg, bg_color=bg, opacity=opacity
),
control=segment.control,
)
else:
yield segment
@functools.lru_cache(maxsize=1024)
@@ -60,6 +54,12 @@ def _get_blended_style_cached(
if __name__ == "__main__":
from rich.live import Live
from rich.panel import Panel
from rich.text import Text
from time import sleep
console = Console()
panel = Panel.fit(

View File

@@ -4,28 +4,47 @@ from rich.text import Text
from tests.utilities.render import render
from textual.renderables.opacity import Opacity
@pytest.mark.skip
def test_simple_opacity():
text = Text("Hello, world!", style="#ff0000 on #00ff00")
assert render(Opacity(text, value=.5)) == ""
STOP = "\x1b[0m"
@pytest.mark.skip
def test_ansi_colors_ignored():
pass
@pytest.fixture
def text():
return Text("Hello, world!", style="#ff0000 on #00ff00", end="")
@pytest.mark.skip
def test_opacity_no_style():
pass
def test_simple_opacity(text):
blended_red_on_green = "\x1b[38;2;127;127;0;48;2;0;255;0m"
assert render(Opacity(text, value=.5)) == (
f"{blended_red_on_green}Hello, world!{STOP}"
)
@pytest.mark.skip
def test_opacity_only_fg():
pass
def test_value_zero_sets_foreground_color_to_background_color(text):
foreground = background = "0;255;0"
assert render(Opacity(text, value=0)) == (
f"\x1b[38;2;{foreground};48;2;{background}mHello, world!{STOP}"
)
@pytest.mark.skip
def test_opacity_only_bg():
pass
def test_opacity_value_of_one_noop(text):
assert render(Opacity(text, value=1)) == render(text)
def test_ansi_colors_noop():
ansi_colored_text = Text("Hello, world!", style="red on green", end="")
assert render(Opacity(ansi_colored_text, value=.5)) == render(ansi_colored_text)
def test_opacity_no_style_noop():
text_no_style = Text("Hello, world!", end="")
assert render(Opacity(text_no_style, value=.2)) == render(text_no_style)
def test_opacity_only_fg_noop():
text_only_fg = Text("Hello, world!", style="#ff0000", end="")
assert render(Opacity(text_only_fg, value=.5)) == render(text_only_fg)
def test_opacity_only_bg_noop():
text_only_bg = Text("Hello, world!", style="on #ff0000", end="")
assert render(Opacity(text_only_bg, value=.5)) == render(text_only_bg)

View File

@@ -19,6 +19,7 @@ def render(renderable: RenderableType, no_wrap: bool = False) -> str:
console = Console(
width=100, file=io.StringIO(), color_system="truecolor", legacy_windows=False
)
console.print(renderable, no_wrap=no_wrap)
output = replace_link_ids(console.file.getvalue())
with console.capture() as capture:
console.print(renderable, no_wrap=no_wrap, end="")
output = replace_link_ids(capture.get())
return output