diff options
| author | Craig Jennings <c@cjennings.net> | 2026-05-07 09:05:54 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-05-07 09:05:54 -0500 |
| commit | 4ece1ebb4487d3e565642e45d586f97172fe97ce (patch) | |
| tree | 5af6afbb683bcae92622b4c70922e5d6d27c6735 /tests | |
| parent | b3ef232a486382601b6788f0c1a1edeb3982075d (diff) | |
| download | dotemacs-4ece1ebb4487d3e565642e45d586f97172fe97ce.tar.gz dotemacs-4ece1ebb4487d3e565642e45d586f97172fe97ce.zip | |
fix: restore daemon icons and consolidate nerd-icons setup
I replaced the load-time icon-stub block in keyboard-compat with per-call :around advice that checks display-graphic-p against the rendering frame. The old block ran at module-load. Under daemon startup no frame exists yet, so display-graphic-p returned nil and the empty-string stubs installed permanently. Every GUI client connecting to that daemon then saw blanks. The new shape lets one daemon serve real icons to GUI clients and blanks to terminal clients.
I also pulled the nerd-icons-completion and nerd-icons-ibuffer integrations, the package install, and a new tint helper into modules/nerd-icons-config.el. Per-feature use stays in the consuming module (dashboard, dirvish, keyboard-compat). The malformed cons-cell on the marginalia hook in selection-framework.el got fixed in the move.
Added a default darkgoldenrod tint, a :filter-return advice on nerd-icons-icon-for-dir so dir icons pick up a color face, and a buffer-local face-remap in dired-mode-hook so plain files in dired render in shadow grey.
13 tests across 3 new files cover the per-call gate, the dir-color helper (idempotent under nerd-icons' memoized return strings), and the bulk-tint helper.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/test-keyboard-compat--icon-blank-in-terminal.el | 54 | ||||
| -rw-r--r-- | tests/test-nerd-icons-config--apply-tint.el | 63 | ||||
| -rw-r--r-- | tests/test-nerd-icons-config--color-dir.el | 57 |
3 files changed, 174 insertions, 0 deletions
diff --git a/tests/test-keyboard-compat--icon-blank-in-terminal.el b/tests/test-keyboard-compat--icon-blank-in-terminal.el new file mode 100644 index 00000000..db2bb6b7 --- /dev/null +++ b/tests/test-keyboard-compat--icon-blank-in-terminal.el @@ -0,0 +1,54 @@ +;;; test-keyboard-compat--icon-blank-in-terminal.el --- Tests for cj/--icon-blank-in-terminal -*- lexical-binding: t; -*- + +;;; Commentary: +;; Tests for the per-call icon-rendering gate that replaced the load-time +;; defun-redefinition. The helper must dispatch on the current frame's +;; `display-graphic-p' so the same daemon can serve real icons to GUI frames +;; and blanks to terminal frames. + +;;; Code: + +(require 'ert) +(require 'cl-lib) + +(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory)) +(require 'keyboard-compat) + +(defmacro test-keyboard-compat--with-graphic-p (graphic-p &rest body) + "Run BODY with `display-graphic-p' stubbed to GRAPHIC-P." + (declare (indent 1) (debug t)) + `(cl-letf (((symbol-function 'display-graphic-p) + (lambda (&optional _) ,graphic-p))) + ,@body)) + +(ert-deftest test-keyboard-compat--icon-blank-in-terminal-passes-through-on-gui () + "Normal: returns ORIG's value when display-graphic-p is non-nil." + (test-keyboard-compat--with-graphic-p t + (let ((orig (lambda (&rest _) "ICON"))) + (should (equal (cj/--icon-blank-in-terminal orig "foo.txt") "ICON"))))) + +(ert-deftest test-keyboard-compat--icon-blank-in-terminal-blank-on-terminal () + "Boundary: returns empty string when display-graphic-p is nil." + (test-keyboard-compat--with-graphic-p nil + (let ((orig (lambda (&rest _) "ICON"))) + (should (equal (cj/--icon-blank-in-terminal orig "foo.txt") ""))))) + +(ert-deftest test-keyboard-compat--icon-blank-in-terminal-forwards-args () + "Normal: forwards all ARGS to ORIG when graphical." + (test-keyboard-compat--with-graphic-p t + (let ((received nil)) + (cj/--icon-blank-in-terminal + (lambda (&rest args) (setq received args) "ok") + 'a 'b 'c) + (should (equal received '(a b c)))))) + +(ert-deftest test-keyboard-compat--icon-blank-in-terminal-does-not-call-orig-on-terminal () + "Error: ORIG must not be invoked when display-graphic-p is nil." + (test-keyboard-compat--with-graphic-p nil + (let ((called nil)) + (cj/--icon-blank-in-terminal + (lambda (&rest _) (setq called t) "ICON")) + (should-not called)))) + +(provide 'test-keyboard-compat--icon-blank-in-terminal) +;;; test-keyboard-compat--icon-blank-in-terminal.el ends here diff --git a/tests/test-nerd-icons-config--apply-tint.el b/tests/test-nerd-icons-config--apply-tint.el new file mode 100644 index 00000000..ef723352 --- /dev/null +++ b/tests/test-nerd-icons-config--apply-tint.el @@ -0,0 +1,63 @@ +;;; test-nerd-icons-config--apply-tint.el --- Tests for cj/nerd-icons-apply-tint -*- lexical-binding: t; -*- + +;;; Commentary: +;; Tests for the bulk-tint helper. Mocks `set-face-foreground' and `facep' +;; at the framework boundary so the tests don't depend on nerd-icons being +;; loaded — only on the symbol list and the dispatch logic. + +;;; Code: + +(require 'ert) +(require 'cl-lib) + +(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory)) +(require 'nerd-icons-config) + +(defmacro test-nerd-icons-config--capture-set-face-foreground (calls-var &rest body) + "Run BODY with `set-face-foreground' and `facep' stubbed. +Each (face color) pair gets pushed onto CALLS-VAR. `facep' returns t +for every symbol so all faces in the list count as defined." + (declare (indent 1) (debug t)) + `(cl-letf (((symbol-function 'set-face-foreground) + (lambda (face color &rest _) (push (cons face color) ,calls-var))) + ((symbol-function 'facep) + (lambda (_) t))) + ,@body)) + +(ert-deftest test-nerd-icons-config--apply-tint-covers-every-face () + "Normal: apply-tint calls set-face-foreground once per face in the list." + (let ((calls nil)) + (test-nerd-icons-config--capture-set-face-foreground calls + (cj/nerd-icons-apply-tint "test-color")) + (should (= (length calls) (length cj/--nerd-icons-color-faces))) + (dolist (face cj/--nerd-icons-color-faces) + (should (assq face calls))))) + +(ert-deftest test-nerd-icons-config--apply-tint-passes-color-arg () + "Normal: apply-tint forwards COLOR to every set-face-foreground call." + (let ((calls nil)) + (test-nerd-icons-config--capture-set-face-foreground calls + (cj/nerd-icons-apply-tint "rebeccapurple")) + (dolist (call calls) + (should (equal (cdr call) "rebeccapurple"))))) + +(ert-deftest test-nerd-icons-config--apply-tint-defaults-to-customvar () + "Normal: with no COLOR arg, uses `cj/nerd-icons-tint-color'." + (let ((calls nil)) + (test-nerd-icons-config--capture-set-face-foreground calls + (let ((cj/nerd-icons-tint-color "default-test-color")) + (cj/nerd-icons-apply-tint))) + (should (cl-every (lambda (call) (equal (cdr call) "default-test-color")) calls)))) + +(ert-deftest test-nerd-icons-config--apply-tint-skips-undefined-faces () + "Boundary: faces that fail `facep' are silently skipped, not errored." + (let ((calls nil)) + (cl-letf (((symbol-function 'set-face-foreground) + (lambda (face color &rest _) (push (cons face color) calls))) + ((symbol-function 'facep) + (lambda (_) nil))) + (cj/nerd-icons-apply-tint "any")) + (should (null calls)))) + +(provide 'test-nerd-icons-config--apply-tint) +;;; test-nerd-icons-config--apply-tint.el ends here diff --git a/tests/test-nerd-icons-config--color-dir.el b/tests/test-nerd-icons-config--color-dir.el new file mode 100644 index 00000000..808c0dc3 --- /dev/null +++ b/tests/test-nerd-icons-config--color-dir.el @@ -0,0 +1,57 @@ +;;; test-nerd-icons-config--color-dir.el --- Tests for cj/--nerd-icons-color-dir -*- lexical-binding: t; -*- + +;;; Commentary: +;; Tests for the :filter-return advice that attaches a color face to the +;; output of `nerd-icons-icon-for-dir'. Without this, directory icons render +;; in the buffer default face — so a face-remap of `default' (buffer-local +;; or global) catches the icons unintentionally. + +;;; Code: + +(require 'ert) +(require 'cl-lib) + +(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory)) +(require 'nerd-icons-config) + +(ert-deftest test-nerd-icons-config--color-dir-attaches-face () + "Normal: adds nerd-icons-yellow to the face stack of a propertized icon." + (let ((icon (propertize "X" 'face '(:family "Symbols Nerd Font Mono" :height 1.0)))) + (let ((result (cj/--nerd-icons-color-dir icon))) + (should (memq 'nerd-icons-yellow + (ensure-list (get-text-property 0 'face result))))))) + +(ert-deftest test-nerd-icons-config--color-dir-preserves-family () + "Normal: retains the original :family / :height attributes." + (let ((icon (propertize "X" 'face '(:family "Symbols Nerd Font Mono" :height 1.0)))) + (let* ((result (cj/--nerd-icons-color-dir icon)) + (face (get-text-property 0 'face result)) + (specs (ensure-list face)) + (plist (seq-find (lambda (x) (and (listp x) (plist-member x :family))) specs))) + (should (equal (plist-get plist :family) "Symbols Nerd Font Mono")) + (should (equal (plist-get plist :height) 1.0))))) + +(ert-deftest test-nerd-icons-config--color-dir-empty-string () + "Boundary: an empty icon string returns unchanged (no range to propertize)." + (let ((icon "")) + (should (equal (cj/--nerd-icons-color-dir icon) "")))) + +(ert-deftest test-nerd-icons-config--color-dir-non-string-passthrough () + "Error: a nil input returns nil rather than erroring." + (should-not (cj/--nerd-icons-color-dir nil))) + +(ert-deftest test-nerd-icons-config--color-dir-idempotent () + "Boundary: calling twice on the same icon adds the face only once. +nerd-icons memoizes its return strings — without this guard, repeated +renders would stack `nerd-icons-yellow' over and over on the cached string." + (let ((icon (propertize "X" 'face '(:family "Symbols Nerd Font Mono" :height 1.0)))) + (cj/--nerd-icons-color-dir icon) + (cj/--nerd-icons-color-dir icon) + (cj/--nerd-icons-color-dir icon) + (let* ((face (get-text-property 0 'face icon)) + (specs (ensure-list face)) + (yellows (cl-count 'nerd-icons-yellow specs))) + (should (= yellows 1))))) + +(provide 'test-nerd-icons-config--color-dir) +;;; test-nerd-icons-config--color-dir.el ends here |
