aboutsummaryrefslogtreecommitdiff
path: root/tests/gallery-widgets
diff options
context:
space:
mode:
Diffstat (limited to 'tests/gallery-widgets')
-rw-r--r--tests/gallery-widgets/test-gallery-widget.el78
1 files changed, 74 insertions, 4 deletions
diff --git a/tests/gallery-widgets/test-gallery-widget.el b/tests/gallery-widgets/test-gallery-widget.el
index 166cd59..9a3c29f 100644
--- a/tests/gallery-widgets/test-gallery-widget.el
+++ b/tests/gallery-widgets/test-gallery-widget.el
@@ -54,6 +54,26 @@
(should-error (gallery-widget--needle-angle "fifty"))
(should-error (gallery-widget--needle-angle nil)))
+;;; --- shared SVG geometry ---
+
+(ert-deftest gallery-widget-semicircle-path-normal ()
+ "A semicircle path is derived from center and radius, not copied literals."
+ (should (equal (gallery-widget--semicircle-path 48 48 47)
+ "M 1 48 A 47 47 0 0 1 95 48")))
+
+(ert-deftest gallery-widget-semicircle-path-can-close-a-hub ()
+ "The same geometry helper closes the smaller half-dome hub."
+ (should (equal (gallery-widget--semicircle-path 48 48 4 t)
+ "M 44 48 A 4 4 0 0 1 52 48 Z")))
+
+(ert-deftest gallery-widget-source-uses-only-public-dom-append ()
+ "The renderer must not depend on svg.el's private `svg--append' API."
+ (with-temp-buffer
+ (insert-file-contents
+ (expand-file-name "docs/prototypes/gallery-widget.el"
+ test-gallery-widget--root))
+ (should-not (search-forward "svg--append" nil t))))
+
;;; --- rendered SVG structure ---
(defun test-gallery-widget--svg-string (value)
@@ -73,10 +93,12 @@
(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)))
+ ;; exactly three ticks, counted as direct occurrences (the earlier
+ ;; split-string arithmetic depended on omit-nulls edge behavior)
+ (should (= 3 (let ((n 0) (pos 0))
+ (while (string-match "class=\"tick\"" xml pos)
+ (setq n (1+ n) pos (match-end 0)))
+ n)))
;; needle + hub in the amber tokens
(should (string-match-p (format "class=\"needle\"[^>]*stroke=\"%s\""
(gallery-widget-token 'gold-hi))
@@ -110,5 +132,53 @@
"The readout shows a rounded integer percent, matching the web card."
(should (string-match-p ">67%<" (test-gallery-widget--svg-string 66.6))))
+(ert-deftest gallery-widget-gauge-out-of-range-readout-clamps ()
+ "Readout and needle agree at out-of-range values: both clamp.
+Regression: the needle clamped to the dial ends while the readout rendered
+the raw value, so a gauge fed 150 pinned the needle at +60 degrees under a
+\"150%\" label."
+ (let ((over (test-gallery-widget--svg-string 150)))
+ (should (string-match-p ">100%<" over))
+ (should-not (string-match-p ">150%<" over)))
+ (let ((under (test-gallery-widget--svg-string -5)))
+ (should (string-match-p ">0%<" under))
+ (should-not (string-match-p ">-5%<" under))))
+
+(ert-deftest gallery-widget-source-dir-load-and-fallback ()
+ "The token-file directory resolves from load context, else default-directory.
+Regression: `file-name-directory' received nil when the load form was re-evaluated
+outside a load and outside a file buffer."
+ (let ((load-file-name "/tmp/proto/gallery-widget.el"))
+ (should (equal (gallery-widget--source-dir) "/tmp/proto/")))
+ (with-temp-buffer
+ (let ((load-file-name nil)
+ (default-directory "/tmp/elsewhere/"))
+ (should (equal (gallery-widget--source-dir) "/tmp/elsewhere/")))))
+
+(ert-deftest gallery-widget-write-svg-writes-file-and-returns-path ()
+ "The output helper writes the SVG document and returns the path."
+ (let ((file (make-temp-file "gallery-widget-test-" nil ".svg")))
+ (unwind-protect
+ (let ((ret (gallery-widget-write-svg
+ (gallery-widget-needle-gauge 42) file)))
+ (should (equal ret file))
+ (should (file-exists-p file))
+ (with-temp-buffer
+ (insert-file-contents file)
+ (should (string-match-p "\\`<svg" (buffer-string)))))
+ (delete-file file))))
+
+(ert-deftest gallery-widget-requires-cl-lib-at-load-time ()
+ "Loading the module alone brings in cl-lib, not just an autoload cookie.
+A cold byte-compile or a changed autoload would otherwise break
+`gallery-widget--node' with a void-function error on first call."
+ (with-temp-buffer
+ (let ((emacs (expand-file-name invocation-name invocation-directory))
+ (widget (expand-file-name "docs/prototypes/gallery-widget.el"
+ test-gallery-widget--root)))
+ (call-process emacs nil t nil "--batch" "-l" widget
+ "--eval" "(princ (if (featurep 'cl-lib) \"cl-lib:yes\" \"cl-lib:no\"))")
+ (should (string-match-p "cl-lib:yes" (buffer-string))))))
+
(provide 'test-gallery-widget)
;;; test-gallery-widget.el ends here