diff options
| author | Craig Jennings <c@cjennings.net> | 2026-06-30 08:11:02 -0400 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-06-30 08:11:02 -0400 |
| commit | e88391f252ba038d9f824308ce2b873d7b29ab79 (patch) | |
| tree | 67ca9bdc0e7108f570d40eb65192537f280bda34 /tests | |
| parent | 7e93212a5fe39985dd8dc6c0368a0c662d3cdf08 (diff) | |
| download | dotemacs-e88391f252ba038d9f824308ce2b873d7b29ab79.tar.gz dotemacs-e88391f252ba038d9f824308ce2b873d7b29ab79.zip | |
feat(buffer-file): legible save prompts for save-some-buffers and disk-changed saves
Replace the cryptic single-key save prompts with read-multiple-choice menus whose options are labeled on screen instead of recalled as keys.
save-some-buffers (C-x s and save-on-exit) is overridden with a reimplementation that reuses the stock candidate selection and abbrev-save tail but swaps map-y-or-n-p's terse key list for a labeled menu, and adds a clean-whitespace-and-save action.
C-x C-s gains a wrapper that fast-paths normal saves to save-buffer; only when the buffer has unsaved edits and the file changed on disk does it show a labeled menu (save / diff / clean / revert / cancel) instead of the bare "Save anyway?" yes/no.
Both menus share a diff toggle, and whitespace-only diffs route to a plain unified diff with trailing whitespace highlighted, since difftastic normalizes trailing whitespace and renders such changes blank.
The interactive wrappers stay thin over pure, tested helpers: the save-loop planner, the key-to-action maps, the whitespace detector, and the renderer choice.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/test-custom-buffer-file--buffer-differs-prompt.el | 197 | ||||
| -rw-r--r-- | tests/test-custom-buffer-file--diff-whitespace-only.el | 146 | ||||
| -rw-r--r-- | tests/test-custom-buffer-file--save-some-buffers.el | 123 |
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 |
