From 662fdf69f46826e519d1a2a48929038c51ffef0a Mon Sep 17 00:00:00 2001 From: beefcarver Date: Fri, 30 Oct 2026 04:31:52 +0000 Subject: [PATCH] test(header): cover flush-right clock, date and volume block --- tests/test_header.py | 46 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 tests/test_header.py diff --git a/tests/test_header.py b/tests/test_header.py new file mode 100644 index 0000000..22e01f7 --- /dev/null +++ b/tests/test_header.py @@ -0,0 +1,46 @@ +from __future__ import annotations + +import re +import types + +import pytest +from rich.cells import cell_len + +from somafm_tui.widgets.header import HeaderBar + +TIME = re.compile(r"\d\d:\d\d:\d\d$") +DATE = re.compile(r"[A-Z][a-z]{2} \d\d [A-Z][a-z]{2}$") +VOLUME = re.compile(r"vol \d+%$") + + +def render_header(width: int, height: int = 3) -> list[str]: + """Render the header without a running app, as plain text per line.""" + fake = type("Fake", (), {})() + fake.app = types.SimpleNamespace( + playing_state="playing", volume=70, current=None, notice=None + ) + fake.size = types.SimpleNamespace(width=width, height=height) + return [line.plain.rstrip() for line in HeaderBar.render(fake).renderables] + + +@pytest.mark.parametrize("width", [54, 60, 100, 143, 200]) +def test_right_block_is_flush_right(width: int) -> None: + """Clock, date and volume all end on the same column, at the edge.""" + clock, date, volume = render_header(width) + assert [cell_len(line) for line in (clock, date, volume)] == [width] * 3 + assert TIME.search(clock) + assert DATE.search(date) + assert VOLUME.search(volume) + + +def test_ragged_middle_does_not_shift_the_right_block() -> None: + """"SOMA FM RADIO" and "SAN FRANCISCO" are shorter than + "LISTENER SUPPORTED"; the right block must not follow their length.""" + clock, date, volume = render_header(143) + assert cell_len(clock) == cell_len(date) == cell_len(volume) == 143 + + +def test_right_block_hidden_on_narrow_terminals() -> None: + """Below the threshold the right block is dropped, not squashed.""" + lines = render_header(30) + assert all(":" not in line for line in lines)