aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authoruser <user@clank>2026-08-18 16:10:10 +0200
committeruser <user@clank>2026-08-18 16:10:10 +0200
commit14dad660036e34a899a406f09195f790bb60709c (patch)
treeaa2f12c2d51011d2a2cd818c9a7c31345d55bc56 /tests
parentsl0ppty: a horizontal handle gets heavier, not taller (diff)
downloadslosh-14dad660036e34a899a406f09195f790bb60709c.tar.gz
slosh-14dad660036e34a899a406f09195f790bb60709c.tar.xz
slosh-14dad660036e34a899a406f09195f790bb60709c.zip
sl0ppty: the split arrow belongs on the button
The arrow rode the middle of the dashed boundary line, which put the two halves of one message in two places: the handle said *press here* and a glyph out in the middle of the pane said *this is what happens*. It also meant the direction was unreadable until you were already on the target, since the dashed line is stage two of the hover. So the arrow moves into the handle and the boundary line goes back to being a plain boundary -- which is the honest shape for it anyway: it is the *edge* of the pane you are about to make, and an edge has no middle worth marking. The handle is now one object that explains itself, and because the handle is drawn from the first stage, brushing any part of an edge tells you where its button is and which way that button splits, without previewing a boundary nobody asked about. Knocked out with ATTR_INVERSE rather than drawn in a second colour: the bar is solid `guide`, so a `guide` glyph on top of it would have been invisible, and inverting gets contrast that follows whatever colour the theme sets for no new knob. Along the handle the arrow sits in the middle, where the pointer is aiming. Across it -- a distinction only the upright pair has, being the two that grow a second cell -- it sits on the edge's own cell rather than the one over the content, because it marks a boundary and the boundary lands on the frame. Verified: `make retest`, **1873 checks measured** (`test_split_ux.py` 100 of them), all green. The test that pinned the arrow to the dashed line is now the test that pins it to the handle, on all four sides, plus one that it is legible from the first stage with no boundary drawn. Checked live on a 116x36 pane: `◄█` at column 2 and `█►` at column 117 on the middle row of their bars, `━━━███▼███━━━` on the bottom border's single row, and -- the case that shows why this is worth it -- hovering the *far left* of the top row draws `███▲███` at column 85, where the handle actually is, having dodged a centred title. A note on the two commits before this one: their messages quote 1801 and 1807 checks, which were carried over from earlier in the session rather than measured. The figure was 1865 at that point. The code and the tests were right; the numbers in those two messages were not.
Diffstat (limited to 'tests')
-rw-r--r--tests/test_split_ux.py43
1 files changed, 35 insertions, 8 deletions
diff --git a/tests/test_split_ux.py b/tests/test_split_ux.py
index d568c97..333ce07 100644
--- a/tests/test_split_ux.py
+++ b/tests/test_split_ux.py
@@ -585,18 +585,45 @@ def test_the_guide_says_which_way_it_goes():
)
-def test_the_arrow_sits_on_the_new_boundary():
+def test_the_arrow_rides_the_handle():
+ """The arrow used to sit halfway along the dashed line, which split the
+ message in two: the handle said *press here* and something out in the middle
+ of the pane said *this is what happens*. It belongs on the button."""
with Session(SH, cols=120, rows=26, config=FAST) as s:
s.settle()
p = s.pane()
- x, y = edge_of(s, p, "r")
- rest(s, x, y)
+ for side in ("l", "r", "t", "b"):
+ hx, hy = edge_of(s, p, side)
+ rest(s, hx, hy)
+ snap = s.snapshot()
+ pos = snap.find(ARROWS[side])
+ # Inside the handle: same row for an upright edge, same column for a
+ # horizontal one, and never out on the boundary line.
+ near = pos is not None and (
+ (side in "lr" and pos[1] == hy and abs(pos[0] - hx) <= 1)
+ or (side in "tb" and pos[1] == hy and abs(pos[0] - hx) <= 3)
+ )
+ check(
+ f"the {side} arrow is on the handle",
+ near,
+ f"{pos} vs handle ({hx},{hy})",
+ )
+ check(
+ f"and the {side} boundary line carries none",
+ pos != (p["x"] + p["w"] // 2, p["y"] + p["h"] // 2),
+ str(pos),
+ )
+
+ # The arrow is part of the button, so it is legible from the first stage:
+ # brushing an edge says which way that handle splits, without previewing
+ # a boundary.
+ rx, ry = s.snapshot().rim(p["id"], "l")
+ rest(s, rx, ry)
snap = s.snapshot()
- pos = snap.find(ARROWS["r"])
check(
- "the arrow is on the dashed line, not the border",
- pos is not None and pos[0] == p["x"] + p["w"] // 2,
- str(pos),
+ "and it shows on rim hover too, with no boundary",
+ ARROWS["l"] in snap.screen() and "╎" not in snap.screen(),
+ repr([l for l in snap.text if ARROWS["l"] in l][:1]),
)
@@ -787,7 +814,7 @@ if __name__ == "__main__":
test_the_floor_is_configurable_in_both_axes()
test_the_keyboard_obeys_the_same_floor()
test_the_guide_says_which_way_it_goes()
- test_the_arrow_sits_on_the_new_boundary()
+ test_the_arrow_rides_the_handle()
test_it_splits_across_the_longer_side()
test_the_aspect_is_the_configured_one()
test_it_falls_back_to_the_axis_that_fits()