Hello!

I've been trying to do some interactive testing so that I can use testcover to
create new tests for `org-agenda-format-item' as Ihor suggested.

I've been quite annoyed at the constant prompts while running the test suite
and then when trying to close Emacs so here is a patch to fix that!

I've tested this in batch-mode on Emacs 28.2, Emacs 29.4, and Emacs 30.2.  I
tested it interactively on Emacs 30.2.  I've done this using guix and will share
my methods in the future as they should be quite reproducible (and maybe good
in a CI?).


note: "test-org-agenda/time-grid" currently fails interactivly as the value of
`org-agenda-time-grid' depends on `(display-graphic-p)' but that's an issue for
another day.

>From b3be8b9a552e1a80e01307b41e0e1b002c09b89d Mon Sep 17 00:00:00 2001
From: Morgan Smith <[email protected]>
Date: Mon, 11 Aug 2025 13:24:36 -0400
Subject: [PATCH 1/2] * testing/lisp/test-org-agenda.el: Isolate test errors

If a test failed, it would not perform the cleanup which would cause
all subsequent tests to fail.

* testing/lisp/test-org-agenda.el (org-test-agenda-with-agenda): Use
unwind-protect to ensure cleanup happens.
---
 testing/lisp/test-org-agenda.el | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/testing/lisp/test-org-agenda.el b/testing/lisp/test-org-agenda.el
index e59461bdb..47425a4e9 100644
--- a/testing/lisp/test-org-agenda.el
+++ b/testing/lisp/test-org-agenda.el
@@ -46,8 +46,10 @@ org-test-agenda-with-agenda
   (declare (indent 1))
   `(org-test-with-temp-text-in-file ,text
      (let ((org-agenda-files `(,buffer-file-name)))
-       ,@body
-       (org-test-agenda--kill-all-agendas))))
+       (unwind-protect
+           (progn
+             ,@body)
+         (org-test-agenda--kill-all-agendas)))))
 
 
 ;; Test the Agenda

base-commit: 1afa553ed174c193f026c12c7ac6ea79214f427e
-- 
2.51.0

>From 87a754612094a3cbfa83803842a25cff9dbb0faa Mon Sep 17 00:00:00 2001
From: Morgan Smith <[email protected]>
Date: Thu, 16 Oct 2025 13:40:58 -0400
Subject: [PATCH 2/2] testing: Suppress interactive prompts during testing and
 on quit

Running the tests interactively would give the user multiple prompts
asking if they wanted to kill a modified buffer.  Then when quitting
Emacs, the user would receive prompts asking if they wanted to save
some of the temporary test files.

* testing/org-test.el (org-test-kill-buffer): New function.
(org-test-at-id, org-test-in-example-file,
org-test-with-temp-text-in-file, org-test-kill-all-examples): Use new
function to kill buffers.
* testing/lisp/test-ob-tangle.el (ob-tangle/tangle-to-self, ob-tangle/bibtex): Use
`org-test-with-temp-text-in-file' to ensure buffers are killed.
* testing/lisp/test-org-agenda.el (test-org-agenda/set-priority): Use
`unwind-protect' for test cleanup and kill a buffer to "agenda-file.org".
* testing/lisp/test-org-capture.el
(test-org-capture/org-capture-expand-olp): Use
`org-test-with-temp-text-in-file' to ensure buffers are killed.

* testing/lisp/test-org-protocol.el
(test-org-protocol/org-protocol-capture-file): Add cleanup for buffers
and files.
* testing/lisp/test-ox.el (test-org-export/org-export-copy-buffer):
Kill buffer.
---
 testing/lisp/test-ob-tangle.el    | 45 +++++++++++++------------------
 testing/lisp/test-org-agenda.el   | 12 +++++----
 testing/lisp/test-org-capture.el  | 18 +++++--------
 testing/lisp/test-org-protocol.el | 16 ++++++-----
 testing/lisp/test-ox.el           |  3 ++-
 testing/org-test.el               | 24 ++++++++++-------
 6 files changed, 58 insertions(+), 60 deletions(-)

diff --git a/testing/lisp/test-ob-tangle.el b/testing/lisp/test-ob-tangle.el
index cd6876370..0104453cb 100644
--- a/testing/lisp/test-ob-tangle.el
+++ b/testing/lisp/test-ob-tangle.el
@@ -555,17 +555,14 @@ ob-tangle/strip-tangle
 
 (ert-deftest ob-tangle/tangle-to-self ()
   "Do not allow tangling into self."
-  (let ((file (make-temp-file "org-tangle-" nil ".org")))
-    (unwind-protect
-        (with-current-buffer (find-file-noselect file)
-          (insert
-           (format "
-#+begin_src elisp :tangle %s
+  (org-test-with-temp-text-in-file
+      "
+#+begin_src elisp :tangle <point>
 2
 #+end_src
-" file))
-          (should-error (org-babel-tangle)))
-      (delete-file file))))
+"
+    (insert file)
+    (should-error (org-babel-tangle))))
 
 (ert-deftest ob-tangle/detangle-false-positive ()
   "Test handling of false positive link during detangle."
@@ -717,29 +714,25 @@ ob-tangle/collect-blocks
 
 (ert-deftest ob-tangle/bibtex ()
   "Tangle BibTeX into a `.bib' file."
-  (let ((file (make-temp-file "org-tangle-" nil ".org"))
-        (bib "@Misc{example,
+  (let ((bib "@Misc{example,
   author = {Richard Stallman and {contributors}},
   title = {{GNU} {Emacs}},
   publisher = {Free Software Foundation},
   url = {https://www.emacs.org/},
 }"))
-    (unwind-protect
-        (with-current-buffer (find-file-noselect file)
-          (insert (format "#+begin_src bibtex :tangle yes
+    (org-test-with-temp-text-in-file
+        (format "#+begin_src bibtex :tangle yes
 %s
-#+end_src"
-                          bib))
-          (org-babel-tangle)
-          (let ((bib-file
-                 (if (fboundp 'file-name-with-extension)
-                     (file-name-with-extension file "bib")
-                   ;; Emacs <28
-                   (concat (file-name-sans-extension file) "." "bib"))))
-            (should (file-exists-p bib-file))
-            (should (string= (string-trim (org-file-contents bib-file))
-                             bib))))
-      (delete-file file))))
+#+end_src" bib)
+      (org-babel-tangle)
+      (let ((bib-file
+             (if (fboundp 'file-name-with-extension)
+                 (file-name-with-extension file "bib")
+               ;; Emacs <28
+               (concat (file-name-sans-extension file) "." "bib"))))
+        (should (file-exists-p bib-file))
+        (should (string= (string-trim (org-file-contents bib-file))
+                         bib))))))
 
 ;; See https://list.orgmode.org/87msfxd81c.fsf@localhost/T/#t
 (ert-deftest ob-tangle/tangle-from-capture-buffer ()
diff --git a/testing/lisp/test-org-agenda.el b/testing/lisp/test-org-agenda.el
index 47425a4e9..1abc53028 100644
--- a/testing/lisp/test-org-agenda.el
+++ b/testing/lisp/test-org-agenda.el
@@ -378,11 +378,13 @@ test-org-agenda/set-priority
     ;; `org-today' or not.
     (org-agenda-list nil "<2017-07-19 Wed>")
     (set-buffer org-agenda-buffer-name)
-    (should
-     (progn (goto-line 3)
-	    (org-agenda-priority ?B)
-	    (looking-at-p " *agenda-file:Scheduled: *\\[#B\\] test agenda"))))
-  (org-test-agenda--kill-all-agendas))
+    (unwind-protect
+        (should
+         (progn (goto-line 3)
+                (org-agenda-priority ?B)
+                (looking-at-p " *agenda-file:Scheduled: *\\[#B\\] test agenda")))
+      (org-test-agenda--kill-all-agendas)
+      (org-test-kill-buffer "agenda-file.org"))))
 
 (ert-deftest test-org-agenda/sticky-agenda-name ()
   "Agenda buffer name after having created one sticky agenda buffer."
diff --git a/testing/lisp/test-org-capture.el b/testing/lisp/test-org-capture.el
index 494fee4cf..1a0496046 100644
--- a/testing/lisp/test-org-capture.el
+++ b/testing/lisp/test-org-capture.el
@@ -1089,28 +1089,22 @@ test-org-capture/org-capture-expand-olp
   (should
    (equal
     '("A" "B" "C")
-    (let ((file (make-temp-file "org-test")))
-      (unwind-protect
-          (org-capture-expand-olp file "A" "B" "C")
-        (delete-file file)))))
+    (org-test-with-temp-text-in-file ""
+      (org-capture-expand-olp file "A" "B" "C"))))
   ;; The current buffer during the funcall of the lambda is the temporary
   ;; test file.
   (should
-   (let ((file (make-temp-file "org-test")))
+   (org-test-with-temp-text-in-file ""
      (equal
       file
-      (unwind-protect
-          (org-capture-expand-olp file (lambda () (buffer-file-name)))
-        (delete-file file)))))
+      (org-capture-expand-olp file (lambda () (buffer-file-name))))))
   ;; `org-capture-expand-olp' rejects outline path that is not
   ;; inlined.
   (should-error
    (equal
     '("A" "B" "C")
-    (let ((file (make-temp-file "org-test")))
-      (unwind-protect
-          (org-capture-expand-olp file '("A" "B" "C"))
-        (delete-file file))))))
+    (org-test-with-temp-text-in-file ""
+      (org-capture-expand-olp file '("A" "B" "C"))))))
 
 (provide 'test-org-capture)
 ;;; test-org-capture.el ends here
diff --git a/testing/lisp/test-org-protocol.el b/testing/lisp/test-org-protocol.el
index 6429432a3..d31940d3e 100644
--- a/testing/lisp/test-org-protocol.el
+++ b/testing/lisp/test-org-protocol.el
@@ -164,12 +164,16 @@ test-org-protocol/org-protocol-capture-file
 	 (temp-file-name (make-temp-file "org-protocol-test"))
 	 (org-capture-templates
 	  `(("t" "Test" plain (file ,temp-file-name) "%a\n%i\n" :kill-buffer t))))
-    (let ((uri "/org-protocol:/capture:/t/file%3A%2F%2F%2Fetc%2Fmailcap/Triple%20Slash/Body"))
-      (should (null (org-protocol-check-filename-for-protocol uri (list uri) nil)))
-      (should (string= (buffer-string) "[[file:///etc/mailcap][Triple Slash]]\nBody")))
-    (let ((uri "/org-protocol:/capture?template=t&url=file%3A%2F%2F%2Fetc%2Fmailcap&title=Triple%20Slash&body=Body"))
-      (should (null (org-protocol-check-filename-for-protocol uri (list uri) nil)))
-      (should (string= (buffer-string) "[[file:///etc/mailcap][Triple Slash]]\nBody")))))
+    (unwind-protect
+        (progn
+          (let ((uri "/org-protocol:/capture:/t/file%3A%2F%2F%2Fetc%2Fmailcap/Triple%20Slash/Body"))
+            (should (null (org-protocol-check-filename-for-protocol uri (list uri) nil)))
+            (should (string= (buffer-string) "[[file:///etc/mailcap][Triple Slash]]\nBody")))
+          (let ((uri "/org-protocol:/capture?template=t&url=file%3A%2F%2F%2Fetc%2Fmailcap&title=Triple%20Slash&body=Body"))
+            (should (null (org-protocol-check-filename-for-protocol uri (list uri) nil)))
+            (should (string= (buffer-string) "[[file:///etc/mailcap][Triple Slash]]\nBody"))))
+      (org-test-kill-buffer (get-file-buffer temp-file-name))
+      (delete-file temp-file-name))))
 
 (ert-deftest test-org-protocol/org-protocol-open-source ()
   "Test org-protocol://open-source links."
diff --git a/testing/lisp/test-ox.el b/testing/lisp/test-ox.el
index 279642d94..ddf37a5f6 100644
--- a/testing/lisp/test-ox.el
+++ b/testing/lisp/test-ox.el
@@ -75,7 +75,8 @@ test-org-export/org-export-copy-buffer
           "* Heading"
           (with-temp-buffer
             (insert-file-contents file)
-            (buffer-string)))))))
+            (buffer-string))))
+        (org-test-kill-buffer (current-buffer)))))
   ;; The copy must not show when re-opening the original file.
   (org-test-with-temp-text-in-file
       "* Heading"
diff --git a/testing/org-test.el b/testing/org-test.el
index 46ec56608..a6e14e3a5 100644
--- a/testing/org-test.el
+++ b/testing/org-test.el
@@ -116,6 +116,15 @@ org-test-compare-with-file
 If file is not given, search for a file named after the test
 currently executed.")
 
+(defun org-test-kill-buffer (buffer)
+  "Kill BUFFER like `kill-buffer' but without user interaction."
+  (setq buffer (get-buffer buffer))
+  (when (and buffer (buffer-live-p buffer))
+    (with-current-buffer buffer
+      ;; Prevent "Buffer *temp* modified; kill anyway?".
+      (set-buffer-modified-p nil)
+      (kill-buffer))))
+
 (defmacro org-test-at-id (id &rest body)
   "Run body after placing the point in the headline identified by ID."
   (declare (indent 1) (debug t))
@@ -135,7 +144,7 @@ org-test-at-id
 	       (error nil))
 	     (save-restriction ,@body)))
        (unless (or visited-p (not to-be-removed))
-	 (kill-buffer to-be-removed)))))
+         (org-test-kill-buffer to-be-removed)))))
 
 (defmacro org-test-in-example-file (file &rest body)
   "Execute body in the Org example file."
@@ -158,8 +167,8 @@ org-test-in-example-file
 	       (org-fold-show-all '(blocks)))
 	   (error nil))
 	 (setq results (save-restriction ,@body))))
-     (unless visited-p
-       (kill-buffer to-be-removed))
+     (unless (or visited-p (not to-be-removed))
+       (org-test-kill-buffer to-be-removed))
      results))
 
 (defmacro org-test-at-marker (file marker &rest body)
@@ -213,12 +222,7 @@ org-test-with-temp-text-in-file
 	   (org-mode)
 	   (progn ,@body))
        (let ((kill-buffer-query-functions nil))
-	 (when buffer
-	   (set-buffer buffer)
-	   ;; Ignore changes, we're deleting the file in the next step
-	   ;; anyways.
-	   (set-buffer-modified-p nil)
-	   (kill-buffer))
+         (org-test-kill-buffer buffer)
 	 (delete-file file)))))
 
 (defun org-test-table-target-expect (target &optional expect laps &rest tblfm)
@@ -451,7 +455,7 @@ org-test-touch-all-examples
 (defun org-test-kill-all-examples ()
   (while org-test-buffers
     (let ((b (pop org-test-buffers)))
-      (when (buffer-live-p b) (kill-buffer b)))))
+      (org-test-kill-buffer b))))
 
 (defun org-test-update-id-locations ()
   (setq org-id-locations-file
-- 
2.51.0

Reply via email to