aboutsummaryrefslogtreecommitdiff
path: root/tests/test-dirvish-config-quick-access.el
blob: 46f9b163bfb66c6aad5cfb37380ba5fdaa1ac191 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
;;; test-dirvish-config-quick-access.el --- Regression for quick-access key shape -*- lexical-binding: t; -*-

;;; Commentary:
;; `dirvish-quick-access' uses transient under the hood.  Entries are a list
;; of (KEY PATH DOC) cells, and transient auto-groups multi-character keys
;; into nested prefix keymaps.  When one entry's KEY is also the prefix of a
;; longer entry's KEY (e.g. "pw" as a leaf and "pwk" as a deeper key), the
;; transient build falls over: the shorter-key slot resolves to the auto-
;; generated sub-prefix keymap rather than to the intended leaf command.
;; Pressing the dirvish `g' binding then raises:
;;
;;   Wrong type argument: command, (keymap (107 . transient:...::N)), command
;;
;; That happened on 2026-05-10 after the `pcr' -> `pwk' rename in commit
;; 4ece1eb made `pw' (wallpaper, leaf) collide with `pwk' (project work).
;; This test guards against any future occurrence by walking the entries
;; list and asserting that no key is a prefix of any other key.

;;; Code:

(require 'ert)
(require 'cl-lib)
(require 'package)

(setq package-user-dir (expand-file-name "elpa" user-emacs-directory))
(package-initialize)
(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory))
(add-to-list 'load-path (expand-file-name "elpa/dirvish-2.3.0/extensions"
                                          user-emacs-directory))
(require 'user-constants)
(require 'keybindings)
(require 'dirvish-config)

(defun test-dirvish-config--key-collisions (entries)
  "Return a list of (SHORTER . LONGER) pairs where SHORTER is a prefix of LONGER.
ENTRIES is the same shape as `dirvish-quick-access-entries' -- a list of
(KEY PATH DOC) cells."
  (let ((keys (mapcar #'car entries))
        collisions)
    (dolist (a keys)
      (dolist (b keys)
        (when (and (not (string= a b))
                   (string-prefix-p a b))
          (push (cons a b) collisions))))
    collisions))

(ert-deftest test-dirvish-config--key-collisions-detects-prefix-of-leaf ()
  "Normal: a leaf KEY that prefixes a longer KEY is reported as a collision."
  (let ((entries '(("pw" "/wallpaper" "wallpaper")
                   ("pwk" "/work" "project work")
                   ("h" "~/" "home"))))
    (should (member '("pw" . "pwk")
                    (test-dirvish-config--key-collisions entries)))))

(ert-deftest test-dirvish-config--key-collisions-clean-list-empty ()
  "Boundary: a list with no overlapping prefixes returns no collisions."
  (let ((entries '(("h"  "~/"   "home")
                   ("dx" "/dx"  "documents")
                   ("dl" "/dl"  "downloads")
                   ("pwk" "/wk" "project work")
                   ("wp" "/wp"  "wallpaper"))))
    (should-not (test-dirvish-config--key-collisions entries))))

(ert-deftest test-dirvish-config--key-collisions-empty-list-empty ()
  "Boundary: an empty entries list has no collisions."
  (should-not (test-dirvish-config--key-collisions '())))

(ert-deftest test-dirvish-config--key-collisions-single-entry-empty ()
  "Boundary: a single-entry list has no collisions."
  (should-not (test-dirvish-config--key-collisions
               '(("h" "~/" "home")))))

(ert-deftest test-dirvish-config-quick-access-entries-have-no-collisions ()
  "Regression: the live `dirvish-quick-access-entries' list contains no key
that is a prefix of another key.  See commentary for why this matters."
  (should-not (test-dirvish-config--key-collisions
               dirvish-quick-access-entries)))

(provide 'test-dirvish-config-quick-access)
;;; test-dirvish-config-quick-access.el ends here