aboutsummaryrefslogtreecommitdiff
path: root/tests/test-ui-navigation-split-follow-undo-kill.el
blob: f6981a36a7033f6d785fd655fd256692c55e88b4 (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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
;;; test-ui-navigation-split-follow-undo-kill.el --- Tests for the split-and-follow + undo-kill-buffer commands -*- lexical-binding: t; -*-

;;; Commentary:
;; Sibling tests cover `toggle-window-split' and the window-resize
;; sticky map.  This file covers the remaining three commands:
;;
;;   cj/split-and-follow-right
;;   cj/split-and-follow-below
;;   cj/undo-kill-buffer
;;
;; `split-window-*', `consult-buffer', `find-file', and `recentf'
;; primitives are stubbed.

;;; Code:

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

(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory))
(require 'ui-navigation)

;; Top-level defvar so let-bindings reach the dynamic var under
;; lexical scope.
(defvar recentf-mode nil)
(defvar recentf-list nil)

;;; cj/split-and-follow-right

(ert-deftest test-ui-navigation-split-right-splits-and-prompts ()
  "Normal: split-and-follow-right calls split-window-right then consult-buffer."
  (let ((sequence nil))
    (cl-letf (((symbol-function 'split-window-right)
               (lambda (&rest _) (push 'split sequence)))
              ((symbol-function 'other-window)
               (lambda (&rest _) (push 'other sequence)))
              ((symbol-function 'consult-buffer)
               (lambda (&rest _) (push 'consult sequence))))
      (cj/split-and-follow-right))
    (should (equal (reverse sequence) '(split other consult)))))

;;; cj/split-and-follow-below

(ert-deftest test-ui-navigation-split-below-splits-and-prompts ()
  "Normal: split-and-follow-below calls split-window-below then consult-buffer."
  (let ((sequence nil))
    (cl-letf (((symbol-function 'split-window-below)
               (lambda (&rest _) (push 'split sequence)))
              ((symbol-function 'other-window)
               (lambda (&rest _) (push 'other sequence)))
              ((symbol-function 'consult-buffer)
               (lambda (&rest _) (push 'consult sequence))))
      (cj/split-and-follow-below))
    (should (equal (reverse sequence) '(split other consult)))))

;;; cj/undo-kill-buffer

(ert-deftest test-ui-navigation-undo-kill-buffer-no-prefix-opens-most-recent ()
  "Normal: no prefix (arg=1, the value `\"p\"' yields) opens the most-recent
non-visited entry, not the second."
  (let ((opened nil)
        (recentf-mode t)
        (recentf-list '("/tmp/dead.org" "/tmp/alive.txt")))
    (cl-letf (((symbol-function 'require) (lambda (&rest _) t))
              ((symbol-function 'recentf-mode) (lambda (&rest _) t))
              ;; Pretend /tmp/alive.txt is open in some buffer.
              ((symbol-function 'buffer-list)
               (lambda (&rest _)
                 (list (let ((b (get-buffer-create "*test-alive*")))
                         (with-current-buffer b
                           (setq buffer-file-name "/tmp/alive.txt"))
                         b))))
              ((symbol-function 'find-file)
               (lambda (f) (setq opened f))))
      (unwind-protect
          (cj/undo-kill-buffer 1)
        (when (get-buffer "*test-alive*") (kill-buffer "*test-alive*"))))
    (should (equal opened "/tmp/dead.org"))))

(ert-deftest test-ui-navigation-undo-kill-buffer-skips-open-file-at-head ()
  "Boundary: an open file at the head of the list is skipped (equal, not eq).
The previous delq compared expand-file-name strings by identity, so a
currently-open most-recent file was never skipped."
  (let ((opened nil)
        (recentf-mode t)
        ;; The open file is FIRST — only an equal-based filter removes it.
        (recentf-list '("/tmp/alive.txt" "/tmp/dead.org")))
    (cl-letf (((symbol-function 'require) (lambda (&rest _) t))
              ((symbol-function 'recentf-mode) (lambda (&rest _) t))
              ((symbol-function 'buffer-list)
               (lambda (&rest _)
                 (list (let ((b (get-buffer-create "*test-alive*")))
                         (with-current-buffer b
                           (setq buffer-file-name "/tmp/alive.txt"))
                         b))))
              ((symbol-function 'find-file)
               (lambda (f) (setq opened f))))
      (unwind-protect
          (cj/undo-kill-buffer 1)
        (when (get-buffer "*test-alive*") (kill-buffer "*test-alive*"))))
    (should (equal opened "/tmp/dead.org"))))

(ert-deftest test-ui-navigation-undo-kill-buffer-numeric-arg-is-one-based ()
  "Normal: a numeric prefix is 1-based — N=2 opens the second non-visited entry."
  (let ((opened nil)
        (recentf-mode t)
        (recentf-list '("/tmp/a.org" "/tmp/b.org" "/tmp/c.org")))
    (cl-letf (((symbol-function 'require) (lambda (&rest _) t))
              ((symbol-function 'recentf-mode) (lambda (&rest _) t))
              ((symbol-function 'buffer-list) (lambda (&rest _) nil))
              ((symbol-function 'find-file)
               (lambda (f) (setq opened f))))
      (cj/undo-kill-buffer 2))
    (should (equal opened "/tmp/b.org"))))

(ert-deftest test-ui-navigation-undo-kill-buffer-no-op-when-list-empty ()
  "Boundary: when the recently-killed list is empty, find-file isn't called."
  (let ((opened nil)
        (recentf-mode t)
        (recentf-list nil))
    (cl-letf (((symbol-function 'require) (lambda (&rest _) t))
              ((symbol-function 'recentf-mode) (lambda (&rest _) t))
              ((symbol-function 'buffer-list) (lambda (&rest _) nil))
              ((symbol-function 'find-file)
               (lambda (f) (setq opened f))))
      (cj/undo-kill-buffer 0))
    (should-not opened)))

(ert-deftest test-ui-navigation-undo-kill-buffer-out-of-range-arg-errors ()
  "Error: a prefix larger than the killed-file list signals a clear user-error,
not a wrong-type-argument from find-file on nil."
  (let ((opened nil)
        (recentf-mode t)
        (recentf-list '("/tmp/a.org")))
    (cl-letf (((symbol-function 'require) (lambda (&rest _) t))
              ((symbol-function 'recentf-mode) (lambda (&rest _) t))
              ((symbol-function 'buffer-list) (lambda (&rest _) nil))
              ((symbol-function 'find-file) (lambda (f) (setq opened f))))
      (should-error (cj/undo-kill-buffer 5) :type 'user-error))
    (should-not opened)))

(provide 'test-ui-navigation-split-follow-undo-kill)
;;; test-ui-navigation-split-follow-undo-kill.el ends here