aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-05-05 03:15:14 -0500
committerCraig Jennings <c@cjennings.net>2026-05-05 03:15:14 -0500
commitcbd2334ee3a589bb9335e1bd2a26f3e906180c38 (patch)
tree4b6a981aea3251d0345ea99df65de116dabb865d
parent77fe06b0c6f01d1d76bdf503c1b12286ac29aa0a (diff)
downloadorg-drill-cbd2334ee3a589bb9335e1bd2a26f3e906180c38.tar.gz
org-drill-cbd2334ee3a589bb9335e1bd2a26f3e906180c38.zip
test: cover org-drill-time-to-inactive-org-timestamp (upstream #59)
I added a regression test for `org-drill-time-to-inactive-org-timestamp` to lock in the cherry-pick from commit 4c6e62a, which fixed upstream issue #59 on the GitLab tracker. Chipschap reported timestamps like `[Y-08-27 Wed 16:%]` getting written into DRILL_LAST_REVIEWED. The root cause is that Org 9.6+ dropped the angle brackets around `(cdr org-time-stamp-formats)`, so the original `(substring ... 1 -1)` started slicing off the leading `%` of `%Y` and the trailing `M` of `%M`. The fix took the Org 9.6+ branch via `(org-time-stamp-format t 'no-bracket)` instead. The new test file has 7 ERT tests across Normal, Boundary, and Error categories. The Error cases assert the output has no stray `%` characters and no literal `Y` in place of the year. I confirmed the same tests fail when I drop in the original buggy implementation, so they catch the bug shape from the report.
-rw-r--r--tests/test-org-drill-time-to-inactive-org-timestamp.el90
1 files changed, 90 insertions, 0 deletions
diff --git a/tests/test-org-drill-time-to-inactive-org-timestamp.el b/tests/test-org-drill-time-to-inactive-org-timestamp.el
new file mode 100644
index 0000000..8676ece
--- /dev/null
+++ b/tests/test-org-drill-time-to-inactive-org-timestamp.el
@@ -0,0 +1,90 @@
+;;; test-org-drill-time-to-inactive-org-timestamp.el --- Tests for inactive org-timestamp formatting -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; Regression tests for `org-drill-time-to-inactive-org-timestamp'.
+;;
+;; Upstream issue #59 (chipschap, 2025-08-28) reported broken timestamps
+;; like `[Y-08-27 Wed 16:%]' written into DRILL_LAST_REVIEWED. Root
+;; cause: in Org 9.6+, `(cdr org-time-stamp-formats)' returns the format
+;; string without the angle brackets it had pre-9.6. The original
+;; `(substring ... 1 -1)' assumed brackets and stripped the leading `%'
+;; of `%Y' and the trailing `M' of `%M', producing `Y-%m-%d %a %H:%' as
+;; the format directive. format-time-string then interpolated `Y' as a
+;; literal and left a trailing `%]' in the output.
+;;
+;; Cherry-pick 4c6e62a switched the Org 9.6+ path to
+;; `(org-time-stamp-format t 'no-bracket)' (which despite the arg name
+;; *does* return a bracketed format). These tests lock that behavior
+;; in.
+
+;;; Code:
+
+(require 'ert)
+(require 'org-drill)
+
+(defconst test-tts-fixed-time
+ ;; Saturday 2024-06-15 12:30:00 local time.
+ (encode-time 0 30 12 15 6 2024)
+ "Fixed reference time used by these tests.")
+
+(defconst test-tts-timestamp-regex
+ "\\`\\[[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} [A-Z][a-z][a-z] [0-9]\\{2\\}:[0-9]\\{2\\}\\]\\'"
+ "Anchored regex for a well-formed inactive org-timestamp like `[2024-06-15 Sat 12:30]'.")
+
+;;;; Normal cases
+
+(ert-deftest test-org-drill-time-to-inactive-org-timestamp-normal-fixed-time-matches-shape ()
+ "A normal time produces a bracketed YYYY-MM-DD Day HH:MM string."
+ (let ((result (org-drill-time-to-inactive-org-timestamp test-tts-fixed-time)))
+ (should (string-match-p test-tts-timestamp-regex result))))
+
+(ert-deftest test-org-drill-time-to-inactive-org-timestamp-normal-fixed-time-exact-string ()
+ "The fixed reference time produces the expected literal timestamp."
+ (should (equal (org-drill-time-to-inactive-org-timestamp test-tts-fixed-time)
+ "[2024-06-15 Sat 12:30]")))
+
+;;;; Boundary cases
+
+(ert-deftest test-org-drill-time-to-inactive-org-timestamp-boundary-midnight ()
+ "Midnight (00:00) formats correctly with leading zeros."
+ (let* ((midnight (encode-time 0 0 0 1 1 2024))
+ (result (org-drill-time-to-inactive-org-timestamp midnight)))
+ (should (string-match-p test-tts-timestamp-regex result))
+ (should (string-match-p "00:00\\]\\'" result))))
+
+(ert-deftest test-org-drill-time-to-inactive-org-timestamp-boundary-end-of-year ()
+ "Last minute of the year formats correctly."
+ (let* ((eoy (encode-time 0 59 23 31 12 2024))
+ (result (org-drill-time-to-inactive-org-timestamp eoy)))
+ (should (string-match-p test-tts-timestamp-regex result))
+ (should (string-match-p "2024-12-31" result))
+ (should (string-match-p "23:59\\]\\'" result))))
+
+(ert-deftest test-org-drill-time-to-inactive-org-timestamp-boundary-leap-day ()
+ "Feb 29 on a leap year formats correctly."
+ (let* ((leap (encode-time 0 0 12 29 2 2024))
+ (result (org-drill-time-to-inactive-org-timestamp leap)))
+ (should (string-match-p test-tts-timestamp-regex result))
+ (should (string-match-p "2024-02-29" result))))
+
+;;;; Error / regression cases
+
+(ert-deftest test-org-drill-time-to-inactive-org-timestamp-error-no-stray-percent-directives ()
+ "Issue #59 regression: output must not contain stray `%' characters.
+
+Pre-fix, Org 9.6+ produced timestamps like `[Y-08-27 Wed 16:%]' because the
+Org 9.5-shaped substring slicing dropped the leading `%' of `%Y' and the
+trailing `M' of `%M'. Any literal `%' in the output indicates the format
+string lost a directive."
+ (let ((result (org-drill-time-to-inactive-org-timestamp test-tts-fixed-time)))
+ (should-not (string-match-p "%" result))))
+
+(ert-deftest test-org-drill-time-to-inactive-org-timestamp-error-year-not-literal-Y ()
+ "Issue #59 regression: the year must be four digits, not the literal char `Y'."
+ (let ((result (org-drill-time-to-inactive-org-timestamp test-tts-fixed-time)))
+ (should-not (string-match-p "\\[Y-" result))
+ (should (string-match-p "\\[2024-" result))))
+
+(provide 'test-org-drill-time-to-inactive-org-timestamp)
+
+;;; test-org-drill-time-to-inactive-org-timestamp.el ends here