aboutsummaryrefslogtreecommitdiffstats
path: root/tests/live_reload.py
diff options
context:
space:
mode:
authoruser <user@clank>2026-08-17 14:36:59 +0200
committeruser <user@clank>2026-08-17 14:36:59 +0200
commitc0022776d0912042819e4ea330cf7491a8196b45 (patch)
tree3c5d547f273d8304e7cd6834fd5a2c730a495064 /tests/live_reload.py
parentsl0ppty: ruff formats the Python, and sorts its imports (diff)
downloadslosh-c0022776d0912042819e4ea330cf7491a8196b45.tar.gz
slosh-c0022776d0912042819e4ea330cf7491a8196b45.tar.xz
slosh-c0022776d0912042819e4ea330cf7491a8196b45.zip
sl0ppty: ruff format the Python
The bumpy one, again. Every `.py` outside `vendor/` plus the three `contrib/` scripts that are Python with no extension: 60 files, 6,714 lines rewritten, no behaviour changed. Nothing here is worth reading -- the next commit adds it to `.git-blame-ignore-revs` so `git blame` walks past it. It is a bigger reformat than the C was, 60% of the lines against 17%, and for a reason worth writing down rather than tuning away: ruff and black break a call that does not fit onto one argument per line, where this code aligned the continuation under the opening paren. The test suite is thousands of `check("some prose", cond, detail)` calls, so nearly every one of them changed shape and the suite grew 3,308 lines. Line length was the one lever that moved it -- 120 columns would have been a 40% reformat and no growth at all -- and it was left at 88, because picking an unusual width to dodge a one-time diff is paying forever to avoid paying once. Import sorting came with it. Two files had `import os, pty, uuid, select, struct, sys, termios, time, fcntl, signal` on one line and now have ten. Verified after, not before, because a formatter that alters behaviour would be worse than none: - `make retest`, 1801 checks green -- and this reformats the suite that does the checking, including `harness.py`, which every one of those files imports. - `make test-live`, the tty tests the fast suite skips. They matter here more than usual: `live_input.py` and `live_m0.py` are two of the files whose comma-imports were split, and nothing in the fast suite would have noticed if that broke them. - All 60 files still compile, `make fmt` twice in a row changes nothing the second time, and `ruff check --select I` has nothing left to say.
Diffstat (limited to 'tests/live_reload.py')
-rw-r--r--tests/live_reload.py139
1 files changed, 91 insertions, 48 deletions
diff --git a/tests/live_reload.py b/tests/live_reload.py
index 6b09f62..2e57a7a 100644
--- a/tests/live_reload.py
+++ b/tests/live_reload.py
@@ -5,6 +5,7 @@ The interesting cases are not "does it notice a write" but the two that a naive
watch gets wrong -- an editor renaming a new file over the old one, and a file
caught mid-save that does not parse.
"""
+
import json
import os
import subprocess
@@ -14,8 +15,8 @@ import uuid
BIN = os.environ.get(
"SL0PPTY_BIN",
- os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "build",
- "sl0ppty"))
+ os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "build", "sl0ppty"),
+)
fails = 0
@@ -29,8 +30,9 @@ def check(name, cond, detail=""):
def frame_colour(session):
"""The focused pane's frame colour, straight from the live session."""
- out = subprocess.run([BIN, "-s", session, "cmd", "snapshot"],
- capture_output=True, text=True).stdout
+ out = subprocess.run(
+ [BIN, "-s", session, "cmd", "snapshot"], capture_output=True, text=True
+ ).stdout
try:
runs = json.loads(out)["styles"]
except Exception:
@@ -53,12 +55,27 @@ def wait_for_colour(session, want, timeout=5.0):
def start(session, cfg_path, extra=()):
env = dict(os.environ, SL0PPTY_CONFIG=cfg_path)
- p = subprocess.Popen([BIN, "--server", "-s", session, *extra,
- "--cols", "60", "--rows", "12",
- "--", "/bin/sh", "-c", "stty raw -echo; cat"],
- stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
- env=env)
- for _ in range(200): # gate on the socket answering
+ p = subprocess.Popen(
+ [
+ BIN,
+ "--server",
+ "-s",
+ session,
+ *extra,
+ "--cols",
+ "60",
+ "--rows",
+ "12",
+ "--",
+ "/bin/sh",
+ "-c",
+ "stty raw -echo; cat",
+ ],
+ stdout=subprocess.DEVNULL,
+ stderr=subprocess.DEVNULL,
+ env=env,
+ )
+ for _ in range(200): # gate on the socket answering
if frame_colour(session):
return p
time.sleep(0.02)
@@ -66,8 +83,7 @@ def start(session, cfg_path, extra=()):
def stop(session, proc):
- subprocess.run([BIN, "-s", session, "cmd", '{"cmd":"quit"}'],
- capture_output=True)
+ subprocess.run([BIN, "-s", session, "cmd", '{"cmd":"quit"}'], capture_output=True)
try:
proc.wait(timeout=3)
except Exception:
@@ -85,36 +101,48 @@ def test_watch():
write(cfg, "#00ff00")
p = start(name, cfg)
try:
- check("the session starts with the config it was given",
- frame_colour(name) == "#00ff00", str(frame_colour(name)))
+ check(
+ "the session starts with the config it was given",
+ frame_colour(name) == "#00ff00",
+ str(frame_colour(name)),
+ )
write(cfg, "#ff0000")
- check("writing the file in place reloads it",
- wait_for_colour(name, "#ff0000") == "#ff0000",
- str(frame_colour(name)))
+ check(
+ "writing the file in place reloads it",
+ wait_for_colour(name, "#ff0000") == "#ff0000",
+ str(frame_colour(name)),
+ )
# The case a watch on the *file* would miss: the inode is replaced, so
# a file watch fires once and then never again.
write(cfg + ".tmp", "#0000ff")
os.rename(cfg + ".tmp", cfg)
- check("and so does an editor renaming a new file over it",
- wait_for_colour(name, "#0000ff") == "#0000ff",
- str(frame_colour(name)))
+ check(
+ "and so does an editor renaming a new file over it",
+ wait_for_colour(name, "#0000ff") == "#0000ff",
+ str(frame_colour(name)),
+ )
with open(cfg, "w") as f:
f.write('theme {\n frame_focus "unterminated\n')
- time.sleep(0.4) # bounded: proving nothing happened needs a wait
- check("a file that does not parse keeps what works",
- frame_colour(name) == "#0000ff", str(frame_colour(name)))
- alive = subprocess.run([BIN, "-s", name, "cmd", "alive"],
- capture_output=True, text=True).stdout.strip()
- check("and the session is still alive to say so", alive == "true",
- repr(alive))
+ time.sleep(0.4) # bounded: proving nothing happened needs a wait
+ check(
+ "a file that does not parse keeps what works",
+ frame_colour(name) == "#0000ff",
+ str(frame_colour(name)),
+ )
+ alive = subprocess.run(
+ [BIN, "-s", name, "cmd", "alive"], capture_output=True, text=True
+ ).stdout.strip()
+ check("and the session is still alive to say so", alive == "true", repr(alive))
write(cfg, "#ffff00")
- check("and it recovers once the file is valid again",
- wait_for_colour(name, "#ffff00") == "#ffff00",
- str(frame_colour(name)))
+ check(
+ "and it recovers once the file is valid again",
+ wait_for_colour(name, "#ffff00") == "#ffff00",
+ str(frame_colour(name)),
+ )
finally:
stop(name, p)
for f in (cfg, cfg + ".tmp"):
@@ -125,8 +153,9 @@ def test_watch():
def toast_count(session, text):
"""How many times `text` appears on screen. Toasts stack, so a config that
reloaded twice announces itself twice."""
- out = subprocess.run([BIN, "-s", session, "cmd", "snapshot"],
- capture_output=True, text=True).stdout
+ out = subprocess.run(
+ [BIN, "-s", session, "cmd", "snapshot"], capture_output=True, text=True
+ ).stdout
try:
rows = json.loads(out)["text"]
except Exception:
@@ -146,13 +175,18 @@ def test_one_save_is_one_reload():
# Recreate it the way an editor that unlinks first would.
os.unlink(cfg)
write(cfg, "#ff0000")
- check("the recreated file is picked up",
- wait_for_colour(name, "#ff0000") == "#ff0000",
- str(frame_colour(name)))
- time.sleep(0.3) # bounded: let any second reload land if it is coming
+ check(
+ "the recreated file is picked up",
+ wait_for_colour(name, "#ff0000") == "#ff0000",
+ str(frame_colour(name)),
+ )
+ time.sleep(0.3) # bounded: let any second reload land if it is coming
n = toast_count(name, "config reloaded")
- check("and announced exactly once, not once per inotify event",
- n == 1, f"{n} toasts")
+ check(
+ "and announced exactly once, not once per inotify event",
+ n == 1,
+ f"{n} toasts",
+ )
finally:
stop(name, p)
if os.path.exists(cfg):
@@ -165,19 +199,28 @@ def test_no_reload():
write(cfg, "#00ff00")
p = start(name, cfg, extra=("--no-reload",))
try:
- check("--no-reload starts with the config all the same",
- frame_colour(name) == "#00ff00", str(frame_colour(name)))
+ check(
+ "--no-reload starts with the config all the same",
+ frame_colour(name) == "#00ff00",
+ str(frame_colour(name)),
+ )
write(cfg, "#ff0000")
- time.sleep(0.5) # bounded, for the same reason as above
- check("but does not pick up a change on its own",
- frame_colour(name) == "#00ff00", str(frame_colour(name)))
+ time.sleep(0.5) # bounded, for the same reason as above
+ check(
+ "but does not pick up a change on its own",
+ frame_colour(name) == "#00ff00",
+ str(frame_colour(name)),
+ )
# ...and asking explicitly still works, which is the point of the flag
# being about *watching* rather than about reloading.
- subprocess.run([BIN, "-s", name, "cmd", '{"cmd":"reload"}'],
- capture_output=True)
- check("while asking for a reload still works",
- wait_for_colour(name, "#ff0000") == "#ff0000",
- str(frame_colour(name)))
+ subprocess.run(
+ [BIN, "-s", name, "cmd", '{"cmd":"reload"}'], capture_output=True
+ )
+ check(
+ "while asking for a reload still works",
+ wait_for_colour(name, "#ff0000") == "#ff0000",
+ str(frame_colour(name)),
+ )
finally:
stop(name, p)
if os.path.exists(cfg):