"""The BBS frames: grey edges, corners fading white → grey → cyan.""" from __future__ import annotations from rich.text import Text from beefy_player.palettes import PALETTES from beefy_player.widgets import frame #: The original ladder, used as a fixed reference in these tests. STOPS = PALETTES["spectrum"] HOT = STOPS[-1] # the corner colour def styles_of(line: Text) -> list[tuple[str, str]]: return [ (line.plain[span.start : span.end], str(span.style)) for span in line.spans ] def test_only_the_top_right_corner_fades_on_the_top_edge() -> None: spans = styles_of(frame.top(30, stops=STOPS)) assert spans[0] == ("╭", frame.EDGE) # plain grey corner # the fade runs into the top-right corner, hot end last assert [style for _text, style in spans[-4:-1]] == [ STOPS[-4], STOPS[-3], STOPS[-2], ] assert spans[-1] == ("╮", f"bold {HOT}") def test_only_the_bottom_left_corner_fades_on_the_bottom_edge() -> None: spans = styles_of(frame.bottom(30, STOPS)) assert spans[0] == ("╰", f"bold {HOT}") assert [style for _text, style in spans[1:4]] == [ STOPS[-2], STOPS[-3], STOPS[-4], ] assert spans[-1] == ("╯", frame.EDGE) # plain grey corner def test_the_sides_glow_towards_their_own_corner_only() -> None: # left column fades up from the bottom-left corner assert [frame.side_style(row, 10, "left", STOPS) for row in range(10)] == [ frame.EDGE, frame.EDGE, frame.EDGE, frame.EDGE, frame.EDGE, frame.EDGE, frame.EDGE, STOPS[-4], STOPS[-3], STOPS[-2], ] # right column fades down from the top-right corner assert [frame.side_style(row, 10, "right", STOPS) for row in range(10)] == [ STOPS[-2], STOPS[-3], STOPS[-4], frame.EDGE, frame.EDGE, frame.EDGE, frame.EDGE, frame.EDGE, frame.EDGE, frame.EDGE, ] def test_the_title_sits_after_the_left_fade() -> None: line = frame.top(30, "STATIONS", STOPS) assert line.plain.startswith("╭─ STATIONS ─") assert "STATIONS" in line.plain # a pane too narrow for the title drops it rather than truncating assert "STATIONS" not in frame.top(10, "STATIONS", STOPS).plain def test_wrap_frames_the_content_on_every_row() -> None: content = [Text("hello"), Text("world")] group = frame.wrap(content, 20, 6, "PANE", STOPS) lines = [line.plain for line in group.renderables] assert len(lines) == 6 assert lines[0].startswith("╭") and lines[-1].startswith("╰") assert all(len(line) == 20 for line in lines) assert all(line.startswith("│") and line.endswith("│") for line in lines[1:-1]) assert lines[1].startswith("│hello") def test_content_wider_than_the_pane_is_trimmed_not_spilled() -> None: """A pane must never draw over its neighbour.""" long_line = Text("x" * 40) group = frame.wrap([long_line], 20, 4, "PANE", STOPS) lines = [line.plain for line in group.renderables] assert all(len(line) == 20 for line in lines) assert lines[1].endswith("│") # the original renderable is left untouched assert long_line.plain == "x" * 40