aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/gallery-widgets/test-gallery-widget.el114
1 files changed, 114 insertions, 0 deletions
diff --git a/tests/gallery-widgets/test-gallery-widget.el b/tests/gallery-widgets/test-gallery-widget.el
new file mode 100644
index 0000000..ec484bb
--- /dev/null
+++ b/tests/gallery-widgets/test-gallery-widget.el
@@ -0,0 +1,114 @@
+;;; test-gallery-widget.el --- ERT tests for gallery-widget.el -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; Tests for the svg.el proof-of-concept renderer in docs/prototypes/.
+;; gallery-widget.el reads the generated tokens.el (same source of truth as
+;; the web gallery and the waybar CSS) and renders gallery widgets as SVG.
+;; These tests exercise the REAL module (loaded by path, not a copy):
+;; token resolution, needle-angle math (normal/boundary/error), and the
+;; rendered SVG document's structure.
+;;
+;; Run from repo root:
+;; make test-elisp
+;; (or emacs --batch -l ert -l tests/gallery-widgets/test-gallery-widget.el \
+;; -f ert-run-tests-batch-and-exit)
+
+;;; Code:
+
+(require 'ert)
+(require 'cl-lib)
+
+(defvar test-gallery-widget--root
+ (expand-file-name "../.." (file-name-directory (or load-file-name buffer-file-name)))
+ "Repo root, derived from this test file's location.")
+
+(load (expand-file-name "docs/prototypes/gallery-widget.el" test-gallery-widget--root))
+
+;;; --- token access ---
+
+(ert-deftest gallery-widget-token-resolves-hex ()
+ "Known tokens resolve to hex color strings from the generated alist."
+ (should (string-match-p "\\`#[0-9a-f]\\{6\\}\\'" (gallery-widget-token 'gold)))
+ (should (string-match-p "\\`#[0-9a-f]\\{6\\}\\'" (gallery-widget-token 'glow-hi)))
+ (should (string-match-p "\\`#[0-9a-f]\\{6\\}\\'" (gallery-widget-token 'wash))))
+
+(ert-deftest gallery-widget-token-missing-errors ()
+ "An unknown token name signals an error rather than returning nil."
+ (should-error (gallery-widget-token 'no-such-token)))
+
+;;; --- needle angle math ---
+
+(ert-deftest gallery-widget-needle-angle-normal ()
+ "0..100 maps linearly onto -60..+60 degrees."
+ (should (= (gallery-widget--needle-angle 0) -60.0))
+ (should (= (gallery-widget--needle-angle 50) 0.0))
+ (should (= (gallery-widget--needle-angle 100) 60.0)))
+
+(ert-deftest gallery-widget-needle-angle-boundary-clamps ()
+ "Out-of-range values clamp to the dial's ends instead of overswinging."
+ (should (= (gallery-widget--needle-angle -5) -60.0))
+ (should (= (gallery-widget--needle-angle 150) 60.0)))
+
+(ert-deftest gallery-widget-needle-angle-error-non-number ()
+ "A non-numeric value signals an error."
+ (should-error (gallery-widget--needle-angle "fifty"))
+ (should-error (gallery-widget--needle-angle nil)))
+
+;;; --- rendered SVG structure ---
+
+(defun test-gallery-widget--svg-string (value)
+ "Render the needle gauge at VALUE and return its XML string."
+ (gallery-widget-svg-string (gallery-widget-needle-gauge value)))
+
+(ert-deftest gallery-widget-gauge-renders-svg-document ()
+ "The gauge renders to a parseable SVG document."
+ (let ((xml (test-gallery-widget--svg-string 42)))
+ (should (string-match-p "\\`<svg" xml))
+ (should (with-temp-buffer
+ (insert xml)
+ (libxml-parse-xml-region (point-min) (point-max))))))
+
+(ert-deftest gallery-widget-gauge-has-expected-parts ()
+ "Arc, three ticks, needle, hub, and value text are all present."
+ (let ((xml (test-gallery-widget--svg-string 42)))
+ ;; arc path stroked in the wash token
+ (should (string-match-p (format "path[^>]*stroke=\"%s\"" (gallery-widget-token 'wash)) xml))
+ ;; exactly three ticks
+ (should (= 3 (cl-count-if (lambda (_) t)
+ (split-string xml "class=\"tick\"" t)
+ :start 1)))
+ ;; needle + hub in the amber tokens
+ (should (string-match-p (format "class=\"needle\"[^>]*stroke=\"%s\""
+ (gallery-widget-token 'gold-hi))
+ xml))
+ ;; hub is a half-dome sitting on the dial's bottom edge, like the web card
+ (should (string-match-p (format "class=\"hub\"[^>]*fill=\"%s\""
+ (gallery-widget-token 'gold))
+ xml))
+ (should (string-match-p "class=\"hub\"[^>]*d=\"M 44 48 A 4 4 0 0 1 52 48 Z\"" xml))
+ ;; value readout
+ (should (string-match-p ">42%<" xml))))
+
+(ert-deftest gallery-widget-gauge-has-glow-filter ()
+ "The needle glow is a real SVG blur filter, not a dropped effect."
+ (let ((xml (test-gallery-widget--svg-string 42)))
+ (should (string-match-p "feGaussianBlur" xml))
+ (should (string-match-p "filter=\"url(#" xml))))
+
+(ert-deftest gallery-widget-gauge-needle-tracks-value ()
+ "The needle endpoint lands where the angle math says: left at 0, up at 50, right at 100."
+ ;; value 50 -> vertical: x2 = pivot x (48), y2 = 48 - 40 = 8
+ (let ((xml (test-gallery-widget--svg-string 50)))
+ (should (string-match-p "class=\"needle\"[^>]*x2=\"48.0+\"" xml))
+ (should (string-match-p "class=\"needle\"[^>]*y2=\"8.0+\"" xml)))
+ ;; value 100 -> +60 deg: x2 = 48 + 40*sin60 ~ 82.64
+ (should (string-match-p "x2=\"82.6" (test-gallery-widget--svg-string 100)))
+ ;; value 0 -> -60 deg: x2 = 48 - 40*sin60 ~ 13.36
+ (should (string-match-p "x2=\"13.3" (test-gallery-widget--svg-string 0))))
+
+(ert-deftest gallery-widget-gauge-integer-percent-in-readout ()
+ "The readout shows a rounded integer percent, matching the web card."
+ (should (string-match-p ">67%<" (test-gallery-widget--svg-string 66.6))))
+
+(provide 'test-gallery-widget)
+;;; test-gallery-widget.el ends here