Docs / docs (push) Successful in 27s
Playwright Tests / test-playwright (1, 2) (push) Failing after 18m28s
Playwright Tests / test-playwright (2, 2) (push) Successful in 5m11s
pre-commit / pre-commit (push) Failing after 2m2s
Test Backend / test-backend (push) Failing after 2m32s
Compose Smoke Test / test-compose (push) Successful in 32s
Playwright Tests / merge-reports (push) Successful in 5m50s
`space` ticks runs on the serve dashboard's table and `enter` compares them: one metric in braille, five distinct hues, and the table of what actually differs under it. Both halves are routes that already existed — the browser's own comparison endpoint for the curves, the runs export for the table, whose input columns are filtered to the ones that vary. The palette is hue rather than the web's lightness ramp on purpose: five steps of one brand hue collapse to a single colour on a 16-colour tty. The screen also subscribes to the engine's event bus over the same websocket a browser uses, so a run that starts and finishes inside a tick is seen rather than only recorded. `a` lists what a run left behind and fetches it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014SmyLMSqcJQ8tUL2qLj21s
80 lines
2.8 KiB
Python
80 lines
2.8 KiB
Python
"""The braille renderer, which is the one part of the dashboard that is logic.
|
|
|
|
The screens around it are wiring the type checker already covers; this is
|
|
arithmetic that a wrong sign would silently flip upside down.
|
|
"""
|
|
|
|
from fluksio.tui.chart import (
|
|
DOTS,
|
|
GUTTER,
|
|
SERIES_STYLES,
|
|
_cells,
|
|
_place,
|
|
legend,
|
|
plot,
|
|
shorten,
|
|
)
|
|
|
|
|
|
def test_a_diagonal_lands_in_the_corners_it_should() -> None:
|
|
"""Bottom left to top right, on a grid small enough to name every dot."""
|
|
# Two cells across, one down: a 4x4 dot grid.
|
|
cells, bounds = _cells([("a", [[0.0, 0.0], [1.0, 1.0]])], cols=2, rows=1)
|
|
assert bounds == (0.0, 1.0, 0.0, 1.0)
|
|
assert set(cells) == {(0, 0), (0, 1)}
|
|
# The low reading sits at the bottom of the left cell...
|
|
assert cells[0, 0][0] & DOTS[0][3]
|
|
# ...and the high one at the top of the right, which is the y axis being
|
|
# the right way up.
|
|
assert cells[0, 1][0] & DOTS[1][0]
|
|
assert cells[0, 0][1] == cells[0, 1][1] == 0
|
|
|
|
|
|
def test_readings_are_joined_rather_than_dotted() -> None:
|
|
"""Two readings far apart are a line, not two lonely dots."""
|
|
cells, _ = _cells([("a", [[0.0, 0.0], [1.0, 1.0]])], cols=10, rows=4)
|
|
assert len(cells) >= 9
|
|
|
|
|
|
def test_a_flat_curve_is_drawn_down_the_middle() -> None:
|
|
"""A metric that never moved has no range to divide by."""
|
|
assert _place(5.0, 5.0, 5.0, 8) == 3
|
|
drawn = plot([("a", [[0.0, 5.0], [1.0, 5.0], [2.0, 5.0]])], 40, 6)
|
|
assert "5" in drawn.plain
|
|
|
|
|
|
def test_each_series_keeps_its_own_colour() -> None:
|
|
drawn = plot(
|
|
[("a", [[0.0, 0.0], [1.0, 0.0]]), ("b", [[0.0, 9.0], [1.0, 9.0]])], 40, 8
|
|
)
|
|
used = {span.style for span in drawn.spans}
|
|
assert SERIES_STYLES[0] in used
|
|
assert SERIES_STYLES[1] in used
|
|
|
|
|
|
def test_the_gutter_carries_the_real_bounds() -> None:
|
|
drawn = plot([("a", [[0.0, 0.5], [10.0, 9.5]])], 60, 8, x_label="step")
|
|
assert "9.5" in drawn.plain
|
|
assert "0.5" in drawn.plain
|
|
# And the x axis says what it is and where it ran.
|
|
assert "step" in drawn.plain
|
|
assert "10" in drawn.plain
|
|
# Nothing wraps: a chart that reflowed would be unreadable.
|
|
assert all(len(line) <= 60 for line in drawn.plain.splitlines())
|
|
|
|
|
|
def test_nothing_to_draw_says_so_instead_of_raising() -> None:
|
|
assert "No readings" in plot([], 40, 8).plain
|
|
assert "No readings" in plot([("a", [])], 40, 8).plain
|
|
# One reading is a dot, not a division by zero.
|
|
assert plot([("a", [[1.0, 2.0]])], 40, 8).plain.count("\n") == 7
|
|
# And a pane with no room for a gutter says that rather than drawing junk.
|
|
assert "Too small" in plot([("a", [[0.0, 1.0]])], GUTTER + 4, 3).plain
|
|
|
|
|
|
def test_a_run_is_named_by_the_tail_of_its_id() -> None:
|
|
assert (
|
|
shorten("0193ab7c-dead-beef-1234-aabbccddeeff (seed 3)") == "ccddeeff (seed 3)"
|
|
)
|
|
assert "■" in legend(["run-aaaaaaaa"]).plain
|