Commit 21f83b50 by PLN (Algolia)

fix(tests): orphan-orbits derives its counts, lcxl3-display collects 30 tests

Both were pre-existing, unrelated to today's check-mix.py/gig-log.py work
(spotted while running the suite for that change).

test_orphan_orbits.py: 9 of 41 tests failed (16-row setlist vs a frozen "13",
and 6 HAND_MEASURED orbit sets vs the parser). Root cause confirmed by git log
+ grep, not a parser bug: the setlist grew from 13 to 16 tracks since the
fixture was written, and commit 2376e431 (2026-08-01, "d10 is the riser") added
a d10 safe-riser idiom to 5 of the hand-measured tracks (bombe_dj, wap,
you_my_sunshine, mafia_sans_serif, desire) after the 2026-07-28 hand
measurement date; piment_bresilien went the other way (d10->d9, PLN's own
request, commit 71bb9bc2/5e5a37ad). Fix: the setlist-length assertions are now
derived from an independent sed-based row count of the setlist file (same
pipeline check-tracks.sh uses) instead of a literal that rots every time PLN
adds a track; the HAND_MEASURED dict and the vague_de_crime->bombe_dj orphan
assertion are re-measured by hand (grep on each file's dN lines, not by
copying the parser's own output) against the corpus as it stands today. No
assertion loosened — 41/41 pass, same invariants, current facts.

test_lcxl3_display.py: pytest collected 0 items. Cause: this was written as a
plain script (module-level `check()` calls, run via `python3
tools/tests/test_lcxl3_display.py`), like test_setlist.py, with no `test_*`
function pytest could find — a file that cannot fail under pytest, i.e.
silent coverage loss. Converted to 30 ordinary pytest test_* functions (one
assert group per logical check), same assertions, nothing dropped or
loosened. Verified live: broke rec_line's hour rollover (divmod 3600->3601)
and watched test_rec_line_formats_hmmss_past_an_hour fail with the exact
wrong value (REC 1:02:02 vs 1:02:03), then reverted.

Suite: 234 passed/9 failed/2 skipped -> 273 passed/2 skipped (ignoring
test_setlist.py, a separate plain-script file, out of scope here — it already
breaks whole-directory pytest collection via a module-level sys.exit and
predates this fix). test_gig_log.py untouched: 169 passed before and after.
parent e72eca1d
......@@ -156,11 +156,26 @@ def test_sound_hints_never_raise_on_an_orbit_with_no_quoted_name(tmp_path):
# the setlist
# --------------------------------------------------------------------------- #
def _raw_setlist_rows() -> list[str]:
"""Independent ground truth for what the setlist file names: the same sed
pipeline check-tracks.sh uses (strip full-line + trailing comments, drop
blanks), NOT oo.load_setlist() counting itself. The set grows over time —
13 became 16 between 2026-07-28 and 2026-09-05 as PLN added tracks — so any
expectation here has to track the file, not a frozen literal."""
import subprocess
out = subprocess.run(
["sed", "-e", "s/#.*//", "-e", "s/[[:space:]]*$//", str(oo.SETLIST)],
capture_output=True, text=True, check=True).stdout
return [ln for ln in out.splitlines() if ln.strip()]
def test_the_real_setlist_loads_and_every_track_exists():
"""A setlist that silently drops a track silently drops a transition, so
load_setlist raises rather than skipping."""
load_setlist raises rather than skipping. The row count is checked against an
independent count of the setlist file (see _raw_setlist_rows), not a frozen
literal — a hardcoded number rots the first time PLN adds a track."""
setlist = oo.load_setlist()
assert len(setlist) == 13
assert len(setlist) == len(_raw_setlist_rows())
for p, label in setlist:
assert p.exists()
assert label
......@@ -187,24 +202,35 @@ def test_setlist_comments_and_blank_lines_are_ignored(tmp_path, monkeypatch):
# parser that only agrees with fixtures
# --------------------------------------------------------------------------- #
# Hand-measured by PLN + me on 2026-07-28, before this parser existed. If the
# parser and the hand count ever disagree, ONE of them is wrong and the tool must
# not be trusted until that is resolved.
# Hand-measured by PLN + me on 2026-07-28, before this parser existed, and
# RE-measured on 2026-09-05 (by reading each file's column-0 `dN` declarations
# with grep, not by copying the parser's output — a hand measurement that quotes
# the thing it checks is a tautology). If the parser and the hand count ever
# disagree, ONE of them is wrong and the tool must not be trusted until that is
# resolved.
HAND_MEASURED = {
"bombe_dj": {1, 2, 3, 4, 5, 7, 8, 9},
"wap": {1, 2, 3, 4, 5, 7, 8, 9},
"piment_bresilien": {1, 2, 3, 4, 5, 7, 8, 10},
# 2026-08-01, commit 2376e43 ("d10 is the riser") added a d10 safe-riser
# idiom to 7 tracks that lacked one — bombe_dj, wap, you_my_sunshine,
# mafia_sans_serif and desire among them. The 07-28 fixture predates that
# commit and was missing d10 on all five; re-measured against the file as
# it stands now.
"bombe_dj": {1, 2, 3, 4, 5, 7, 8, 9, 10},
"wap": {1, 2, 3, 4, 5, 7, 8, 9, 10},
# piment_bresilien is the ONE track in this set that moved its riser the
# other way: PLN asked (2026-08-02, commits 71bb9bc/5e5a37a) to move d10 to
# d9 ("eg a synmenace iirc") rather than adopt the new d10 idiom — the file
# carries a `-- Menace` comment on d9 confirming it. So this one loses d10,
# not gains it.
"piment_bresilien": {1, 2, 3, 4, 5, 7, 8, 9},
"perfect": {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12},
"gimme_acid": {1, 2, 3, 4, 5, 8, 9, 10, 11, 12},
"vague_de_crime": {1, 2, 3, 4, 5, 6, 7, 8, 10},
"mafia_sans_serif": {1, 2, 3, 4, 5, 7, 8},
"mafia_sans_serif": {1, 2, 3, 4, 5, 7, 8, 10},
# d7 became d6 on 2026-07-30 (PLN's edit, committed in ce887b7: the Guitar
# Sunshine block moved down a slot with ^91->^90 and ^59->^58, the same
# consolidation he made in do_it_right). Re-derived by reading the file's
# column-0 `dN` declarations, not by copying the parser's output — a hand
# measurement that quotes the thing it checks is a tautology.
"you_my_sunshine": {1, 2, 3, 4, 5, 6, 8, 9, 11},
"desire": {1, 2, 3, 4, 5, 6, 7, 8, 9},
# consolidation he made in do_it_right).
"you_my_sunshine": {1, 2, 3, 4, 5, 6, 8, 9, 10, 11},
"desire": {1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
"the_revolution_will_be_sampled": {1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12},
}
......@@ -217,8 +243,12 @@ def test_the_parser_agrees_with_the_hand_measurement(stem, want):
def test_the_ear_report_reproduces_vague_de_crime_to_bombe_dj():
"""The ORIGINAL bug report, as a test. PLN heard the crimewave synth survive
into the next track; the mechanism says d6 and d10 are the survivors."""
assert oo.orphans(oo.resolve("vague_de_crime"), oo.resolve("bombe_dj")) == {6, 10}
into the next track; the mechanism says d6 is the survivor.
d10 was a second survivor when this was first written, but commit 2376e43
(2026-08-01) gave bombe_dj its own d10 safe riser — both tracks now declare
d10, so it stopped being a ghost. Only d6 (crimewave) still orphans."""
assert oo.orphans(oo.resolve("vague_de_crime"), oo.resolve("bombe_dj")) == {6}
def test_d6_of_vague_de_crime_really_is_the_crimewave_sound_he_heard():
......@@ -281,14 +311,11 @@ def test_check_tracks_reads_the_SAME_setlist_file():
def test_the_setlist_survives_the_shell_parse_too():
"""The setlist annotates each path with codename + BPM after a '#'. The shell
reader has to strip TRAILING comments, not just full-line ones, or every track
reports "no such file"."""
reports "no such file". Row count is checked against oo.load_setlist() itself
(derived), not a frozen literal — see _raw_setlist_rows."""
import re as _re
import subprocess
out = subprocess.run(
["sed", "-e", "s/#.*//", "-e", "s/[[:space:]]*$//", str(oo.SETLIST)],
capture_output=True, text=True, check=True).stdout
rows = [ln for ln in out.splitlines() if ln.strip()]
assert len(rows) == 13
rows = _raw_setlist_rows()
assert len(rows) == len(oo.load_setlist())
for r in rows:
assert not _re.search(r"[#\[]", r), f"comment leaked into {r!r}"
assert (oo.REPO / r).exists(), r
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment