aboutsummaryrefslogtreecommitdiffstats
path: root/tests/test_kittygfx.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_kittygfx.py')
-rw-r--r--tests/test_kittygfx.py153
1 files changed, 100 insertions, 53 deletions
diff --git a/tests/test_kittygfx.py b/tests/test_kittygfx.py
index 38d361c..270b4e7 100644
--- a/tests/test_kittygfx.py
+++ b/tests/test_kittygfx.py
@@ -55,8 +55,11 @@ class Tty:
def cmds(self, action):
"""Every graphics command with the given ``a=`` action."""
- return [c for c in re.findall(r"\x1b_G([^;\x1b]*)", self.blob)
- if f"a={action}" in c.split(",")]
+ return [
+ c
+ for c in re.findall(r"\x1b_G([^;\x1b]*)", self.blob)
+ if f"a={action}" in c.split(",")
+ ]
def keys(cmd):
@@ -76,8 +79,7 @@ def t_no_termios_falls_back():
try:
check("missing termios disables graphics", kittygfx._query_tty(0) is False)
except Exception as exc: # the original Windows startup crash
- check("missing termios does not escape", False,
- f"{type(exc).__name__}: {exc}")
+ check("missing termios does not escape", False, f"{type(exc).__name__}: {exc}")
finally:
builtins.__import__ = original_import
@@ -103,8 +105,7 @@ def t_probe_failure_is_never_fatal():
check("probe exception disables graphics", kittygfx.supported() is False)
check("failed result is cached", kittygfx.supported() is False)
except Exception as exc:
- check("probe exception does not escape", False,
- f"{type(exc).__name__}: {exc}")
+ check("probe exception does not escape", False, f"{type(exc).__name__}: {exc}")
finally:
kittygfx._query_tty = original_query
kittygfx._supported = original_supported
@@ -118,7 +119,7 @@ def main() -> int:
t_no_termios_falls_back()
t_probe_failure_is_never_fatal()
- kittygfx._uploaded[kittygfx.LOGO_ID] = (768, 801) # pretend it's uploaded
+ kittygfx._uploaded[kittygfx.LOGO_ID] = (768, 801) # pretend it's uploaded
# -- the bug: anonymous placements STACK ------------------------------- #
# A placement is identified by (image id, placement id). With no p key
@@ -128,80 +129,126 @@ def main() -> int:
for _ in range(50):
kittygfx.place(4, 10, 60, 26)
placements = tty.cmds("p")
- check("place() emits one command per call", len(placements) == 50,
- f"{len(placements)}")
- check("every placement carries a placement id (replaces, not stacks)",
- all("p" in keys(c) for c in placements),
- f"{placements[0] if placements else '(none)'}")
- check("the placement id is the same every time (one image on screen)",
- len({keys(c)["p"] for c in placements}) == 1,
- f"{sorted({keys(c).get('p') for c in placements})}")
- check("...and it is non-zero (p=0 means anonymous)",
- keys(placements[0])["p"] not in ("0", ""), f"{placements[0]}")
+ check(
+ "place() emits one command per call",
+ len(placements) == 50,
+ f"{len(placements)}",
+ )
+ check(
+ "every placement carries a placement id (replaces, not stacks)",
+ all("p" in keys(c) for c in placements),
+ f"{placements[0] if placements else '(none)'}",
+ )
+ check(
+ "the placement id is the same every time (one image on screen)",
+ len({keys(c)["p"] for c in placements}) == 1,
+ f"{sorted({keys(c).get('p') for c in placements})}",
+ )
+ check(
+ "...and it is non-zero (p=0 means anonymous)",
+ keys(placements[0])["p"] not in ("0", ""),
+ f"{placements[0]}",
+ )
# -- the rest of the escape still says what it used to ------------------ #
with Tty() as tty:
ok = kittygfx.place(4, 10, 60, 26)
k = keys(tty.cmds("p")[0])
check("place() reports success", ok)
- check("image id, source pixels and cell box are unchanged",
- (k["i"], k["s"], k["v"], k["c"], k["r"])
- == (str(kittygfx.LOGO_ID), "768", "801", "60", "26"), f"{k}")
- check("the terminal is told not to move the cursor (C=1)",
- k.get("C") == "1", f"{k}")
- check("the cursor is saved and restored around the placement",
- tty.blob.startswith("\x1b[s") and tty.blob.endswith("\x1b[u"),
- repr(tty.blob[:8] + "..." + tty.blob[-8:]))
- check("the placement is positioned 1-based (row 4 -> line 5)",
- "\x1b[5;11H" in tty.blob, repr(tty.blob[:24]))
+ check(
+ "image id, source pixels and cell box are unchanged",
+ (k["i"], k["s"], k["v"], k["c"], k["r"])
+ == (str(kittygfx.LOGO_ID), "768", "801", "60", "26"),
+ f"{k}",
+ )
+ check(
+ "the terminal is told not to move the cursor (C=1)",
+ k.get("C") == "1",
+ f"{k}",
+ )
+ check(
+ "the cursor is saved and restored around the placement",
+ tty.blob.startswith("\x1b[s") and tty.blob.endswith("\x1b[u"),
+ repr(tty.blob[:8] + "..." + tty.blob[-8:]),
+ )
+ check(
+ "the placement is positioned 1-based (row 4 -> line 5)",
+ "\x1b[5;11H" in tty.blob,
+ repr(tty.blob[:24]),
+ )
# -- deleting still removes EVERY placement of the image ---------------- #
# d=i is by image id, so it takes the placement with us regardless of p.
with Tty() as tty:
kittygfx.clear()
k = keys(tty.cmds("d")[0])
- check("clear() deletes by image id (d=i), keeping the upload",
- k.get("d") == "i" and k.get("i") == str(kittygfx.LOGO_ID), f"{k}")
- check("clear() does not free the image data (lowercase d)",
- kittygfx.is_uploaded(), "upload was dropped")
+ check(
+ "clear() deletes by image id (d=i), keeping the upload",
+ k.get("d") == "i" and k.get("i") == str(kittygfx.LOGO_ID),
+ f"{k}",
+ )
+ check(
+ "clear() does not free the image data (lowercase d)",
+ kittygfx.is_uploaded(),
+ "upload was dropped",
+ )
with Tty() as tty:
kittygfx.delete()
k = keys(tty.cmds("d")[0])
check("delete() frees the image data too (d=I)", k.get("d") == "I", f"{k}")
- check("...and forgets the upload, so the next place() refuses",
- not kittygfx.is_uploaded() and kittygfx.place(0, 0, 10, 10) is False)
+ check(
+ "...and forgets the upload, so the next place() refuses",
+ not kittygfx.is_uploaded() and kittygfx.place(0, 0, 10, 10) is False,
+ )
# -- refusals ----------------------------------------------------------- #
kittygfx._uploaded[kittygfx.LOGO_ID] = (768, 801)
with Tty() as tty:
- check("a zero-sized box is refused, not sent",
- kittygfx.place(0, 0, 0, 10) is False
- and kittygfx.place(0, 0, 10, 0) is False and not tty.sent,
- f"{tty.sent}")
+ check(
+ "a zero-sized box is refused, not sent",
+ kittygfx.place(0, 0, 0, 10) is False
+ and kittygfx.place(0, 0, 10, 0) is False
+ and not tty.sent,
+ f"{tty.sent}",
+ )
kittygfx._uploaded.pop(kittygfx.LOGO_ID, None)
# -- fit(): aspect ratio against non-square cells ----------------------- #
- check("fit() keeps the aspect ratio for 9x22 cells",
- kittygfx.fit((768, 801), 60, 99, cell=(9, 22)) == (60, 26),
- f"{kittygfx.fit((768, 801), 60, 99, cell=(9, 22))}")
- check("fit() shrinks to the row budget instead of overflowing",
- kittygfx.fit((768, 801), 60, 10, cell=(9, 22))[1] == 10,
- f"{kittygfx.fit((768, 801), 60, 10, cell=(9, 22))}")
- check("fit() never returns a zero dimension",
- all(v >= 1 for v in kittygfx.fit((768, 801), 1, 1, cell=(9, 22))))
- check("fit() survives a degenerate image size",
- kittygfx.fit((0, 0), 60, 26) == (60, 26))
+ check(
+ "fit() keeps the aspect ratio for 9x22 cells",
+ kittygfx.fit((768, 801), 60, 99, cell=(9, 22)) == (60, 26),
+ f"{kittygfx.fit((768, 801), 60, 99, cell=(9, 22))}",
+ )
+ check(
+ "fit() shrinks to the row budget instead of overflowing",
+ kittygfx.fit((768, 801), 60, 10, cell=(9, 22))[1] == 10,
+ f"{kittygfx.fit((768, 801), 60, 10, cell=(9, 22))}",
+ )
+ check(
+ "fit() never returns a zero dimension",
+ all(v >= 1 for v in kittygfx.fit((768, 801), 1, 1, cell=(9, 22))),
+ )
+ check(
+ "fit() survives a degenerate image size",
+ kittygfx.fit((0, 0), 60, 26) == (60, 26),
+ )
# -- png_size() reads the header, not the pixels ------------------------ #
- logo = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
- "logo.png")
+ logo = os.path.join(
+ os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "logo.png"
+ )
if os.path.exists(logo):
- check("png_size() reads logo.png's IHDR",
- kittygfx.png_size(logo) == (768, 801), f"{kittygfx.png_size(logo)}")
+ check(
+ "png_size() reads logo.png's IHDR",
+ kittygfx.png_size(logo) == (768, 801),
+ f"{kittygfx.png_size(logo)}",
+ )
check("png_size() returns None for a non-PNG", kittygfx.png_size(__file__) is None)
- check("png_size() returns None for a missing file",
- kittygfx.png_size("/nonexistent/nope.png") is None)
+ check(
+ "png_size() returns None for a missing file",
+ kittygfx.png_size("/nonexistent/nope.png") is None,
+ )
print(f"\n{PASS} passed, {FAIL} failed")
return 1 if FAIL else 0