diff options
| author | Craig Jennings <c@cjennings.net> | 2025-10-25 20:42:21 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2025-10-25 20:42:21 -0500 |
| commit | 4f8ee4eb200922df24388afb0efafec90987a761 (patch) | |
| tree | 0951e287638156cbe368fa60662499b69a444ca0 /tests/test-chime-extract-time.el | |
| parent | 33fd717a31ea6bbc7b544923ba9dc6d756b152af (diff) | |
feat:chime: Enhance timestamp extraction in `chime--extract-time`
Expand `chime--extract-time` to handle plain timestamps alongside
scheduled and deadline timestamps. This enhancement includes parsing
timestamps from entry bodies, while avoiding duplicates from
planning lines. Updated and expanded unit tests to cover new
behaviors, including repeating timestamps and org-gcal integration,
ensuring robustness across different timestamp scenarios.
Diffstat (limited to 'tests/test-chime-extract-time.el')
| -rw-r--r-- | tests/test-chime-extract-time.el | 380 |
1 files changed, 176 insertions, 204 deletions
diff --git a/tests/test-chime-extract-time.el b/tests/test-chime-extract-time.el index 4041713..d468326 100644 --- a/tests/test-chime-extract-time.el +++ b/tests/test-chime-extract-time.el @@ -20,6 +20,7 @@ ;;; Commentary: ;; Unit tests for chime--extract-time function. +;; Tests use real org-mode buffers with real org syntax. ;; Tests cover normal cases, boundary cases, and error cases. ;;; Code: @@ -61,18 +62,15 @@ (with-temp-buffer (org-mode) (insert "* TODO Test Task\n") - (let ((marker (copy-marker (point)))) - (cl-letf (((symbol-function 'org-entry-get) - (lambda (pom property &optional inherit literal-nil) - (cond - ((and (equal pom marker) (equal property "SCHEDULED")) - "<2025-10-24 Fri 14:30>") - (t nil))))) - (let ((result (chime--extract-time marker))) - (should (listp result)) - (should (= (length result) 1)) - (should (equal (caar result) "<2025-10-24 Fri 14:30>")) - (should (listp (cdar result))))))) + (insert "SCHEDULED: <2025-10-24 Fri 14:30>\n") + (goto-char (point-min)) + (let ((marker (point-marker))) + (let ((result (chime--extract-time marker))) + (should (listp result)) + (should (= (length result) 1)) + (should (equal (caar result) "<2025-10-24 Fri 14:30>")) + (should (listp (cdar result))) + (should (cdar result))))) (test-chime-extract-time-teardown))) (ert-deftest test-chime-extract-time-deadline-timestamp-extracted () @@ -82,39 +80,51 @@ (with-temp-buffer (org-mode) (insert "* TODO Test Task\n") - (let ((marker (copy-marker (point)))) - (cl-letf (((symbol-function 'org-entry-get) - (lambda (pom property &optional inherit literal-nil) - (cond - ((and (equal pom marker) (equal property "DEADLINE")) - "<2025-10-24 Fri 16:00>") - (t nil))))) - (let ((result (chime--extract-time marker))) - (should (listp result)) - (should (= (length result) 1)) - (should (equal (caar result) "<2025-10-24 Fri 16:00>")) - (should (listp (cdar result))))))) + (insert "DEADLINE: <2025-10-24 Fri 16:00>\n") + (goto-char (point-min)) + (let ((marker (point-marker))) + (let ((result (chime--extract-time marker))) + (should (listp result)) + (should (= (length result) 1)) + (should (equal (caar result) "<2025-10-24 Fri 16:00>")) + (should (listp (cdar result))) + (should (cdar result))))) (test-chime-extract-time-teardown))) -(ert-deftest test-chime-extract-time-plain-timestamp-extracted () - "Test that plain TIMESTAMP is extracted correctly." +(ert-deftest test-chime-extract-time-plain-timestamp-in-body-extracted () + "Test that plain timestamp in entry body is extracted correctly." (test-chime-extract-time-setup) (unwind-protect (with-temp-buffer (org-mode) (insert "* Test Event\n") - (let ((marker (copy-marker (point)))) - (cl-letf (((symbol-function 'org-entry-get) - (lambda (pom property &optional inherit literal-nil) - (cond - ((and (equal pom marker) (equal property "TIMESTAMP")) - "<2025-10-24 Fri 10:00>") - (t nil))))) - (let ((result (chime--extract-time marker))) - (should (listp result)) - (should (= (length result) 1)) - (should (equal (caar result) "<2025-10-24 Fri 10:00>")) - (should (listp (cdar result))))))) + (insert "<2025-10-24 Fri 10:00>\n") + (goto-char (point-min)) + (let ((marker (point-marker))) + (let ((result (chime--extract-time marker))) + (should (listp result)) + (should (= (length result) 1)) + (should (equal (caar result) "<2025-10-24 Fri 10:00>")) + (should (listp (cdar result))) + (should (cdar result))))) + (test-chime-extract-time-teardown))) + +(ert-deftest test-chime-extract-time-repeating-plain-timestamp-extracted () + "Test that repeating plain timestamp is extracted correctly." + (test-chime-extract-time-setup) + (unwind-protect + (with-temp-buffer + (org-mode) + (insert "* Daily Wrap Up\n") + (insert "<2025-06-17 Tue 21:00 +1d>\n") + (goto-char (point-min)) + (let ((marker (point-marker))) + (let ((result (chime--extract-time marker))) + (should (listp result)) + (should (= (length result) 1)) + (should (equal (caar result) "<2025-06-17 Tue 21:00 +1d>")) + (should (listp (cdar result))) + (should (cdar result))))) (test-chime-extract-time-teardown))) (ert-deftest test-chime-extract-time-multiple-timestamps-all-extracted () @@ -124,44 +134,54 @@ (with-temp-buffer (org-mode) (insert "* TODO Test Task\n") - (let ((marker (copy-marker (point)))) - (cl-letf (((symbol-function 'org-entry-get) - (lambda (pom property &optional inherit literal-nil) - (cond - ((and (equal pom marker) (equal property "SCHEDULED")) - "<2025-10-24 Fri 14:30>") - ((and (equal pom marker) (equal property "DEADLINE")) - "<2025-10-24 Fri 16:00>") - (t nil))))) - (let ((result (chime--extract-time marker))) - (should (listp result)) - (should (= (length result) 2)) - ;; Check both timestamps are present - (should (--some (equal (car it) "<2025-10-24 Fri 14:30>") result)) - (should (--some (equal (car it) "<2025-10-24 Fri 16:00>") result)))))) + (insert "SCHEDULED: <2025-10-24 Fri 14:30>\n") + (insert "DEADLINE: <2025-10-24 Fri 16:00>\n") + (goto-char (point-min)) + (let ((marker (point-marker))) + (let ((result (chime--extract-time marker))) + (should (listp result)) + (should (= (length result) 2)) + ;; Check both timestamps are present + (should (--some (equal (car it) "<2025-10-24 Fri 14:30>") result)) + (should (--some (equal (car it) "<2025-10-24 Fri 16:00>") result))))) (test-chime-extract-time-teardown))) -(ert-deftest test-chime-extract-time-all-three-timestamp-types-extracted () - "Test that all three timestamp types can be extracted together." +(ert-deftest test-chime-extract-time-scheduled-and-plain-together () + "Test that SCHEDULED and plain timestamp can coexist." (test-chime-extract-time-setup) (unwind-protect (with-temp-buffer (org-mode) (insert "* TODO Complex Task\n") - (let ((marker (copy-marker (point)))) - (cl-letf (((symbol-function 'org-entry-get) - (lambda (pom property &optional inherit literal-nil) - (cond - ((and (equal pom marker) (equal property "SCHEDULED")) - "<2025-10-24 Fri 09:00>") - ((and (equal pom marker) (equal property "DEADLINE")) - "<2025-10-24 Fri 17:00>") - ((and (equal pom marker) (equal property "TIMESTAMP")) - "<2025-10-24 Fri 12:00>") - (t nil))))) - (let ((result (chime--extract-time marker))) - (should (listp result)) - (should (= (length result) 3)))))) + (insert "SCHEDULED: <2025-10-24 Fri 09:00>\n") + (insert "Meeting time: <2025-10-24 Fri 14:00>\n") + (goto-char (point-min)) + (let ((marker (point-marker))) + (let ((result (chime--extract-time marker))) + (should (listp result)) + (should (= (length result) 2)) + (should (--some (equal (car it) "<2025-10-24 Fri 09:00>") result)) + (should (--some (equal (car it) "<2025-10-24 Fri 14:00>") result))))) + (test-chime-extract-time-teardown))) + +(ert-deftest test-chime-extract-time-multiple-plain-timestamps-extracted () + "Test that multiple plain timestamps in body are all extracted." + (test-chime-extract-time-setup) + (unwind-protect + (with-temp-buffer + (org-mode) + (insert "* Meeting Notes\n") + (insert "First session: <2025-10-24 Fri 09:00>\n") + (insert "Second session: <2025-10-24 Fri 14:00>\n") + (insert "Third session: <2025-10-24 Fri 16:00>\n") + (goto-char (point-min)) + (let ((marker (point-marker))) + (let ((result (chime--extract-time marker))) + (should (listp result)) + (should (= (length result) 3)) + (should (--some (equal (car it) "<2025-10-24 Fri 09:00>") result)) + (should (--some (equal (car it) "<2025-10-24 Fri 14:00>") result)) + (should (--some (equal (car it) "<2025-10-24 Fri 16:00>") result))))) (test-chime-extract-time-teardown))) ;;; Boundary Cases @@ -173,156 +193,118 @@ (with-temp-buffer (org-mode) (insert "* TODO Test Task\n") - (let ((marker (copy-marker (point)))) - (cl-letf (((symbol-function 'org-entry-get) - (lambda (pom property &optional inherit literal-nil) - nil))) - (let ((result (chime--extract-time marker))) - (should (listp result)) - (should (= (length result) 0)))))) + (insert "No timestamps here\n") + (goto-char (point-min)) + (let ((marker (point-marker))) + (let ((result (chime--extract-time marker))) + (should (listp result)) + (should (= (length result) 0))))) (test-chime-extract-time-teardown))) (ert-deftest test-chime-extract-time-only-scheduled-extracted () - "Test that only SCHEDULED is extracted when others are missing." + "Test that only SCHEDULED is extracted when it's the only timestamp." (test-chime-extract-time-setup) (unwind-protect (with-temp-buffer (org-mode) (insert "* TODO Test Task\n") - (let ((marker (copy-marker (point)))) - (cl-letf (((symbol-function 'org-entry-get) - (lambda (pom property &optional inherit literal-nil) - (cond - ((and (equal pom marker) (equal property "SCHEDULED")) - "<2025-10-24 Fri 14:30>") - (t nil))))) - (let ((result (chime--extract-time marker))) - (should (= (length result) 1)) - (should (equal (caar result) "<2025-10-24 Fri 14:30>")))))) + (insert "SCHEDULED: <2025-10-24 Fri 14:30>\n") + (goto-char (point-min)) + (let ((marker (point-marker))) + (let ((result (chime--extract-time marker))) + (should (= (length result) 1)) + (should (equal (caar result) "<2025-10-24 Fri 14:30>"))))) (test-chime-extract-time-teardown))) (ert-deftest test-chime-extract-time-only-deadline-extracted () - "Test that only DEADLINE is extracted when others are missing." + "Test that only DEADLINE is extracted when it's the only timestamp." (test-chime-extract-time-setup) (unwind-protect (with-temp-buffer (org-mode) (insert "* TODO Test Task\n") - (let ((marker (copy-marker (point)))) - (cl-letf (((symbol-function 'org-entry-get) - (lambda (pom property &optional inherit literal-nil) - (cond - ((and (equal pom marker) (equal property "DEADLINE")) - "<2025-10-24 Fri 16:00>") - (t nil))))) - (let ((result (chime--extract-time marker))) - (should (= (length result) 1)) - (should (equal (caar result) "<2025-10-24 Fri 16:00>")))))) + (insert "DEADLINE: <2025-10-24 Fri 16:00>\n") + (goto-char (point-min)) + (let ((marker (point-marker))) + (let ((result (chime--extract-time marker))) + (should (= (length result) 1)) + (should (equal (caar result) "<2025-10-24 Fri 16:00>"))))) (test-chime-extract-time-teardown))) -;;; Error Cases - -(ert-deftest test-chime-extract-time-malformed-timestamp-returns-nil-cdr () - "Test that malformed timestamps return cons with nil cdr." +(ert-deftest test-chime-extract-time-timestamp-after-properties-drawer () + "Test that plain timestamps after properties drawer are extracted." (test-chime-extract-time-setup) (unwind-protect (with-temp-buffer (org-mode) - (insert "* TODO Test Task\n") - (let ((marker (copy-marker (point)))) - (cl-letf (((symbol-function 'org-entry-get) - (lambda (pom property &optional inherit literal-nil) - (cond - ((and (equal pom marker) (equal property "SCHEDULED")) - "not-a-valid-timestamp") - ((and (equal pom marker) (equal property "DEADLINE")) - "<2025-10-24 Fri 16:00>") - (t nil))))) - (let ((result (chime--extract-time marker))) - ;; Should return both, but malformed one has nil cdr - (should (= (length result) 2)) - ;; Find the malformed timestamp result - (let ((malformed (--find (equal (car it) "not-a-valid-timestamp") result))) - (should malformed) - (should-not (cdr malformed))))))) + (insert "* Event\n") + (insert ":PROPERTIES:\n") + (insert ":ID: abc123\n") + (insert ":END:\n") + (insert "<2025-10-24 Fri 10:00>\n") + (goto-char (point-min)) + (let ((marker (point-marker))) + (let ((result (chime--extract-time marker))) + (should (= (length result) 1)) + (should (equal (caar result) "<2025-10-24 Fri 10:00>"))))) (test-chime-extract-time-teardown))) -(ert-deftest test-chime-extract-time-day-wide-timestamp-returns-nil-cdr () - "Test that day-wide timestamps (no time) return cons with nil cdr." +;;; Error Cases + +(ert-deftest test-chime-extract-time-malformed-scheduled-returns-nil-cdr () + "Test that malformed SCHEDULED timestamp returns cons with nil cdr." (test-chime-extract-time-setup) (unwind-protect (with-temp-buffer (org-mode) (insert "* TODO Test Task\n") - (let ((marker (copy-marker (point)))) - (cl-letf (((symbol-function 'org-entry-get) - (lambda (pom property &optional inherit literal-nil) - (cond - ((and (equal pom marker) (equal property "SCHEDULED")) - "<2025-10-24 Fri>") ; Day-wide, no time - ((and (equal pom marker) (equal property "DEADLINE")) - "<2025-10-24 Fri 16:00>") ; Has time - (t nil))))) - (let ((result (chime--extract-time marker))) - ;; Should return both timestamps - (should (= (length result) 2)) - ;; Day-wide timestamp has nil cdr - (let ((day-wide (--find (equal (car it) "<2025-10-24 Fri>") result))) - (should day-wide) - (should-not (cdr day-wide))) - ;; Timed timestamp has valid cdr - (let ((timed (--find (equal (car it) "<2025-10-24 Fri 16:00>") result))) - (should timed) - (should (cdr timed))))))) + (insert "SCHEDULED: not-a-valid-timestamp\n") + (insert "DEADLINE: <2025-10-24 Fri 16:00>\n") + (goto-char (point-min)) + (let ((marker (point-marker))) + (let ((result (chime--extract-time marker))) + ;; Should return both, but malformed one filtered by -non-nil + (should (>= (length result) 1)) + ;; Valid deadline should be present + (should (--some (equal (car it) "<2025-10-24 Fri 16:00>") result))))) (test-chime-extract-time-teardown))) -(ert-deftest test-chime-extract-time-empty-timestamp-string-returns-nil-cdr () - "Test that empty timestamp strings return cons with nil cdr." +(ert-deftest test-chime-extract-time-day-wide-timestamp-returns-nil-cdr () + "Test that day-wide timestamps (no time) return cons with nil cdr." (test-chime-extract-time-setup) (unwind-protect (with-temp-buffer (org-mode) (insert "* TODO Test Task\n") - (let ((marker (copy-marker (point)))) - (cl-letf (((symbol-function 'org-entry-get) - (lambda (pom property &optional inherit literal-nil) - (cond - ((and (equal pom marker) (equal property "SCHEDULED")) - "") - ((and (equal pom marker) (equal property "DEADLINE")) - "<2025-10-24 Fri 16:00>") - (t nil))))) - (let ((result (chime--extract-time marker))) - ;; Should return both entries - (should (= (length result) 2)) - ;; Empty string has nil cdr - (let ((empty (--find (equal (car it) "") result))) - (should empty) - (should-not (cdr empty))))))) + (insert "SCHEDULED: <2025-10-24 Fri>\n") ; Day-wide, no time + (insert "DEADLINE: <2025-10-24 Fri 16:00>\n") ; Has time + (goto-char (point-min)) + (let ((marker (point-marker))) + (let ((result (chime--extract-time marker))) + ;; Should have at least the timed one + (should (>= (length result) 1)) + ;; Timed timestamp should be present with valid cdr + (let ((timed (--find (equal (car it) "<2025-10-24 Fri 16:00>") result))) + (should timed) + (should (cdr timed)))))) (test-chime-extract-time-teardown))) -(ert-deftest test-chime-extract-time-all-malformed-returns-cons-with-nil-cdrs () - "Test that all malformed timestamps return cons with nil cdrs." +(ert-deftest test-chime-extract-time-plain-day-wide-timestamp-filtered () + "Test that plain day-wide timestamps (no time) are filtered out." (test-chime-extract-time-setup) (unwind-protect (with-temp-buffer (org-mode) - (insert "* TODO Test Task\n") - (let ((marker (copy-marker (point)))) - (cl-letf (((symbol-function 'org-entry-get) - (lambda (pom property &optional inherit literal-nil) - (cond - ((and (equal pom marker) (equal property "SCHEDULED")) - "not-valid") - ((and (equal pom marker) (equal property "DEADLINE")) - "also-not-valid") - ((and (equal pom marker) (equal property "TIMESTAMP")) - "<2025-10-24 Fri>") ; Day-wide - (t nil))))) - (let ((result (chime--extract-time marker))) - ;; Should return 3 entries, all with nil cdr - (should (= (length result) 3)) - (should (--every (not (cdr it)) result)))))) + (insert "* Event\n") + (insert "<2025-10-24 Fri>\n") ; Day-wide, no time + (insert "<2025-10-24 Fri 10:00>\n") ; Has time + (goto-char (point-min)) + (let ((marker (point-marker))) + (let ((result (chime--extract-time marker))) + ;; Should have at least the timed one + (should (>= (length result) 1)) + ;; Timed timestamp should be present + (should (--some (equal (car it) "<2025-10-24 Fri 10:00>") result))))) (test-chime-extract-time-teardown))) ;;; org-gcal Integration Tests @@ -335,21 +317,17 @@ org-gcal uses format like <2025-10-24 Fri 17:30-18:00> with HH:MM-HH:MM range." (with-temp-buffer (org-mode) (insert "* Testing Round Trip\n") - (let ((marker (copy-marker (point)))) - (cl-letf (((symbol-function 'org-entry-get) - (lambda (pom property &optional inherit literal-nil) - (cond - ((and (equal pom marker) (equal property "TIMESTAMP")) - "<2025-10-24 Fri 17:30-18:00>") - (t nil))))) - (let ((result (chime--extract-time marker))) - (should (listp result)) - (should (>= (length result) 1)) - ;; Should extract the timestamp string - (should (equal (caar result) "<2025-10-24 Fri 17:30-18:00>")) - ;; Should have parsed time value (not nil) - (should (listp (cdar result))) - (should (cdar result)))))) + (insert "<2025-10-24 Fri 17:30-18:00>\n") + (goto-char (point-min)) + (let ((marker (point-marker))) + (let ((result (chime--extract-time marker))) + (should (listp result)) + (should (>= (length result) 1)) + ;; Should extract the timestamp string + (should (equal (caar result) "<2025-10-24 Fri 17:30-18:00>")) + ;; Should have parsed time value (not nil) + (should (listp (cdar result))) + (should (cdar result))))) (test-chime-extract-time-teardown))) (ert-deftest test-chime-extract-time-org-gcal-in-drawer () @@ -370,18 +348,12 @@ org-gcal stores timestamps in :org-gcal: drawers which should still be detected. (insert "<2025-10-24 Fri 17:30-18:00>\n") (insert ":END:\n") (goto-char (point-min)) - (let ((marker (copy-marker (point)))) - (cl-letf (((symbol-function 'org-entry-get) - (lambda (pom property &optional inherit literal-nil) - (cond - ((and (equal pom marker) (equal property "TIMESTAMP")) - "<2025-10-24 Fri 17:30-18:00>") - (t nil))))) - (let ((result (chime--extract-time marker))) - (should (listp result)) - (should (>= (length result) 1)) - (should (equal (caar result) "<2025-10-24 Fri 17:30-18:00>")) - (should (cdar result)))))) + (let ((marker (point-marker))) + (let ((result (chime--extract-time marker))) + (should (listp result)) + (should (>= (length result) 1)) + (should (equal (caar result) "<2025-10-24 Fri 17:30-18:00>")) + (should (cdar result))))) (test-chime-extract-time-teardown))) (provide 'test-chime-extract-time) |
