"""Unit tests for the shared route-graph widget (the fan-lane braille renderer).""" from __future__ import annotations import re from meshterm.ui.pathgraph import ( DST_NODE, SRC_NODE, PathLayer, _coalesce_prefixes, render_path_graph, ) _ANSI = re.compile(r"\x1b\[[0-9;]*m") WHITE = (255, 255, 255) GREEN = (74, 222, 128) YELLOW = (250, 204, 21) GREY = (120, 120, 120) def _glyph(node: str) -> tuple[str, str]: # Deliberately off-palette marker colours, so colour assertions about *edges* # can never accidentally match a marker's escape sequence. if node in (SRC_NODE, DST_NODE): return ("★", "#123456") return ("●", "#654321") def _render(layers, label_of=None): # noqa: ANN001 return render_path_graph( layers, 60, glyph_of=_glyph, label_of=label_of or (lambda node: "you" if node in (SRC_NODE, DST_NODE) else node[:2]), label_rgb_of=lambda _node: WHITE, ) def _sgr(rgb: tuple[int, int, int]) -> str: r, g, b = rgb return f"38;2;{r};{g};{b}m" def test_no_layers_render_nothing() -> None: assert render_path_graph( [], 60, glyph_of=_glyph, label_of=lambda n: None, label_rgb_of=lambda n: WHITE ) == [] def test_identical_paths_collapse_to_the_top_layer() -> None: """The same route in two layers draws once, in the higher priority's colour.""" layers = [ PathLayer(("aa", "bb"), YELLOW, 2), PathLayer(("aa", "bb"), WHITE, 4), ] joined = "\n".join(_render(layers)) assert _sgr(WHITE) in joined assert _sgr(YELLOW) not in joined def test_distinct_layers_draw_in_their_own_colours() -> None: """Three different routes keep three edge colours on one canvas.""" layers = [ PathLayer(("aa", "bb"), YELLOW, 2), PathLayer(("cc",), GREEN, 3), PathLayer(("dd", "ee", "ff"), WHITE, 4), ] joined = "\n".join(_render(layers)) for rgb in (YELLOW, GREEN, WHITE): assert _sgr(rgb) in joined def test_labels_follow_the_callback_only_self_named() -> None: """A ``None`` label leaves the marker bare — a caller's unnamed-relay mode.""" layers = [PathLayer(("ab", "cd"), WHITE, 4)] lines = _render( layers, label_of=lambda node: "Base" if node in (SRC_NODE, DST_NODE) else None, ) plain = _ANSI.sub("", "\n".join(lines)) assert "Base" in plain assert "ab" not in plain and "cd" not in plain def test_endpoint_labels_may_leave_the_marker_row() -> None: """Endpoints place like relays: a long name lands whole, even off the centre row.""" layers = [PathLayer(tuple(f"{i:02x}" for i in range(6)), WHITE, 4)] lines = _render( layers, label_of=lambda node: "VeryLongStationName" if node in (SRC_NODE, DST_NODE) else None, ) plain = _ANSI.sub("", "\n".join(lines)) # The name fits the 60-cell canvas, so it is kept whole — no fixed label budget clips it. assert "VeryLongStationName" in plain assert "…" not in plain def test_prefix_dupe_relay_folds_onto_its_only_wide_match() -> None: """A 1-byte hop beside the same node's wide id, across layers, becomes one node.""" layers = [ PathLayer(("e9043958308d", "be"), WHITE, 3), PathLayer(("3d63c6429436", "be1d1c1dbc4b"), GREY, 2), ] out = _coalesce_prefixes(layers) assert out[0].hops == ("e9043958308d", "be1d1c1dbc4b") # "be" rewritten to the wide id assert out[1].hops == ("3d63c6429436", "be1d1c1dbc4b") def test_ambiguous_prefix_relay_is_left_alone() -> None: """A short hop that prefixes two distinct present nodes is not guessed onto either.""" layers = [ PathLayer(("be",), WHITE, 3), PathLayer(("be1d1c1dbc4b",), GREY, 2), PathLayer(("bedd2bff0011",), GREY, 2), ] out = _coalesce_prefixes(layers) assert out[0].hops == ("be",) # opens two present nodes — kept as its honest short self def test_a_shared_relay_draws_a_single_marker() -> None: """A relay two paths pass through is one vertex, labelled once — never doubled.""" layers = [PathLayer(("aa", "bb"), WHITE, 3), PathLayer(("cc", "bb"), YELLOW, 2)] plain = _ANSI.sub("", "\n".join(_render(layers))) assert plain.count("bb") == 1 # the shared relay is seated once assert plain.count("aa") == 1 and plain.count("cc") == 1 def test_labels_ellipsize_only_when_wider_than_the_canvas() -> None: """A name shortens only when it physically cannot fit — wider than the whole canvas.""" name = "x" * 30 lines = render_path_graph( [PathLayer(("aa",), WHITE, 4)], 20, glyph_of=_glyph, label_of=lambda node: name if node in (SRC_NODE, DST_NODE) else None, label_rgb_of=lambda _node: WHITE, ) plain = _ANSI.sub("", "\n".join(lines)) assert name not in plain # the full 30-cell name cannot fit a 20-cell canvas assert "…" in plain # so it is ellipsized to what fits assert all(len(_ANSI.sub("", ln)) <= 20 for ln in lines) # never overruns the width