blob: d4ecd318d5ffebee502a9e9cb0e6416dfeac1525 (
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
|
;;; test-custom-buffer-file--save-some-buffers.el --- save-loop prompt pieces -*- lexical-binding: t; -*-
;;; Commentary:
;; Pure-logic tests for the read-multiple-choice save loop that replaces
;; save-some-buffers' terse map-y-or-n-p prompt: the key->action mapping (what
;; to do with this buffer, and how the choice steers the rest of the loop) and
;; the labeled choice list. The interactive loop, the file saves, and the
;; override wiring are exercised live, not here.
;;; Code:
(require 'ert)
(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory))
(require 'custom-buffer-file)
(declare-function cj/--save-some-buffers-action "custom-buffer-file" (key))
(declare-function cj/--save-some-buffers-choices "custom-buffer-file" ())
;;; --------------------- cj/--save-some-buffers-action ------------------------
;; Each result is (THIS-ACTION . LOOP-EFFECT):
;; THIS-ACTION ∈ save | clean-save | skip | diff
;; LOOP-EFFECT ∈ continue | save-rest | stop | reprompt
(ert-deftest test-cbf-ssb-action-save ()
"Normal: y saves this buffer and continues prompting."
(should (equal (cj/--save-some-buffers-action ?y) '(save . continue))))
(ert-deftest test-cbf-ssb-action-skip ()
"Normal: n skips this buffer and continues."
(should (equal (cj/--save-some-buffers-action ?n) '(skip . continue))))
(ert-deftest test-cbf-ssb-action-clean-save ()
"Normal: w cleans whitespace, saves this buffer, and continues."
(should (equal (cj/--save-some-buffers-action ?w) '(clean-save . continue))))
(ert-deftest test-cbf-ssb-action-save-rest ()
"Boundary: ! saves this buffer and all remaining without asking."
(should (equal (cj/--save-some-buffers-action ?!) '(save . save-rest))))
(ert-deftest test-cbf-ssb-action-save-this-stop ()
"Boundary: . saves this buffer and skips the rest."
(should (equal (cj/--save-some-buffers-action ?.) '(save . stop))))
(ert-deftest test-cbf-ssb-action-quit ()
"Boundary: q saves no more buffers (skips this and the rest)."
(should (equal (cj/--save-some-buffers-action ?q) '(skip . stop))))
(ert-deftest test-cbf-ssb-action-diff ()
"Normal: d views the diff and re-prompts rather than resolving."
(should (equal (cj/--save-some-buffers-action ?d) '(diff . reprompt))))
(ert-deftest test-cbf-ssb-action-unknown ()
"Error: an unmapped key returns nil."
(should-not (cj/--save-some-buffers-action ?z)))
;;; --------------------- cj/--save-some-buffers-choices -----------------------
(ert-deftest test-cbf-ssb-choices-cover-all-keys ()
"Normal: the choice list offers every save-loop key, each labeled."
(let ((choices (cj/--save-some-buffers-choices)))
(dolist (key '(?y ?n ?w ?d ?! ?. ?q))
(let ((entry (assq key choices)))
(should entry)
;; entry is (KEY NAME &optional DESC); NAME must be a non-empty label.
(should (stringp (nth 1 entry)))
(should (> (length (nth 1 entry)) 0))))))
(ert-deftest test-cbf-ssb-choices-terse-names ()
"Boundary: inline names are single words so the menu takes minimum space."
(dolist (entry (cj/--save-some-buffers-choices))
(let ((name (nth 1 entry)))
(should (stringp name))
(should-not (string-match-p " " name)))))
(ert-deftest test-cbf-ssb-choices-clean-mentions-whitespace ()
"Normal: the clean-and-save choice is labeled with whitespace."
(let ((entry (assq ?w (cj/--save-some-buffers-choices))))
(should (string-match-p "whitespace"
(mapconcat #'identity (cdr entry) " ")))))
;;; ---------------------- cj/--save-some-buffers-plan -------------------------
;; The pure planner: given the candidate BUFFERS and a KEY-FN that yields a
;; (non-diff) key per buffer, resolve each to `save' / `clean-save' / `skip',
;; honoring ! (save the rest) and . / q (stop after this). Buffers are opaque
;; here (symbols stand in), so the planner is testable without real buffers.
(declare-function cj/--save-some-buffers-plan "custom-buffer-file" (buffers key-fn))
(ert-deftest test-cbf-ssb-plan-mixed ()
"Normal: y / n / w resolve per-buffer to save / skip / clean-save."
(let* ((keys '((a . ?y) (b . ?n) (c . ?w)))
(plan (cj/--save-some-buffers-plan
'(a b c) (lambda (buf) (cdr (assq buf keys))))))
(should (equal plan '((a . save) (b . skip) (c . clean-save))))))
(ert-deftest test-cbf-ssb-plan-save-rest ()
"Boundary: ! saves this and all remaining without consulting KEY-FN again."
(let* ((asked nil)
(plan (cj/--save-some-buffers-plan
'(a b c)
(lambda (buf) (push buf asked) (if (eq buf 'a) ?! ?n)))))
(should (equal plan '((a . save) (b . save) (c . save))))
;; key-fn consulted only for the first buffer; the rest ride save-all.
(should (equal asked '(a)))))
(ert-deftest test-cbf-ssb-plan-save-this-stop ()
"Boundary: . saves this buffer and skips the rest."
(let ((plan (cj/--save-some-buffers-plan
'(a b c) (lambda (buf) (if (eq buf 'a) ?. ?y)))))
(should (equal plan '((a . save) (b . skip) (c . skip))))))
(ert-deftest test-cbf-ssb-plan-quit-skips-all ()
"Boundary: q skips this buffer and all remaining."
(let ((plan (cj/--save-some-buffers-plan
'(a b c) (lambda (_) ?q))))
(should (equal plan '((a . skip) (b . skip) (c . skip))))))
(ert-deftest test-cbf-ssb-plan-empty ()
"Boundary: no candidate buffers yields an empty plan."
(should-not (cj/--save-some-buffers-plan '() (lambda (_) ?y))))
(provide 'test-custom-buffer-file--save-some-buffers)
;;; test-custom-buffer-file--save-some-buffers.el ends here
|