aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/test-custom-buffer-file--buffer-differs-prompt.el197
-rw-r--r--tests/test-custom-buffer-file--diff-whitespace-only.el146
-rw-r--r--tests/test-custom-buffer-file--save-some-buffers.el123
3 files changed, 466 insertions, 0 deletions
diff --git a/tests/test-custom-buffer-file--buffer-differs-prompt.el b/tests/test-custom-buffer-file--buffer-differs-prompt.el
new file mode 100644
index 000000000..109ca121f
--- /dev/null
+++ b/tests/test-custom-buffer-file--buffer-differs-prompt.el
@@ -0,0 +1,197 @@
+;;; test-custom-buffer-file--buffer-differs-prompt.el --- disk-changed save prompt pieces -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; Pure-logic tests for the disk-changed save prompt (the C-x C-s case where the
+;; buffer is modified AND the file changed on disk): the question string (with a
+;; terse whitespace-only parenthetical), the labeled-but-terse choice list, and
+;; the key->action mapping. The interactive read loop, the diff display, and the
+;; save/revert dispatch 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/--buffer-differs-prompt-string "custom-buffer-file" (name ws-only-p))
+(declare-function cj/--buffer-differs-choices "custom-buffer-file" ())
+(declare-function cj/--buffer-differs-action "custom-buffer-file" (key))
+
+;;; ------------------- cj/--buffer-differs-prompt-string ----------------------
+
+(ert-deftest test-cbf-buffer-differs-prompt-plain ()
+ "Normal: without whitespace-only, the prompt names the buffer, no parenthetical."
+ (let ((s (cj/--buffer-differs-prompt-string "todo.org" nil)))
+ (should (string-match-p "todo\\.org" s))
+ (should-not (string-match-p "whitespace" s))))
+
+(ert-deftest test-cbf-buffer-differs-prompt-whitespace-only ()
+ "Normal: whitespace-only folds in a terse \"(whitespace only)\" parenthetical."
+ (let ((s (cj/--buffer-differs-prompt-string "todo.org" t)))
+ (should (string-match-p "todo\\.org" s))
+ (should (string-match-p "(whitespace only)" s))))
+
+;;; ---------------------- cj/--buffer-differs-choices -------------------------
+
+(ert-deftest test-cbf-buffer-differs-choices-keys ()
+ "Normal: the menu offers save, diff, clean, revert, and cancel."
+ (let ((c (cj/--buffer-differs-choices)))
+ (dolist (key '(?s ?d ?w ?r ?c))
+ (should (assq key c)))))
+
+(ert-deftest test-cbf-buffer-differs-choices-terse-names ()
+ "Boundary: inline names stay terse (one word) so the menu fits at a glance."
+ (dolist (entry (cj/--buffer-differs-choices))
+ (let ((name (nth 1 entry)))
+ (should (stringp name))
+ (should-not (string-match-p " " name)))))
+
+(ert-deftest test-cbf-buffer-differs-choices-clean-help-mentions-whitespace ()
+ "Normal: the clean option's description (the ? help) names whitespace."
+ (let ((entry (assq ?w (cj/--buffer-differs-choices))))
+ (should (string-match-p "whitespace" (or (nth 2 entry) "")))))
+
+(ert-deftest test-cbf-buffer-differs-choices-revert-help-mentions-disk ()
+ "Normal: the revert option's description makes clear it rereads from disk."
+ (let ((entry (assq ?r (cj/--buffer-differs-choices))))
+ (should (string-match-p "disk" (or (nth 2 entry) "")))))
+
+;;; ---------------------- cj/--buffer-differs-action --------------------------
+
+(ert-deftest test-cbf-buffer-differs-action-save ()
+ "Normal: s overwrites the file with the buffer."
+ (should (eq (cj/--buffer-differs-action ?s) 'save)))
+
+(ert-deftest test-cbf-buffer-differs-action-clean ()
+ "Normal: w cleans whitespace, then saves."
+ (should (eq (cj/--buffer-differs-action ?w) 'clean-save)))
+
+(ert-deftest test-cbf-buffer-differs-action-revert ()
+ "Normal: r discards edits and rereads from disk."
+ (should (eq (cj/--buffer-differs-action ?r) 'revert)))
+
+(ert-deftest test-cbf-buffer-differs-action-diff ()
+ "Normal: d peeks at the diff (re-prompt is the caller's concern)."
+ (should (eq (cj/--buffer-differs-action ?d) 'diff)))
+
+(ert-deftest test-cbf-buffer-differs-action-cancel ()
+ "Boundary: c cancels, leaving the buffer untouched."
+ (should (eq (cj/--buffer-differs-action ?c) 'cancel)))
+
+(ert-deftest test-cbf-buffer-differs-action-unknown ()
+ "Error: an unmapped key returns nil."
+ (should-not (cj/--buffer-differs-action ?z)))
+
+;;; ------------------- cj/--buffer-changed-on-disk-p --------------------------
+;; Real visited-file buffers; modtime state is driven (set-visited-file-modtime),
+;; not mocked. The trigger is the disk-changed conflict: modified AND the file
+;; changed on disk since visited.
+
+(declare-function cj/--buffer-changed-on-disk-p "custom-buffer-file" (buffer))
+
+(defun test-cbf-cod--with-visited (edit-fn body-fn)
+ "Visit a temp file, run EDIT-FN in its buffer, call BODY-FN with the buffer."
+ (let ((f (make-temp-file "cbf-cod-" nil ".txt")))
+ (unwind-protect
+ (progn
+ (with-temp-file f (insert "original\n"))
+ (let ((buf (find-file-noselect f)))
+ (unwind-protect
+ (with-current-buffer buf (funcall edit-fn) (funcall body-fn buf))
+ (with-current-buffer buf (set-buffer-modified-p nil))
+ (kill-buffer buf))))
+ (when (file-exists-p f) (delete-file f)))))
+
+(ert-deftest test-cbf-changed-on-disk-detects ()
+ "Normal: modified buffer whose recorded modtime no longer matches is changed-on-disk."
+ (test-cbf-cod--with-visited
+ (lambda () (goto-char (point-max)) (insert "edit\n") (set-visited-file-modtime '(0 0)))
+ (lambda (buf) (should (cj/--buffer-changed-on-disk-p buf)))))
+
+(ert-deftest test-cbf-changed-on-disk-clean-modtime ()
+ "Boundary: modified buffer whose modtime still matches is not changed-on-disk."
+ (test-cbf-cod--with-visited
+ (lambda () (goto-char (point-max)) (insert "edit\n"))
+ (lambda (buf) (should-not (cj/--buffer-changed-on-disk-p buf)))))
+
+(ert-deftest test-cbf-changed-on-disk-unmodified ()
+ "Boundary: an unmodified buffer is never changed-on-disk (nothing of mine to lose)."
+ (test-cbf-cod--with-visited
+ (lambda () (set-visited-file-modtime '(0 0)))
+ (lambda (buf) (should-not (cj/--buffer-changed-on-disk-p buf)))))
+
+;;; -------------- cj/--buffer-differs-dispatch (data direction) ---------------
+;; The destructive directions, driven against real files: `save' overwrites the
+;; disk with the buffer (buffer wins); `revert' discards the buffer's edits and
+;; rereads the disk (disk wins); `clean-save' strips trailing whitespace first.
+
+(declare-function cj/--buffer-differs-dispatch "custom-buffer-file" (buffer action))
+(declare-function cj/save-buffer "custom-buffer-file" ())
+
+(defun test-cbf-disp--with-conflict (buffer-insert disk-content body-fn)
+ "Visit a temp file, BUFFER-INSERT into the buffer, overwrite the file with
+DISK-CONTENT underneath, then call BODY-FN with the buffer and file path."
+ (let ((f (make-temp-file "cbf-disp-" nil ".txt")))
+ (unwind-protect
+ (progn
+ (with-temp-file f (insert "original\n"))
+ (let ((buf (find-file-noselect f)))
+ (unwind-protect
+ (with-current-buffer buf
+ (goto-char (point-max)) (insert buffer-insert)
+ (with-temp-file f (insert disk-content))
+ (funcall body-fn buf f))
+ (with-current-buffer buf (set-buffer-modified-p nil))
+ (kill-buffer buf))))
+ (when (file-exists-p f) (delete-file f)))))
+
+(defun test-cbf-disp--disk (f)
+ "Return the on-disk contents of F."
+ (with-temp-buffer (insert-file-contents f) (buffer-string)))
+
+(ert-deftest test-cbf-buffer-differs-dispatch-save-overwrites-disk ()
+ "Normal: save writes the buffer over the disk version (buffer wins)."
+ (test-cbf-disp--with-conflict
+ "my edit\n" "disk changed underneath\n"
+ (lambda (buf f)
+ (cj/--buffer-differs-dispatch buf 'save)
+ (should-not (buffer-modified-p buf))
+ (should (string= (test-cbf-disp--disk f) "original\nmy edit\n")))))
+
+(ert-deftest test-cbf-buffer-differs-dispatch-revert-discards-edits ()
+ "Normal: revert discards the buffer's edits and rereads the disk (disk wins)."
+ (test-cbf-disp--with-conflict
+ "my edit\n" "disk version\n"
+ (lambda (buf f)
+ (cj/--buffer-differs-dispatch buf 'revert)
+ (should-not (buffer-modified-p buf))
+ (should (string= (with-current-buffer buf (buffer-string)) "disk version\n")))))
+
+(ert-deftest test-cbf-buffer-differs-dispatch-clean-save-strips-whitespace ()
+ "Normal: clean-save strips trailing whitespace, then overwrites the disk."
+ (test-cbf-disp--with-conflict
+ "edit \n" "disk changed\n"
+ (lambda (buf f)
+ (cj/--buffer-differs-dispatch buf 'clean-save)
+ (should-not (buffer-modified-p buf))
+ (should (string= (test-cbf-disp--disk f) "original\nedit\n")))))
+
+(ert-deftest test-cbf-save-buffer-fast-path-no-conflict ()
+ "Boundary: with no disk conflict, cj/save-buffer just saves (no prompt path)."
+ (let ((f (make-temp-file "cbf-fast-" nil ".txt")))
+ (unwind-protect
+ (progn
+ (with-temp-file f (insert "base\n"))
+ (let ((buf (find-file-noselect f)))
+ (unwind-protect
+ (with-current-buffer buf
+ (goto-char (point-max)) (insert "added\n")
+ (cj/save-buffer) ; modtime matches -> fast path
+ (should-not (buffer-modified-p))
+ (should (string= (test-cbf-disp--disk f) "base\nadded\n")))
+ (with-current-buffer buf (set-buffer-modified-p nil))
+ (kill-buffer buf))))
+ (when (file-exists-p f) (delete-file f)))))
+
+(provide 'test-custom-buffer-file--buffer-differs-prompt)
+;;; test-custom-buffer-file--buffer-differs-prompt.el ends here
diff --git a/tests/test-custom-buffer-file--diff-whitespace-only.el b/tests/test-custom-buffer-file--diff-whitespace-only.el
new file mode 100644
index 000000000..e792637b5
--- /dev/null
+++ b/tests/test-custom-buffer-file--diff-whitespace-only.el
@@ -0,0 +1,146 @@
+;;; test-custom-buffer-file--diff-whitespace-only.el --- whitespace-only diff detection -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; Tests for cj/--diff-whitespace-only-p, the route-1 detector behind the
+;; buffer-differs save prompt: two files differ ONLY in whitespace when a plain
+;; diff finds changes but `diff -w' (ignore all whitespace) finds none. Uses
+;; real temp files and the real diff(1) binary (a system boundary we keep), so
+;; nothing is mocked.
+
+;;; Code:
+
+(require 'ert)
+(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory))
+(require 'custom-buffer-file)
+
+(declare-function cj/--diff-whitespace-only-p "custom-buffer-file" (file-a file-b))
+
+(defun test-cbf-ws--two-files (content-a content-b fn)
+ "Write CONTENT-A and CONTENT-B to temp files, call FN with their paths, clean up."
+ (let ((a (make-temp-file "cbf-ws-a-"))
+ (b (make-temp-file "cbf-ws-b-")))
+ (unwind-protect
+ (progn
+ (with-temp-file a (insert content-a))
+ (with-temp-file b (insert content-b))
+ (funcall fn a b))
+ (delete-file a)
+ (delete-file b))))
+
+(ert-deftest test-cbf-diff-whitespace-only-trailing ()
+ "Normal: files differing only by trailing whitespace are whitespace-only."
+ (test-cbf-ws--two-files
+ "alpha\nbeta\n" "alpha \nbeta\n"
+ (lambda (a b) (should (cj/--diff-whitespace-only-p a b)))))
+
+(ert-deftest test-cbf-diff-whitespace-only-indentation ()
+ "Normal: files differing only by leading indentation are whitespace-only."
+ (test-cbf-ws--two-files
+ "(foo)\n(bar)\n" "(foo)\n (bar)\n"
+ (lambda (a b) (should (cj/--diff-whitespace-only-p a b)))))
+
+(ert-deftest test-cbf-diff-whitespace-only-real-content ()
+ "Normal: files differing in actual content are NOT whitespace-only."
+ (test-cbf-ws--two-files
+ "alpha\nbeta\n" "alpha\nGAMMA\n"
+ (lambda (a b) (should-not (cj/--diff-whitespace-only-p a b)))))
+
+(ert-deftest test-cbf-diff-whitespace-only-identical ()
+ "Boundary: identical files do not differ at all, so not whitespace-only."
+ (test-cbf-ws--two-files
+ "alpha\nbeta\n" "alpha\nbeta\n"
+ (lambda (a b) (should-not (cj/--diff-whitespace-only-p a b)))))
+
+(ert-deftest test-cbf-diff-whitespace-only-mixed ()
+ "Boundary: whitespace change plus a real content change is NOT whitespace-only."
+ (test-cbf-ws--two-files
+ "alpha\nbeta\n" "alpha \nGAMMA\n"
+ (lambda (a b) (should-not (cj/--diff-whitespace-only-p a b)))))
+
+;;; -------------------- cj/--diff-buffer-renderer -----------------------------
+;; Which renderer the diff command uses: whitespace-only diffs go to a plain
+;; unified diff (trailing whitespace highlighted, so it is actually visible)
+;; because difftastic treats trailing-whitespace as no change and renders it
+;; blank. Real content diffs use difftastic when available, else plain diff.
+
+(declare-function cj/--diff-buffer-renderer "custom-buffer-file" (ws-only difft-available))
+
+(ert-deftest test-cbf-diff-renderer-whitespace-over-difftastic ()
+ "Normal: a whitespace-only diff uses the whitespace renderer even when difft is present."
+ (should (eq (cj/--diff-buffer-renderer t t) 'whitespace)))
+
+(ert-deftest test-cbf-diff-renderer-whitespace-no-difft ()
+ "Boundary: whitespace-only still uses the whitespace renderer without difft."
+ (should (eq (cj/--diff-buffer-renderer t nil) 'whitespace)))
+
+(ert-deftest test-cbf-diff-renderer-content-uses-difftastic ()
+ "Normal: a content diff uses difftastic when it is available."
+ (should (eq (cj/--diff-buffer-renderer nil t) 'difftastic)))
+
+(ert-deftest test-cbf-diff-renderer-content-no-difft-regular ()
+ "Boundary: a content diff falls back to the regular renderer without difft."
+ (should (eq (cj/--diff-buffer-renderer nil nil) 'regular)))
+
+;;; --------------- cj/--buffer-file-whitespace-only-p (buffer) ----------------
+;; Buffer-vs-its-file variant: writes the buffer to a temp file and reuses the
+;; detector against the buffer's visited file. Uses a real visited-file buffer.
+
+(declare-function cj/--buffer-file-whitespace-only-p "custom-buffer-file" (buffer))
+
+(defun test-cbf-ws--with-visited (disk-content edit-fn body-fn)
+ "Visit a temp file holding DISK-CONTENT, apply EDIT-FN in it, call BODY-FN with the buffer."
+ (let ((f (make-temp-file "cbf-bws-" nil ".txt")))
+ (unwind-protect
+ (progn
+ (with-temp-file f (insert disk-content))
+ (let ((buf (find-file-noselect f)))
+ (unwind-protect
+ (with-current-buffer buf
+ (funcall edit-fn)
+ (funcall body-fn buf))
+ (with-current-buffer buf (set-buffer-modified-p nil))
+ (kill-buffer buf))))
+ (when (file-exists-p f) (delete-file f)))))
+
+(ert-deftest test-cbf-buffer-file-ws-only-trailing ()
+ "Normal: an unsaved trailing-whitespace edit is whitespace-only vs the file."
+ (test-cbf-ws--with-visited
+ "alpha\nbeta\n"
+ (lambda () (goto-char (point-min)) (end-of-line) (insert " "))
+ (lambda (buf) (should (cj/--buffer-file-whitespace-only-p buf)))))
+
+(ert-deftest test-cbf-buffer-file-ws-only-content ()
+ "Normal: an unsaved content edit is NOT whitespace-only vs the file."
+ (test-cbf-ws--with-visited
+ "alpha\nbeta\n"
+ (lambda () (goto-char (point-max)) (insert "gamma\n"))
+ (lambda (buf) (should-not (cj/--buffer-file-whitespace-only-p buf)))))
+
+;;; --------- cj/diff-buffer-with-file return value (for the toggle) -----------
+
+(ert-deftest test-cbf-diff-returns-buffer-when-differs ()
+ "Normal: cj/diff-buffer-with-file returns the live diff buffer when the buffer differs."
+ (test-cbf-ws--with-visited
+ "x\ny\n"
+ (lambda () (goto-char (point-max)) (insert "ADDED\n"))
+ (lambda (buf)
+ (let ((db (with-current-buffer buf (cj/diff-buffer-with-file))))
+ (should (bufferp db))
+ (should (buffer-live-p db))))))
+
+(ert-deftest test-cbf-diff-returns-nil-when-identical ()
+ "Boundary: with no differences, cj/diff-buffer-with-file returns nil."
+ (test-cbf-ws--with-visited
+ "x\ny\n"
+ (lambda () nil)
+ (lambda (buf)
+ (should-not (with-current-buffer buf (cj/diff-buffer-with-file))))))
+
+(ert-deftest test-cbf-buffer-file-ws-only-non-file ()
+ "Boundary: a buffer not visiting a file is not whitespace-only."
+ (with-temp-buffer
+ (insert "scratch")
+ (should-not (cj/--buffer-file-whitespace-only-p (current-buffer)))))
+
+(provide 'test-custom-buffer-file--diff-whitespace-only)
+;;; test-custom-buffer-file--diff-whitespace-only.el ends here
diff --git a/tests/test-custom-buffer-file--save-some-buffers.el b/tests/test-custom-buffer-file--save-some-buffers.el
new file mode 100644
index 000000000..d4ecd318d
--- /dev/null
+++ b/tests/test-custom-buffer-file--save-some-buffers.el
@@ -0,0 +1,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