diff options
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/theme-studio/README.md | 18 | ||||
| -rwxr-xr-x | scripts/theme-studio/run-tests.sh | 73 |
2 files changed, 91 insertions, 0 deletions
diff --git a/scripts/theme-studio/README.md b/scripts/theme-studio/README.md index 68d74815..044ccc2e 100644 --- a/scripts/theme-studio/README.md +++ b/scripts/theme-studio/README.md @@ -30,6 +30,24 @@ During color work, disable Hyprland inactive-window dimming so colors read true: hyprctl keyword decoration:dim_inactive false ``` +## Tests + +```bash +make theme-studio-test # from the repo root, runs the whole pyramid +scripts/theme-studio/run-tests.sh # or call the runner directly +``` + +The runner regenerates the page, runs the Python templating tests +(`test_generate.py`), the Node unit tests for `colormath.js` +(`test-colormath.mjs`, including the inline-integrity check), a syntax check of +the spliced page script, and the browser hash gates in headless Chrome +(`#selftest`, `#cursortest`, `#readouttest`, `#deltatest`, `#oklchtest`, +`#planetest`). It exits non-zero on any failure. The browser gates need a +Chromium-family browser; without one they report SKIPPED rather than passing +silently. The pure color math and the extracted picker logic (`planeCell`, +`paletteWarnings`) live in `colormath.js` so they are unit-tested directly in +Node; the DOM glue is covered by the browser hash gates. + ## Files - `generate.py` — emits the HTML+JS, and embeds the package data. Edit here to diff --git a/scripts/theme-studio/run-tests.sh b/scripts/theme-studio/run-tests.sh new file mode 100755 index 00000000..b1fe54fa --- /dev/null +++ b/scripts/theme-studio/run-tests.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash +# Test runner for the theme-studio tool. Drives the whole pyramid in one command: +# - regenerate theme-studio.html from generate.py +# - Python templating tests (export-strip + placeholder substitution) +# - Node unit tests for colormath.js (+ inline-integrity) +# - syntax-check the spliced page <script> +# - browser hash gates in headless Chrome (#selftest and the metric tests) +# +# Exit status is non-zero if any stage fails. Browser gates need a Chromium-family +# browser; when none is found they are reported as SKIPPED (not passed) so the +# gap is visible rather than silently green. +# +# Usage: scripts/theme-studio/run-tests.sh (or: make theme-studio-test) +set -uo pipefail + +HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$HERE" + +fail=0 +pass_msg() { printf ' PASS %s\n' "$1"; } +fail_msg() { printf ' FAIL %s\n' "$1"; fail=1; } +skip_msg() { printf ' SKIP %s\n' "$1"; } + +echo "theme-studio tests" + +# 1. Regenerate the page (the browser gates and inline-integrity read it). +if python3 generate.py >/dev/null; then pass_msg "generate.py wrote theme-studio.html" +else fail_msg "generate.py failed"; fi + +# 2. Python templating tests. +if python3 -m unittest test_generate >/tmp/ts-pytest.log 2>&1; then + pass_msg "Python templating tests ($(grep -oE 'Ran [0-9]+' /tmp/ts-pytest.log | awk '{print $2}') tests)" +else fail_msg "Python templating tests"; sed 's/^/ /' /tmp/ts-pytest.log; fi + +# 3. Node unit tests + inline-integrity. Node 26 broke `--test <dir>`; glob the files. +if node --test ./*.mjs >/tmp/ts-node.log 2>&1; then + pass_msg "Node unit tests ($(grep -E '^. tests' /tmp/ts-node.log | grep -oE '[0-9]+' | head -1) tests)" +else fail_msg "Node unit tests"; grep -E 'not ok|AssertionError|Error' /tmp/ts-node.log | sed 's/^/ /' | head -20; fi + +# 4. Syntax-check the inlined page script. +python3 - <<'PY' && node --check /tmp/ts-script.js >/dev/null 2>&1 && pass_msg "spliced page <script> parses" || fail_msg "spliced page <script> syntax" +import re +h = open('theme-studio.html').read() +open('/tmp/ts-script.js', 'w').write(re.search(r'<script>(.*)</script>', h, re.S).group(1)) +PY + +# 5. Browser hash gates. +CHROME="" +for c in google-chrome-stable google-chrome chromium chromium-browser; do + if command -v "$c" >/dev/null 2>&1; then CHROME="$c"; break; fi +done +HASHES="selftest cursortest readouttest deltatest oklchtest planetest" +if [ -z "$CHROME" ]; then + for t in $HASHES; do skip_msg "#$t (no Chromium-family browser found)"; done +else + PROF="$(mktemp -d)" + trap 'rm -rf "$PROF"' EXIT + for t in $HASHES; do + upper="$(echo "$t" | tr '[:lower:]' '[:upper:]')" + res="$("$CHROME" --headless --no-sandbox --disable-gpu --user-data-dir="$PROF" \ + --virtual-time-budget=8000 --dump-dom "file://$HERE/theme-studio.html#$t" 2>/dev/null \ + | grep -o "${upper}[^<]*" | head -1)" + case "$res" in + *PASS*) pass_msg "#$t" ;; + *FAIL*) fail_msg "#$t -> $res" ;; + *) fail_msg "#$t -> no verdict (browser did not run the test)" ;; + esac + done +fi + +echo +if [ "$fail" -eq 0 ]; then echo "all stages green"; else echo "FAILURES above"; fi +exit "$fail" |
