aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--scripts/theme-studio/README.md18
-rwxr-xr-xscripts/theme-studio/run-tests.sh73
3 files changed, 96 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index 7182f617..a1f403e8 100644
--- a/Makefile
+++ b/Makefile
@@ -46,7 +46,7 @@ EMACS_TEST = $(EMACS_BATCH) -L $(TEST_DIR) -L $(MODULE_DIR)
# No colors - using plain text symbols instead
.PHONY: help targets test test-all test-unit test-integration test-file test-name \
- test-bash benchmark coverage coverage-summary coverage-clean \
+ test-bash theme-studio-test benchmark coverage coverage-summary coverage-clean \
validate-parens validate-modules compile compile-file lint profile \
clean clean-compiled clean-tests reset
@@ -66,6 +66,7 @@ help:
@echo " make test-file FILE=<filename> - Run specific test file"
@echo " make test-name TEST=<pattern> - Run tests matching pattern"
@echo " make test-bash - Run the bats shell-script tests ($(words $(BASH_TESTS)) files)"
+ @echo " make theme-studio-test - Run the theme-studio tool tests (Python + Node + browser)"
@echo " make benchmark - Run performance benchmarks (:perf-tagged)"
@echo ""
@echo " Coverage:"
@@ -121,6 +122,9 @@ test-bash:
@echo "[i] Running bats shell-script tests ($(words $(BASH_TESTS)) files)..."
@bats $(BASH_TESTS)
+theme-studio-test:
+ @scripts/theme-studio/run-tests.sh
+
BANNER = ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# Run the .el test files in $(1), each in its own Emacs, with :slow and :perf
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"