fix(r3): fold heid's code review — equal stage widths, the axis guard, players, and tests that read the observable
The one drift: the separator was a border on B, making B's stage 1px narrower than A's; it is now a 1px column gap, so the stages are the same size to the pixel. Tests now read what the contract promises instead of a proxy: the strip's ring order, the full bakeoff sequence, 1:1 and Fit by geometry, the 900px break from both sides, A wrapping, each form naming its own item, a sibling-prefix symlink, both reveals, the strip's flag, the back arrow unlinked, a one-axis picture, a focused player, two videos with no toggle. The contract names .cmp-cap, a press on a stage, INV-4's URL-driven picker and the redirect branch's isinstance check. r3.toml gains ten rows.
This commit is contained in:
+33
-3
@@ -61,6 +61,11 @@ def test_compare_renders_the_pair(tmp_path):
|
||||
assert "p.png" in label_a and "#1" in label_a, label_a
|
||||
assert "r.png" in label_b and "#3" in label_b, label_b
|
||||
assert _frames(body) == {"p.png": "A", "q.png": "", "r.png": "B", "s.png": ""}
|
||||
assert list(_frames(body)) == ["p.png", "q.png", "r.png", "s.png"], "the strip is in RING order"
|
||||
# each side's flag form names its OWN item
|
||||
for key, rel in (("a", "p.png"), ("b", "r.png")):
|
||||
form = re.search(r'data-region="flag-%s".*?</form>' % key, body, re.S).group(0)
|
||||
assert f'name="target" value="{rel}"' in form, (key, form)
|
||||
|
||||
|
||||
def _four(root: pathlib.Path) -> pathlib.Path:
|
||||
@@ -103,9 +108,16 @@ def test_an_outside_symlink_in_the_ring_is_404(tmp_path):
|
||||
outside.write_bytes(PNG)
|
||||
(b / "zz-link.png").symlink_to(outside)
|
||||
assert "zz-link.png" in review_chain(booth_items(b)), "the fixture must put it in the ring"
|
||||
# a SIBLING whose name shares the booth's prefix is outside too (the
|
||||
# containment check compares with the separator, never a bare prefix)
|
||||
sib = tmp_path / "g-extra"
|
||||
sib.mkdir()
|
||||
(sib / "x.png").write_bytes(PNG)
|
||||
(b / "zz-sib.png").symlink_to(sib / "x.png")
|
||||
c = _client(tmp_path)
|
||||
assert c.get("/b/g/compare?a=zz-link.png&b=p.png").status_code == 404
|
||||
assert c.get("/b/g/compare?a=p.png&b=zz-link.png").status_code == 404
|
||||
for rel in ("zz-link.png", "zz-sib.png"):
|
||||
assert c.get(f"/b/g/compare?a={rel}&b=p.png").status_code == 404, rel
|
||||
assert c.get(f"/b/g/compare?a=p.png&b={rel}").status_code == 404, rel
|
||||
|
||||
|
||||
def test_a_look_records_both_seen(tmp_path):
|
||||
@@ -144,6 +156,18 @@ def test_no_data_region_repeats(tmp_path):
|
||||
assert _frames(body)["q.png"] == "AB", "a == b marks the one frame both ways"
|
||||
|
||||
|
||||
def test_a_video_or_track_plays_in_its_own_stage_and_two_get_no_toggle(tmp_path):
|
||||
"""C4: video and audio play in their own stage; the Fit | 1:1 toggle is
|
||||
bound only when a side is a picture, so two videos get none."""
|
||||
_booth(tmp_path, "g", {"a.webm": b"\x1aE\xdf\xa3", "b.mp3": b"ID3", "c.png": PNG})
|
||||
c = _client(tmp_path)
|
||||
body = c.get("/b/g/compare?a=a.webm&b=b.mp3").text
|
||||
assert re.search(r'<video class="cmp-media"[^>]*src="a.webm"', body)
|
||||
assert re.search(r'<audio class="cmp-media"[^>]*src="b.mp3"', body)
|
||||
assert 'id="vtoggle"' not in body
|
||||
assert 'id="vtoggle"' in c.get("/b/g/compare?a=a.webm&b=c.png").text
|
||||
|
||||
|
||||
# ---- C3: stepping --------------------------------------------------------------
|
||||
|
||||
def _ring6(root: pathlib.Path) -> pathlib.Path:
|
||||
@@ -170,6 +194,8 @@ def test_linked_steps_keep_the_distance_and_wrap(tmp_path):
|
||||
assert _step(body, "both-next") == ("04.png", "07.png")
|
||||
body = c.get("/b/g/compare?a=04.png&b=07.png").text
|
||||
assert _step(body, "both-next") == ("05.png", "01.png")
|
||||
body = c.get("/b/g/compare?a=07.png&b=02.png").text
|
||||
assert _step(body, "both-next") == ("01.png", "04.png"), "A wraps as B does"
|
||||
body = c.get("/b/g/compare?a=01.png&b=05.png").text
|
||||
assert _step(body, "both-prev") == ("07.png", "04.png")
|
||||
# each side on its own moves only itself, and wraps the same way
|
||||
@@ -214,6 +240,8 @@ def test_view_state_rides_the_links(tmp_path):
|
||||
frame = re.search(r'<a class="film-f[^"]*"\s+href="([^"]+)" data-rel="q.png"', body).group(1)
|
||||
assert parse_qs(urlsplit(frame.replace("&", "&")).query) == {
|
||||
"a": ["q.png"], "b": ["r.png"], "side": ["a"], "link": ["0"]}
|
||||
links = _compare_links(c.get("/b/g/compare?a=p.png&b=r.png&link=0").text)
|
||||
assert links and all(h.endswith("&link=0") and "side=" not in h for h in links), links
|
||||
for odd in ("side=z&link=maybe", "side=A&link=00", "side=&link="):
|
||||
r = c.get(f"/b/g/compare?a=p.png&b=r.png&{odd}")
|
||||
assert r.status_code == 200, odd
|
||||
@@ -227,7 +255,9 @@ def test_view_state_rides_the_links(tmp_path):
|
||||
|
||||
def _flag(c: TestClient, form: dict, accept: str | None = None):
|
||||
headers = {"accept": accept} if accept else {}
|
||||
return c.post("/b/g/flag", data={"target": "q.png", "on": "1", **form}, headers=headers)
|
||||
r = c.post("/b/g/flag", data={"target": "q.png", "on": "1", **form}, headers=headers)
|
||||
assert r.status_code == (204 if accept else 303), (form, r.status_code)
|
||||
return r
|
||||
|
||||
|
||||
def test_a_flag_without_js_lands_on_the_same_pair(tmp_path):
|
||||
|
||||
Reference in New Issue
Block a user