Hello! I was trying to solve my first bug report. I decided the first thing I needed to do was to try and find the appropriate tests or create them myself. Well after a decent bit of effort creating these patches, I finally discovered that I am simply unable to reproduce the bug. I should remember this lesson.
Please enjoy these new tests! I tested them on emacs 30.2 and emacs built from the development branch at commit 9663c959c73 (2025-04-07). I should probably start running my tests on older emacs too... Thanks, Morgan
>From 9a2ce953e6d5b42f1ee0f8528451c28563428b48 Mon Sep 17 00:00:00 2001 From: Morgan Smith <[email protected]> Date: Sun, 5 Oct 2025 16:15:39 -0400 Subject: [PATCH 1/3] test-org/org-log-done: Refactor redundant code * testing/lisp/test-org.el (test-org/org-log-done): Refactor redundant code. Expand docstring. Add two TODOs. --- testing/lisp/test-org.el | 173 +++++++++++++-------------------------- 1 file changed, 59 insertions(+), 114 deletions(-) diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el index 0dc7cb1a2..b5851b43a 100644 --- a/testing/lisp/test-org.el +++ b/testing/lisp/test-org.el @@ -8899,131 +8899,76 @@ test-org/auto-repeat-maybe (buffer-string)))))) (ert-deftest test-org/org-log-done () - "Test `org-log-done' specifications." - ;; nil value. - (should - (string= - "* DONE task" - (let ((org-log-done nil) - (org-todo-keywords '((sequence "TODO" "DONE")))) - (org-test-with-temp-text - "* TODO task" - (org-todo "DONE") - (when (memq 'org-add-log-note (default-value 'post-command-hook)) - (org-add-log-note)) - (buffer-string))))) - ;; `time' value. - (should - (string= - (format - "* DONE task -CLOSED: %s" - (org-test-with-temp-text "" - (org-insert-timestamp (current-time) t t) - (buffer-string))) - (let ((org-log-done 'time) - (org-log-done-with-time t) - (org-todo-keywords '((sequence "TODO" "DONE")))) - (org-test-with-temp-text - "* TODO task" - (org-todo "DONE") - (when (memq 'org-add-log-note (default-value 'post-command-hook)) - (org-add-log-note)) - (buffer-string))))) - (should - (string= - (format - "* DONE task -CLOSED: %s" - (org-test-with-temp-text "" - (org-insert-timestamp (current-time) nil t) - (buffer-string))) - (let ((org-log-done 'time) - (org-log-done-with-time nil) - (org-todo-keywords '((sequence "TODO" "DONE")))) - (org-test-with-temp-text - "* TODO task" - (org-todo "DONE") - (when (memq 'org-add-log-note (default-value 'post-command-hook)) - (org-add-log-note)) - (buffer-string))))) - ;; TODO: Test `note' value. - ;; Test startup overrides. - (should - (string= - "#+STARTUP: nologdone -* DONE task" - (let ((org-log-done 'time) - (org-todo-keywords '((sequence "TODO" "DONE")))) - (org-test-with-temp-text - "#+STARTUP: nologdone -<point>* TODO task" - (org-set-regexps-and-options) - (org-todo "DONE") - (when (memq 'org-add-log-note (default-value 'post-command-hook)) - (org-add-log-note)) - (buffer-string))))) - (should - (string= - (format - "#+STARTUP: logdone + "Test `org-log-done' specifications. +Behavior can be modified by setting `org-log-done', by keywords in +\"#+STARTUP:\" or by special syntax in `org-todo-keywords'." + ;; TODO: Test special syntax in `org-todo-keywords'. + (let ((time-string + (org-test-with-temp-text "" + (org-insert-timestamp (current-time) t t) + (buffer-string))) + (date-string + (org-test-with-temp-text "" + (org-insert-timestamp (current-time) nil t) + (buffer-string)))) + (cl-flet + ((test-org-log-done + (org-log-done-val org-log-done-with-time-val + test-string expected-string) + (let ((org-log-done org-log-done-val) + (org-log-done-with-time org-log-done-with-time-val)) + (should + (string= + expected-string + (org-test-with-temp-text + test-string + (org-set-regexps-and-options) + (org-todo "DONE") + (when (memq 'org-add-log-note (default-value 'post-command-hook)) + (org-add-log-note)) + (buffer-string))))))) + (let ((org-todo-keywords '((sequence "TODO" "DONE")))) + (test-org-log-done nil t "* TODO task" "* DONE task") + (test-org-log-done 'time t "* TODO task" + (concat "* DONE task\nCLOSED: " time-string)) + (test-org-log-done 'time nil"* TODO task" + (concat "* DONE task\nCLOSED: " date-string)) + ;; TODO: Test org-log-done `note' value. + ;; Test startup overrides. + (test-org-log-done 'time t "#+STARTUP: nologdone\n<point>* TODO task" + "#+STARTUP: nologdone +* DONE task") + (test-org-log-done nil t "#+STARTUP: logdone\n<point>* TODO task" + (concat "#+STARTUP: logdone * DONE task -CLOSED: %s" - (org-test-with-temp-text "" - (org-insert-timestamp (current-time) t t) - (buffer-string))) - (let ((org-log-done nil) - (org-log-done-with-time t) - (org-todo-keywords '((sequence "TODO" "DONE")))) - (org-test-with-temp-text - "#+STARTUP: logdone -<point>* TODO task" - (org-set-regexps-and-options) - (org-todo "DONE") - (when (memq 'org-add-log-note (default-value 'post-command-hook)) - (org-add-log-note)) - (buffer-string))))) - ;; Test local property overrides. - (should - (string= - "* DONE task +CLOSED: " time-string)) + ;; TODO: Test "#+STARTUP: lognotedone" + ;; Test local property overrides. + ;; TODO: Test `lognotedone' property. + (test-org-log-done 'time t + "* TODO task :PROPERTIES: :LOGGING: nil :END:" - (let ((org-log-done 'time) - (org-todo-keywords '((sequence "TODO" "DONE")))) - (org-test-with-temp-text - "* TODO task + + "* DONE task :PROPERTIES: :LOGGING: nil +:END:") + + (test-org-log-done 'nil t + "* TODO task +:PROPERTIES: +:LOGGING: logdone :END:" - (org-todo "DONE") - (when (memq 'org-add-log-note (default-value 'post-command-hook)) - (org-add-log-note)) - (buffer-string))))) - (should - (string= - (format - "* DONE task + + (format + "* DONE task CLOSED: %s :PROPERTIES: :LOGGING: logdone :END:" - (org-test-with-temp-text "" - (org-insert-timestamp (current-time) t t) - (buffer-string))) - (let ((org-log-done nil) - (org-log-done-with-time t) - (org-todo-keywords '((sequence "TODO" "DONE")))) - (org-test-with-temp-text - "* TODO task -:PROPERTIES: -:LOGGING: logdone -:END:" - (org-todo "DONE") - (when (memq 'org-add-log-note (default-value 'post-command-hook)) - (org-add-log-note)) - (buffer-string)))))) + time-string))))) (ert-deftest test-org/org-todo-prefix () "Test `org-todo' prefix arg behavior." base-commit: 3a0aed0c6e11469dd9e970b87570e64c789c0687 -- 2.51.0
>From d22ceaa0197030e812adc8a59943f885cd7e2385 Mon Sep 17 00:00:00 2001 From: Morgan Smith <[email protected]> Date: Sun, 5 Oct 2025 17:03:49 -0400 Subject: [PATCH 2/3] test-org/org-log-done: Test setting logging in `org-todo-keywords' * testing/lisp/test-org.el (test-org/org-log-done): Add a test for the "!" syntax in `org-todo-keywords'. --- testing/lisp/test-org.el | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el index b5851b43a..555ea8813 100644 --- a/testing/lisp/test-org.el +++ b/testing/lisp/test-org.el @@ -8902,7 +8902,6 @@ test-org/org-log-done "Test `org-log-done' specifications. Behavior can be modified by setting `org-log-done', by keywords in \"#+STARTUP:\" or by special syntax in `org-todo-keywords'." - ;; TODO: Test special syntax in `org-todo-keywords'. (let ((time-string (org-test-with-temp-text "" (org-insert-timestamp (current-time) t t) @@ -8968,7 +8967,18 @@ test-org/org-log-done :PROPERTIES: :LOGGING: logdone :END:" - time-string))))) + time-string))) + ;; Test special syntax in `org-todo-keywords'. + ;; TODO: Test "DONE(@)" which will create a note + (dolist (org-todo-keywords + '(((sequence "TODO" "DONE(!)")) + ((sequence "TODO(/!)" "DONE")))) + (test-org-log-done 'time t "* TODO task" + (concat "* DONE task\nCLOSED: " time-string + "\n- State \"DONE\" from \"TODO\" " time-string)) + (test-org-log-done nil t "* TODO task" + (concat "* DONE task +- State \"DONE\" from \"TODO\" " time-string)))))) (ert-deftest test-org/org-todo-prefix () "Test `org-todo' prefix arg behavior." -- 2.51.0
>From 8ce1fc116188867b894294e5923fd5a7b6cdb271 Mon Sep 17 00:00:00 2001 From: Morgan Smith <[email protected]> Date: Sun, 5 Oct 2025 18:13:49 -0400 Subject: [PATCH 3/3] test-org/org-log-done: Add tests for recording notes * testing/lisp/test-org.el (test-org/org-log-done): Set `org-log-buffer-setup-hook' to instantly take a note without user input. Test taking a note using the variable `org-log-done', the startup property and drawer property "lognotedone", and the "@" syntax in `org-todo-keywords'. --- testing/lisp/test-org.el | 61 ++++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 11 deletions(-) diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el index 555ea8813..96b45fbb8 100644 --- a/testing/lisp/test-org.el +++ b/testing/lisp/test-org.el @@ -8910,12 +8910,16 @@ test-org/org-log-done (org-test-with-temp-text "" (org-insert-timestamp (current-time) nil t) (buffer-string)))) - (cl-flet - ((test-org-log-done + (cl-flet* + ((test-org-insert-note () + (insert "note") + (org-ctrl-c-ctrl-c)) + (test-org-log-done (org-log-done-val org-log-done-with-time-val test-string expected-string) (let ((org-log-done org-log-done-val) - (org-log-done-with-time org-log-done-with-time-val)) + (org-log-done-with-time org-log-done-with-time-val) + (org-log-buffer-setup-hook (list #'test-org-insert-note))) (should (string= expected-string @@ -8932,7 +8936,11 @@ test-org/org-log-done (concat "* DONE task\nCLOSED: " time-string)) (test-org-log-done 'time nil"* TODO task" (concat "* DONE task\nCLOSED: " date-string)) - ;; TODO: Test org-log-done `note' value. + (test-org-log-done 'note t "* TODO task" + (concat "* DONE task\nCLOSED: " time-string + " +- CLOSING NOTE " time-string " \\\\ + note")) ;; Test startup overrides. (test-org-log-done 'time t "#+STARTUP: nologdone\n<point>* TODO task" "#+STARTUP: nologdone @@ -8941,7 +8949,12 @@ test-org/org-log-done (concat "#+STARTUP: logdone * DONE task CLOSED: " time-string)) - ;; TODO: Test "#+STARTUP: lognotedone" + (test-org-log-done nil t "#+STARTUP: lognotedone\n<point>* TODO task" + (concat "#+STARTUP: lognotedone +* DONE task\nCLOSED: " time-string + " +- CLOSING NOTE " time-string " \\\\ + note")) ;; Test local property overrides. ;; TODO: Test `lognotedone' property. (test-org-log-done 'time t @@ -8967,18 +8980,44 @@ test-org/org-log-done :PROPERTIES: :LOGGING: logdone :END:" - time-string))) + time-string)) + (test-org-log-done 'nil t + "* TODO task +:PROPERTIES: +:LOGGING: lognotedone +:END:" + (format + "* DONE task +CLOSED: %s +:PROPERTIES: +:LOGGING: lognotedone +:END: +- CLOSING NOTE %s \\\\ + note" + time-string time-string))) ;; Test special syntax in `org-todo-keywords'. - ;; TODO: Test "DONE(@)" which will create a note (dolist (org-todo-keywords '(((sequence "TODO" "DONE(!)")) ((sequence "TODO(/!)" "DONE")))) - (test-org-log-done 'time t "* TODO task" - (concat "* DONE task\nCLOSED: " time-string - "\n- State \"DONE\" from \"TODO\" " time-string)) + (test-org-log-done + 'time t "* TODO task" + (concat "* DONE task\nCLOSED: " time-string + "\n- State \"DONE\" from \"TODO\" " time-string)) (test-org-log-done nil t "* TODO task" (concat "* DONE task -- State \"DONE\" from \"TODO\" " time-string)))))) +- State \"DONE\" from \"TODO\" " time-string))) + (dolist (org-todo-keywords + '(((sequence "TODO" "DONE(@)")) + ((sequence "TODO(/@)" "DONE")))) + (test-org-log-done + 'time t "* TODO task" + (concat "* DONE task\nCLOSED: " time-string + "\n- State \"DONE\" from \"TODO\" " time-string " \\\\ + note")) + (test-org-log-done nil t "* TODO task" + (concat "* DONE task +- State \"DONE\" from \"TODO\" " time-string " \\\\ + note")))))) (ert-deftest test-org/org-todo-prefix () "Test `org-todo' prefix arg behavior." -- 2.51.0
