diff options
| author | user <user@clank> | 2026-08-14 20:58:48 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-08-14 20:58:48 +0200 |
| commit | 76d2032ff807d536114f46e1a183eeb62eacdc61 (patch) | |
| tree | d88197d2d50ff48c470128e61fee6c44b72735f2 /tests | |
| parent | sl0ppty: find the crossing whichever way the tree is nested (diff) | |
| download | slosh-76d2032ff807d536114f46e1a183eeb62eacdc61.tar.gz slosh-76d2032ff807d536114f46e1a183eeb62eacdc61.tar.xz slosh-76d2032ff807d536114f46e1a183eeb62eacdc61.zip | |
sl0ppty: contrib themes, a way to look at them, and a handover
Six themes, each setting every colour the config knows about. A theme that has
fallen behind silently keeps the compiled-in default for whatever it forgot,
which looks like a bug in the theme rather than a missing line in it, so a test
compares each file against the names config.c actually parses.
contrib/theme-tour applies one to a running session, or cycles the lot. It does
that by writing over the file the session was started with and letting the
config watcher notice, which makes the showcase a demonstration of the watcher
as well.
HANDOVER.md is for the next context. It deliberately does not restate DESIGN.md
or the README; it is the part that was only learnable by getting it wrong —
which state is derived and which is intent and what happens when you confuse
them, the dwell repaint list, that glyph width and glyph weight are different
problems, that settle() in the harness is a sleep in disguise, and that a test
pinned to a coordinate it does not care about will eventually look like a
regression it is not.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/test_themes.py | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/tests/test_themes.py b/tests/test_themes.py new file mode 100644 index 0000000..5e21bc7 --- /dev/null +++ b/tests/test_themes.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 +"""The themes in contrib/. + +Mostly a guard: a theme file that has fallen behind the config silently keeps +the compiled-in default for whatever it forgot, which looks like a bug in the +theme rather than a missing line in it. +""" +import glob +import os +import re +import sys + +from harness import Session, check, report + +SH = ["/bin/sh", "-c", 'printf "\\033]2;p\\007"; stty raw -echo; cat'] +HERE = os.path.dirname(os.path.abspath(__file__)) +THEMES = sorted(glob.glob(os.path.join(HERE, "..", "contrib", "themes", "*.kdl"))) + + +def declared_in_config(): + src = open(os.path.join(HERE, "..", "src", "config.c")).read() + return set(re.findall(r'\{"([a-z_]+)", &c->', src)) + + +def set_by(path): + return set(re.findall(r'^ ([a-z_]+) "', open(path).read(), re.M)) + + +def test_there_are_themes(): + check("contrib ships some", len(THEMES) >= 3, str(THEMES)) + + +def test_each_sets_every_colour_the_config_knows(): + want = declared_in_config() + for t in THEMES: + missing = want - set_by(t) + check(f"{os.path.basename(t)} sets all {len(want)} of them", + not missing, "missing: " + ", ".join(sorted(missing))) + + +def test_each_one_parses_and_reaches_the_screen(): + for t in THEMES: + declared = dict(re.findall(r'^ ([a-z_]+) "(#[0-9a-fA-F]{6})"', + open(t).read(), re.M)) + with Session(SH, cols=50, rows=10, config=os.path.abspath(t)) as s: + s.settle(30) + snap, p = s.snapshot(), s.pane() + drawn = (snap.style_at(p["x"], p["y"] + 1) or {}).get("fg") + check(f"{os.path.basename(t)} draws its own frame colour", + drawn == declared["frame_focus"], + f"{drawn} != {declared['frame_focus']}") + check(f"{os.path.basename(t)} leaves the session alive", s.alive(), "") + + +if __name__ == "__main__": + test_there_are_themes() + test_each_sets_every_colour_the_config_knows() + test_each_one_parses_and_reaches_the_screen() + sys.exit(report()) |
