aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-05-22 19:00:36 -0500
committerCraig Jennings <c@cjennings.net>2026-05-22 19:00:36 -0500
commit5c160bd5f33b0e27ecac32af99f650ea50d844fe (patch)
tree4370bd67c5ef524acc351edd39d1fa2d43048cc8 /tests
parentda5f5d9470657eeffef64afad5e60c3224e481c8 (diff)
downloaddotemacs-5c160bd5f33b0e27ecac32af99f650ea50d844fe.tar.gz
dotemacs-5c160bd5f33b0e27ecac32af99f650ea50d844fe.zip
refactor(dashboard): derive the navigator and keybindings from one launcher table
The 12 dashboard launchers were inlined twice (once as navigator icon buttons, once as dashboard-mode-map keybindings), so adding or reordering one meant editing both lists, and the icon-row order could drift from the key order. I pulled them into a single cj/dashboard--launchers table of (KEY ICON-FN ICON-NAME LABEL TOOLTIP ACTION) tuples. cj/dashboard--navigator-rows chunks it four per row into the navigator buttons, and cj/dashboard--bind-launchers binds each key to its action. The icons and the keys now come from one place, with no behavior change: same icons, labels, order, and keys, locked by tests.
Diffstat (limited to 'tests')
-rw-r--r--tests/test-dashboard-config-launchers.el97
1 files changed, 97 insertions, 0 deletions
diff --git a/tests/test-dashboard-config-launchers.el b/tests/test-dashboard-config-launchers.el
new file mode 100644
index 00000000..633d6612
--- /dev/null
+++ b/tests/test-dashboard-config-launchers.el
@@ -0,0 +1,97 @@
+;;; test-dashboard-config-launchers.el --- Tests for the dashboard launcher table -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; Locks the single-source launcher table that drives both the dashboard
+;; navigator icon rows and the dashboard-mode-map keybindings. The bug this
+;; guards against: the icon row and the keymap were maintained as two separate
+;; inline lists that could drift in order or wiring. These tests assert the
+;; table, the derived 3x4 navigator rows, and that every key binds to the
+;; right command (including Music's two-call action).
+
+;;; Code:
+
+(require 'ert)
+(require 'cl-lib)
+
+(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory))
+(add-to-list 'load-path (expand-file-name "tests" user-emacs-directory))
+(setq load-prefer-newer t)
+
+;; deps dashboard-config pulls transitively / actions reference
+(unless (fboundp 'cj/kill-all-other-buffers-and-windows)
+ (defun cj/kill-all-other-buffers-and-windows () nil))
+(unless (fboundp 'cj/make-buffer-undead) (defun cj/make-buffer-undead (_n) nil))
+(defvar user-home-dir "/tmp/")
+
+(require 'dashboard-config)
+
+(defconst test-dash--keys '("c" "d" "t" "a" "r" "b" "f" "m" "e" "i" "s" "g"))
+
+;; ----------------------------- launcher table --------------------------------
+
+(ert-deftest test-dashboard-launchers-keys-in-order ()
+ "Normal: 12 launchers with the expected keys in display order."
+ (should (= 12 (length cj/dashboard--launchers)))
+ (should (equal test-dash--keys (mapcar (lambda (l) (nth 0 l)) cj/dashboard--launchers))))
+
+(ert-deftest test-dashboard-launchers-labels-in-order ()
+ "Normal: labels in display order."
+ (should (equal '("Code" "Files" "Terminal" "Agenda" "Feeds" "Books"
+ "Flashcards" "Music" "Email" "IRC" "Slack" "Telegram")
+ (mapcar (lambda (l) (nth 3 l)) cj/dashboard--launchers))))
+
+;; --------------------------- navigator rows ----------------------------------
+
+(ert-deftest test-dashboard-navigator-rows-three-rows-of-four ()
+ "Normal: navigator derives 3 rows of 4, with the right labels and button shape."
+ (cl-letf (((symbol-function 'nerd-icons-faicon) (lambda (n &rest _) (concat "I:" n)))
+ ((symbol-function 'nerd-icons-devicon) (lambda (n &rest _) (concat "I:" n)))
+ ((symbol-function 'nerd-icons-mdicon) (lambda (n &rest _) (concat "I:" n))))
+ (let ((rows (cj/dashboard--navigator-rows)))
+ (should (= 3 (length rows)))
+ (should (cl-every (lambda (r) (= 4 (length r))) rows))
+ (should (equal '("Code" "Files" "Terminal" "Agenda")
+ (mapcar (lambda (b) (nth 1 b)) (nth 0 rows))))
+ (let ((btn (car (car rows)))) ; (icon label tooltip action nil " " "")
+ (should (string= "I:nf-fa-code" (nth 0 btn)))
+ (should (string= "Code" (nth 1 btn)))
+ (should (functionp (nth 3 btn)))
+ (should (null (nth 4 btn)))))))
+
+;; ---------------------------- keymap binding ---------------------------------
+
+(ert-deftest test-dashboard-bind-launchers-binds-every-key ()
+ "Normal: every launcher key binds to a command; q is left to the caller."
+ (let ((map (make-sparse-keymap)))
+ (cj/dashboard--bind-launchers map)
+ (dolist (key test-dash--keys)
+ (should (commandp (keymap-lookup map key))))
+ (should-not (keymap-lookup map "q"))))
+
+(ert-deftest test-dashboard-bind-launchers-each-key-runs-its-command ()
+ "Behavior: invoking each key runs its launcher's command(s) — Music runs two."
+ (let ((map (make-sparse-keymap)) (calls nil))
+ (cl-letf (((symbol-function 'projectile-switch-project) (lambda (&rest _) (push 'code calls)))
+ ((symbol-function 'dirvish) (lambda (&rest _) (push 'files calls)))
+ ((symbol-function 'vterm) (lambda (&rest _) (push 'term calls)))
+ ((symbol-function 'cj/main-agenda-display) (lambda (&rest _) (push 'agenda calls)))
+ ((symbol-function 'cj/elfeed-open) (lambda (&rest _) (push 'feeds calls)))
+ ((symbol-function 'calibredb) (lambda (&rest _) (push 'books calls)))
+ ((symbol-function 'cj/drill-start) (lambda (&rest _) (push 'cards calls)))
+ ((symbol-function 'cj/music-playlist-toggle) (lambda (&rest _) (push 'm-toggle calls)))
+ ((symbol-function 'cj/music-playlist-load) (lambda (&rest _) (push 'm-load calls)))
+ ((symbol-function 'mu4e) (lambda (&rest _) (push 'email calls)))
+ ((symbol-function 'cj/erc-switch-to-buffer-with-completion) (lambda (&rest _) (push 'irc calls)))
+ ((symbol-function 'cj/slack-start) (lambda (&rest _) (push 'slack calls)))
+ ((symbol-function 'cj/telega) (lambda (&rest _) (push 'tg calls))))
+ (cj/dashboard--bind-launchers map)
+ (dolist (key test-dash--keys)
+ (call-interactively (keymap-lookup map key)))
+ (should (memq 'code calls))
+ (should (memq 'tg calls))
+ (should (memq 'm-toggle calls))
+ (should (memq 'm-load calls))
+ (should (= 13 (length calls)))))) ; 12 keys, Music fires two
+
+(provide 'test-dashboard-config-launchers)
+;;; test-dashboard-config-launchers.el ends here