diff options
53 files changed, 1705 insertions, 2413 deletions
diff --git a/tests/test-bootstrap.el b/tests/test-bootstrap.el index f53b9f1..40c333a 100644 --- a/tests/test-bootstrap.el +++ b/tests/test-bootstrap.el @@ -45,5 +45,28 @@ ;; Load chime from parent directory (load (expand-file-name "../chime.el") nil t) +;; Load the near-universal test helpers so individual test files don't each +;; repeat the require. testutil-general carries the base-dir fixture used by +;; `chime-deftest' below; testutil-time carries the dynamic-time helpers. +(require 'testutil-general (expand-file-name "testutil-general.el")) +(require 'testutil-time (expand-file-name "testutil-time.el")) + +(defmacro chime-deftest (name arglist &rest body) + "Define an ERT test NAME with chime's standard base-dir fixture. +ARGLIST is the `ert-deftest' argument list (normally nil). When the +first form in BODY is a string it is kept as the test docstring. The +remaining forms run inside the test base directory, created beforehand +with `chime-create-test-base-dir' and removed afterward with +`chime-delete-test-base-dir' even if a form signals." + (declare (indent 2) (doc-string 3)) + (let* ((doc (and (stringp (car body)) (cdr body) (car body))) + (forms (if doc (cdr body) body))) + `(ert-deftest ,name ,arglist + ,@(and doc (list doc)) + (chime-create-test-base-dir) + (unwind-protect + (progn ,@forms) + (chime-delete-test-base-dir))))) + (provide 'test-bootstrap) ;;; test-bootstrap.el ends here diff --git a/tests/test-chime--deduplicate-events-by-title.el b/tests/test-chime--deduplicate-events-by-title.el index 66ec37a..13066eb 100644 --- a/tests/test-chime--deduplicate-events-by-title.el +++ b/tests/test-chime--deduplicate-events-by-title.el @@ -30,10 +30,6 @@ (setq chime-debug t) (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) - ;;; Test Helpers (defun test-make-event (title) diff --git a/tests/test-chime-12hour-format.el b/tests/test-chime-12hour-format.el index 0fcb91a..c18cbc5 100644 --- a/tests/test-chime-12hour-format.el +++ b/tests/test-chime-12hour-format.el @@ -31,10 +31,6 @@ (setq chime-debug t) (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) - ;;; Tests for chime--convert-12hour-to-24hour (ert-deftest test-12hour-convert-1pm-to-13 () diff --git a/tests/test-chime-all-day-events.el b/tests/test-chime-all-day-events.el index 1cacf69..168f545 100644 --- a/tests/test-chime-all-day-events.el +++ b/tests/test-chime-all-day-events.el @@ -9,8 +9,6 @@ ;;; Code: (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) ;;; Helper Functions diff --git a/tests/test-chime-apply-blacklist.el b/tests/test-chime-apply-blacklist.el index abfc3e8..3f16a3d 100644 --- a/tests/test-chime-apply-blacklist.el +++ b/tests/test-chime-apply-blacklist.el @@ -27,9 +27,6 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) - ;;; Setup and Teardown (defun test-chime-apply-blacklist-setup () diff --git a/tests/test-chime-apply-whitelist.el b/tests/test-chime-apply-whitelist.el index 1552ee2..6e3be24 100644 --- a/tests/test-chime-apply-whitelist.el +++ b/tests/test-chime-apply-whitelist.el @@ -27,9 +27,6 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) - ;;; Setup and Teardown (defun test-chime-apply-whitelist-setup () diff --git a/tests/test-chime-async-helpers.el b/tests/test-chime-async-helpers.el index 3e0e562..c7eb5ba 100644 --- a/tests/test-chime-async-helpers.el +++ b/tests/test-chime-async-helpers.el @@ -27,7 +27,6 @@ ;;; Code: (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) ;;; Setup and Teardown diff --git a/tests/test-chime-check-event.el b/tests/test-chime-check-event.el index e362504..db63c9e 100644 --- a/tests/test-chime-check-event.el +++ b/tests/test-chime-check-event.el @@ -27,8 +27,6 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) ;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) (require 'testutil-events (expand-file-name "testutil-events.el")) ;;; Normal Cases diff --git a/tests/test-chime-check-interval.el b/tests/test-chime-check-interval.el index 74cbe14..4a79197 100644 --- a/tests/test-chime-check-interval.el +++ b/tests/test-chime-check-interval.el @@ -26,9 +26,6 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) - ;;; Setup and Teardown (defun test-chime-check-interval-setup () diff --git a/tests/test-chime-day-wide-notifications.el b/tests/test-chime-day-wide-notifications.el index 260abfc..b5638fb 100644 --- a/tests/test-chime-day-wide-notifications.el +++ b/tests/test-chime-day-wide-notifications.el @@ -23,7 +23,6 @@ ;;; Code: (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) (ert-deftest test-chime-day-wide-notifications-normal-wraps-with-medium-severity () "Normal: each generated text is wrapped as (TEXT . \\='medium)." diff --git a/tests/test-chime-day-wide-time-matching.el b/tests/test-chime-day-wide-time-matching.el index 88242e2..1a87326 100644 --- a/tests/test-chime-day-wide-time-matching.el +++ b/tests/test-chime-day-wide-time-matching.el @@ -33,10 +33,6 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) - (defmacro test-chime-with-restored-day-wide-alert-times (&rest body) "Run BODY and restore default `chime-day-wide-alert-times' afterwards." (declare (indent 0) (debug t)) diff --git a/tests/test-chime-debug-functions.el b/tests/test-chime-debug-functions.el index 7ef85e5..01e6663 100644 --- a/tests/test-chime-debug-functions.el +++ b/tests/test-chime-debug-functions.el @@ -30,10 +30,6 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) (require 'chime-debug (expand-file-name "../chime-debug.el")) -;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) - ;;; Setup and Teardown (defun test-chime-debug-functions-setup () diff --git a/tests/test-chime-edge-coverage.el b/tests/test-chime-edge-coverage.el index 1325e77..0133099 100644 --- a/tests/test-chime-edge-coverage.el +++ b/tests/test-chime-edge-coverage.el @@ -26,7 +26,6 @@ ;;; Code: (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) (require 'cl-lib) ;;;; chime--day-wide-notification-text fallback (chime.el ~ "t branch") diff --git a/tests/test-chime-event-contract.el b/tests/test-chime-event-contract.el index 697dccb..deeb626 100644 --- a/tests/test-chime-event-contract.el +++ b/tests/test-chime-event-contract.el @@ -25,8 +25,6 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) (require 'testutil-events (expand-file-name "testutil-events.el")) (ert-deftest test-chime-event-contract-make-event-creates-valid-event () diff --git a/tests/test-chime-event-is-today.el b/tests/test-chime-event-is-today.el index 305749a..deb4f70 100644 --- a/tests/test-chime-event-is-today.el +++ b/tests/test-chime-event-is-today.el @@ -31,10 +31,6 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) - ;;; Helpers — build events at real dates (defun test--real-today-at (hour minute) diff --git a/tests/test-chime-extract-time.el b/tests/test-chime-extract-time.el index 120c45b..d2be145 100644 --- a/tests/test-chime-extract-time.el +++ b/tests/test-chime-extract-time.el @@ -28,31 +28,15 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) - -;;; Setup and Teardown - -(defun test-chime-extract-time-setup () - "Setup function run before each test." - (chime-create-test-base-dir)) - -(defun test-chime-extract-time-teardown () - "Teardown function run after each test." - (chime-delete-test-base-dir)) - ;;; Tests for org-gcal events -(ert-deftest test-chime-extract-time-gcal-event-from-drawer () +(chime-deftest test-chime-extract-time-gcal-event-from-drawer () "Test that org-gcal events extract timestamps ONLY from :org-gcal: drawer. REFACTORED: Uses dynamic timestamps" - (test-chime-extract-time-setup) - (unwind-protect - (let* ((time (test-time-tomorrow-at 14 0)) - (timestamp-str (format-time-string "<%Y-%m-%d %a %H:%M-15:00>" time)) - (test-content (format "* Meeting + (let* ((time (test-time-tomorrow-at 14 0)) + (timestamp-str (format-time-string "<%Y-%m-%d %a %H:%M-15:00>" time)) + (test-content (format "* Meeting :PROPERTIES: :entry-id: abc123@google.com :END: @@ -60,33 +44,30 @@ REFACTORED: Uses dynamic timestamps" %s :END: " timestamp-str)) - (test-file (chime-create-temp-test-file-with-content test-content)) - (test-buffer (find-file-noselect test-file))) - (with-current-buffer test-buffer - (org-mode) - (goto-char (point-min)) - (let* ((marker (point-marker)) - (times (chime--extract-time marker))) - ;; Should extract the timestamp from :org-gcal: drawer - (should (= 1 (length times))) - (should (string-match-p "14:00" (car (car times)))))) - (kill-buffer test-buffer)) - (test-chime-extract-time-teardown))) - -(ert-deftest test-chime-extract-time-gcal-event-ignores-body-timestamps () + (test-file (chime-create-temp-test-file-with-content test-content)) + (test-buffer (find-file-noselect test-file))) + (with-current-buffer test-buffer + (org-mode) + (goto-char (point-min)) + (let* ((marker (point-marker)) + (times (chime--extract-time marker))) + ;; Should extract the timestamp from :org-gcal: drawer + (should (= 1 (length times))) + (should (string-match-p "14:00" (car (car times)))))) + (kill-buffer test-buffer))) + +(chime-deftest test-chime-extract-time-gcal-event-ignores-body-timestamps () "Test that org-gcal events ignore plain timestamps in body text. When an event is rescheduled, old timestamps might remain in the body. The :org-gcal: drawer has the correct time, so we should ignore body text. REFACTORED: Uses dynamic timestamps" - (test-chime-extract-time-setup) - (unwind-protect - (let* ((new-time (test-time-tomorrow-at 14 0)) - (old-time (test-time-today-at 14 0)) - (new-timestamp (test-timestamp-string new-time)) - (old-timestamp (test-timestamp-string old-time)) - (test-content (format "* Meeting + (let* ((new-time (test-time-tomorrow-at 14 0)) + (old-time (test-time-today-at 14 0)) + (new-timestamp (test-timestamp-string new-time)) + (old-timestamp (test-timestamp-string old-time)) + (test-content (format "* Meeting :PROPERTIES: :entry-id: abc123@google.com :END: @@ -95,34 +76,31 @@ REFACTORED: Uses dynamic timestamps" :END: Old time was %s " new-timestamp old-timestamp)) - (test-file (chime-create-temp-test-file-with-content test-content)) - (test-buffer (find-file-noselect test-file))) - (with-current-buffer test-buffer - (org-mode) - (goto-char (point-min)) - (let* ((marker (point-marker)) - (times (chime--extract-time marker))) - ;; Should extract ONLY from drawer (tomorrow), ignore body (today) - (should (= 1 (length times))) - (should (string-match-p "14:00" (car (car times)))) - ;; Verify it's the new timestamp, not the old one - (should (string-match-p (format-time-string "%Y-%m-%d" new-time) (car (car times)))))) - (kill-buffer test-buffer)) - (test-chime-extract-time-teardown))) - -(ert-deftest test-chime-extract-time-gcal-event-ignores-scheduled () + (test-file (chime-create-temp-test-file-with-content test-content)) + (test-buffer (find-file-noselect test-file))) + (with-current-buffer test-buffer + (org-mode) + (goto-char (point-min)) + (let* ((marker (point-marker)) + (times (chime--extract-time marker))) + ;; Should extract ONLY from drawer (tomorrow), ignore body (today) + (should (= 1 (length times))) + (should (string-match-p "14:00" (car (car times)))) + ;; Verify it's the new timestamp, not the old one + (should (string-match-p (format-time-string "%Y-%m-%d" new-time) (car (car times)))))) + (kill-buffer test-buffer))) + +(chime-deftest test-chime-extract-time-gcal-event-ignores-scheduled () "Test that org-gcal events ignore SCHEDULED/DEADLINE properties. For org-gcal events, the :org-gcal: drawer is the source of truth. REFACTORED: Uses dynamic timestamps" - (test-chime-extract-time-setup) - (unwind-protect - (let* ((drawer-time (test-time-tomorrow-at 14 0)) - (scheduled-time (test-time-days-from-now 2)) - (drawer-timestamp (test-timestamp-string drawer-time)) - (scheduled-timestamp (test-timestamp-string scheduled-time)) - (test-content (format "* Meeting + (let* ((drawer-time (test-time-tomorrow-at 14 0)) + (scheduled-time (test-time-days-from-now 2)) + (drawer-timestamp (test-timestamp-string drawer-time)) + (scheduled-timestamp (test-timestamp-string scheduled-time)) + (test-content (format "* Meeting SCHEDULED: %s :PROPERTIES: :entry-id: abc123@google.com @@ -131,33 +109,30 @@ SCHEDULED: %s %s :END: " scheduled-timestamp drawer-timestamp)) - (test-file (chime-create-temp-test-file-with-content test-content)) - (test-buffer (find-file-noselect test-file))) - (with-current-buffer test-buffer - (org-mode) - (goto-char (point-min)) - (let* ((marker (point-marker)) - (times (chime--extract-time marker))) - ;; Should extract ONLY from drawer (tomorrow), ignore SCHEDULED (day after) - (should (= 1 (length times))) - (should (string-match-p "14:00" (car (car times)))) - (should (string-match-p (format-time-string "%Y-%m-%d" drawer-time) (car (car times)))))) - (kill-buffer test-buffer)) - (test-chime-extract-time-teardown))) - -(ert-deftest test-chime-extract-time-gcal-event-multiple-in-drawer () + (test-file (chime-create-temp-test-file-with-content test-content)) + (test-buffer (find-file-noselect test-file))) + (with-current-buffer test-buffer + (org-mode) + (goto-char (point-min)) + (let* ((marker (point-marker)) + (times (chime--extract-time marker))) + ;; Should extract ONLY from drawer (tomorrow), ignore SCHEDULED (day after) + (should (= 1 (length times))) + (should (string-match-p "14:00" (car (car times)))) + (should (string-match-p (format-time-string "%Y-%m-%d" drawer-time) (car (car times)))))) + (kill-buffer test-buffer))) + +(chime-deftest test-chime-extract-time-gcal-event-multiple-in-drawer () "Test that org-gcal events extract all timestamps from :org-gcal: drawer. Some recurring events might have multiple timestamps in the drawer. REFACTORED: Uses dynamic timestamps" - (test-chime-extract-time-setup) - (unwind-protect - (let* ((time1 (test-time-tomorrow-at 14 0)) - (time2 (test-time-days-from-now 2 14 0)) - (timestamp1 (test-timestamp-string time1)) - (timestamp2 (test-timestamp-string time2)) - (test-content (format "* Meeting + (let* ((time1 (test-time-tomorrow-at 14 0)) + (time2 (test-time-days-from-now 2 14 0)) + (timestamp1 (test-timestamp-string time1)) + (timestamp2 (test-timestamp-string time2)) + (test-content (format "* Meeting :PROPERTIES: :entry-id: abc123@google.com :END: @@ -166,153 +141,137 @@ REFACTORED: Uses dynamic timestamps" %s :END: " timestamp1 timestamp2)) - (test-file (chime-create-temp-test-file-with-content test-content)) - (test-buffer (find-file-noselect test-file))) - (with-current-buffer test-buffer - (org-mode) - (goto-char (point-min)) - (let* ((marker (point-marker)) - (times (chime--extract-time marker))) - ;; Should extract both timestamps from drawer - (should (= 2 (length times))) - (should (string-match-p "14:00" (car (car times)))) - (should (string-match-p "14:00" (car (cadr times)))))) - (kill-buffer test-buffer)) - (test-chime-extract-time-teardown))) + (test-file (chime-create-temp-test-file-with-content test-content)) + (test-buffer (find-file-noselect test-file))) + (with-current-buffer test-buffer + (org-mode) + (goto-char (point-min)) + (let* ((marker (point-marker)) + (times (chime--extract-time marker))) + ;; Should extract both timestamps from drawer + (should (= 2 (length times))) + (should (string-match-p "14:00" (car (car times)))) + (should (string-match-p "14:00" (car (cadr times)))))) + (kill-buffer test-buffer))) ;;; Tests for regular org events -(ert-deftest test-chime-extract-time-regular-event-scheduled () +(chime-deftest test-chime-extract-time-regular-event-scheduled () "Test that regular events extract SCHEDULED timestamp. REFACTORED: Uses dynamic timestamps" - (test-chime-extract-time-setup) - (unwind-protect - (let* ((time (test-time-tomorrow-at 14 0)) - (timestamp (test-timestamp-string time)) - (test-content (format "* Task + (let* ((time (test-time-tomorrow-at 14 0)) + (timestamp (test-timestamp-string time)) + (test-content (format "* Task SCHEDULED: %s " timestamp)) - (test-file (chime-create-temp-test-file-with-content test-content)) - (test-buffer (find-file-noselect test-file))) - (with-current-buffer test-buffer - (org-mode) - (goto-char (point-min)) - (let* ((marker (point-marker)) - (times (chime--extract-time marker))) - ;; Should extract SCHEDULED timestamp - (should (= 1 (length times))) - (should (string-match-p "14:00" (car (car times)))))) - (kill-buffer test-buffer)) - (test-chime-extract-time-teardown))) - -(ert-deftest test-chime-extract-time-regular-event-deadline () + (test-file (chime-create-temp-test-file-with-content test-content)) + (test-buffer (find-file-noselect test-file))) + (with-current-buffer test-buffer + (org-mode) + (goto-char (point-min)) + (let* ((marker (point-marker)) + (times (chime--extract-time marker))) + ;; Should extract SCHEDULED timestamp + (should (= 1 (length times))) + (should (string-match-p "14:00" (car (car times)))))) + (kill-buffer test-buffer))) + +(chime-deftest test-chime-extract-time-regular-event-deadline () "Test that regular events extract DEADLINE timestamp. REFACTORED: Uses dynamic timestamps" - (test-chime-extract-time-setup) - (unwind-protect - (let* ((time (test-time-tomorrow-at 17 0)) - (timestamp (test-timestamp-string time)) - (test-content (format "* Task + (let* ((time (test-time-tomorrow-at 17 0)) + (timestamp (test-timestamp-string time)) + (test-content (format "* Task DEADLINE: %s " timestamp)) - (test-file (chime-create-temp-test-file-with-content test-content)) - (test-buffer (find-file-noselect test-file))) - (with-current-buffer test-buffer - (org-mode) - (goto-char (point-min)) - (let* ((marker (point-marker)) - (times (chime--extract-time marker))) - ;; Should extract DEADLINE timestamp - (should (= 1 (length times))) - (should (string-match-p "17:00" (car (car times)))))) - (kill-buffer test-buffer)) - (test-chime-extract-time-teardown))) - -(ert-deftest test-chime-extract-time-regular-event-plain-timestamps () + (test-file (chime-create-temp-test-file-with-content test-content)) + (test-buffer (find-file-noselect test-file))) + (with-current-buffer test-buffer + (org-mode) + (goto-char (point-min)) + (let* ((marker (point-marker)) + (times (chime--extract-time marker))) + ;; Should extract DEADLINE timestamp + (should (= 1 (length times))) + (should (string-match-p "17:00" (car (car times)))))) + (kill-buffer test-buffer))) + +(chime-deftest test-chime-extract-time-regular-event-plain-timestamps () "Test that regular events extract plain timestamps when no SCHEDULED/DEADLINE. REFACTORED: Uses dynamic timestamps" - (test-chime-extract-time-setup) - (unwind-protect - (let* ((time (test-time-tomorrow-at 14 0)) - (timestamp (test-timestamp-string time)) - (test-content (format "* Meeting notes + (let* ((time (test-time-tomorrow-at 14 0)) + (timestamp (test-timestamp-string time)) + (test-content (format "* Meeting notes Discussed: %s " timestamp)) - (test-file (chime-create-temp-test-file-with-content test-content)) - (test-buffer (find-file-noselect test-file))) - (with-current-buffer test-buffer - (org-mode) - (goto-char (point-min)) - (let* ((marker (point-marker)) - (times (chime--extract-time marker))) - ;; Should extract plain timestamp - (should (= 1 (length times))) - (should (string-match-p "14:00" (car (car times)))))) - (kill-buffer test-buffer)) - (test-chime-extract-time-teardown))) - -(ert-deftest test-chime-extract-time-regular-event-scheduled-and-plain () + (test-file (chime-create-temp-test-file-with-content test-content)) + (test-buffer (find-file-noselect test-file))) + (with-current-buffer test-buffer + (org-mode) + (goto-char (point-min)) + (let* ((marker (point-marker)) + (times (chime--extract-time marker))) + ;; Should extract plain timestamp + (should (= 1 (length times))) + (should (string-match-p "14:00" (car (car times)))))) + (kill-buffer test-buffer))) + +(chime-deftest test-chime-extract-time-regular-event-scheduled-and-plain () "Test that regular events extract both SCHEDULED and plain timestamps. SCHEDULED/DEADLINE appear first, then plain timestamps. REFACTORED: Uses dynamic timestamps" - (test-chime-extract-time-setup) - (unwind-protect - (let* ((scheduled-time (test-time-tomorrow-at 14 0)) - (plain-time (test-time-days-from-now 2 15 0)) - (scheduled-timestamp (test-timestamp-string scheduled-time)) - (plain-timestamp (format-time-string "<%Y-%m-%d %a %H:%M>" plain-time)) - (test-content (format "* Task + (let* ((scheduled-time (test-time-tomorrow-at 14 0)) + (plain-time (test-time-days-from-now 2 15 0)) + (scheduled-timestamp (test-timestamp-string scheduled-time)) + (plain-timestamp (format-time-string "<%Y-%m-%d %a %H:%M>" plain-time)) + (test-content (format "* Task SCHEDULED: %s Note: also happens %s " scheduled-timestamp plain-timestamp)) - (test-file (chime-create-temp-test-file-with-content test-content)) - (test-buffer (find-file-noselect test-file))) - (with-current-buffer test-buffer - (org-mode) - (goto-char (point-min)) - (let* ((marker (point-marker)) - (times (chime--extract-time marker))) - ;; Should extract both: SCHEDULED first, then plain - (should (= 2 (length times))) - ;; First should be SCHEDULED - (should (string-match-p "14:00" (car (car times)))) - ;; Second should be plain at 15:00 - (should (string-match-p "15:00" (car (cadr times)))))) - (kill-buffer test-buffer)) - (test-chime-extract-time-teardown))) - -(ert-deftest test-chime-extract-time-regular-event-multiple-plain () + (test-file (chime-create-temp-test-file-with-content test-content)) + (test-buffer (find-file-noselect test-file))) + (with-current-buffer test-buffer + (org-mode) + (goto-char (point-min)) + (let* ((marker (point-marker)) + (times (chime--extract-time marker))) + ;; Should extract both: SCHEDULED first, then plain + (should (= 2 (length times))) + ;; First should be SCHEDULED + (should (string-match-p "14:00" (car (car times)))) + ;; Second should be plain at 15:00 + (should (string-match-p "15:00" (car (cadr times)))))) + (kill-buffer test-buffer))) + +(chime-deftest test-chime-extract-time-regular-event-multiple-plain () "Test that regular events extract all plain timestamps. REFACTORED: Uses dynamic timestamps" - (test-chime-extract-time-setup) - (unwind-protect - (let* ((time1 (test-time-tomorrow-at 14 0)) - (time2 (test-time-days-from-now 2 15 0)) - (timestamp1 (test-timestamp-string time1)) - (timestamp2 (test-timestamp-string time2)) - (test-content (format "* Meeting notes + (let* ((time1 (test-time-tomorrow-at 14 0)) + (time2 (test-time-days-from-now 2 15 0)) + (timestamp1 (test-timestamp-string time1)) + (timestamp2 (test-timestamp-string time2)) + (test-content (format "* Meeting notes First discussion: %s Second discussion: %s " timestamp1 timestamp2)) - (test-file (chime-create-temp-test-file-with-content test-content)) - (test-buffer (find-file-noselect test-file))) - (with-current-buffer test-buffer - (org-mode) - (goto-char (point-min)) - (let* ((marker (point-marker)) - (times (chime--extract-time marker))) - ;; Should extract both plain timestamps - (should (= 2 (length times))) - (should (string-match-p "14:00" (car (car times)))) - (should (string-match-p "15:00" (car (cadr times)))))) - (kill-buffer test-buffer)) - (test-chime-extract-time-teardown))) + (test-file (chime-create-temp-test-file-with-content test-content)) + (test-buffer (find-file-noselect test-file))) + (with-current-buffer test-buffer + (org-mode) + (goto-char (point-min)) + (let* ((marker (point-marker)) + (times (chime--extract-time marker))) + ;; Should extract both plain timestamps + (should (= 2 (length times))) + (should (string-match-p "14:00" (car (car times)))) + (should (string-match-p "15:00" (car (cadr times)))))) + (kill-buffer test-buffer))) (provide 'test-chime-extract-time) ;;; test-chime-extract-time.el ends here diff --git a/tests/test-chime-extract-title.el b/tests/test-chime-extract-title.el index d778c7e..f7efd33 100644 --- a/tests/test-chime-extract-title.el +++ b/tests/test-chime-extract-title.el @@ -27,9 +27,6 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) - ;;; Normal Cases (ert-deftest test-chime-extract-title-plain-heading () diff --git a/tests/test-chime-filter-day-wide-events.el b/tests/test-chime-filter-day-wide-events.el index 6e24f00..415598d 100644 --- a/tests/test-chime-filter-day-wide-events.el +++ b/tests/test-chime-filter-day-wide-events.el @@ -28,10 +28,6 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) - ;;; Normal Cases (ert-deftest test-chime-filter-day-wide-events-keeps-timed-event () diff --git a/tests/test-chime-format-event-for-tooltip.el b/tests/test-chime-format-event-for-tooltip.el index 5e2cabb..0569477 100644 --- a/tests/test-chime-format-event-for-tooltip.el +++ b/tests/test-chime-format-event-for-tooltip.el @@ -26,222 +26,175 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) - -;;; Setup and Teardown - -(defun test-chime-format-event-for-tooltip-setup () - "Setup function run before each test." - (chime-create-test-base-dir)) - -(defun test-chime-format-event-for-tooltip-teardown () - "Teardown function run after each test." - (chime-delete-test-base-dir)) - ;;; Normal Cases -(ert-deftest test-chime-format-event-for-tooltip-normal-minutes () +(chime-deftest test-chime-format-event-for-tooltip-normal-minutes () "Test formatting event with minutes until event. REFACTORED: Uses dynamic timestamps" - (test-chime-format-event-for-tooltip-setup) - (unwind-protect - (let* ((time (test-time-tomorrow-at 14 10)) - (timestamp (test-timestamp-string time)) - (result (chime--format-event-for-tooltip - timestamp - 10 - "Team Meeting"))) - (should (stringp result)) - (should (string-match-p "Team Meeting" result)) - (should (string-match-p "02:10 PM" result)) - (should (string-match-p "10 minutes" result))) - (test-chime-format-event-for-tooltip-teardown))) - -(ert-deftest test-chime-format-event-for-tooltip-normal-hours () + (let* ((time (test-time-tomorrow-at 14 10)) + (timestamp (test-timestamp-string time)) + (result (chime--format-event-for-tooltip + timestamp + 10 + "Team Meeting"))) + (should (stringp result)) + (should (string-match-p "Team Meeting" result)) + (should (string-match-p "02:10 PM" result)) + (should (string-match-p "10 minutes" result)))) + +(chime-deftest test-chime-format-event-for-tooltip-normal-hours () "Test formatting event with hours until event. REFACTORED: Uses dynamic timestamps" - (test-chime-format-event-for-tooltip-setup) - (unwind-protect - (let* ((time (test-time-tomorrow-at 15 30)) - (timestamp (test-timestamp-string time)) - (result (chime--format-event-for-tooltip - timestamp - 90 - "Afternoon Meeting"))) - (should (stringp result)) - (should (string-match-p "Afternoon Meeting" result)) - (should (string-match-p "03:30 PM" result)) - (should (string-match-p "1 hour" result))) - (test-chime-format-event-for-tooltip-teardown))) - -(ert-deftest test-chime-format-event-for-tooltip-normal-multiple-hours () + (let* ((time (test-time-tomorrow-at 15 30)) + (timestamp (test-timestamp-string time)) + (result (chime--format-event-for-tooltip + timestamp + 90 + "Afternoon Meeting"))) + (should (stringp result)) + (should (string-match-p "Afternoon Meeting" result)) + (should (string-match-p "03:30 PM" result)) + (should (string-match-p "1 hour" result)))) + +(chime-deftest test-chime-format-event-for-tooltip-normal-multiple-hours () "Test formatting event with multiple hours until event. REFACTORED: Uses dynamic timestamps" - (test-chime-format-event-for-tooltip-setup) - (unwind-protect - (let* ((time (test-time-tomorrow-at 17 0)) - (timestamp (test-timestamp-string time)) - (result (chime--format-event-for-tooltip - timestamp - 300 - "End of Day Review"))) - (should (stringp result)) - (should (string-match-p "End of Day Review" result)) - (should (string-match-p "05:00 PM" result)) - (should (string-match-p "5 hours" result))) - (test-chime-format-event-for-tooltip-teardown))) + (let* ((time (test-time-tomorrow-at 17 0)) + (timestamp (test-timestamp-string time)) + (result (chime--format-event-for-tooltip + timestamp + 300 + "End of Day Review"))) + (should (stringp result)) + (should (string-match-p "End of Day Review" result)) + (should (string-match-p "05:00 PM" result)) + (should (string-match-p "5 hours" result)))) ;;; Boundary Cases -(ert-deftest test-chime-format-event-for-tooltip-boundary-exactly-one-day () +(chime-deftest test-chime-format-event-for-tooltip-boundary-exactly-one-day () "Test formatting event exactly 1 day away (1440 minutes). REFACTORED: Uses dynamic timestamps" - (test-chime-format-event-for-tooltip-setup) - (unwind-protect - (let* ((time (test-time-days-from-now 1 9 0)) - (timestamp (test-timestamp-string time)) - (result (chime--format-event-for-tooltip - timestamp - 1440 - "Tomorrow Event"))) - (should (stringp result)) - (should (string-match-p "Tomorrow Event" result)) - (should (string-match-p "09:00 AM" result)) - (should (string-match-p "in 1 day" result))) - (test-chime-format-event-for-tooltip-teardown))) - -(ert-deftest test-chime-format-event-for-tooltip-boundary-multiple-days () + (let* ((time (test-time-days-from-now 1 9 0)) + (timestamp (test-timestamp-string time)) + (result (chime--format-event-for-tooltip + timestamp + 1440 + "Tomorrow Event"))) + (should (stringp result)) + (should (string-match-p "Tomorrow Event" result)) + (should (string-match-p "09:00 AM" result)) + (should (string-match-p "in 1 day" result)))) + +(chime-deftest test-chime-format-event-for-tooltip-boundary-multiple-days () "Test formatting event multiple days away. REFACTORED: Uses dynamic timestamps" - (test-chime-format-event-for-tooltip-setup) - (unwind-protect - (let* ((time (test-time-days-from-now 3 10 0)) - (timestamp (test-timestamp-string time)) - (result (chime--format-event-for-tooltip - timestamp - 4320 ; 3 days - "Future Meeting"))) - (should (stringp result)) - (should (string-match-p "Future Meeting" result)) - (should (string-match-p "10:00 AM" result)) - (should (string-match-p "in 3 days" result))) - (test-chime-format-event-for-tooltip-teardown))) - -(ert-deftest test-chime-format-event-for-tooltip-boundary-just-under-one-day () + (let* ((time (test-time-days-from-now 3 10 0)) + (timestamp (test-timestamp-string time)) + (result (chime--format-event-for-tooltip + timestamp + 4320 ; 3 days + "Future Meeting"))) + (should (stringp result)) + (should (string-match-p "Future Meeting" result)) + (should (string-match-p "10:00 AM" result)) + (should (string-match-p "in 3 days" result)))) + +(chime-deftest test-chime-format-event-for-tooltip-boundary-just-under-one-day () "Test formatting event just under 1 day away (1439 minutes). REFACTORED: Uses dynamic timestamps" - (test-chime-format-event-for-tooltip-setup) - (unwind-protect - (let* ((time (test-time-tomorrow-at 8 59)) - (timestamp (test-timestamp-string time)) - (result (chime--format-event-for-tooltip - timestamp - 1439 - "Almost Tomorrow"))) - (should (stringp result)) - (should (string-match-p "Almost Tomorrow" result)) - (should (string-match-p "08:59 AM" result)) - ;; Should show hours/minutes, not days - (should (string-match-p "23 hours" result))) - (test-chime-format-event-for-tooltip-teardown))) - -(ert-deftest test-chime-format-event-for-tooltip-boundary-zero-minutes () + (let* ((time (test-time-tomorrow-at 8 59)) + (timestamp (test-timestamp-string time)) + (result (chime--format-event-for-tooltip + timestamp + 1439 + "Almost Tomorrow"))) + (should (stringp result)) + (should (string-match-p "Almost Tomorrow" result)) + (should (string-match-p "08:59 AM" result)) + ;; Should show hours/minutes, not days + (should (string-match-p "23 hours" result)))) + +(chime-deftest test-chime-format-event-for-tooltip-boundary-zero-minutes () "Test formatting event happening right now (0 minutes). REFACTORED: Uses dynamic timestamps" - (test-chime-format-event-for-tooltip-setup) - (unwind-protect - (let* ((time (test-time-today-at 14 0)) - (timestamp (test-timestamp-string time)) - (result (chime--format-event-for-tooltip - timestamp - 0 - "Current Event"))) - (should (stringp result)) - (should (string-match-p "Current Event" result)) - (should (string-match-p "02:00 PM" result)) - (should (string-match-p "right now" result))) - (test-chime-format-event-for-tooltip-teardown))) - -(ert-deftest test-chime-format-event-for-tooltip-boundary-one-minute () + (let* ((time (test-time-today-at 14 0)) + (timestamp (test-timestamp-string time)) + (result (chime--format-event-for-tooltip + timestamp + 0 + "Current Event"))) + (should (stringp result)) + (should (string-match-p "Current Event" result)) + (should (string-match-p "02:00 PM" result)) + (should (string-match-p "right now" result)))) + +(chime-deftest test-chime-format-event-for-tooltip-boundary-one-minute () "Test formatting event 1 minute away. REFACTORED: Uses dynamic timestamps" - (test-chime-format-event-for-tooltip-setup) - (unwind-protect - (let* ((time (test-time-today-at 14 1)) - (timestamp (test-timestamp-string time)) - (result (chime--format-event-for-tooltip - timestamp - 1 - "Imminent Event"))) - (should (stringp result)) - (should (string-match-p "Imminent Event" result)) - (should (string-match-p "02:01 PM" result)) - (should (string-match-p "1 minute" result))) - (test-chime-format-event-for-tooltip-teardown))) - -(ert-deftest test-chime-format-event-for-tooltip-boundary-long-title () + (let* ((time (test-time-today-at 14 1)) + (timestamp (test-timestamp-string time)) + (result (chime--format-event-for-tooltip + timestamp + 1 + "Imminent Event"))) + (should (stringp result)) + (should (string-match-p "Imminent Event" result)) + (should (string-match-p "02:01 PM" result)) + (should (string-match-p "1 minute" result)))) + +(chime-deftest test-chime-format-event-for-tooltip-boundary-long-title () "Test formatting event with very long title. REFACTORED: Uses dynamic timestamps" - (test-chime-format-event-for-tooltip-setup) - (unwind-protect - (let* ((time (test-time-today-at 14 10)) - (timestamp (test-timestamp-string time)) - (long-title (make-string 200 ?x)) - (result (chime--format-event-for-tooltip - timestamp - 10 - long-title))) - (should (stringp result)) - (should (string-match-p long-title result))) - (test-chime-format-event-for-tooltip-teardown))) + (let* ((time (test-time-today-at 14 10)) + (timestamp (test-timestamp-string time)) + (long-title (make-string 200 ?x)) + (result (chime--format-event-for-tooltip + timestamp + 10 + long-title))) + (should (stringp result)) + (should (string-match-p long-title result)))) ;;; Error Cases -(ert-deftest test-chime-format-event-for-tooltip-error-nil-title () +(chime-deftest test-chime-format-event-for-tooltip-error-nil-title () "Test formatting with nil title doesn't crash. REFACTORED: Uses dynamic timestamps" - (test-chime-format-event-for-tooltip-setup) - (unwind-protect - (let* ((time (test-time-today-at 14 10)) - (timestamp (test-timestamp-string time))) - ;; Should not crash with nil title - (should-not (condition-case nil - (progn - (chime--format-event-for-tooltip - timestamp - 10 - nil) - nil) - (error t)))) - (test-chime-format-event-for-tooltip-teardown))) - -(ert-deftest test-chime-format-event-for-tooltip-error-empty-title () + (let* ((time (test-time-today-at 14 10)) + (timestamp (test-timestamp-string time))) + ;; Should not crash with nil title + (should-not (condition-case nil + (progn + (chime--format-event-for-tooltip + timestamp + 10 + nil) + nil) + (error t))))) + +(chime-deftest test-chime-format-event-for-tooltip-error-empty-title () "Test formatting with empty title. REFACTORED: Uses dynamic timestamps" - (test-chime-format-event-for-tooltip-setup) - (unwind-protect - (let* ((time (test-time-today-at 14 10)) - (timestamp (test-timestamp-string time)) - (result (chime--format-event-for-tooltip - timestamp - 10 - ""))) - (should (stringp result)) - (should (string-match-p "02:10 PM" result))) - (test-chime-format-event-for-tooltip-teardown))) + (let* ((time (test-time-today-at 14 10)) + (timestamp (test-timestamp-string time)) + (result (chime--format-event-for-tooltip + timestamp + 10 + ""))) + (should (stringp result)) + (should (string-match-p "02:10 PM" result)))) (provide 'test-chime-format-event-for-tooltip) ;;; test-chime-format-event-for-tooltip.el ends here diff --git a/tests/test-chime-format-refresh.el b/tests/test-chime-format-refresh.el index 0e2b58b..8393119 100644 --- a/tests/test-chime-format-refresh.el +++ b/tests/test-chime-format-refresh.el @@ -26,10 +26,6 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) - ;;; Setup and Teardown (defun test-chime-format-refresh-setup () diff --git a/tests/test-chime-gather-info.el b/tests/test-chime-gather-info.el index 132f0ad..d21c06d 100644 --- a/tests/test-chime-gather-info.el +++ b/tests/test-chime-gather-info.el @@ -29,8 +29,6 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) ;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) (require 'testutil-events (expand-file-name "testutil-events.el")) ;;; Setup and Teardown diff --git a/tests/test-chime-get-tags.el b/tests/test-chime-get-tags.el index aecd2ea..1fca101 100644 --- a/tests/test-chime-get-tags.el +++ b/tests/test-chime-get-tags.el @@ -27,9 +27,6 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) - ;;;; Tests for chime--get-tags ;;; Normal Cases diff --git a/tests/test-chime-group-events-by-day.el b/tests/test-chime-group-events-by-day.el index b8546ee..277e6e1 100644 --- a/tests/test-chime-group-events-by-day.el +++ b/tests/test-chime-group-events-by-day.el @@ -38,10 +38,6 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) - ;;; Setup and Teardown (defun test-chime-group-events-by-day-setup () diff --git a/tests/test-chime-has-timestamp.el b/tests/test-chime-has-timestamp.el index 1c79fb7..3e946ab 100644 --- a/tests/test-chime-has-timestamp.el +++ b/tests/test-chime-has-timestamp.el @@ -26,239 +26,171 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) - -;;; Setup and Teardown - -(defun test-chime-has-timestamp-setup () - "Setup function run before each test." - (chime-create-test-base-dir)) - -(defun test-chime-has-timestamp-teardown () - "Teardown function run after each test." - (chime-delete-test-base-dir)) - ;;; Normal Cases -(ert-deftest test-chime-has-timestamp-standard-timestamp-with-time-returns-non-nil () +(chime-deftest test-chime-has-timestamp-standard-timestamp-with-time-returns-non-nil () "Test that standard timestamp with time returns non-nil. REFACTORED: Uses dynamic timestamps" - (test-chime-has-timestamp-setup) - (unwind-protect - (let* ((time (test-time-tomorrow-at 14 30)) - (timestamp (test-timestamp-string time)) - (result (chime--has-timestamp timestamp))) - (should result)) - (test-chime-has-timestamp-teardown))) - -(ert-deftest test-chime-has-timestamp-timestamp-without-brackets-returns-non-nil () + (let* ((time (test-time-tomorrow-at 14 30)) + (timestamp (test-timestamp-string time)) + (result (chime--has-timestamp timestamp))) + (should result))) + +(chime-deftest test-chime-has-timestamp-timestamp-without-brackets-returns-non-nil () "Test that timestamp without brackets but with time returns non-nil. REFACTORED: Uses dynamic timestamps" - (test-chime-has-timestamp-setup) - (unwind-protect - (let* ((time (test-time-tomorrow-at 14 30)) - (timestamp (format-time-string "%Y-%m-%d %a %H:%M" time)) - (result (chime--has-timestamp timestamp))) - (should result)) - (test-chime-has-timestamp-teardown))) - -(ert-deftest test-chime-has-timestamp-timestamp-with-time-range-returns-non-nil () + (let* ((time (test-time-tomorrow-at 14 30)) + (timestamp (format-time-string "%Y-%m-%d %a %H:%M" time)) + (result (chime--has-timestamp timestamp))) + (should result))) + +(chime-deftest test-chime-has-timestamp-timestamp-with-time-range-returns-non-nil () "Test that timestamp with time range returns non-nil. REFACTORED: Uses dynamic timestamps" - (test-chime-has-timestamp-setup) - (unwind-protect - (let* ((time (test-time-tomorrow-at 14 0)) - (timestamp (format-time-string "<%Y-%m-%d %a %H:%M-15:30>" time)) - (result (chime--has-timestamp timestamp))) - (should result)) - (test-chime-has-timestamp-teardown))) - -(ert-deftest test-chime-has-timestamp-scheduled-with-time-returns-non-nil () + (let* ((time (test-time-tomorrow-at 14 0)) + (timestamp (format-time-string "<%Y-%m-%d %a %H:%M-15:30>" time)) + (result (chime--has-timestamp timestamp))) + (should result))) + +(chime-deftest test-chime-has-timestamp-scheduled-with-time-returns-non-nil () "Test that SCHEDULED timestamp with time returns non-nil. REFACTORED: Uses dynamic timestamps" - (test-chime-has-timestamp-setup) - (unwind-protect - (let* ((time (test-time-tomorrow-at 9 0)) - (timestamp (concat "SCHEDULED: " (test-timestamp-string time))) - (result (chime--has-timestamp timestamp))) - (should result)) - (test-chime-has-timestamp-teardown))) - -(ert-deftest test-chime-has-timestamp-deadline-with-time-returns-non-nil () + (let* ((time (test-time-tomorrow-at 9 0)) + (timestamp (concat "SCHEDULED: " (test-timestamp-string time))) + (result (chime--has-timestamp timestamp))) + (should result))) + +(chime-deftest test-chime-has-timestamp-deadline-with-time-returns-non-nil () "Test that DEADLINE timestamp with time returns non-nil. REFACTORED: Uses dynamic timestamps" - (test-chime-has-timestamp-setup) - (unwind-protect - (let* ((time (test-time-tomorrow-at 17 0)) - (timestamp (concat "DEADLINE: " (test-timestamp-string time))) - (result (chime--has-timestamp timestamp))) - (should result)) - (test-chime-has-timestamp-teardown))) - -(ert-deftest test-chime-has-timestamp-repeater-with-time-returns-non-nil () + (let* ((time (test-time-tomorrow-at 17 0)) + (timestamp (concat "DEADLINE: " (test-timestamp-string time))) + (result (chime--has-timestamp timestamp))) + (should result))) + +(chime-deftest test-chime-has-timestamp-repeater-with-time-returns-non-nil () "Test that timestamp with repeater and time returns non-nil. REFACTORED: Uses dynamic timestamps" - (test-chime-has-timestamp-setup) - (unwind-protect - (let* ((time (test-time-tomorrow-at 14 0)) - (timestamp (format-time-string "<%Y-%m-%d %a %H:%M +1w>" time)) - (result (chime--has-timestamp timestamp))) - (should result)) - (test-chime-has-timestamp-teardown))) - -(ert-deftest test-chime-has-timestamp-midnight-timestamp-returns-non-nil () + (let* ((time (test-time-tomorrow-at 14 0)) + (timestamp (format-time-string "<%Y-%m-%d %a %H:%M +1w>" time)) + (result (chime--has-timestamp timestamp))) + (should result))) + +(chime-deftest test-chime-has-timestamp-midnight-timestamp-returns-non-nil () "Test that midnight timestamp (00:00) returns non-nil. REFACTORED: Uses dynamic timestamps" - (test-chime-has-timestamp-setup) - (unwind-protect - (let* ((time (test-time-tomorrow-at 0 0)) - (timestamp (test-timestamp-string time)) - (result (chime--has-timestamp timestamp))) - (should result)) - (test-chime-has-timestamp-teardown))) + (let* ((time (test-time-tomorrow-at 0 0)) + (timestamp (test-timestamp-string time)) + (result (chime--has-timestamp timestamp))) + (should result))) ;;; Boundary Cases -(ert-deftest test-chime-has-timestamp-day-wide-timestamp-returns-nil () +(chime-deftest test-chime-has-timestamp-day-wide-timestamp-returns-nil () "Test that day-wide timestamp without time returns nil. REFACTORED: Uses dynamic timestamps" - (test-chime-has-timestamp-setup) - (unwind-protect - (let* ((time (test-time-tomorrow-at 0 0)) - (timestamp (test-timestamp-string time t)) - (result (chime--has-timestamp timestamp))) - (should-not result)) - (test-chime-has-timestamp-teardown))) - -(ert-deftest test-chime-has-timestamp-date-only-returns-nil () + (let* ((time (test-time-tomorrow-at 0 0)) + (timestamp (test-timestamp-string time t)) + (result (chime--has-timestamp timestamp))) + (should-not result))) + +(chime-deftest test-chime-has-timestamp-date-only-returns-nil () "Test that date-only timestamp without day name returns nil. REFACTORED: Uses dynamic timestamps" - (test-chime-has-timestamp-setup) - (unwind-protect - (let* ((time (test-time-tomorrow-at 0 0)) - (timestamp (format-time-string "<%Y-%m-%d>" time)) - (result (chime--has-timestamp timestamp))) - (should-not result)) - (test-chime-has-timestamp-teardown))) - -(ert-deftest test-chime-has-timestamp-single-digit-hour-returns-non-nil () + (let* ((time (test-time-tomorrow-at 0 0)) + (timestamp (format-time-string "<%Y-%m-%d>" time)) + (result (chime--has-timestamp timestamp))) + (should-not result))) + +(chime-deftest test-chime-has-timestamp-single-digit-hour-returns-non-nil () "Test that timestamp with single-digit hour returns non-nil. REFACTORED: Uses dynamic timestamps" - (test-chime-has-timestamp-setup) - (unwind-protect - (let* ((time (test-time-tomorrow-at 9 0)) - (timestamp (format-time-string "<%Y-%m-%d %a %-H:%M>" time)) - (result (chime--has-timestamp timestamp))) - (should result)) - (test-chime-has-timestamp-teardown))) - -(ert-deftest test-chime-has-timestamp-embedded-in-text-returns-non-nil () + (let* ((time (test-time-tomorrow-at 9 0)) + (timestamp (format-time-string "<%Y-%m-%d %a %-H:%M>" time)) + (result (chime--has-timestamp timestamp))) + (should result))) + +(chime-deftest test-chime-has-timestamp-embedded-in-text-returns-non-nil () "Test that timestamp embedded in text returns non-nil. REFACTORED: Uses dynamic timestamps" - (test-chime-has-timestamp-setup) - (unwind-protect - (let* ((time (test-time-tomorrow-at 14 0)) - (timestamp (concat "Meeting scheduled for " (test-timestamp-string time) " in conference room")) - (result (chime--has-timestamp timestamp))) - (should result)) - (test-chime-has-timestamp-teardown))) - -(ert-deftest test-chime-has-timestamp-multiple-timestamps-returns-non-nil () + (let* ((time (test-time-tomorrow-at 14 0)) + (timestamp (concat "Meeting scheduled for " (test-timestamp-string time) " in conference room")) + (result (chime--has-timestamp timestamp))) + (should result))) + +(chime-deftest test-chime-has-timestamp-multiple-timestamps-returns-non-nil () "Test that string with multiple timestamps returns non-nil for first match. REFACTORED: Uses dynamic timestamps" - (test-chime-has-timestamp-setup) - (unwind-protect - (let* ((time1 (test-time-tomorrow-at 14 0)) - (time2 (test-time-days-from-now 2)) - (timestamp (concat (test-timestamp-string time1) " and " - (format-time-string "<%Y-%m-%d %a %H:%M>" time2))) - (result (chime--has-timestamp timestamp))) - (should result)) - (test-chime-has-timestamp-teardown))) + (let* ((time1 (test-time-tomorrow-at 14 0)) + (time2 (test-time-days-from-now 2)) + (timestamp (concat (test-timestamp-string time1) " and " + (format-time-string "<%Y-%m-%d %a %H:%M>" time2))) + (result (chime--has-timestamp timestamp))) + (should result))) ;;; Error Cases -(ert-deftest test-chime-has-timestamp-empty-string-returns-nil () +(chime-deftest test-chime-has-timestamp-empty-string-returns-nil () "Test that empty string returns nil." - (test-chime-has-timestamp-setup) - (unwind-protect - (let* ((timestamp "") - (result (chime--has-timestamp timestamp))) - (should-not result)) - (test-chime-has-timestamp-teardown))) - -(ert-deftest test-chime-has-timestamp-nil-input-returns-nil () + (let* ((timestamp "") + (result (chime--has-timestamp timestamp))) + (should-not result))) + +(chime-deftest test-chime-has-timestamp-nil-input-returns-nil () "Test that nil input returns nil." - (test-chime-has-timestamp-setup) - (unwind-protect - (let* ((timestamp nil) - (result (chime--has-timestamp timestamp))) - (should-not result)) - (test-chime-has-timestamp-teardown))) - -(ert-deftest test-chime-has-timestamp-no-timestamp-returns-nil () + (let* ((timestamp nil) + (result (chime--has-timestamp timestamp))) + (should-not result))) + +(chime-deftest test-chime-has-timestamp-no-timestamp-returns-nil () "Test that string without timestamp returns nil." - (test-chime-has-timestamp-setup) - (unwind-protect - (let* ((timestamp "Just a regular string with no timestamp") - (result (chime--has-timestamp timestamp))) - (should-not result)) - (test-chime-has-timestamp-teardown))) - -(ert-deftest test-chime-has-timestamp-invalid-format-returns-nil () + (let* ((timestamp "Just a regular string with no timestamp") + (result (chime--has-timestamp timestamp))) + (should-not result))) + +(chime-deftest test-chime-has-timestamp-invalid-format-returns-nil () "Test that invalid timestamp format returns nil. REFACTORED: Uses dynamic timestamps (keeps invalid format for testing)" - (test-chime-has-timestamp-setup) - (unwind-protect - (let* ((time (test-time-tomorrow-at 14 0)) - ;; Intentionally wrong format (MM-DD-YYYY instead of YYYY-MM-DD) for testing - (timestamp (format-time-string "<%m-%d-%Y %a %H:%M>" time)) - (result (chime--has-timestamp timestamp))) - (should-not result)) - (test-chime-has-timestamp-teardown))) - -(ert-deftest test-chime-has-timestamp-partial-timestamp-returns-nil () + (let* ((time (test-time-tomorrow-at 14 0)) + ;; Intentionally wrong format (MM-DD-YYYY instead of YYYY-MM-DD) for testing + (timestamp (format-time-string "<%m-%d-%Y %a %H:%M>" time)) + (result (chime--has-timestamp timestamp))) + (should-not result))) + +(chime-deftest test-chime-has-timestamp-partial-timestamp-returns-nil () "Test that partial timestamp returns nil. REFACTORED: Uses dynamic timestamps (keeps partial format for testing)" - (test-chime-has-timestamp-setup) - (unwind-protect - (let* ((time (test-time-tomorrow-at 0 0)) - ;; Intentionally incomplete timestamp for testing - (timestamp (format-time-string "<%Y-%m-%d" time)) - (result (chime--has-timestamp timestamp))) - (should-not result)) - (test-chime-has-timestamp-teardown))) + (let* ((time (test-time-tomorrow-at 0 0)) + ;; Intentionally incomplete timestamp for testing + (timestamp (format-time-string "<%Y-%m-%d" time)) + (result (chime--has-timestamp timestamp))) + (should-not result))) ;;; org-gcal Integration Tests -(ert-deftest test-chime-has-timestamp-org-gcal-time-range-returns-non-nil () +(chime-deftest test-chime-has-timestamp-org-gcal-time-range-returns-non-nil () "Test that org-gcal time range format is detected. org-gcal uses format like <2025-10-24 Fri 17:30-18:00> which should be detected. REFACTORED: Uses dynamic timestamps" - (test-chime-has-timestamp-setup) - (unwind-protect - (let* ((time (test-time-tomorrow-at 17 30)) - (timestamp (format-time-string "<%Y-%m-%d %a %H:%M-18:00>" time)) - (result (chime--has-timestamp timestamp))) - (should result)) - (test-chime-has-timestamp-teardown))) + (let* ((time (test-time-tomorrow-at 17 30)) + (timestamp (format-time-string "<%Y-%m-%d %a %H:%M-18:00>" time)) + (result (chime--has-timestamp timestamp))) + (should result))) (provide 'test-chime-has-timestamp) ;;; test-chime-has-timestamp.el ends here diff --git a/tests/test-chime-intervals-for-marker.el b/tests/test-chime-intervals-for-marker.el index 9b73394..295dcd5 100644 --- a/tests/test-chime-intervals-for-marker.el +++ b/tests/test-chime-intervals-for-marker.el @@ -32,7 +32,6 @@ ;;; Code: (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) (require 'cl-lib) ;;; Helpers diff --git a/tests/test-chime-jump-to-event.el b/tests/test-chime-jump-to-event.el index 6db885b..29cb279 100644 --- a/tests/test-chime-jump-to-event.el +++ b/tests/test-chime-jump-to-event.el @@ -19,7 +19,6 @@ ;;; Code: (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -(require 'testutil-general (expand-file-name "testutil-general.el")) (defun test-chime-jump-to-event--make-temp-org-file (content) "Write CONTENT to a temp .org file under the test base dir and return its path." diff --git a/tests/test-chime-make-tooltip.el b/tests/test-chime-make-tooltip.el index 7ace684..6b704b1 100644 --- a/tests/test-chime-make-tooltip.el +++ b/tests/test-chime-make-tooltip.el @@ -28,8 +28,6 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) ;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) (require 'testutil-events (expand-file-name "testutil-events.el")) ;;; Setup and Teardown diff --git a/tests/test-chime-modeline-faces.el b/tests/test-chime-modeline-faces.el index dc8eae8..27c180a 100644 --- a/tests/test-chime-modeline-faces.el +++ b/tests/test-chime-modeline-faces.el @@ -29,8 +29,6 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) (require 'testutil-events (expand-file-name "testutil-events.el")) ;;; Setup/Teardown diff --git a/tests/test-chime-modeline-no-events-text.el b/tests/test-chime-modeline-no-events-text.el index f64c71f..eaf0633 100644 --- a/tests/test-chime-modeline-no-events-text.el +++ b/tests/test-chime-modeline-no-events-text.el @@ -31,10 +31,6 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) - ;;; Setup and Teardown (defvar test-chime-modeline-no-events-text--orig-lookahead nil) diff --git a/tests/test-chime-modeline.el b/tests/test-chime-modeline.el index 63ba26c..27a1936 100644 --- a/tests/test-chime-modeline.el +++ b/tests/test-chime-modeline.el @@ -30,8 +30,6 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) ;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) (require 'testutil-events (expand-file-name "testutil-events.el")) ;;; Setup and Teardown diff --git a/tests/test-chime-notification-boundaries.el b/tests/test-chime-notification-boundaries.el index 853dd4d..fa288f0 100644 --- a/tests/test-chime-notification-boundaries.el +++ b/tests/test-chime-notification-boundaries.el @@ -27,322 +27,269 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) - -;;; Setup and Teardown - -(defun test-chime-notification-boundaries-setup () - "Setup function run before each test." - (chime-create-test-base-dir)) - -(defun test-chime-notification-boundaries-teardown () - "Teardown function run after each test." - (chime-delete-test-base-dir)) - ;;; Exact Matching Tests -(ert-deftest test-chime-notification-boundary-exact-10-minutes () +(chime-deftest test-chime-notification-boundary-exact-10-minutes () "Test that notification fires exactly at 10-minute interval. Event at 14:10, interval 10 minutes, current time 14:00. Should match: current_time + 10 minutes = 14:10 = event_time" - (test-chime-notification-boundaries-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 0)) - (event-time (test-time-today-at 14 10)) - (timestamp-str (test-timestamp-string event-time))) - (with-test-time now - (let* ((event `((times . ((,timestamp-str . ,event-time))) - (title . "Test Event") - (intervals . ((10 . medium))))) - (result (chime--notifications event))) - ;; Should match: event is exactly 10 minutes away - (should (= 1 (length result)))))) - (test-chime-notification-boundaries-teardown))) - -(ert-deftest test-chime-notification-boundary-9-minutes-no-match () + (let* ((now (test-time-today-at 14 0)) + (event-time (test-time-today-at 14 10)) + (timestamp-str (test-timestamp-string event-time))) + (with-test-time now + (let* ((event `((times . ((,timestamp-str . ,event-time))) + (title . "Test Event") + (intervals . ((10 . medium))))) + (result (chime--notifications event))) + ;; Should match: event is exactly 10 minutes away + (should (= 1 (length result))))))) + +(chime-deftest test-chime-notification-boundary-9-minutes-no-match () "Test that notification does NOT fire at 9 minutes (1 minute before interval). Event at 14:10, interval 10 minutes, current time 14:01. Should NOT match: current_time + 10 minutes = 14:11 ≠ 14:10" - (test-chime-notification-boundaries-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 1)) ; 1 minute past the hour - (event-time (test-time-today-at 14 10)) - (timestamp-str (test-timestamp-string event-time))) - (with-test-time now - (let* ((event `((times . ((,timestamp-str . ,event-time))) - (title . "Test Event") - (intervals . ((10 . medium))))) - (result (chime--notifications event))) - ;; Should NOT match: event is 9 minutes away, not 10 - (should (= 0 (length result)))))) - (test-chime-notification-boundaries-teardown))) - -(ert-deftest test-chime-notification-boundary-11-minutes-no-match () + (let* ((now (test-time-today-at 14 1)) ; 1 minute past the hour + (event-time (test-time-today-at 14 10)) + (timestamp-str (test-timestamp-string event-time))) + (with-test-time now + (let* ((event `((times . ((,timestamp-str . ,event-time))) + (title . "Test Event") + (intervals . ((10 . medium))))) + (result (chime--notifications event))) + ;; Should NOT match: event is 9 minutes away, not 10 + (should (= 0 (length result))))))) + +(chime-deftest test-chime-notification-boundary-11-minutes-no-match () "Test that notification does NOT fire at 11 minutes (1 minute after interval). Event at 14:11, interval 10 minutes, current time 14:00. Should NOT match: current_time + 10 minutes = 14:10 ≠ 14:11" - (test-chime-notification-boundaries-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 0)) - (event-time (test-time-today-at 14 11)) - (timestamp-str (test-timestamp-string event-time))) - (with-test-time now - (let* ((event `((times . ((,timestamp-str . ,event-time))) - (title . "Test Event") - (intervals . ((10 . medium))))) - (result (chime--notifications event))) - ;; Should NOT match: event is 11 minutes away, not 10 - (should (= 0 (length result)))))) - (test-chime-notification-boundaries-teardown))) + (let* ((now (test-time-today-at 14 0)) + (event-time (test-time-today-at 14 11)) + (timestamp-str (test-timestamp-string event-time))) + (with-test-time now + (let* ((event `((times . ((,timestamp-str . ,event-time))) + (title . "Test Event") + (intervals . ((10 . medium))))) + (result (chime--notifications event))) + ;; Should NOT match: event is 11 minutes away, not 10 + (should (= 0 (length result))))))) ;;; Multi-Day Interval Tests -(ert-deftest test-chime-notification-boundary-4-days-exact () +(chime-deftest test-chime-notification-boundary-4-days-exact () "Test notification for event exactly 4 days away. This tests the user's reported bug: event on Saturday (4 days from Tuesday). With default 10-minute interval, should NOT match. Event at Saturday 10:00am, current time Tuesday 10:00am, interval 10 minutes. Should NOT match: Tuesday 10:00 + 10 min = Tuesday 10:10 ≠ Saturday 10:00" - (test-chime-notification-boundaries-setup) - (unwind-protect - (let* ((now (test-time-now)) - ;; Event 4 days from now at same time - (event-time (time-add now (seconds-to-time (* 4 24 3600)))) - (timestamp-str (test-timestamp-string event-time))) - (with-test-time now - (let* ((event `((times . ((,timestamp-str . ,event-time))) - (title . "Saturday Event") - (intervals . ((10 . medium))))) ; Default 10 minutes - (result (chime--notifications event))) - ;; Should NOT match: event is 4 days away, interval is 10 minutes - (should (= 0 (length result)))))) - (test-chime-notification-boundaries-teardown))) - -(ert-deftest test-chime-notification-boundary-4-days-with-4-day-interval () + (let* ((now (test-time-now)) + ;; Event 4 days from now at same time + (event-time (time-add now (seconds-to-time (* 4 24 3600)))) + (timestamp-str (test-timestamp-string event-time))) + (with-test-time now + (let* ((event `((times . ((,timestamp-str . ,event-time))) + (title . "Saturday Event") + (intervals . ((10 . medium))))) ; Default 10 minutes + (result (chime--notifications event))) + ;; Should NOT match: event is 4 days away, interval is 10 minutes + (should (= 0 (length result))))))) + +(chime-deftest test-chime-notification-boundary-4-days-with-4-day-interval () "Test notification for event 4 days away with 4-day interval. Event at Saturday 10:00am, current time Tuesday 10:00am, interval 5760 minutes (4 days). Should match: Tuesday 10:00 + 4 days = Saturday 10:00 = event_time" - (test-chime-notification-boundaries-setup) - (unwind-protect - (let* ((now (test-time-now)) - ;; Event exactly 4 days from now - (event-time (time-add now (seconds-to-time (* 4 24 3600)))) - (timestamp-str (test-timestamp-string event-time))) - (with-test-time now - (let* ((event `((times . ((,timestamp-str . ,event-time))) - (title . "Saturday Event") - (intervals . ((5760 . medium))))) ; 4 days = 5760 minutes - (result (chime--notifications event))) - ;; Should match: event is exactly 4 days away, interval is 4 days - (should (= 1 (length result)))))) - (test-chime-notification-boundaries-teardown))) - -(ert-deftest test-chime-notification-boundary-1-week-interval () + (let* ((now (test-time-now)) + ;; Event exactly 4 days from now + (event-time (time-add now (seconds-to-time (* 4 24 3600)))) + (timestamp-str (test-timestamp-string event-time))) + (with-test-time now + (let* ((event `((times . ((,timestamp-str . ,event-time))) + (title . "Saturday Event") + (intervals . ((5760 . medium))))) ; 4 days = 5760 minutes + (result (chime--notifications event))) + ;; Should match: event is exactly 4 days away, interval is 4 days + (should (= 1 (length result))))))) + +(chime-deftest test-chime-notification-boundary-1-week-interval () "Test notification for event exactly 1 week away with 1-week interval. Event 7 days from now, interval 10080 minutes (7 days). Should match: current_time + 7 days = event_time" - (test-chime-notification-boundaries-setup) - (unwind-protect - (let* ((now (test-time-now)) - ;; Event exactly 7 days from now - (event-time (time-add now (seconds-to-time (* 7 24 3600)))) - (timestamp-str (test-timestamp-string event-time))) - (with-test-time now - (let* ((event `((times . ((,timestamp-str . ,event-time))) - (title . "Next Week Event") - (intervals . ((10080 . medium))))) ; 7 days = 10080 minutes - (result (chime--notifications event))) - ;; Should match: event is exactly 7 days away, interval is 7 days - (should (= 1 (length result)))))) - (test-chime-notification-boundaries-teardown))) + (let* ((now (test-time-now)) + ;; Event exactly 7 days from now + (event-time (time-add now (seconds-to-time (* 7 24 3600)))) + (timestamp-str (test-timestamp-string event-time))) + (with-test-time now + (let* ((event `((times . ((,timestamp-str . ,event-time))) + (title . "Next Week Event") + (intervals . ((10080 . medium))))) ; 7 days = 10080 minutes + (result (chime--notifications event))) + ;; Should match: event is exactly 7 days away, interval is 7 days + (should (= 1 (length result))))))) ;;; Cross-Month Boundary Tests (Testing for day-of-month matching bug) -(ert-deftest test-chime-notification-boundary-same-day-different-month () +(chime-deftest test-chime-notification-boundary-same-day-different-month () "Test that events on same day-of-month but different months do NOT match. This tests for the bug in chime--time= that only compares day:hour:minute. Event on Nov 18 at 10:00, current time Oct 18 at 10:00 minus 10 minutes. Should NOT match even though day-of-month (18) is the same." - (test-chime-notification-boundaries-setup) - (unwind-protect - (let* (;; Oct 18, 2024 at 9:50am - (now (encode-time 0 50 9 18 10 2024)) - ;; Nov 18, 2024 at 10:00am (31 days + 10 minutes later) - (event-time (encode-time 0 0 10 18 11 2024)) - (timestamp-str (test-timestamp-string event-time))) - (with-test-time now - (let* ((event `((times . ((,timestamp-str . ,event-time))) - (title . "Next Month Event") - (intervals . ((10 . medium))))) - (result (chime--notifications event))) - ;; Should NOT match: different months, even though day-of-month matches - (should (= 0 (length result)))))) - (test-chime-notification-boundaries-teardown))) - -(ert-deftest test-chime-notification-boundary-same-day-different-year () + (let* (;; Oct 18, 2024 at 9:50am + (now (encode-time 0 50 9 18 10 2024)) + ;; Nov 18, 2024 at 10:00am (31 days + 10 minutes later) + (event-time (encode-time 0 0 10 18 11 2024)) + (timestamp-str (test-timestamp-string event-time))) + (with-test-time now + (let* ((event `((times . ((,timestamp-str . ,event-time))) + (title . "Next Month Event") + (intervals . ((10 . medium))))) + (result (chime--notifications event))) + ;; Should NOT match: different months, even though day-of-month matches + (should (= 0 (length result))))))) + +(chime-deftest test-chime-notification-boundary-same-day-different-year () "Test that events on same day/month but different years do NOT match. Event on Nov 18, 2025 at 10:00, current time Nov 18, 2024 at 9:50. Should NOT match even though month and day-of-month are the same." - (test-chime-notification-boundaries-setup) - (unwind-protect - (let* (;; Nov 18, 2024 at 9:50am - (now (encode-time 0 50 9 18 11 2024)) - ;; Nov 18, 2025 at 10:00am (1 year + 10 minutes later) - (event-time (encode-time 0 0 10 18 11 2025)) - (timestamp-str (test-timestamp-string event-time))) - (with-test-time now - (let* ((event `((times . ((,timestamp-str . ,event-time))) - (title . "Next Year Event") - (intervals . ((10 . medium))))) - (result (chime--notifications event))) - ;; Should NOT match: different years - (should (= 0 (length result)))))) - (test-chime-notification-boundaries-teardown))) + (let* (;; Nov 18, 2024 at 9:50am + (now (encode-time 0 50 9 18 11 2024)) + ;; Nov 18, 2025 at 10:00am (1 year + 10 minutes later) + (event-time (encode-time 0 0 10 18 11 2025)) + (timestamp-str (test-timestamp-string event-time))) + (with-test-time now + (let* ((event `((times . ((,timestamp-str . ,event-time))) + (title . "Next Year Event") + (intervals . ((10 . medium))))) + (result (chime--notifications event))) + ;; Should NOT match: different years + (should (= 0 (length result))))))) ;;; Cross-Day Boundary Tests -(ert-deftest test-chime-notification-boundary-crosses-midnight () +(chime-deftest test-chime-notification-boundary-crosses-midnight () "Test notification that crosses midnight boundary. Event at 00:10 (next day), current time 23:50 (today), interval 20 minutes. Should match: 23:50 + 20 minutes = 00:10 next day" - (test-chime-notification-boundaries-setup) - (unwind-protect - (let* ((now (test-time-today-at 23 50)) - ;; 20 minutes later crosses midnight - (event-time (time-add now (seconds-to-time (* 20 60)))) - (timestamp-str (test-timestamp-string event-time))) - (with-test-time now - (let* ((event `((times . ((,timestamp-str . ,event-time))) - (title . "Midnight Event") - (intervals . ((20 . medium))))) - (result (chime--notifications event))) - ;; Should match: event is exactly 20 minutes away - (should (= 1 (length result)))))) - (test-chime-notification-boundaries-teardown))) - -(ert-deftest test-chime-notification-boundary-just-before-midnight-no-match () + (let* ((now (test-time-today-at 23 50)) + ;; 20 minutes later crosses midnight + (event-time (time-add now (seconds-to-time (* 20 60)))) + (timestamp-str (test-timestamp-string event-time))) + (with-test-time now + (let* ((event `((times . ((,timestamp-str . ,event-time))) + (title . "Midnight Event") + (intervals . ((20 . medium))))) + (result (chime--notifications event))) + ;; Should match: event is exactly 20 minutes away + (should (= 1 (length result))))))) + +(chime-deftest test-chime-notification-boundary-just-before-midnight-no-match () "Test that notification doesn't fire just before crossing midnight. Event at 00:10 (next day), current time 23:51 (today), interval 20 minutes. Should NOT match: 23:51 + 20 minutes = 00:11 ≠ 00:10" - (test-chime-notification-boundaries-setup) - (unwind-protect - (let* ((now (test-time-today-at 23 51)) - ;; 19 minutes later - (event-time (time-add now (seconds-to-time (* 19 60)))) - (timestamp-str (test-timestamp-string event-time))) - (with-test-time now - (let* ((event `((times . ((,timestamp-str . ,event-time))) - (title . "Midnight Event") - (intervals . ((20 . medium))))) - (result (chime--notifications event))) - ;; Should NOT match: event is 19 minutes away, not 20 - (should (= 0 (length result)))))) - (test-chime-notification-boundaries-teardown))) + (let* ((now (test-time-today-at 23 51)) + ;; 19 minutes later + (event-time (time-add now (seconds-to-time (* 19 60)))) + (timestamp-str (test-timestamp-string event-time))) + (with-test-time now + (let* ((event `((times . ((,timestamp-str . ,event-time))) + (title . "Midnight Event") + (intervals . ((20 . medium))))) + (result (chime--notifications event))) + ;; Should NOT match: event is 19 minutes away, not 20 + (should (= 0 (length result))))))) ;;; Multiple Interval Tests -(ert-deftest test-chime-notification-boundary-multiple-intervals-one-matches () +(chime-deftest test-chime-notification-boundary-multiple-intervals-one-matches () "Test that only matching intervals trigger notifications. Event at 14:10, current time 14:00, intervals 10 and 20 minutes. Should match only the 10-minute interval." - (test-chime-notification-boundaries-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 0)) - (event-time (test-time-today-at 14 10)) - (timestamp-str (test-timestamp-string event-time))) - (with-test-time now - (let* ((event `((times . ((,timestamp-str . ,event-time))) - (title . "Test Event") - (intervals . ((10 . medium) (20 . high))))) - (result (chime--notifications event))) - ;; Should match only 10-minute interval - (should (= 1 (length result)))))) - (test-chime-notification-boundaries-teardown))) - -(ert-deftest test-chime-notification-boundary-multiple-intervals-all-match () + (let* ((now (test-time-today-at 14 0)) + (event-time (test-time-today-at 14 10)) + (timestamp-str (test-timestamp-string event-time))) + (with-test-time now + (let* ((event `((times . ((,timestamp-str . ,event-time))) + (title . "Test Event") + (intervals . ((10 . medium) (20 . high))))) + (result (chime--notifications event))) + ;; Should match only 10-minute interval + (should (= 1 (length result))))))) + +(chime-deftest test-chime-notification-boundary-multiple-intervals-all-match () "Test that multiple matching intervals all trigger. Event at 14:20, current time 14:00, intervals 10 and 20 minutes. At 14:00, only 20-minute interval should match. At 14:10, only 10-minute interval should match." - (test-chime-notification-boundaries-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 0)) - (event-time (test-time-today-at 14 20)) - (timestamp-str (test-timestamp-string event-time))) - (with-test-time now - (let* ((event `((times . ((,timestamp-str . ,event-time))) - (title . "Test Event") - (intervals . ((10 . medium) (20 . high))))) - (result (chime--notifications event))) - ;; At 14:00, event is 20 minutes away, so only 20-minute interval matches - (should (= 1 (length result))))) - - ;; Now test at 14:10 (10 minutes before event) - (let ((now-2 (test-time-today-at 14 10))) - (with-test-time now-2 - (let* ((event `((times . ((,timestamp-str . ,event-time))) - (title . "Test Event") - (intervals . ((10 . medium) (20 . high))))) - (result (chime--notifications event))) - ;; At 14:10, event is 10 minutes away, so only 10-minute interval matches - (should (= 1 (length result))))))) - (test-chime-notification-boundaries-teardown))) + (let* ((now (test-time-today-at 14 0)) + (event-time (test-time-today-at 14 20)) + (timestamp-str (test-timestamp-string event-time))) + (with-test-time now + (let* ((event `((times . ((,timestamp-str . ,event-time))) + (title . "Test Event") + (intervals . ((10 . medium) (20 . high))))) + (result (chime--notifications event))) + ;; At 14:00, event is 20 minutes away, so only 20-minute interval matches + (should (= 1 (length result))))) + + ;; Now test at 14:10 (10 minutes before event) + (let ((now-2 (test-time-today-at 14 10))) + (with-test-time now-2 + (let* ((event `((times . ((,timestamp-str . ,event-time))) + (title . "Test Event") + (intervals . ((10 . medium) (20 . high))))) + (result (chime--notifications event))) + ;; At 14:10, event is 10 minutes away, so only 10-minute interval matches + (should (= 1 (length result)))))))) ;;; Escalating Notification Tests -(ert-deftest test-chime-notification-boundary-escalating-intervals () +(chime-deftest test-chime-notification-boundary-escalating-intervals () "Test escalating notifications: 1 day, 1 hour, 10 minutes before event. Simulates the common use case of multiple notifications at different times." - (test-chime-notification-boundaries-setup) - (unwind-protect - (let* ((base-time (test-time-today-at 10 0)) - (event-time (time-add base-time (seconds-to-time (* 24 3600)))) ; 1 day later - (timestamp-str (test-timestamp-string event-time))) - - ;; Test 1: 24 hours before (1 day interval) - (with-test-time base-time - (let* ((event `((times . ((,timestamp-str . ,event-time))) - (title . "Important Event") - (intervals . ((1440 . low) (60 . medium) (10 . high))))) - (result (chime--notifications event))) - ;; Should match 1440-minute (1 day) interval - (should (= 1 (length result))))) - - ;; Test 2: 1 hour before (60-minute interval) - (let ((time-1h-before (time-add event-time (seconds-to-time (* -60 60))))) - (with-test-time time-1h-before - (let* ((event `((times . ((,timestamp-str . ,event-time))) - (title . "Important Event") - (intervals . ((1440 . low) (60 . medium) (10 . high))))) - (result (chime--notifications event))) - ;; Should match 60-minute interval - (should (= 1 (length result)))))) - - ;; Test 3: 10 minutes before (10-minute interval) - (let ((time-10m-before (time-add event-time (seconds-to-time (* -10 60))))) - (with-test-time time-10m-before - (let* ((event `((times . ((,timestamp-str . ,event-time))) - (title . "Important Event") - (intervals . ((1440 . low) (60 . medium) (10 . high))))) - (result (chime--notifications event))) - ;; Should match 10-minute interval - (should (= 1 (length result))))))) - (test-chime-notification-boundaries-teardown))) + (let* ((base-time (test-time-today-at 10 0)) + (event-time (time-add base-time (seconds-to-time (* 24 3600)))) ; 1 day later + (timestamp-str (test-timestamp-string event-time))) + + ;; Test 1: 24 hours before (1 day interval) + (with-test-time base-time + (let* ((event `((times . ((,timestamp-str . ,event-time))) + (title . "Important Event") + (intervals . ((1440 . low) (60 . medium) (10 . high))))) + (result (chime--notifications event))) + ;; Should match 1440-minute (1 day) interval + (should (= 1 (length result))))) + + ;; Test 2: 1 hour before (60-minute interval) + (let ((time-1h-before (time-add event-time (seconds-to-time (* -60 60))))) + (with-test-time time-1h-before + (let* ((event `((times . ((,timestamp-str . ,event-time))) + (title . "Important Event") + (intervals . ((1440 . low) (60 . medium) (10 . high))))) + (result (chime--notifications event))) + ;; Should match 60-minute interval + (should (= 1 (length result)))))) + + ;; Test 3: 10 minutes before (10-minute interval) + (let ((time-10m-before (time-add event-time (seconds-to-time (* -10 60))))) + (with-test-time time-10m-before + (let* ((event `((times . ((,timestamp-str . ,event-time))) + (title . "Important Event") + (intervals . ((1440 . low) (60 . medium) (10 . high))))) + (result (chime--notifications event))) + ;; Should match 10-minute interval + (should (= 1 (length result)))))))) (provide 'test-chime-notification-boundaries) ;;; test-chime-notification-boundaries.el ends here diff --git a/tests/test-chime-notification-text.el b/tests/test-chime-notification-text.el index a707d29..7363cd2 100644 --- a/tests/test-chime-notification-text.el +++ b/tests/test-chime-notification-text.el @@ -26,10 +26,6 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) - ;;; Setup and Teardown (defun test-chime-notification-text-setup () diff --git a/tests/test-chime-notifications.el b/tests/test-chime-notifications.el index 17ce540..e3c7cc2 100644 --- a/tests/test-chime-notifications.el +++ b/tests/test-chime-notifications.el @@ -26,221 +26,177 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) - -;;; Setup and Teardown - -(defun test-chime-notifications-setup () - "Setup function run before each test." - (chime-create-test-base-dir)) - -(defun test-chime-notifications-teardown () - "Teardown function run after each test." - (chime-delete-test-base-dir)) - ;;; Normal Cases -(ert-deftest test-chime-notifications-single-time-single-interval-returns-pair () +(chime-deftest test-chime-notifications-single-time-single-interval-returns-pair () "Test that single time with single interval returns one notification pair. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-notifications-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 0)) - ;; Event at 14:10 (10 minutes from now) - (event-time (test-time-today-at 14 10)) - (timestamp-str (test-timestamp-string event-time))) - (with-test-time now - (let* ((event `((times . ((,timestamp-str . ,event-time))) - (title . "Test Event") - (intervals . ((10 . medium))))) - (result (chime--notifications event))) - ;; Should return list with one pair - (should (listp result)) - (should (= 1 (length result)))))) - (test-chime-notifications-teardown))) - -(ert-deftest test-chime-notifications-single-time-multiple-intervals-returns-multiple-pairs () + (let* ((now (test-time-today-at 14 0)) + ;; Event at 14:10 (10 minutes from now) + (event-time (test-time-today-at 14 10)) + (timestamp-str (test-timestamp-string event-time))) + (with-test-time now + (let* ((event `((times . ((,timestamp-str . ,event-time))) + (title . "Test Event") + (intervals . ((10 . medium))))) + (result (chime--notifications event))) + ;; Should return list with one pair + (should (listp result)) + (should (= 1 (length result))))))) + +(chime-deftest test-chime-notifications-single-time-multiple-intervals-returns-multiple-pairs () "Test that single time with multiple intervals returns multiple notification pairs. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-notifications-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 0)) - ;; Event at 14:10 - (event-time (test-time-today-at 14 10)) - (timestamp-str (test-timestamp-string event-time))) - (with-test-time now - (let* ((event `((times . ((,timestamp-str . ,event-time))) - (title . "Test Event") - (intervals . ((10 . medium) (5 . medium))))) ; Two intervals, only 10 matches - (result (chime--notifications event))) - ;; Should return only matching interval - (should (listp result)) - (should (= 1 (length result)))))) - (test-chime-notifications-teardown))) - -(ert-deftest test-chime-notifications-multiple-times-single-interval-returns-matching-pairs () + (let* ((now (test-time-today-at 14 0)) + ;; Event at 14:10 + (event-time (test-time-today-at 14 10)) + (timestamp-str (test-timestamp-string event-time))) + (with-test-time now + (let* ((event `((times . ((,timestamp-str . ,event-time))) + (title . "Test Event") + (intervals . ((10 . medium) (5 . medium))))) ; Two intervals, only 10 matches + (result (chime--notifications event))) + ;; Should return only matching interval + (should (listp result)) + (should (= 1 (length result))))))) + +(chime-deftest test-chime-notifications-multiple-times-single-interval-returns-matching-pairs () "Test that multiple times with single interval returns matching notifications. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-notifications-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 0)) - ;; Two events: one at 14:10, one at 14:05 - (event-time-1 (test-time-today-at 14 10)) - (event-time-2 (test-time-today-at 14 5)) - (timestamp-str-1 (test-timestamp-string event-time-1)) - (timestamp-str-2 (test-timestamp-string event-time-2))) - (with-test-time now - (let* ((event `((times . ((,timestamp-str-1 . ,event-time-1) - (,timestamp-str-2 . ,event-time-2))) - (title . "Test Event") - (intervals . ((10 . medium))))) ; Only first time matches - (result (chime--notifications event))) - ;; Should return only matching time - (should (listp result)) - (should (= 1 (length result)))))) - (test-chime-notifications-teardown))) - -(ert-deftest test-chime-notifications-multiple-times-multiple-intervals-returns-all-matches () + (let* ((now (test-time-today-at 14 0)) + ;; Two events: one at 14:10, one at 14:05 + (event-time-1 (test-time-today-at 14 10)) + (event-time-2 (test-time-today-at 14 5)) + (timestamp-str-1 (test-timestamp-string event-time-1)) + (timestamp-str-2 (test-timestamp-string event-time-2))) + (with-test-time now + (let* ((event `((times . ((,timestamp-str-1 . ,event-time-1) + (,timestamp-str-2 . ,event-time-2))) + (title . "Test Event") + (intervals . ((10 . medium))))) ; Only first time matches + (result (chime--notifications event))) + ;; Should return only matching time + (should (listp result)) + (should (= 1 (length result))))))) + +(chime-deftest test-chime-notifications-multiple-times-multiple-intervals-returns-all-matches () "Test that multiple times and intervals return all matching combinations. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-notifications-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 0)) - ;; Event at 14:10 and 14:05 - (event-time-1 (test-time-today-at 14 10)) - (event-time-2 (test-time-today-at 14 5)) - (timestamp-str-1 (test-timestamp-string event-time-1)) - (timestamp-str-2 (test-timestamp-string event-time-2))) - (with-test-time now - (let* ((event `((times . ((,timestamp-str-1 . ,event-time-1) - (,timestamp-str-2 . ,event-time-2))) - (title . "Test Event") - (intervals . ((10 . medium) (5 . medium))))) ; Both match (10 with first, 5 with second) - (result (chime--notifications event))) - ;; Should return both matching pairs - (should (listp result)) - (should (= 2 (length result)))))) - (test-chime-notifications-teardown))) - -(ert-deftest test-chime-notifications-zero-interval-returns-current-time-match () + (let* ((now (test-time-today-at 14 0)) + ;; Event at 14:10 and 14:05 + (event-time-1 (test-time-today-at 14 10)) + (event-time-2 (test-time-today-at 14 5)) + (timestamp-str-1 (test-timestamp-string event-time-1)) + (timestamp-str-2 (test-timestamp-string event-time-2))) + (with-test-time now + (let* ((event `((times . ((,timestamp-str-1 . ,event-time-1) + (,timestamp-str-2 . ,event-time-2))) + (title . "Test Event") + (intervals . ((10 . medium) (5 . medium))))) ; Both match (10 with first, 5 with second) + (result (chime--notifications event))) + ;; Should return both matching pairs + (should (listp result)) + (should (= 2 (length result))))))) + +(chime-deftest test-chime-notifications-zero-interval-returns-current-time-match () "Test that zero interval (notify now) works correctly. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-notifications-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 0)) - ;; Event at exactly current time - (event-time (test-time-today-at 14 0)) - (timestamp-str (test-timestamp-string event-time))) - (with-test-time now - (let* ((event `((times . ((,timestamp-str . ,event-time))) - (title . "Test Event") - (intervals . ((0 . high))))) - (result (chime--notifications event))) - ;; Should return one matching pair - (should (listp result)) - (should (= 1 (length result)))))) - (test-chime-notifications-teardown))) - -(ert-deftest test-chime-notifications-filters-day-wide-events () + (let* ((now (test-time-today-at 14 0)) + ;; Event at exactly current time + (event-time (test-time-today-at 14 0)) + (timestamp-str (test-timestamp-string event-time))) + (with-test-time now + (let* ((event `((times . ((,timestamp-str . ,event-time))) + (title . "Test Event") + (intervals . ((0 . high))))) + (result (chime--notifications event))) + ;; Should return one matching pair + (should (listp result)) + (should (= 1 (length result))))))) + +(chime-deftest test-chime-notifications-filters-day-wide-events () "Test that day-wide events (without time) are filtered out. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-notifications-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 0)) - ;; Mix of day-wide and timed events - (event-time (test-time-today-at 14 10)) - (timestamp-str-day (test-timestamp-string event-time t)) ; Day-wide - (timestamp-str-timed (test-timestamp-string event-time))) ; Timed - (with-test-time now - (let* ((event `((times . ((,timestamp-str-day . ,event-time) ; Day-wide - (,timestamp-str-timed . ,event-time))) ; Timed - (title . "Test Event") - (intervals . ((10 . medium))))) - (result (chime--notifications event))) - ;; Should return only timed event - (should (listp result)) - (should (= 1 (length result)))))) - (test-chime-notifications-teardown))) + (let* ((now (test-time-today-at 14 0)) + ;; Mix of day-wide and timed events + (event-time (test-time-today-at 14 10)) + (timestamp-str-day (test-timestamp-string event-time t)) ; Day-wide + (timestamp-str-timed (test-timestamp-string event-time))) ; Timed + (with-test-time now + (let* ((event `((times . ((,timestamp-str-day . ,event-time) ; Day-wide + (,timestamp-str-timed . ,event-time))) ; Timed + (title . "Test Event") + (intervals . ((10 . medium))))) + (result (chime--notifications event))) + ;; Should return only timed event + (should (listp result)) + (should (= 1 (length result))))))) ;;; Boundary Cases -(ert-deftest test-chime-notifications-empty-times-returns-empty-list () +(chime-deftest test-chime-notifications-empty-times-returns-empty-list () "Test that event with no times returns empty list. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-notifications-setup) - (unwind-protect - (let ((now (test-time-today-at 14 0))) - (with-test-time now - (let* ((event `((times . (())) - (title . "Test Event") - (intervals . ((10 . medium))))) - (result (chime--notifications event))) - (should (listp result)) - (should (= 0 (length result)))))) - (test-chime-notifications-teardown))) - -(ert-deftest test-chime-notifications-empty-intervals-returns-empty-list () + (let ((now (test-time-today-at 14 0))) + (with-test-time now + (let* ((event `((times . (())) + (title . "Test Event") + (intervals . ((10 . medium))))) + (result (chime--notifications event))) + (should (listp result)) + (should (= 0 (length result))))))) + +(chime-deftest test-chime-notifications-empty-intervals-returns-empty-list () "Test that event with no intervals returns empty list. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-notifications-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 0)) - (event-time (test-time-today-at 14 10)) - (timestamp-str (test-timestamp-string event-time))) - (with-test-time now - (let* ((event `((times . ((,timestamp-str . ,event-time))) - (title . "Test Event") - (intervals . ()))) - (result (chime--notifications event))) - (should (listp result)) - (should (= 0 (length result)))))) - (test-chime-notifications-teardown))) + (let* ((now (test-time-today-at 14 0)) + (event-time (test-time-today-at 14 10)) + (timestamp-str (test-timestamp-string event-time))) + (with-test-time now + (let* ((event `((times . ((,timestamp-str . ,event-time))) + (title . "Test Event") + (intervals . ()))) + (result (chime--notifications event))) + (should (listp result)) + (should (= 0 (length result))))))) ;;; Error Cases -(ert-deftest test-chime-notifications-nil-times-returns-empty-list () +(chime-deftest test-chime-notifications-nil-times-returns-empty-list () "Test that event with nil times returns empty list. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-notifications-setup) - (unwind-protect - (let ((now (test-time-today-at 14 0))) - (with-test-time now - (let* ((event `((times . (nil)) - (title . "Test Event") - (intervals . ((10 . medium))))) - (result (chime--notifications event))) - (should (listp result)) - (should (= 0 (length result)))))) - (test-chime-notifications-teardown))) - -(ert-deftest test-chime-notifications-nil-intervals-returns-empty-list () + (let ((now (test-time-today-at 14 0))) + (with-test-time now + (let* ((event `((times . (nil)) + (title . "Test Event") + (intervals . ((10 . medium))))) + (result (chime--notifications event))) + (should (listp result)) + (should (= 0 (length result))))))) + +(chime-deftest test-chime-notifications-nil-intervals-returns-empty-list () "Test that event with nil intervals returns empty list. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-notifications-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 0)) - (event-time (test-time-today-at 14 10)) - (timestamp-str (test-timestamp-string event-time))) - (with-test-time now - (let* ((event `((times . ((,timestamp-str . ,event-time))) - (title . "Test Event") - (intervals . nil))) - (result (chime--notifications event))) - (should (listp result)) - (should (= 0 (length result)))))) - (test-chime-notifications-teardown))) + (let* ((now (test-time-today-at 14 0)) + (event-time (test-time-today-at 14 10)) + (timestamp-str (test-timestamp-string event-time))) + (with-test-time now + (let* ((event `((times . ((,timestamp-str . ,event-time))) + (title . "Test Event") + (intervals . nil))) + (result (chime--notifications event))) + (should (listp result)) + (should (= 0 (length result))))))) (provide 'test-chime-notifications) ;;; test-chime-notifications.el ends here diff --git a/tests/test-chime-notify.el b/tests/test-chime-notify.el index cd7b350..0b77993 100644 --- a/tests/test-chime-notify.el +++ b/tests/test-chime-notify.el @@ -26,9 +26,6 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) - ;;; Setup and Teardown (defun test-chime-notify-setup () diff --git a/tests/test-chime-overdue-todos.el b/tests/test-chime-overdue-todos.el index 84bc091..32e50c3 100644 --- a/tests/test-chime-overdue-todos.el +++ b/tests/test-chime-overdue-todos.el @@ -31,10 +31,6 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) - ;;; Test Helper Functions (defun test-overdue--create-event (title timestamp has-time) @@ -47,19 +43,9 @@ HAS-TIME determines if timestamp has time component." (times . ,times) (intervals . (10))))) -;;; Setup and Teardown - -(defun test-chime-overdue-setup () - "Setup function run before each test." - (chime-create-test-base-dir)) - -(defun test-chime-overdue-teardown () - "Teardown function run after each test." - (chime-delete-test-base-dir)) - ;;; Tests for chime--event-has-any-passed-time -(ert-deftest test-overdue-has-passed-time-yesterday-all-day () +(chime-deftest test-overdue-has-passed-time-yesterday-all-day () "Test that all-day event from yesterday is recognized as passed. TIME RELATIONSHIPS: @@ -70,20 +56,17 @@ EXPECTED BEHAVIOR: Should return t (yesterday is in the past) REFACTORED: Uses dynamic timestamps via testutil-time.el" - (test-chime-overdue-setup) - (unwind-protect - (let* ((now (test-time-now)) - (yesterday (test-time-yesterday-at 0 0)) - (yesterday-timestamp (test-timestamp-string yesterday t)) - (event (test-overdue--create-event - "Yesterday Event" - yesterday-timestamp - nil))) ; all-day event - (with-test-time now - (should (chime--event-has-any-passed-time event)))) - (test-chime-overdue-teardown))) - -(ert-deftest test-overdue-has-passed-time-today-all-day () + (let* ((now (test-time-now)) + (yesterday (test-time-yesterday-at 0 0)) + (yesterday-timestamp (test-timestamp-string yesterday t)) + (event (test-overdue--create-event + "Yesterday Event" + yesterday-timestamp + nil))) ; all-day event + (with-test-time now + (should (chime--event-has-any-passed-time event))))) + +(chime-deftest test-overdue-has-passed-time-today-all-day () "Test that all-day event from today is recognized as passed. TIME RELATIONSHIPS: @@ -111,19 +94,16 @@ REFACTORING NOTES: Simple case - just needs TODAY timestamp and TODAY current-time. REFACTORED: Uses dynamic timestamps via testutil-time.el" - (test-chime-overdue-setup) - (unwind-protect - (let* ((now (test-time-now)) - (today-timestamp (test-timestamp-string now t)) - (event (test-overdue--create-event - "Today Event" - today-timestamp - nil))) ; all-day event - (with-test-time now - (should (chime--event-has-any-passed-time event)))) - (test-chime-overdue-teardown))) - -(ert-deftest test-overdue-has-passed-time-tomorrow-all-day () + (let* ((now (test-time-now)) + (today-timestamp (test-timestamp-string now t)) + (event (test-overdue--create-event + "Today Event" + today-timestamp + nil))) ; all-day event + (with-test-time now + (should (chime--event-has-any-passed-time event))))) + +(chime-deftest test-overdue-has-passed-time-tomorrow-all-day () "Test that all-day event from tomorrow is NOT recognized as passed. TIME RELATIONSHIPS: @@ -134,20 +114,17 @@ EXPECTED BEHAVIOR: Should return nil (tomorrow is in the future) REFACTORED: Uses dynamic timestamps via testutil-time.el" - (test-chime-overdue-setup) - (unwind-protect - (let* ((now (test-time-now)) - (tomorrow (test-time-tomorrow-at 0 0)) - (tomorrow-timestamp (test-timestamp-string tomorrow t)) - (event (test-overdue--create-event - "Tomorrow Event" - tomorrow-timestamp - nil))) ; all-day event - (with-test-time now - (should-not (chime--event-has-any-passed-time event)))) - (test-chime-overdue-teardown))) - -(ert-deftest test-overdue-has-passed-time-timed-event-past () + (let* ((now (test-time-now)) + (tomorrow (test-time-tomorrow-at 0 0)) + (tomorrow-timestamp (test-timestamp-string tomorrow t)) + (event (test-overdue--create-event + "Tomorrow Event" + tomorrow-timestamp + nil))) ; all-day event + (with-test-time now + (should-not (chime--event-has-any-passed-time event))))) + +(chime-deftest test-overdue-has-passed-time-timed-event-past () "Test that timed event in the past is recognized as passed. TIME RELATIONSHIPS: @@ -158,20 +135,17 @@ EXPECTED BEHAVIOR: Should return t (event time has passed) REFACTORED: Uses dynamic timestamps via testutil-time.el" - (test-chime-overdue-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 0)) - (past-event (test-time-today-at 9 0)) - (past-timestamp (test-timestamp-string past-event)) - (event (test-overdue--create-event - "Past Meeting" - past-timestamp - t))) ; timed event - (with-test-time now - (should (chime--event-has-any-passed-time event)))) - (test-chime-overdue-teardown))) - -(ert-deftest test-overdue-has-passed-time-timed-event-future () + (let* ((now (test-time-today-at 14 0)) + (past-event (test-time-today-at 9 0)) + (past-timestamp (test-timestamp-string past-event)) + (event (test-overdue--create-event + "Past Meeting" + past-timestamp + t))) ; timed event + (with-test-time now + (should (chime--event-has-any-passed-time event))))) + +(chime-deftest test-overdue-has-passed-time-timed-event-future () "Test that timed event in the future is NOT recognized as passed. TIME RELATIONSHIPS: @@ -182,22 +156,19 @@ EXPECTED BEHAVIOR: Should return nil (event time is in future) REFACTORED: Uses dynamic timestamps via testutil-time.el" - (test-chime-overdue-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 0)) - (future-event (test-time-today-at 16 0)) - (future-timestamp (test-timestamp-string future-event)) - (event (test-overdue--create-event - "Future Meeting" - future-timestamp - t))) ; timed event - (with-test-time now - (should-not (chime--event-has-any-passed-time event)))) - (test-chime-overdue-teardown))) + (let* ((now (test-time-today-at 14 0)) + (future-event (test-time-today-at 16 0)) + (future-timestamp (test-timestamp-string future-event)) + (event (test-overdue--create-event + "Future Meeting" + future-timestamp + t))) ; timed event + (with-test-time now + (should-not (chime--event-has-any-passed-time event))))) ;;; Tests for chime--display-as-day-wide-event with overdue setting -(ert-deftest test-overdue-display-yesterday-all-day-with-overdue-enabled () +(chime-deftest test-overdue-display-yesterday-all-day-with-overdue-enabled () "Test that yesterday's all-day event is displayed when overdue is enabled. TIME RELATIONSHIPS: @@ -209,133 +180,115 @@ EXPECTED BEHAVIOR: Should display (overdue enabled shows past events) REFACTORED: Uses dynamic timestamps via testutil-time.el" - (test-chime-overdue-setup) - (unwind-protect - (let* ((now (test-time-now)) - (yesterday (test-time-yesterday-at 0 0)) - (yesterday-timestamp (test-timestamp-string yesterday t)) - (chime-show-any-overdue-with-day-wide-alerts t) - (chime-day-wide-advance-notice nil) - (event (test-overdue--create-event - "Yesterday Birthday" - yesterday-timestamp - nil))) - (with-test-time now - (should (chime--display-as-day-wide-event event)))) - (test-chime-overdue-teardown))) - -(ert-deftest test-overdue-display-yesterday-all-day-with-overdue-disabled () + (let* ((now (test-time-now)) + (yesterday (test-time-yesterday-at 0 0)) + (yesterday-timestamp (test-timestamp-string yesterday t)) + (chime-show-any-overdue-with-day-wide-alerts t) + (chime-day-wide-advance-notice nil) + (event (test-overdue--create-event + "Yesterday Birthday" + yesterday-timestamp + nil))) + (with-test-time now + (should (chime--display-as-day-wide-event event))))) + +(chime-deftest test-overdue-display-yesterday-all-day-with-overdue-disabled () "Test that yesterday's all-day event is NOT displayed when overdue is disabled. This prevents showing old birthdays/holidays from the past. REFACTORED: Uses dynamic timestamps via testutil-time.el" - (test-chime-overdue-setup) - (unwind-protect - (let* ((now (test-time-now)) - (yesterday (test-time-yesterday-at 0 0)) - (yesterday-timestamp (test-timestamp-string yesterday t)) - (chime-show-any-overdue-with-day-wide-alerts nil) - (chime-day-wide-advance-notice nil) - (event (test-overdue--create-event - "Yesterday Birthday" - yesterday-timestamp - nil))) - (with-test-time now - (should-not (chime--display-as-day-wide-event event)))) - (test-chime-overdue-teardown))) - -(ert-deftest test-overdue-display-yesterday-timed-with-overdue-enabled () + (let* ((now (test-time-now)) + (yesterday (test-time-yesterday-at 0 0)) + (yesterday-timestamp (test-timestamp-string yesterday t)) + (chime-show-any-overdue-with-day-wide-alerts nil) + (chime-day-wide-advance-notice nil) + (event (test-overdue--create-event + "Yesterday Birthday" + yesterday-timestamp + nil))) + (with-test-time now + (should-not (chime--display-as-day-wide-event event))))) + +(chime-deftest test-overdue-display-yesterday-timed-with-overdue-enabled () "Test that yesterday's timed event is displayed when overdue is enabled. TIME: TODAY 10am, Event: YESTERDAY 2pm, overdue=t EXPECTED: Display (show past timed events when enabled) REFACTORED: Uses dynamic timestamps via testutil-time.el" - (test-chime-overdue-setup) - (unwind-protect - (let* ((now (test-time-now)) - (yesterday (test-time-yesterday-at 14 0)) - (yesterday-timestamp (test-timestamp-string yesterday)) - (chime-show-any-overdue-with-day-wide-alerts t) - (chime-day-wide-advance-notice nil) - (event (test-overdue--create-event - "Yesterday Meeting" - yesterday-timestamp - t))) - (with-test-time now - (should (chime--display-as-day-wide-event event)))) - (test-chime-overdue-teardown))) - -(ert-deftest test-overdue-display-yesterday-timed-with-overdue-disabled () + (let* ((now (test-time-now)) + (yesterday (test-time-yesterday-at 14 0)) + (yesterday-timestamp (test-timestamp-string yesterday)) + (chime-show-any-overdue-with-day-wide-alerts t) + (chime-day-wide-advance-notice nil) + (event (test-overdue--create-event + "Yesterday Meeting" + yesterday-timestamp + t))) + (with-test-time now + (should (chime--display-as-day-wide-event event))))) + +(chime-deftest test-overdue-display-yesterday-timed-with-overdue-disabled () "Test that yesterday's timed event is NOT displayed when overdue is disabled. TIME: TODAY 10am, Event: YESTERDAY 2pm, overdue=nil EXPECTED: Hide (don't show past timed events when disabled) REFACTORED: Uses dynamic timestamps via testutil-time.el" - (test-chime-overdue-setup) - (unwind-protect - (let* ((now (test-time-now)) - (yesterday (test-time-yesterday-at 14 0)) - (yesterday-timestamp (test-timestamp-string yesterday)) - (chime-show-any-overdue-with-day-wide-alerts nil) - (chime-day-wide-advance-notice nil) - (event (test-overdue--create-event - "Yesterday Meeting" - yesterday-timestamp - t))) - (with-test-time now - (should-not (chime--display-as-day-wide-event event)))) - (test-chime-overdue-teardown))) - -(ert-deftest test-overdue-display-today-all-day-always-shown () + (let* ((now (test-time-now)) + (yesterday (test-time-yesterday-at 14 0)) + (yesterday-timestamp (test-timestamp-string yesterday)) + (chime-show-any-overdue-with-day-wide-alerts nil) + (chime-day-wide-advance-notice nil) + (event (test-overdue--create-event + "Yesterday Meeting" + yesterday-timestamp + t))) + (with-test-time now + (should-not (chime--display-as-day-wide-event event))))) + +(chime-deftest test-overdue-display-today-all-day-always-shown () "Test that today's all-day event is always displayed regardless of overdue setting. TIME: TODAY 10am, Event: TODAY (all-day), both overdue=t and =nil EXPECTED: Always display (today's events shown regardless of setting) REFACTORED: Uses dynamic timestamps via testutil-time.el" - (test-chime-overdue-setup) - (unwind-protect - (let* ((now (test-time-now)) - (today-timestamp (test-timestamp-string now t)) - (chime-day-wide-advance-notice nil) - (event (test-overdue--create-event - "Today Birthday" - today-timestamp - nil))) - (with-test-time now - ;; Should show with overdue enabled - (let ((chime-show-any-overdue-with-day-wide-alerts t)) - (should (chime--display-as-day-wide-event event))) - ;; Should also show with overdue disabled (it's today, not overdue) - (let ((chime-show-any-overdue-with-day-wide-alerts nil)) - (should (chime--display-as-day-wide-event event))))) - (test-chime-overdue-teardown))) - -(ert-deftest test-overdue-display-week-old-all-day-with-overdue-enabled () + (let* ((now (test-time-now)) + (today-timestamp (test-timestamp-string now t)) + (chime-day-wide-advance-notice nil) + (event (test-overdue--create-event + "Today Birthday" + today-timestamp + nil))) + (with-test-time now + ;; Should show with overdue enabled + (let ((chime-show-any-overdue-with-day-wide-alerts t)) + (should (chime--display-as-day-wide-event event))) + ;; Should also show with overdue disabled (it's today, not overdue) + (let ((chime-show-any-overdue-with-day-wide-alerts nil)) + (should (chime--display-as-day-wide-event event)))))) + +(chime-deftest test-overdue-display-week-old-all-day-with-overdue-enabled () "Test that week-old all-day event is displayed when overdue is enabled. TIME: TODAY (Oct 28), Event: 7 DAYS AGO (Oct 21), overdue=t EXPECTED: Display (show old events when enabled) REFACTORED: Uses dynamic timestamps via testutil-time.el" - (test-chime-overdue-setup) - (unwind-protect - (let* ((now (test-time-now)) - (week-ago (test-time-days-ago 7)) - (week-ago-timestamp (test-timestamp-string week-ago t)) - (chime-show-any-overdue-with-day-wide-alerts t) - (chime-day-wide-advance-notice nil) - (event (test-overdue--create-event - "Week Old Event" - week-ago-timestamp - nil))) - (with-test-time now - (should (chime--display-as-day-wide-event event)))) - (test-chime-overdue-teardown))) - -(ert-deftest test-overdue-display-week-old-all-day-with-overdue-disabled () + (let* ((now (test-time-now)) + (week-ago (test-time-days-ago 7)) + (week-ago-timestamp (test-timestamp-string week-ago t)) + (chime-show-any-overdue-with-day-wide-alerts t) + (chime-day-wide-advance-notice nil) + (event (test-overdue--create-event + "Week Old Event" + week-ago-timestamp + nil))) + (with-test-time now + (should (chime--display-as-day-wide-event event))))) + +(chime-deftest test-overdue-display-week-old-all-day-with-overdue-disabled () "Test that week-old all-day event is NOT displayed when overdue is disabled. This prevents showing old birthdays/holidays from past weeks. @@ -343,48 +296,42 @@ TIME: TODAY (Oct 28), Event: 7 DAYS AGO (Oct 21), overdue=nil EXPECTED: Hide (prevent old birthday spam) REFACTORED: Uses dynamic timestamps via testutil-time.el" - (test-chime-overdue-setup) - (unwind-protect - (let* ((now (test-time-now)) - (week-ago (test-time-days-ago 7)) - (week-ago-timestamp (test-timestamp-string week-ago t)) - (chime-show-any-overdue-with-day-wide-alerts nil) - (chime-day-wide-advance-notice nil) - (event (test-overdue--create-event - "Week Old Event" - week-ago-timestamp - nil))) - (with-test-time now - (should-not (chime--display-as-day-wide-event event)))) - (test-chime-overdue-teardown))) + (let* ((now (test-time-now)) + (week-ago (test-time-days-ago 7)) + (week-ago-timestamp (test-timestamp-string week-ago t)) + (chime-show-any-overdue-with-day-wide-alerts nil) + (chime-day-wide-advance-notice nil) + (event (test-overdue--create-event + "Week Old Event" + week-ago-timestamp + nil))) + (with-test-time now + (should-not (chime--display-as-day-wide-event event))))) ;;; Tests verifying overdue doesn't affect future events -(ert-deftest test-overdue-future-event-not-affected-by-overdue-setting () +(chime-deftest test-overdue-future-event-not-affected-by-overdue-setting () "Test that future events are not affected by overdue setting. TIME: TODAY (Oct 28), Event: 2 DAYS FROM NOW (Oct 30), both overdue settings EXPECTED: Never display (future events not shown without advance notice) REFACTORED: Uses dynamic timestamps via testutil-time.el" - (test-chime-overdue-setup) - (unwind-protect - (let* ((now (test-time-now)) - (future (test-time-days-from-now 2)) - (future-timestamp (test-timestamp-string future t)) - (chime-day-wide-advance-notice nil) - (event (test-overdue--create-event - "Future Event" - future-timestamp - nil))) - (with-test-time now - ;; Should NOT show with overdue enabled (it's future, not today) - (let ((chime-show-any-overdue-with-day-wide-alerts t)) - (should-not (chime--display-as-day-wide-event event))) - ;; Should NOT show with overdue disabled (it's future, not today) - (let ((chime-show-any-overdue-with-day-wide-alerts nil)) - (should-not (chime--display-as-day-wide-event event))))) - (test-chime-overdue-teardown))) + (let* ((now (test-time-now)) + (future (test-time-days-from-now 2)) + (future-timestamp (test-timestamp-string future t)) + (chime-day-wide-advance-notice nil) + (event (test-overdue--create-event + "Future Event" + future-timestamp + nil))) + (with-test-time now + ;; Should NOT show with overdue enabled (it's future, not today) + (let ((chime-show-any-overdue-with-day-wide-alerts t)) + (should-not (chime--display-as-day-wide-event event))) + ;; Should NOT show with overdue disabled (it's future, not today) + (let ((chime-show-any-overdue-with-day-wide-alerts nil)) + (should-not (chime--display-as-day-wide-event event)))))) (provide 'test-chime-overdue-todos) ;;; test-chime-overdue-todos.el ends here diff --git a/tests/test-chime-process-notifications.el b/tests/test-chime-process-notifications.el index 75cac9b..1a93842 100644 --- a/tests/test-chime-process-notifications.el +++ b/tests/test-chime-process-notifications.el @@ -26,363 +26,310 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) - -;;; Setup and Teardown - -(defun test-chime-process-notifications-setup () - "Setup function run before each test." - (chime-create-test-base-dir)) - -(defun test-chime-process-notifications-teardown () - "Teardown function run after each test." - (chime-delete-test-base-dir)) - ;;; Normal Cases -(ert-deftest test-chime-process-notifications-normal-single-event-calls-notify () +(chime-deftest test-chime-process-notifications-normal-single-event-calls-notify () "Test that single event with notification calls chime--notify. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-process-notifications-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 0)) - ;; Event at 14:10 (10 minutes from now) - (event-time (test-time-today-at 14 10)) - (timestamp-str (test-timestamp-string event-time)) - (notify-called nil) - (notify-messages '())) - (with-test-time now - (cl-letf (((symbol-function 'chime--notify) - (lambda (msg) - (setq notify-called t) - (push msg notify-messages))) - ((symbol-function 'chime--current-time-is-day-wide-time) - (lambda () nil))) - (let* ((event `((times . ((,timestamp-str . ,event-time))) - (title . "Team Meeting") - (intervals . ((10 . medium))))) - (events (list event))) - (chime--process-notifications events) - ;; Should call notify - (should notify-called) - (should (= 1 (length notify-messages))) - (should (string-match-p "Team Meeting" (caar notify-messages))))))) - (test-chime-process-notifications-teardown))) - -(ert-deftest test-chime-process-notifications-normal-multiple-events-calls-notify-multiple-times () + (let* ((now (test-time-today-at 14 0)) + ;; Event at 14:10 (10 minutes from now) + (event-time (test-time-today-at 14 10)) + (timestamp-str (test-timestamp-string event-time)) + (notify-called nil) + (notify-messages '())) + (with-test-time now + (cl-letf (((symbol-function 'chime--notify) + (lambda (msg) + (setq notify-called t) + (push msg notify-messages))) + ((symbol-function 'chime--current-time-is-day-wide-time) + (lambda () nil))) + (let* ((event `((times . ((,timestamp-str . ,event-time))) + (title . "Team Meeting") + (intervals . ((10 . medium))))) + (events (list event))) + (chime--process-notifications events) + ;; Should call notify + (should notify-called) + (should (= 1 (length notify-messages))) + (should (string-match-p "Team Meeting" (caar notify-messages)))))))) + +(chime-deftest test-chime-process-notifications-normal-multiple-events-calls-notify-multiple-times () "Test that multiple events with notifications call chime--notify multiple times. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-process-notifications-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 0)) - ;; Event 1 at 14:10 - (event-time-1 (test-time-today-at 14 10)) - (timestamp-str-1 (test-timestamp-string event-time-1)) - ;; Event 2 at 14:05 - (event-time-2 (test-time-today-at 14 5)) - (timestamp-str-2 (test-timestamp-string event-time-2)) - (notify-count 0)) - (with-test-time now - (cl-letf (((symbol-function 'chime--notify) - (lambda (msg) (setq notify-count (1+ notify-count)))) - ((symbol-function 'chime--current-time-is-day-wide-time) - (lambda () nil))) - (let* ((event1 `((times . ((,timestamp-str-1 . ,event-time-1))) - (title . "Meeting 1") - (intervals . ((10 . medium))))) - (event2 `((times . ((,timestamp-str-2 . ,event-time-2))) - (title . "Meeting 2") - (intervals . ((5 . medium))))) - (events (list event1 event2))) - (chime--process-notifications events) - ;; Should call notify twice (once per event) - (should (= 2 notify-count)))))) - (test-chime-process-notifications-teardown))) - -(ert-deftest test-chime-process-notifications-normal-deduplication-removes-duplicates () + (let* ((now (test-time-today-at 14 0)) + ;; Event 1 at 14:10 + (event-time-1 (test-time-today-at 14 10)) + (timestamp-str-1 (test-timestamp-string event-time-1)) + ;; Event 2 at 14:05 + (event-time-2 (test-time-today-at 14 5)) + (timestamp-str-2 (test-timestamp-string event-time-2)) + (notify-count 0)) + (with-test-time now + (cl-letf (((symbol-function 'chime--notify) + (lambda (msg) (setq notify-count (1+ notify-count)))) + ((symbol-function 'chime--current-time-is-day-wide-time) + (lambda () nil))) + (let* ((event1 `((times . ((,timestamp-str-1 . ,event-time-1))) + (title . "Meeting 1") + (intervals . ((10 . medium))))) + (event2 `((times . ((,timestamp-str-2 . ,event-time-2))) + (title . "Meeting 2") + (intervals . ((5 . medium))))) + (events (list event1 event2))) + (chime--process-notifications events) + ;; Should call notify twice (once per event) + (should (= 2 notify-count))))))) + +(chime-deftest test-chime-process-notifications-normal-deduplication-removes-duplicates () "Test that duplicate notification messages are deduplicated. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-process-notifications-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 0)) - ;; Two events with same title and time - should dedupe - (event-time (test-time-today-at 14 10)) - (timestamp-str (test-timestamp-string event-time)) - (notify-messages '())) - (with-test-time now - (cl-letf (((symbol-function 'chime--notify) - (lambda (msg) (push msg notify-messages))) - ((symbol-function 'chime--current-time-is-day-wide-time) - (lambda () nil))) - (let* ((event1 `((times . ((,timestamp-str . ,event-time))) - (title . "Team Meeting") - (intervals . ((10 . medium))))) - (event2 `((times . ((,timestamp-str . ,event-time))) - (title . "Team Meeting") - (intervals . ((10 . medium))))) - (events (list event1 event2))) - (chime--process-notifications events) - ;; Should only call notify once due to deduplication - (should (= 1 (length notify-messages))))))) - (test-chime-process-notifications-teardown))) - -(ert-deftest test-chime-process-notifications-normal-day-wide-notifications-called-at-right-time () + (let* ((now (test-time-today-at 14 0)) + ;; Two events with same title and time - should dedupe + (event-time (test-time-today-at 14 10)) + (timestamp-str (test-timestamp-string event-time)) + (notify-messages '())) + (with-test-time now + (cl-letf (((symbol-function 'chime--notify) + (lambda (msg) (push msg notify-messages))) + ((symbol-function 'chime--current-time-is-day-wide-time) + (lambda () nil))) + (let* ((event1 `((times . ((,timestamp-str . ,event-time))) + (title . "Team Meeting") + (intervals . ((10 . medium))))) + (event2 `((times . ((,timestamp-str . ,event-time))) + (title . "Team Meeting") + (intervals . ((10 . medium))))) + (events (list event1 event2))) + (chime--process-notifications events) + ;; Should only call notify once due to deduplication + (should (= 1 (length notify-messages)))))))) + +(chime-deftest test-chime-process-notifications-normal-day-wide-notifications-called-at-right-time () "Test that day-wide notifications are sent when current time matches. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-process-notifications-setup) - (unwind-protect - (let* ((now (test-time-today-at 9 0)) - ;; Day-wide event - (event-time (test-time-today-at 0 0)) - (timestamp-str (test-timestamp-string event-time t)) ; Day-wide - (notify-count 0)) - (with-test-time now - (cl-letf (((symbol-function 'chime--notify) - (lambda (msg) (setq notify-count (1+ notify-count)))) - ;; Mock day-wide time to return true - ((symbol-function 'chime--current-time-is-day-wide-time) - (lambda () t)) - ((symbol-function 'chime--day-wide-notifications) - (lambda (events) (list "Day-wide alert")))) - (let* ((event `((times . ((,timestamp-str . ,event-time))) - (title . "All Day Event") - (intervals . ()))) - (events (list event))) - (chime--process-notifications events) - ;; Should call notify at least once for day-wide - (should (>= notify-count 1)))))) - (test-chime-process-notifications-teardown))) - -(ert-deftest test-chime-process-notifications-normal-no-day-wide-when-wrong-time () + (let* ((now (test-time-today-at 9 0)) + ;; Day-wide event + (event-time (test-time-today-at 0 0)) + (timestamp-str (test-timestamp-string event-time t)) ; Day-wide + (notify-count 0)) + (with-test-time now + (cl-letf (((symbol-function 'chime--notify) + (lambda (msg) (setq notify-count (1+ notify-count)))) + ;; Mock day-wide time to return true + ((symbol-function 'chime--current-time-is-day-wide-time) + (lambda () t)) + ((symbol-function 'chime--day-wide-notifications) + (lambda (events) (list "Day-wide alert")))) + (let* ((event `((times . ((,timestamp-str . ,event-time))) + (title . "All Day Event") + (intervals . ()))) + (events (list event))) + (chime--process-notifications events) + ;; Should call notify at least once for day-wide + (should (>= notify-count 1))))))) + +(chime-deftest test-chime-process-notifications-normal-no-day-wide-when-wrong-time () "Test that day-wide notifications are not sent when time doesn't match. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-process-notifications-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 0)) - (event-time (test-time-today-at 0 0)) - (timestamp-str (test-timestamp-string event-time t)) ; Day-wide - (day-wide-called nil)) - (with-test-time now - (cl-letf (((symbol-function 'chime--notify) (lambda (msg) nil)) - ;; Mock day-wide time to return false - ((symbol-function 'chime--current-time-is-day-wide-time) - (lambda () nil)) - ((symbol-function 'chime--day-wide-notifications) - (lambda (events) - (setq day-wide-called t) - '()))) - (let* ((event `((times . ((,timestamp-str . ,event-time))) - (title . "All Day Event") - (intervals . ()))) - (events (list event))) - (chime--process-notifications events) - ;; Day-wide function should not be called - (should-not day-wide-called))))) - (test-chime-process-notifications-teardown))) + (let* ((now (test-time-today-at 14 0)) + (event-time (test-time-today-at 0 0)) + (timestamp-str (test-timestamp-string event-time t)) ; Day-wide + (day-wide-called nil)) + (with-test-time now + (cl-letf (((symbol-function 'chime--notify) (lambda (msg) nil)) + ;; Mock day-wide time to return false + ((symbol-function 'chime--current-time-is-day-wide-time) + (lambda () nil)) + ((symbol-function 'chime--day-wide-notifications) + (lambda (events) + (setq day-wide-called t) + '()))) + (let* ((event `((times . ((,timestamp-str . ,event-time))) + (title . "All Day Event") + (intervals . ()))) + (events (list event))) + (chime--process-notifications events) + ;; Day-wide function should not be called + (should-not day-wide-called)))))) ;;; Boundary Cases -(ert-deftest test-chime-process-notifications-boundary-empty-events-no-notifications () +(chime-deftest test-chime-process-notifications-boundary-empty-events-no-notifications () "Test that empty events list produces no notifications. REFACTORED: No timestamps used" - (test-chime-process-notifications-setup) - (unwind-protect - (let ((notify-called nil)) - (cl-letf (((symbol-function 'chime--notify) - (lambda (msg) (setq notify-called t))) - ((symbol-function 'chime--current-time-is-day-wide-time) - (lambda () nil))) - (let ((events '())) - (chime--process-notifications events) - ;; Should not call notify - (should-not notify-called)))) - (test-chime-process-notifications-teardown))) - -(ert-deftest test-chime-process-notifications-boundary-events-with-no-matches-no-notifications () + (let ((notify-called nil)) + (cl-letf (((symbol-function 'chime--notify) + (lambda (msg) (setq notify-called t))) + ((symbol-function 'chime--current-time-is-day-wide-time) + (lambda () nil))) + (let ((events '())) + (chime--process-notifications events) + ;; Should not call notify + (should-not notify-called))))) + +(chime-deftest test-chime-process-notifications-boundary-events-with-no-matches-no-notifications () "Test that events with no matching notifications don't call notify. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-process-notifications-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 0)) - ;; Event at 15:00 (60 minutes away, doesn't match 10 min interval) - (event-time (test-time-today-at 15 0)) - (timestamp-str (test-timestamp-string event-time)) - (notify-called nil)) - (with-test-time now - (cl-letf (((symbol-function 'chime--notify) - (lambda (msg) (setq notify-called t))) - ((symbol-function 'chime--current-time-is-day-wide-time) - (lambda () nil))) - (let* ((event `((times . ((,timestamp-str . ,event-time))) - (title . "Future Event") - (intervals . ((10 . medium))))) - (events (list event))) - (chime--process-notifications events) - ;; Should not call notify - (should-not notify-called))))) - (test-chime-process-notifications-teardown))) - -(ert-deftest test-chime-process-notifications-boundary-single-event-edge-case () + (let* ((now (test-time-today-at 14 0)) + ;; Event at 15:00 (60 minutes away, doesn't match 10 min interval) + (event-time (test-time-today-at 15 0)) + (timestamp-str (test-timestamp-string event-time)) + (notify-called nil)) + (with-test-time now + (cl-letf (((symbol-function 'chime--notify) + (lambda (msg) (setq notify-called t))) + ((symbol-function 'chime--current-time-is-day-wide-time) + (lambda () nil))) + (let* ((event `((times . ((,timestamp-str . ,event-time))) + (title . "Future Event") + (intervals . ((10 . medium))))) + (events (list event))) + (chime--process-notifications events) + ;; Should not call notify + (should-not notify-called)))))) + +(chime-deftest test-chime-process-notifications-boundary-single-event-edge-case () "Test processing single event works correctly. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-process-notifications-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 0)) - (event-time (test-time-today-at 14 10)) - (timestamp-str (test-timestamp-string event-time)) - (notify-count 0)) - (with-test-time now - (cl-letf (((symbol-function 'chime--notify) - (lambda (msg) (setq notify-count (1+ notify-count)))) - ((symbol-function 'chime--current-time-is-day-wide-time) - (lambda () nil))) - (let* ((event `((times . ((,timestamp-str . ,event-time))) - (title . "Single Event") - (intervals . ((10 . medium))))) - (events (list event))) - (chime--process-notifications events) - ;; Should call notify exactly once - (should (= 1 notify-count)))))) - (test-chime-process-notifications-teardown))) + (let* ((now (test-time-today-at 14 0)) + (event-time (test-time-today-at 14 10)) + (timestamp-str (test-timestamp-string event-time)) + (notify-count 0)) + (with-test-time now + (cl-letf (((symbol-function 'chime--notify) + (lambda (msg) (setq notify-count (1+ notify-count)))) + ((symbol-function 'chime--current-time-is-day-wide-time) + (lambda () nil))) + (let* ((event `((times . ((,timestamp-str . ,event-time))) + (title . "Single Event") + (intervals . ((10 . medium))))) + (events (list event))) + (chime--process-notifications events) + ;; Should call notify exactly once + (should (= 1 notify-count))))))) ;;; Error Cases -(ert-deftest test-chime-process-notifications-error-nil-events-handles-gracefully () +(chime-deftest test-chime-process-notifications-error-nil-events-handles-gracefully () "Test that nil events parameter doesn't crash. REFACTORED: No timestamps used" - (test-chime-process-notifications-setup) - (unwind-protect - (let ((notify-called nil)) - (cl-letf (((symbol-function 'chime--notify) - (lambda (msg) (setq notify-called t))) - ((symbol-function 'chime--current-time-is-day-wide-time) - (lambda () nil))) - ;; Should not error with nil events - (should-not (condition-case nil - (progn (chime--process-notifications nil) nil) - (error t))) - ;; Should not call notify - (should-not notify-called))) - (test-chime-process-notifications-teardown))) - -(ert-deftest test-chime-process-notifications-error-invalid-event-structure-handles-gracefully () + (let ((notify-called nil)) + (cl-letf (((symbol-function 'chime--notify) + (lambda (msg) (setq notify-called t))) + ((symbol-function 'chime--current-time-is-day-wide-time) + (lambda () nil))) + ;; Should not error with nil events + (should-not (condition-case nil + (progn (chime--process-notifications nil) nil) + (error t))) + ;; Should not call notify + (should-not notify-called)))) + +(chime-deftest test-chime-process-notifications-error-invalid-event-structure-handles-gracefully () "Test that invalid event structure doesn't crash. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-process-notifications-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 0)) - (notify-called nil)) - (with-test-time now - (cl-letf (((symbol-function 'chime--notify) - (lambda (msg) (setq notify-called t))) - ((symbol-function 'chime--current-time-is-day-wide-time) - (lambda () nil))) - (let* (;; Invalid event: missing required fields - (events (list '((invalid . "structure"))))) - ;; Should not crash even with invalid events - (should-not (condition-case nil - (progn (chime--process-notifications events) nil) - (error t))))))) - (test-chime-process-notifications-teardown))) - -(ert-deftest test-chime-process-notifications-error-mixed-valid-invalid-events-processes-valid () + (let* ((now (test-time-today-at 14 0)) + (notify-called nil)) + (with-test-time now + (cl-letf (((symbol-function 'chime--notify) + (lambda (msg) (setq notify-called t))) + ((symbol-function 'chime--current-time-is-day-wide-time) + (lambda () nil))) + (let* (;; Invalid event: missing required fields + (events (list '((invalid . "structure"))))) + ;; Should not crash even with invalid events + (should-not (condition-case nil + (progn (chime--process-notifications events) nil) + (error t)))))))) + +(chime-deftest test-chime-process-notifications-error-mixed-valid-invalid-events-processes-valid () "Test that mix of valid and invalid events processes valid ones. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-process-notifications-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 0)) - ;; Valid event - (event-time (test-time-today-at 14 10)) - (timestamp-str (test-timestamp-string event-time)) - (notify-count 0)) - (with-test-time now - (cl-letf (((symbol-function 'chime--notify) - (lambda (msg) (setq notify-count (1+ notify-count)))) - ((symbol-function 'chime--current-time-is-day-wide-time) - (lambda () nil))) - (let* ((valid-event `((times . ((,timestamp-str . ,event-time))) - (title . "Valid Event") - (intervals . ((10 . medium))))) - ;; Invalid event - (invalid-event '((invalid . "data"))) - (events (list valid-event invalid-event))) - ;; Should not crash - (should-not (condition-case nil - (progn (chime--process-notifications events) nil) - (error t))) - ;; Should process at least the valid event - (should (>= notify-count 1)))))) - (test-chime-process-notifications-teardown))) + (let* ((now (test-time-today-at 14 0)) + ;; Valid event + (event-time (test-time-today-at 14 10)) + (timestamp-str (test-timestamp-string event-time)) + (notify-count 0)) + (with-test-time now + (cl-letf (((symbol-function 'chime--notify) + (lambda (msg) (setq notify-count (1+ notify-count)))) + ((symbol-function 'chime--current-time-is-day-wide-time) + (lambda () nil))) + (let* ((valid-event `((times . ((,timestamp-str . ,event-time))) + (title . "Valid Event") + (intervals . ((10 . medium))))) + ;; Invalid event + (invalid-event '((invalid . "data"))) + (events (list valid-event invalid-event))) + ;; Should not crash + (should-not (condition-case nil + (progn (chime--process-notifications events) nil) + (error t))) + ;; Should process at least the valid event + (should (>= notify-count 1))))))) ;;; Day-wide bundling -(ert-deftest test-chime-process-notifications-day-wide-multiple-events-single-notify () +(chime-deftest test-chime-process-notifications-day-wide-multiple-events-single-notify () "Multiple day-wide events should produce a single bundled notification, not one notification per event." - (test-chime-process-notifications-setup) - (unwind-protect - (let* ((now (test-time-today-at 8 0)) - (notify-count 0) - (notify-messages '())) - (with-test-time now - (cl-letf (((symbol-function 'chime--notify) - (lambda (msg) - (setq notify-count (1+ notify-count)) - (push msg notify-messages))) - ((symbol-function 'chime--current-time-is-day-wide-time) - (lambda () t)) - ((symbol-function 'chime--day-wide-notifications) - (lambda (events) - (list (cons "Blake's birthday is today" 'medium) - (cons "Holiday: Memorial Day is today" 'medium) - (cons "Submit expense report is due or scheduled today" 'medium))))) - (chime--process-notifications '()) - ;; Should fire exactly ONE notification for all day-wide events - (should (= 1 notify-count)) - ;; The single notification body should contain all event messages - (let ((body (caar notify-messages))) - (should (string-match-p "Blake's birthday" body)) - (should (string-match-p "Memorial Day" body)) - (should (string-match-p "expense report" body)))))) - (test-chime-process-notifications-teardown))) - -(ert-deftest test-chime-process-notifications-day-wide-single-event-no-bundling () + (let* ((now (test-time-today-at 8 0)) + (notify-count 0) + (notify-messages '())) + (with-test-time now + (cl-letf (((symbol-function 'chime--notify) + (lambda (msg) + (setq notify-count (1+ notify-count)) + (push msg notify-messages))) + ((symbol-function 'chime--current-time-is-day-wide-time) + (lambda () t)) + ((symbol-function 'chime--day-wide-notifications) + (lambda (events) + (list (cons "Blake's birthday is today" 'medium) + (cons "Holiday: Memorial Day is today" 'medium) + (cons "Submit expense report is due or scheduled today" 'medium))))) + (chime--process-notifications '()) + ;; Should fire exactly ONE notification for all day-wide events + (should (= 1 notify-count)) + ;; The single notification body should contain all event messages + (let ((body (caar notify-messages))) + (should (string-match-p "Blake's birthday" body)) + (should (string-match-p "Memorial Day" body)) + (should (string-match-p "expense report" body))))))) + +(chime-deftest test-chime-process-notifications-day-wide-single-event-no-bundling () "A single day-wide event should produce a normal notification, not bundled." - (test-chime-process-notifications-setup) - (unwind-protect - (let* ((now (test-time-today-at 8 0)) - (notify-count 0) - (notify-messages '())) - (with-test-time now - (cl-letf (((symbol-function 'chime--notify) - (lambda (msg) - (setq notify-count (1+ notify-count)) - (push msg notify-messages))) - ((symbol-function 'chime--current-time-is-day-wide-time) - (lambda () t)) - ((symbol-function 'chime--day-wide-notifications) - (lambda (events) - (list (cons "Blake's birthday is today" 'medium))))) - (chime--process-notifications '()) - ;; Single event: still one notification - (should (= 1 notify-count)) - ;; Should be the plain message, not wrapped in a bundle - (let ((body (caar notify-messages))) - (should (string= "Blake's birthday is today" body)))))) - (test-chime-process-notifications-teardown))) + (let* ((now (test-time-today-at 8 0)) + (notify-count 0) + (notify-messages '())) + (with-test-time now + (cl-letf (((symbol-function 'chime--notify) + (lambda (msg) + (setq notify-count (1+ notify-count)) + (push msg notify-messages))) + ((symbol-function 'chime--current-time-is-day-wide-time) + (lambda () t)) + ((symbol-function 'chime--day-wide-notifications) + (lambda (events) + (list (cons "Blake's birthday is today" 'medium))))) + (chime--process-notifications '()) + ;; Single event: still one notification + (should (= 1 notify-count)) + ;; Should be the plain message, not wrapped in a bundle + (let ((body (caar notify-messages))) + (should (string= "Blake's birthday is today" body))))))) (provide 'test-chime-process-notifications) ;;; test-chime-process-notifications.el ends here diff --git a/tests/test-chime-propertize-modeline.el b/tests/test-chime-propertize-modeline.el index cc0dbb2..c0a0874 100644 --- a/tests/test-chime-propertize-modeline.el +++ b/tests/test-chime-propertize-modeline.el @@ -27,8 +27,6 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) ;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) (require 'testutil-events (expand-file-name "testutil-events.el")) ;;; Setup/Teardown diff --git a/tests/test-chime-sanitize-title.el b/tests/test-chime-sanitize-title.el index 672cf70..8856a8e 100644 --- a/tests/test-chime-sanitize-title.el +++ b/tests/test-chime-sanitize-title.el @@ -32,358 +32,254 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) - -;;; Setup and Teardown - -(defun test-chime-sanitize-title-setup () - "Setup function run before each test." - (chime-create-test-base-dir)) - -(defun test-chime-sanitize-title-teardown () - "Teardown function run after each test." - (chime-delete-test-base-dir)) - ;;; Normal Cases - Already Balanced -(ert-deftest test-chime-sanitize-title-balanced-parens-unchanged () +(chime-deftest test-chime-sanitize-title-balanced-parens-unchanged () "Test that balanced parentheses are unchanged. REFACTORED: No timestamps used" - (test-chime-sanitize-title-setup) - (unwind-protect - (let* ((title "Meeting (Team Sync)") - (result (chime--sanitize-title title))) - (should (string-equal title result))) - (test-chime-sanitize-title-teardown))) - -(ert-deftest test-chime-sanitize-title-balanced-brackets-unchanged () + (let* ((title "Meeting (Team Sync)") + (result (chime--sanitize-title title))) + (should (string-equal title result)))) + +(chime-deftest test-chime-sanitize-title-balanced-brackets-unchanged () "Test that balanced brackets are unchanged. REFACTORED: No timestamps used" - (test-chime-sanitize-title-setup) - (unwind-protect - (let* ((title "Review [PR #123]") - (result (chime--sanitize-title title))) - (should (string-equal title result))) - (test-chime-sanitize-title-teardown))) - -(ert-deftest test-chime-sanitize-title-balanced-braces-unchanged () + (let* ((title "Review [PR #123]") + (result (chime--sanitize-title title))) + (should (string-equal title result)))) + +(chime-deftest test-chime-sanitize-title-balanced-braces-unchanged () "Test that balanced braces are unchanged. REFACTORED: No timestamps used" - (test-chime-sanitize-title-setup) - (unwind-protect - (let* ((title "Code Review {urgent}") - (result (chime--sanitize-title title))) - (should (string-equal title result))) - (test-chime-sanitize-title-teardown))) - -(ert-deftest test-chime-sanitize-title-mixed-balanced-unchanged () + (let* ((title "Code Review {urgent}") + (result (chime--sanitize-title title))) + (should (string-equal title result)))) + +(chime-deftest test-chime-sanitize-title-mixed-balanced-unchanged () "Test that mixed balanced delimiters are unchanged. REFACTORED: No timestamps used" - (test-chime-sanitize-title-setup) - (unwind-protect - (let* ((title "Meeting [Team] (Sync) {Urgent}") - (result (chime--sanitize-title title))) - (should (string-equal title result))) - (test-chime-sanitize-title-teardown))) - -(ert-deftest test-chime-sanitize-title-nested-balanced-unchanged () + (let* ((title "Meeting [Team] (Sync) {Urgent}") + (result (chime--sanitize-title title))) + (should (string-equal title result)))) + +(chime-deftest test-chime-sanitize-title-nested-balanced-unchanged () "Test that nested balanced delimiters are unchanged. REFACTORED: No timestamps used" - (test-chime-sanitize-title-setup) - (unwind-protect - (let* ((title "Review (PR [#123] {urgent})") - (result (chime--sanitize-title title))) - (should (string-equal title result))) - (test-chime-sanitize-title-teardown))) - -(ert-deftest test-chime-sanitize-title-no-delimiters-unchanged () + (let* ((title "Review (PR [#123] {urgent})") + (result (chime--sanitize-title title))) + (should (string-equal title result)))) + +(chime-deftest test-chime-sanitize-title-no-delimiters-unchanged () "Test that titles without delimiters are unchanged. REFACTORED: No timestamps used" - (test-chime-sanitize-title-setup) - (unwind-protect - (let* ((title "Simple Meeting Title") - (result (chime--sanitize-title title))) - (should (string-equal title result))) - (test-chime-sanitize-title-teardown))) + (let* ((title "Simple Meeting Title") + (result (chime--sanitize-title title))) + (should (string-equal title result)))) ;;; Unmatched Opening Delimiters -(ert-deftest test-chime-sanitize-title-unmatched-opening-paren () +(chime-deftest test-chime-sanitize-title-unmatched-opening-paren () "Test that unmatched opening parenthesis is closed." - (test-chime-sanitize-title-setup) - (unwind-protect - (let* ((title "CTO/COO XLT (Extended Leadership") - (result (chime--sanitize-title title))) - (should (string-equal "CTO/COO XLT (Extended Leadership)" result))) - (test-chime-sanitize-title-teardown))) - -(ert-deftest test-chime-sanitize-title-unmatched-opening-paren-at-end () + (let* ((title "CTO/COO XLT (Extended Leadership") + (result (chime--sanitize-title title))) + (should (string-equal "CTO/COO XLT (Extended Leadership)" result)))) + +(chime-deftest test-chime-sanitize-title-unmatched-opening-paren-at-end () "Test that unmatched opening parenthesis at end is closed." - (test-chime-sanitize-title-setup) - (unwind-protect - (let* ((title "Spice Cake (") - (result (chime--sanitize-title title))) - (should (string-equal "Spice Cake ()" result))) - (test-chime-sanitize-title-teardown))) - -(ert-deftest test-chime-sanitize-title-multiple-unmatched-opening-parens () + (let* ((title "Spice Cake (") + (result (chime--sanitize-title title))) + (should (string-equal "Spice Cake ()" result)))) + +(chime-deftest test-chime-sanitize-title-multiple-unmatched-opening-parens () "Test that multiple unmatched opening parentheses are closed." - (test-chime-sanitize-title-setup) - (unwind-protect - (let* ((title "Meeting (Team (Sync") - (result (chime--sanitize-title title))) - (should (string-equal "Meeting (Team (Sync))" result))) - (test-chime-sanitize-title-teardown))) - -(ert-deftest test-chime-sanitize-title-unmatched-opening-bracket () + (let* ((title "Meeting (Team (Sync") + (result (chime--sanitize-title title))) + (should (string-equal "Meeting (Team (Sync))" result)))) + +(chime-deftest test-chime-sanitize-title-unmatched-opening-bracket () "Test that unmatched opening bracket is closed." - (test-chime-sanitize-title-setup) - (unwind-protect - (let* ((title "Review [PR #123") - (result (chime--sanitize-title title))) - (should (string-equal "Review [PR #123]" result))) - (test-chime-sanitize-title-teardown))) - -(ert-deftest test-chime-sanitize-title-unmatched-opening-brace () + (let* ((title "Review [PR #123") + (result (chime--sanitize-title title))) + (should (string-equal "Review [PR #123]" result)))) + +(chime-deftest test-chime-sanitize-title-unmatched-opening-brace () "Test that unmatched opening brace is closed." - (test-chime-sanitize-title-setup) - (unwind-protect - (let* ((title "Code Review {urgent") - (result (chime--sanitize-title title))) - (should (string-equal "Code Review {urgent}" result))) - (test-chime-sanitize-title-teardown))) - -(ert-deftest test-chime-sanitize-title-mixed-unmatched-opening-delimiters () + (let* ((title "Code Review {urgent") + (result (chime--sanitize-title title))) + (should (string-equal "Code Review {urgent}" result)))) + +(chime-deftest test-chime-sanitize-title-mixed-unmatched-opening-delimiters () "Test that mixed unmatched opening delimiters are all closed." - (test-chime-sanitize-title-setup) - (unwind-protect - (let* ((title "Meeting [Team (Sync {Urgent") - (result (chime--sanitize-title title))) - (should (string-equal "Meeting [Team (Sync {Urgent})]" result))) - (test-chime-sanitize-title-teardown))) + (let* ((title "Meeting [Team (Sync {Urgent") + (result (chime--sanitize-title title))) + (should (string-equal "Meeting [Team (Sync {Urgent})]" result)))) ;;; Unmatched Closing Delimiters -(ert-deftest test-chime-sanitize-title-unmatched-closing-paren () +(chime-deftest test-chime-sanitize-title-unmatched-closing-paren () "Test that unmatched closing parenthesis is removed." - (test-chime-sanitize-title-setup) - (unwind-protect - (let* ((title "Meeting Title)") - (result (chime--sanitize-title title))) - (should (string-equal "Meeting Title" result))) - (test-chime-sanitize-title-teardown))) - -(ert-deftest test-chime-sanitize-title-multiple-unmatched-closing-parens () + (let* ((title "Meeting Title)") + (result (chime--sanitize-title title))) + (should (string-equal "Meeting Title" result)))) + +(chime-deftest test-chime-sanitize-title-multiple-unmatched-closing-parens () "Test that multiple unmatched closing parentheses are removed." - (test-chime-sanitize-title-setup) - (unwind-protect - (let* ((title "Meeting Title))") - (result (chime--sanitize-title title))) - (should (string-equal "Meeting Title" result))) - (test-chime-sanitize-title-teardown))) - -(ert-deftest test-chime-sanitize-title-unmatched-closing-bracket () + (let* ((title "Meeting Title))") + (result (chime--sanitize-title title))) + (should (string-equal "Meeting Title" result)))) + +(chime-deftest test-chime-sanitize-title-unmatched-closing-bracket () "Test that unmatched closing bracket is removed." - (test-chime-sanitize-title-setup) - (unwind-protect - (let* ((title "Review PR]") - (result (chime--sanitize-title title))) - (should (string-equal "Review PR" result))) - (test-chime-sanitize-title-teardown))) - -(ert-deftest test-chime-sanitize-title-unmatched-closing-brace () + (let* ((title "Review PR]") + (result (chime--sanitize-title title))) + (should (string-equal "Review PR" result)))) + +(chime-deftest test-chime-sanitize-title-unmatched-closing-brace () "Test that unmatched closing brace is removed." - (test-chime-sanitize-title-setup) - (unwind-protect - (let* ((title "Code Review}") - (result (chime--sanitize-title title))) - (should (string-equal "Code Review" result))) - (test-chime-sanitize-title-teardown))) + (let* ((title "Code Review}") + (result (chime--sanitize-title title))) + (should (string-equal "Code Review" result)))) ;;; Complex Mixed Cases -(ert-deftest test-chime-sanitize-title-opening-and-closing-mixed () +(chime-deftest test-chime-sanitize-title-opening-and-closing-mixed () "Test title with both unmatched opening and closing delimiters." - (test-chime-sanitize-title-setup) - (unwind-protect - (let* ((title "Meeting (Team) Extra)") - (result (chime--sanitize-title title))) - ;; Should remove the extra closing paren - (should (string-equal "Meeting (Team) Extra" result))) - (test-chime-sanitize-title-teardown))) - -(ert-deftest test-chime-sanitize-title-complex-nesting-with-unmatched () + (let* ((title "Meeting (Team) Extra)") + (result (chime--sanitize-title title))) + ;; Should remove the extra closing paren + (should (string-equal "Meeting (Team) Extra" result)))) + +(chime-deftest test-chime-sanitize-title-complex-nesting-with-unmatched () "Test complex nested delimiters with some unmatched." - (test-chime-sanitize-title-setup) - (unwind-protect - (let* ((title "Meeting [Team (Sync] Extra") - (result (chime--sanitize-title title))) - ;; The ']' doesn't match the '[' (because '(' is in between) - ;; So it's removed, and we close the '(' and '[' properly: ')' and ']' - (should (string-equal "Meeting [Team (Sync Extra)]" result))) - (test-chime-sanitize-title-teardown))) - -(ert-deftest test-chime-sanitize-title-all-types-unmatched () + (let* ((title "Meeting [Team (Sync] Extra") + (result (chime--sanitize-title title))) + ;; The ']' doesn't match the '[' (because '(' is in between) + ;; So it's removed, and we close the '(' and '[' properly: ')' and ']' + (should (string-equal "Meeting [Team (Sync Extra)]" result)))) + +(chime-deftest test-chime-sanitize-title-all-types-unmatched () "Test with all three delimiter types unmatched." - (test-chime-sanitize-title-setup) - (unwind-protect - (let* ((title "Meeting (Team [Project {Status") - (result (chime--sanitize-title title))) - (should (string-equal "Meeting (Team [Project {Status}])" result))) - (test-chime-sanitize-title-teardown))) + (let* ((title "Meeting (Team [Project {Status") + (result (chime--sanitize-title title))) + (should (string-equal "Meeting (Team [Project {Status}])" result)))) ;;; Edge Cases -(ert-deftest test-chime-sanitize-title-nil-returns-empty-string () +(chime-deftest test-chime-sanitize-title-nil-returns-empty-string () "Test that nil title returns empty string." - (test-chime-sanitize-title-setup) - (unwind-protect - (let* ((result (chime--sanitize-title nil))) - (should (string-equal "" result))) - (test-chime-sanitize-title-teardown))) + (let* ((result (chime--sanitize-title nil))) + (should (string-equal "" result)))) -(ert-deftest test-chime-sanitize-title-empty-string-unchanged () +(chime-deftest test-chime-sanitize-title-empty-string-unchanged () "Test that empty string is unchanged." - (test-chime-sanitize-title-setup) - (unwind-protect - (let* ((title "") - (result (chime--sanitize-title title))) - (should (string-equal "" result))) - (test-chime-sanitize-title-teardown))) - -(ert-deftest test-chime-sanitize-title-only-opening-delimiters () + (let* ((title "") + (result (chime--sanitize-title title))) + (should (string-equal "" result)))) + +(chime-deftest test-chime-sanitize-title-only-opening-delimiters () "Test title with only opening delimiters." - (test-chime-sanitize-title-setup) - (unwind-protect - (let* ((title "([{") - (result (chime--sanitize-title title))) - (should (string-equal "([{}])" result))) - (test-chime-sanitize-title-teardown))) - -(ert-deftest test-chime-sanitize-title-only-closing-delimiters () + (let* ((title "([{") + (result (chime--sanitize-title title))) + (should (string-equal "([{}])" result)))) + +(chime-deftest test-chime-sanitize-title-only-closing-delimiters () "Test title with only closing delimiters." - (test-chime-sanitize-title-setup) - (unwind-protect - (let* ((title ")]}") - (result (chime--sanitize-title title))) - (should (string-equal "" result))) - (test-chime-sanitize-title-teardown))) - -(ert-deftest test-chime-sanitize-title-very-long-title-with-unmatched () + (let* ((title ")]}") + (result (chime--sanitize-title title))) + (should (string-equal "" result)))) + +(chime-deftest test-chime-sanitize-title-very-long-title-with-unmatched () "Test very long title with unmatched delimiter." - (test-chime-sanitize-title-setup) - (unwind-protect - (let* ((title "This is a very long meeting title that contains many words and might wrap in the notification display (Extended Info") - (result (chime--sanitize-title title))) - (should (string-equal "This is a very long meeting title that contains many words and might wrap in the notification display (Extended Info)" result))) - (test-chime-sanitize-title-teardown))) + (let* ((title "This is a very long meeting title that contains many words and might wrap in the notification display (Extended Info") + (result (chime--sanitize-title title))) + (should (string-equal "This is a very long meeting title that contains many words and might wrap in the notification display (Extended Info)" result)))) ;;; Real-World Bug Cases -(ert-deftest test-chime-sanitize-title-bug-case-extended-leadership () +(chime-deftest test-chime-sanitize-title-bug-case-extended-leadership () "Test the actual bug case from vineti.meetings.org." - (test-chime-sanitize-title-setup) - (unwind-protect - (let* ((title "1:01pm CTO/COO XLT (Extended Leadership") - (result (chime--sanitize-title title))) - (should (string-equal "1:01pm CTO/COO XLT (Extended Leadership)" result))) - (test-chime-sanitize-title-teardown))) - -(ert-deftest test-chime-sanitize-title-bug-case-spice-cake () + (let* ((title "1:01pm CTO/COO XLT (Extended Leadership") + (result (chime--sanitize-title title))) + (should (string-equal "1:01pm CTO/COO XLT (Extended Leadership)" result)))) + +(chime-deftest test-chime-sanitize-title-bug-case-spice-cake () "Test the actual bug case from journal/2023-11-22.org." - (test-chime-sanitize-title-setup) - (unwind-protect - (let* ((title "Spice Cake (") - (result (chime--sanitize-title title))) - (should (string-equal "Spice Cake ()" result))) - (test-chime-sanitize-title-teardown))) - -(ert-deftest test-chime-sanitize-title-lisp-serialization-safety () - "Test that sanitized title can be safely read by Lisp reader." - (test-chime-sanitize-title-setup) - (unwind-protect - (let* ((title "Meeting (Team Sync") - (sanitized (chime--sanitize-title title)) - ;; Simulate what happens in async serialization - (serialized (format "'((title . \"%s\"))" sanitized))) - ;; This should not signal an error - (should (listp (read serialized))) - (should (string-equal "Meeting (Team Sync)" sanitized))) - (test-chime-sanitize-title-teardown))) + (let* ((title "Spice Cake (") + (result (chime--sanitize-title title))) + (should (string-equal "Spice Cake ()" result)))) -(ert-deftest test-chime-sanitize-title-async-serialization-with-unmatched-parens () +(chime-deftest test-chime-sanitize-title-lisp-serialization-safety () + "Test that sanitized title can be safely read by Lisp reader." + (let* ((title "Meeting (Team Sync") + (sanitized (chime--sanitize-title title)) + ;; Simulate what happens in async serialization + (serialized (format "'((title . \"%s\"))" sanitized))) + ;; This should not signal an error + (should (listp (read serialized))) + (should (string-equal "Meeting (Team Sync)" sanitized)))) + +(chime-deftest test-chime-sanitize-title-async-serialization-with-unmatched-parens () "Test that titles with unmatched parens won't break async serialization." - (test-chime-sanitize-title-setup) - (unwind-protect - (let* ((problematic-titles '("Meeting (Team" - "Review [PR" - "Code {Status" - "Event ((" - "Task ))"))) - (dolist (title problematic-titles) - (let* ((sanitized (chime--sanitize-title title)) - (serialized (format "'((title . \"%s\"))" sanitized))) - ;; Should not signal 'invalid-read-syntax error - (should (listp (read serialized)))))) - (test-chime-sanitize-title-teardown))) + (let* ((problematic-titles '("Meeting (Team" + "Review [PR" + "Code {Status" + "Event ((" + "Task ))"))) + (dolist (title problematic-titles) + (let* ((sanitized (chime--sanitize-title title)) + (serialized (format "'((title . \"%s\"))" sanitized))) + ;; Should not signal 'invalid-read-syntax error + (should (listp (read serialized))))))) ;;; Integration with chime--extract-title -(ert-deftest test-chime-extract-title-sanitizes-output () +(chime-deftest test-chime-extract-title-sanitizes-output () "Test that chime--extract-title applies sanitization. REFACTORED: Uses dynamic timestamps" - (test-chime-sanitize-title-setup) - (unwind-protect - (let* ((time (test-time-tomorrow-at 14 0)) - (timestamp (test-timestamp-string time)) - (test-file (chime-create-temp-test-file-with-content - (format "* TODO Meeting (Team Sync\n%s\n" timestamp))) - (test-buffer (find-file-noselect test-file))) - (with-current-buffer test-buffer - (org-mode) ; Enable org-mode - (goto-char (point-min)) - ;; Search for the heading - (re-search-forward "^\\* TODO" nil t) - (beginning-of-line) - (let* ((marker (point-marker)) - (title (chime--extract-title marker))) - ;; Should be sanitized with closing paren added - (should (string-equal "Meeting (Team Sync)" title)))) - (kill-buffer test-buffer)) - (test-chime-sanitize-title-teardown))) - -(ert-deftest test-chime-extract-title-handles-nil () + (let* ((time (test-time-tomorrow-at 14 0)) + (timestamp (test-timestamp-string time)) + (test-file (chime-create-temp-test-file-with-content + (format "* TODO Meeting (Team Sync\n%s\n" timestamp))) + (test-buffer (find-file-noselect test-file))) + (with-current-buffer test-buffer + (org-mode) ; Enable org-mode + (goto-char (point-min)) + ;; Search for the heading + (re-search-forward "^\\* TODO" nil t) + (beginning-of-line) + (let* ((marker (point-marker)) + (title (chime--extract-title marker))) + ;; Should be sanitized with closing paren added + (should (string-equal "Meeting (Team Sync)" title)))) + (kill-buffer test-buffer))) + +(chime-deftest test-chime-extract-title-handles-nil () "Test that chime--extract-title handles nil gracefully. REFACTORED: Uses dynamic timestamps" - (test-chime-sanitize-title-setup) - (unwind-protect - (let* ((time (test-time-tomorrow-at 14 0)) - (timestamp (test-timestamp-string time)) - (test-file (chime-create-temp-test-file-with-content - (format "* TODO\n%s\n" timestamp))) - (test-buffer (find-file-noselect test-file))) - (with-current-buffer test-buffer - (org-mode) ; Enable org-mode - (goto-char (point-min)) - ;; Search for the heading - (re-search-forward "^\\* TODO" nil t) - (beginning-of-line) - (let* ((marker (point-marker)) - (title (chime--extract-title marker))) - ;; Should return empty string for nil title - (should (string-equal "" title)))) - (kill-buffer test-buffer)) - (test-chime-sanitize-title-teardown))) + (let* ((time (test-time-tomorrow-at 14 0)) + (timestamp (test-timestamp-string time)) + (test-file (chime-create-temp-test-file-with-content + (format "* TODO\n%s\n" timestamp))) + (test-buffer (find-file-noselect test-file))) + (with-current-buffer test-buffer + (org-mode) ; Enable org-mode + (goto-char (point-min)) + ;; Search for the heading + (re-search-forward "^\\* TODO" nil t) + (beginning-of-line) + (let* ((marker (point-marker)) + (title (chime--extract-title marker))) + ;; Should return empty string for nil title + (should (string-equal "" title)))) + (kill-buffer test-buffer))) (provide 'test-chime-sanitize-title) ;;; test-chime-sanitize-title.el ends here diff --git a/tests/test-chime-time-left.el b/tests/test-chime-time-left.el index b9bd176..5d27636 100644 --- a/tests/test-chime-time-left.el +++ b/tests/test-chime-time-left.el @@ -26,9 +26,6 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) - ;;; Setup and Teardown (defun test-chime-time-left-setup () diff --git a/tests/test-chime-time-utilities.el b/tests/test-chime-time-utilities.el index 26e4d96..29488df 100644 --- a/tests/test-chime-time-utilities.el +++ b/tests/test-chime-time-utilities.el @@ -28,10 +28,6 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) - ;;;; Tests for chime--get-minutes-into-day ;;; Normal Cases diff --git a/tests/test-chime-timestamp-parse.el b/tests/test-chime-timestamp-parse.el index 5dc30bf..e06b832 100644 --- a/tests/test-chime-timestamp-parse.el +++ b/tests/test-chime-timestamp-parse.el @@ -26,375 +26,283 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) - -;;; Setup and Teardown - -(defun test-chime-timestamp-parse-setup () - "Setup function run before each test." - (chime-create-test-base-dir)) - -(defun test-chime-timestamp-parse-teardown () - "Teardown function run after each test." - (chime-delete-test-base-dir)) - ;;; Normal Cases -(ert-deftest test-chime-timestamp-parse-standard-timestamp-returns-time-list () +(chime-deftest test-chime-timestamp-parse-standard-timestamp-returns-time-list () "Test that a standard timestamp with time component returns a time list. REFACTORED: Uses dynamic timestamps" - (test-chime-timestamp-parse-setup) - (unwind-protect - (let* ((time (test-time-tomorrow-at 14 30)) - (timestamp (test-timestamp-string time)) - (result (chime--timestamp-parse timestamp))) - ;; Should return a time list (list of integers) - (should (listp result)) - (should (= (length result) 2)) - (should (integerp (car result))) - (should (integerp (cadr result))) - ;; Result should not be nil - (should result)) - (test-chime-timestamp-parse-teardown))) - -(ert-deftest test-chime-timestamp-parse-scheduled-timestamp-returns-time-list () + (let* ((time (test-time-tomorrow-at 14 30)) + (timestamp (test-timestamp-string time)) + (result (chime--timestamp-parse timestamp))) + ;; Should return a time list (list of integers) + (should (listp result)) + (should (= (length result) 2)) + (should (integerp (car result))) + (should (integerp (cadr result))) + ;; Result should not be nil + (should result))) + +(chime-deftest test-chime-timestamp-parse-scheduled-timestamp-returns-time-list () "Test that a SCHEDULED timestamp parses correctly. REFACTORED: Uses dynamic timestamps" - (test-chime-timestamp-parse-setup) - (unwind-protect - (let* ((time (test-time-tomorrow-at 9 0)) - (timestamp (test-timestamp-string time)) - (result (chime--timestamp-parse timestamp))) - (should (listp result)) - (should (= (length result) 2)) - (should result)) - (test-chime-timestamp-parse-teardown))) - -(ert-deftest test-chime-timestamp-parse-deadline-timestamp-returns-time-list () + (let* ((time (test-time-tomorrow-at 9 0)) + (timestamp (test-timestamp-string time)) + (result (chime--timestamp-parse timestamp))) + (should (listp result)) + (should (= (length result) 2)) + (should result))) + +(chime-deftest test-chime-timestamp-parse-deadline-timestamp-returns-time-list () "Test that a DEADLINE timestamp parses correctly. REFACTORED: Uses dynamic timestamps" - (test-chime-timestamp-parse-setup) - (unwind-protect - (let* ((time (test-time-tomorrow-at 17 0)) - (timestamp (test-timestamp-string time)) - (result (chime--timestamp-parse timestamp))) - (should (listp result)) - (should (= (length result) 2)) - (should result)) - (test-chime-timestamp-parse-teardown))) - -(ert-deftest test-chime-timestamp-parse-timestamp-with-weekly-repeater-returns-time-list () + (let* ((time (test-time-tomorrow-at 17 0)) + (timestamp (test-timestamp-string time)) + (result (chime--timestamp-parse timestamp))) + (should (listp result)) + (should (= (length result) 2)) + (should result))) + +(chime-deftest test-chime-timestamp-parse-timestamp-with-weekly-repeater-returns-time-list () "Test that a timestamp with +1w repeater parses correctly. REFACTORED: Uses dynamic timestamps" - (test-chime-timestamp-parse-setup) - (unwind-protect - (let* ((time (test-time-tomorrow-at 14 0)) - (timestamp (format-time-string "<%Y-%m-%d %a %H:%M +1w>" time)) - (result (chime--timestamp-parse timestamp))) - (should (listp result)) - (should (= (length result) 2)) - (should result)) - (test-chime-timestamp-parse-teardown))) - -(ert-deftest test-chime-timestamp-parse-timestamp-with-completion-repeater-returns-time-list () + (let* ((time (test-time-tomorrow-at 14 0)) + (timestamp (format-time-string "<%Y-%m-%d %a %H:%M +1w>" time)) + (result (chime--timestamp-parse timestamp))) + (should (listp result)) + (should (= (length result) 2)) + (should result))) + +(chime-deftest test-chime-timestamp-parse-timestamp-with-completion-repeater-returns-time-list () "Test that a timestamp with .+1d repeater parses correctly. REFACTORED: Uses dynamic timestamps" - (test-chime-timestamp-parse-setup) - (unwind-protect - (let* ((time (test-time-tomorrow-at 8 0)) - (timestamp (format-time-string "<%Y-%m-%d %a %H:%M .+1d>" time)) - (result (chime--timestamp-parse timestamp))) - (should (listp result)) - (should (= (length result) 2)) - (should result)) - (test-chime-timestamp-parse-teardown))) - -(ert-deftest test-chime-timestamp-parse-timestamp-with-catchup-repeater-returns-time-list () + (let* ((time (test-time-tomorrow-at 8 0)) + (timestamp (format-time-string "<%Y-%m-%d %a %H:%M .+1d>" time)) + (result (chime--timestamp-parse timestamp))) + (should (listp result)) + (should (= (length result) 2)) + (should result))) + +(chime-deftest test-chime-timestamp-parse-timestamp-with-catchup-repeater-returns-time-list () "Test that a timestamp with ++1w repeater parses correctly. REFACTORED: Uses dynamic timestamps" - (test-chime-timestamp-parse-setup) - (unwind-protect - (let* ((time (test-time-tomorrow-at 10 30)) - (timestamp (format-time-string "<%Y-%m-%d %a %H:%M ++1w>" time)) - (result (chime--timestamp-parse timestamp))) - (should (listp result)) - (should (= (length result) 2)) - (should result)) - (test-chime-timestamp-parse-teardown))) - -(ert-deftest test-chime-timestamp-parse-timestamp-with-time-range-returns-start-time () + (let* ((time (test-time-tomorrow-at 10 30)) + (timestamp (format-time-string "<%Y-%m-%d %a %H:%M ++1w>" time)) + (result (chime--timestamp-parse timestamp))) + (should (listp result)) + (should (= (length result) 2)) + (should result))) + +(chime-deftest test-chime-timestamp-parse-timestamp-with-time-range-returns-start-time () "Test that a timestamp with time range returns the start time. REFACTORED: Uses dynamic timestamps" - (test-chime-timestamp-parse-setup) - (unwind-protect - (let* ((time (test-time-tomorrow-at 14 0)) - (timestamp (format-time-string "<%Y-%m-%d %a %H:%M-15:30>" time)) - (result (chime--timestamp-parse timestamp))) - (should (listp result)) - (should (= (length result) 2)) - (should result)) - (test-chime-timestamp-parse-teardown))) - -(ert-deftest test-chime-timestamp-parse-timestamp-with-date-range-returns-start-date () + (let* ((time (test-time-tomorrow-at 14 0)) + (timestamp (format-time-string "<%Y-%m-%d %a %H:%M-15:30>" time)) + (result (chime--timestamp-parse timestamp))) + (should (listp result)) + (should (= (length result) 2)) + (should result))) + +(chime-deftest test-chime-timestamp-parse-timestamp-with-date-range-returns-start-date () "Test that a timestamp with date range returns start date time. REFACTORED: Uses dynamic timestamps" - (test-chime-timestamp-parse-setup) - (unwind-protect - (let* ((time1 (test-time-tomorrow-at 10 0)) - (time2 (test-time-days-from-now 2)) - (timestamp (concat (test-timestamp-string time1) "--" - (format-time-string "<%Y-%m-%d %a %H:%M>" time2))) - (result (chime--timestamp-parse timestamp))) - (should (listp result)) - (should (= (length result) 2)) - (should result)) - (test-chime-timestamp-parse-teardown))) + (let* ((time1 (test-time-tomorrow-at 10 0)) + (time2 (test-time-days-from-now 2)) + (timestamp (concat (test-timestamp-string time1) "--" + (format-time-string "<%Y-%m-%d %a %H:%M>" time2))) + (result (chime--timestamp-parse timestamp))) + (should (listp result)) + (should (= (length result) 2)) + (should result))) ;;; Boundary Cases -(ert-deftest test-chime-timestamp-parse-midnight-timestamp-returns-time-list () +(chime-deftest test-chime-timestamp-parse-midnight-timestamp-returns-time-list () "Test that midnight (00:00) timestamp parses correctly. REFACTORED: Uses dynamic timestamps" - (test-chime-timestamp-parse-setup) - (unwind-protect - (let* ((time (test-time-tomorrow-at 0 0)) - (timestamp (test-timestamp-string time)) - (result (chime--timestamp-parse timestamp))) - (should (listp result)) - (should (= (length result) 2)) - (should result)) - (test-chime-timestamp-parse-teardown))) - -(ert-deftest test-chime-timestamp-parse-last-minute-of-day-returns-time-list () + (let* ((time (test-time-tomorrow-at 0 0)) + (timestamp (test-timestamp-string time)) + (result (chime--timestamp-parse timestamp))) + (should (listp result)) + (should (= (length result) 2)) + (should result))) + +(chime-deftest test-chime-timestamp-parse-last-minute-of-day-returns-time-list () "Test that last minute of day (23:59) timestamp parses correctly. REFACTORED: Uses dynamic timestamps" - (test-chime-timestamp-parse-setup) - (unwind-protect - (let* ((time (test-time-tomorrow-at 23 59)) - (timestamp (test-timestamp-string time)) - (result (chime--timestamp-parse timestamp))) - (should (listp result)) - (should (= (length result) 2)) - (should result)) - (test-chime-timestamp-parse-teardown))) - -(ert-deftest test-chime-timestamp-parse-year-boundary-new-years-eve-returns-time-list () + (let* ((time (test-time-tomorrow-at 23 59)) + (timestamp (test-timestamp-string time)) + (result (chime--timestamp-parse timestamp))) + (should (listp result)) + (should (= (length result) 2)) + (should result))) + +(chime-deftest test-chime-timestamp-parse-year-boundary-new-years-eve-returns-time-list () "Test that New Year's Eve timestamp parses correctly. REFACTORED: Uses dynamic timestamps" - (test-chime-timestamp-parse-setup) - (unwind-protect - (let* ((now (test-time-now)) - (decoded (decode-time now)) - (year (nth 5 decoded)) - ;; Create Dec 31 at 23:30 for current test year - (time (encode-time 0 30 23 31 12 year)) - (timestamp (test-timestamp-string time)) - (result (chime--timestamp-parse timestamp))) - (should (listp result)) - (should (= (length result) 2)) - (should result)) - (test-chime-timestamp-parse-teardown))) - -(ert-deftest test-chime-timestamp-parse-year-boundary-new-years-day-returns-time-list () + (let* ((now (test-time-now)) + (decoded (decode-time now)) + (year (nth 5 decoded)) + ;; Create Dec 31 at 23:30 for current test year + (time (encode-time 0 30 23 31 12 year)) + (timestamp (test-timestamp-string time)) + (result (chime--timestamp-parse timestamp))) + (should (listp result)) + (should (= (length result) 2)) + (should result))) + +(chime-deftest test-chime-timestamp-parse-year-boundary-new-years-day-returns-time-list () "Test that New Year's Day timestamp parses correctly. REFACTORED: Uses dynamic timestamps" - (test-chime-timestamp-parse-setup) - (unwind-protect - (let* ((now (test-time-now)) - (decoded (decode-time now)) - (year (1+ (nth 5 decoded))) ; Next year - ;; Create Jan 1 at 00:30 for next test year - (time (encode-time 0 30 0 1 1 year)) - (timestamp (test-timestamp-string time)) - (result (chime--timestamp-parse timestamp))) - (should (listp result)) - (should (= (length result) 2)) - (should result)) - (test-chime-timestamp-parse-teardown))) - -(ert-deftest test-chime-timestamp-parse-single-digit-time-returns-time-list () + (let* ((now (test-time-now)) + (decoded (decode-time now)) + (year (1+ (nth 5 decoded))) ; Next year + ;; Create Jan 1 at 00:30 for next test year + (time (encode-time 0 30 0 1 1 year)) + (timestamp (test-timestamp-string time)) + (result (chime--timestamp-parse timestamp))) + (should (listp result)) + (should (= (length result) 2)) + (should result))) + +(chime-deftest test-chime-timestamp-parse-single-digit-time-returns-time-list () "Test that single-digit hours and minutes parse correctly. REFACTORED: Uses dynamic timestamps" - (test-chime-timestamp-parse-setup) - (unwind-protect - (let* ((time (test-time-tomorrow-at 1 5)) - (timestamp (test-timestamp-string time)) - (result (chime--timestamp-parse timestamp))) - (should (listp result)) - (should (= (length result) 2)) - (should result)) - (test-chime-timestamp-parse-teardown))) - -(ert-deftest test-chime-timestamp-parse-leap-year-feb-29-returns-time-list () + (let* ((time (test-time-tomorrow-at 1 5)) + (timestamp (test-timestamp-string time)) + (result (chime--timestamp-parse timestamp))) + (should (listp result)) + (should (= (length result) 2)) + (should result))) + +(chime-deftest test-chime-timestamp-parse-leap-year-feb-29-returns-time-list () "Test that Feb 29 in leap year parses correctly. REFACTORED: Uses dynamic timestamps (2024 leap year)" - (test-chime-timestamp-parse-setup) - (unwind-protect - (let* (;; Use 2024 as a known leap year - (time (encode-time 0 0 14 29 2 2024)) - (timestamp (test-timestamp-string time)) - (result (chime--timestamp-parse timestamp))) - (should (listp result)) - (should (= (length result) 2)) - (should result)) - (test-chime-timestamp-parse-teardown))) - -(ert-deftest test-chime-timestamp-parse-month-boundary-end-of-month-returns-time-list () + (let* (;; Use 2024 as a known leap year + (time (encode-time 0 0 14 29 2 2024)) + (timestamp (test-timestamp-string time)) + (result (chime--timestamp-parse timestamp))) + (should (listp result)) + (should (= (length result) 2)) + (should result))) + +(chime-deftest test-chime-timestamp-parse-month-boundary-end-of-month-returns-time-list () "Test that end of month timestamp parses correctly. REFACTORED: Uses dynamic timestamps (Oct 31)" - (test-chime-timestamp-parse-setup) - (unwind-protect - (let* ((now (test-time-now)) - (decoded (decode-time now)) - (year (nth 5 decoded)) - ;; Create Oct 31 at 14:00 for current test year - (time (encode-time 0 0 14 31 10 year)) - (timestamp (test-timestamp-string time)) - (result (chime--timestamp-parse timestamp))) - (should (listp result)) - (should (= (length result) 2)) - (should result)) - (test-chime-timestamp-parse-teardown))) + (let* ((now (test-time-now)) + (decoded (decode-time now)) + (year (nth 5 decoded)) + ;; Create Oct 31 at 14:00 for current test year + (time (encode-time 0 0 14 31 10 year)) + (timestamp (test-timestamp-string time)) + (result (chime--timestamp-parse timestamp))) + (should (listp result)) + (should (= (length result) 2)) + (should result))) ;;; Bug Reproduction Tests -(ert-deftest test-chime-timestamp-parse-tomorrow-timestamp-returns-correct-date () +(chime-deftest test-chime-timestamp-parse-tomorrow-timestamp-returns-correct-date () "Test that a tomorrow timestamp is parsed as tomorrow, not today. This reproduces the bug where timestamps like <2025-11-03 Mon 10:00-10:30> on Nov 02 are incorrectly grouped as 'Today' instead of 'Tomorrow'." - (test-chime-timestamp-parse-setup) - (unwind-protect - (with-test-time (encode-time 0 23 11 2 11 2025) ; Nov 02, 2025 11:23:00 AM - (let* ((tomorrow-timestamp "<2025-11-03 Mon 10:00-10:30>") - (parsed (chime--timestamp-parse tomorrow-timestamp)) - (now (current-time))) - ;; Should parse successfully - (should parsed) - ;; Convert parsed time (HIGH LOW) to full time by appending (0 0) - (let* ((parsed-time (append parsed '(0 0))) - (parsed-decoded (decode-time parsed-time)) - (time-diff-seconds (- (time-to-seconds parsed-time) - (time-to-seconds now)))) - ;; Verify the parsed date is Nov 03, 2025 (not Nov 02!) - (should (= 3 (decoded-time-day parsed-decoded))) - (should (= 11 (decoded-time-month parsed-decoded))) - (should (= 2025 (decoded-time-year parsed-decoded))) - ;; Verify the parsed time is 10:00 - (should (= 10 (decoded-time-hour parsed-decoded))) - (should (= 0 (decoded-time-minute parsed-decoded))) - ;; Time difference should be ~22h 37m (81420 seconds) - (should (> time-diff-seconds 81360)) ; At least 22h 36m - (should (< time-diff-seconds 81480))))) ; At most 22h 38m - (test-chime-timestamp-parse-teardown))) + (with-test-time (encode-time 0 23 11 2 11 2025) ; Nov 02, 2025 11:23:00 AM + (let* ((tomorrow-timestamp "<2025-11-03 Mon 10:00-10:30>") + (parsed (chime--timestamp-parse tomorrow-timestamp)) + (now (current-time))) + ;; Should parse successfully + (should parsed) + ;; Convert parsed time (HIGH LOW) to full time by appending (0 0) + (let* ((parsed-time (append parsed '(0 0))) + (parsed-decoded (decode-time parsed-time)) + (time-diff-seconds (- (time-to-seconds parsed-time) + (time-to-seconds now)))) + ;; Verify the parsed date is Nov 03, 2025 (not Nov 02!) + (should (= 3 (decoded-time-day parsed-decoded))) + (should (= 11 (decoded-time-month parsed-decoded))) + (should (= 2025 (decoded-time-year parsed-decoded))) + ;; Verify the parsed time is 10:00 + (should (= 10 (decoded-time-hour parsed-decoded))) + (should (= 0 (decoded-time-minute parsed-decoded))) + ;; Time difference should be ~22h 37m (81420 seconds) + (should (> time-diff-seconds 81360)) ; At least 22h 36m + (should (< time-diff-seconds 81480)))))) ;;; Error Cases -(ert-deftest test-chime-timestamp-parse-empty-string-returns-nil () +(chime-deftest test-chime-timestamp-parse-empty-string-returns-nil () "Test that empty string returns nil." - (test-chime-timestamp-parse-setup) - (unwind-protect - (let* ((timestamp "") - (result (chime--timestamp-parse timestamp))) - (should (null result))) - (test-chime-timestamp-parse-teardown))) - -(ert-deftest test-chime-timestamp-parse-nil-input-returns-nil () + (let* ((timestamp "") + (result (chime--timestamp-parse timestamp))) + (should (null result)))) + +(chime-deftest test-chime-timestamp-parse-nil-input-returns-nil () "Test that nil input returns nil." - (test-chime-timestamp-parse-setup) - (unwind-protect - (let* ((timestamp nil) - (result (chime--timestamp-parse timestamp))) - (should (null result))) - (test-chime-timestamp-parse-teardown))) - -(ert-deftest test-chime-timestamp-parse-missing-opening-bracket-returns-nil () + (let* ((timestamp nil) + (result (chime--timestamp-parse timestamp))) + (should (null result)))) + +(chime-deftest test-chime-timestamp-parse-missing-opening-bracket-returns-nil () "Test that timestamp missing opening bracket returns nil." - (test-chime-timestamp-parse-setup) - (unwind-protect - (let* ((timestamp "2025-10-24 Fri 14:00>") - (result (chime--timestamp-parse timestamp))) - (should (null result))) - (test-chime-timestamp-parse-teardown))) - -(ert-deftest test-chime-timestamp-parse-missing-closing-bracket-returns-nil () + (let* ((timestamp "2025-10-24 Fri 14:00>") + (result (chime--timestamp-parse timestamp))) + (should (null result)))) + +(chime-deftest test-chime-timestamp-parse-missing-closing-bracket-returns-nil () "Test that timestamp missing closing bracket returns nil." - (test-chime-timestamp-parse-setup) - (unwind-protect - (let* ((timestamp "<2025-10-24 Fri 14:00") - (result (chime--timestamp-parse timestamp))) - (should (null result))) - (test-chime-timestamp-parse-teardown))) - -(ert-deftest test-chime-timestamp-parse-invalid-date-format-returns-nil () + (let* ((timestamp "<2025-10-24 Fri 14:00") + (result (chime--timestamp-parse timestamp))) + (should (null result)))) + +(chime-deftest test-chime-timestamp-parse-invalid-date-format-returns-nil () "Test that invalid date format returns nil." - (test-chime-timestamp-parse-setup) - (unwind-protect - (let* ((timestamp "<10-24-2025 Fri 14:00>") - (result (chime--timestamp-parse timestamp))) - (should (null result))) - (test-chime-timestamp-parse-teardown))) - -(ert-deftest test-chime-timestamp-parse-invalid-month-returns-nil () + (let* ((timestamp "<10-24-2025 Fri 14:00>") + (result (chime--timestamp-parse timestamp))) + (should (null result)))) + +(chime-deftest test-chime-timestamp-parse-invalid-month-returns-nil () "Test that invalid month value returns nil." - (test-chime-timestamp-parse-setup) - (unwind-protect - (let* ((timestamp "<2025-13-24 Fri 14:00>") - (result (chime--timestamp-parse timestamp))) - (should (null result))) - (test-chime-timestamp-parse-teardown))) - -(ert-deftest test-chime-timestamp-parse-invalid-day-returns-nil () + (let* ((timestamp "<2025-13-24 Fri 14:00>") + (result (chime--timestamp-parse timestamp))) + (should (null result)))) + +(chime-deftest test-chime-timestamp-parse-invalid-day-returns-nil () "Test that invalid day value returns nil." - (test-chime-timestamp-parse-setup) - (unwind-protect - (let* ((timestamp "<2025-10-32 Fri 14:00>") - (result (chime--timestamp-parse timestamp))) - (should (null result))) - (test-chime-timestamp-parse-teardown))) - -(ert-deftest test-chime-timestamp-parse-invalid-time-hour-returns-nil () + (let* ((timestamp "<2025-10-32 Fri 14:00>") + (result (chime--timestamp-parse timestamp))) + (should (null result)))) + +(chime-deftest test-chime-timestamp-parse-invalid-time-hour-returns-nil () "Test that invalid hour value returns nil." - (test-chime-timestamp-parse-setup) - (unwind-protect - (let* ((timestamp "<2025-10-24 Fri 25:00>") - (result (chime--timestamp-parse timestamp))) - (should (null result))) - (test-chime-timestamp-parse-teardown))) - -(ert-deftest test-chime-timestamp-parse-invalid-time-minute-returns-nil () + (let* ((timestamp "<2025-10-24 Fri 25:00>") + (result (chime--timestamp-parse timestamp))) + (should (null result)))) + +(chime-deftest test-chime-timestamp-parse-invalid-time-minute-returns-nil () "Test that invalid minute value returns nil." - (test-chime-timestamp-parse-setup) - (unwind-protect - (let* ((timestamp "<2025-10-24 Fri 14:60>") - (result (chime--timestamp-parse timestamp))) - (should (null result))) - (test-chime-timestamp-parse-teardown))) - -(ert-deftest test-chime-timestamp-parse-date-only-no-time-returns-nil () + (let* ((timestamp "<2025-10-24 Fri 14:60>") + (result (chime--timestamp-parse timestamp))) + (should (null result)))) + +(chime-deftest test-chime-timestamp-parse-date-only-no-time-returns-nil () "Test that day-wide timestamp without time returns nil." - (test-chime-timestamp-parse-setup) - (unwind-protect - (let* ((timestamp "<2025-10-24 Fri>") - (result (chime--timestamp-parse timestamp))) - (should (null result))) - (test-chime-timestamp-parse-teardown))) + (let* ((timestamp "<2025-10-24 Fri>") + (result (chime--timestamp-parse timestamp))) + (should (null result)))) (provide 'test-chime-timestamp-parse) ;;; test-chime-timestamp-parse.el ends here diff --git a/tests/test-chime-timestamp-within-interval-p.el b/tests/test-chime-timestamp-within-interval-p.el index 2cb6439..5857463 100644 --- a/tests/test-chime-timestamp-within-interval-p.el +++ b/tests/test-chime-timestamp-within-interval-p.el @@ -26,287 +26,222 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) - -;;; Setup and Teardown - -(defun test-chime-timestamp-within-interval-p-setup () - "Setup function run before each test." - (chime-create-test-base-dir)) - -(defun test-chime-timestamp-within-interval-p-teardown () - "Teardown function run after each test." - (chime-delete-test-base-dir)) - ;;; Normal Cases -(ert-deftest test-chime-timestamp-within-interval-p-exactly-at-interval-returns-t () +(chime-deftest test-chime-timestamp-within-interval-p-exactly-at-interval-returns-t () "Test that timestamp exactly at interval returns t. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-timestamp-within-interval-p-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 0)) - ;; Timestamp at 14:10 (10 minutes from 14:00) - (timestamp (test-time-today-at 14 10)) - (interval 10)) - (with-test-time now - (let ((result (chime--timestamp-within-interval-p timestamp interval))) - (should result)))) - (test-chime-timestamp-within-interval-p-teardown))) - -(ert-deftest test-chime-timestamp-within-interval-p-zero-interval-returns-t () + (let* ((now (test-time-today-at 14 0)) + ;; Timestamp at 14:10 (10 minutes from 14:00) + (timestamp (test-time-today-at 14 10)) + (interval 10)) + (with-test-time now + (let ((result (chime--timestamp-within-interval-p timestamp interval))) + (should result))))) + +(chime-deftest test-chime-timestamp-within-interval-p-zero-interval-returns-t () "Test that zero interval (notify now) returns t for current time. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-timestamp-within-interval-p-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 30)) - ;; Timestamp at exactly current time (14:30) - (timestamp (test-time-today-at 14 30)) - (interval 0)) - (with-test-time now - (let ((result (chime--timestamp-within-interval-p timestamp interval))) - (should result)))) - (test-chime-timestamp-within-interval-p-teardown))) - -(ert-deftest test-chime-timestamp-within-interval-p-five-minutes-returns-t () + (let* ((now (test-time-today-at 14 30)) + ;; Timestamp at exactly current time (14:30) + (timestamp (test-time-today-at 14 30)) + (interval 0)) + (with-test-time now + (let ((result (chime--timestamp-within-interval-p timestamp interval))) + (should result))))) + +(chime-deftest test-chime-timestamp-within-interval-p-five-minutes-returns-t () "Test that 5-minute interval works correctly. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-timestamp-within-interval-p-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 25)) - ;; Timestamp at 14:30 (5 minutes from 14:25) - (timestamp (test-time-today-at 14 30)) - (interval 5)) - (with-test-time now - (let ((result (chime--timestamp-within-interval-p timestamp interval))) - (should result)))) - (test-chime-timestamp-within-interval-p-teardown))) - -(ert-deftest test-chime-timestamp-within-interval-p-sixty-minutes-returns-t () + (let* ((now (test-time-today-at 14 25)) + ;; Timestamp at 14:30 (5 minutes from 14:25) + (timestamp (test-time-today-at 14 30)) + (interval 5)) + (with-test-time now + (let ((result (chime--timestamp-within-interval-p timestamp interval))) + (should result))))) + +(chime-deftest test-chime-timestamp-within-interval-p-sixty-minutes-returns-t () "Test that 60-minute (1 hour) interval works correctly. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-timestamp-within-interval-p-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 0)) - ;; Timestamp at 15:00 (60 minutes from 14:00) - (timestamp (test-time-today-at 15 0)) - (interval 60)) - (with-test-time now - (let ((result (chime--timestamp-within-interval-p timestamp interval))) - (should result)))) - (test-chime-timestamp-within-interval-p-teardown))) - -(ert-deftest test-chime-timestamp-within-interval-p-large-interval-returns-t () + (let* ((now (test-time-today-at 14 0)) + ;; Timestamp at 15:00 (60 minutes from 14:00) + (timestamp (test-time-today-at 15 0)) + (interval 60)) + (with-test-time now + (let ((result (chime--timestamp-within-interval-p timestamp interval))) + (should result))))) + +(chime-deftest test-chime-timestamp-within-interval-p-large-interval-returns-t () "Test that large interval (1 day = 1440 minutes) works correctly. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-timestamp-within-interval-p-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 0)) - ;; Timestamp at 14:00 next day (1440 minutes from now) - ;; Add 86400 seconds (1440 minutes = 1 day) to now - ;; Convert to list format for compatibility - (timestamp (apply #'encode-time (decode-time (time-add now (seconds-to-time 86400))))) - (interval 1440)) - (with-test-time now - (let ((result (chime--timestamp-within-interval-p timestamp interval))) - (should result)))) - (test-chime-timestamp-within-interval-p-teardown))) - -(ert-deftest test-chime-timestamp-within-interval-p-thirty-minutes-returns-t () + (let* ((now (test-time-today-at 14 0)) + ;; Timestamp at 14:00 next day (1440 minutes from now) + ;; Add 86400 seconds (1440 minutes = 1 day) to now + ;; Convert to list format for compatibility + (timestamp (apply #'encode-time (decode-time (time-add now (seconds-to-time 86400))))) + (interval 1440)) + (with-test-time now + (let ((result (chime--timestamp-within-interval-p timestamp interval))) + (should result))))) + +(chime-deftest test-chime-timestamp-within-interval-p-thirty-minutes-returns-t () "Test that 30-minute interval works correctly. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-timestamp-within-interval-p-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 15)) - ;; Timestamp at 14:45 (30 minutes from 14:15) - (timestamp (test-time-today-at 14 45)) - (interval 30)) - (with-test-time now - (let ((result (chime--timestamp-within-interval-p timestamp interval))) - (should result)))) - (test-chime-timestamp-within-interval-p-teardown))) + (let* ((now (test-time-today-at 14 15)) + ;; Timestamp at 14:45 (30 minutes from 14:15) + (timestamp (test-time-today-at 14 45)) + (interval 30)) + (with-test-time now + (let ((result (chime--timestamp-within-interval-p timestamp interval))) + (should result))))) ;;; Boundary Cases -(ert-deftest test-chime-timestamp-within-interval-p-one-minute-before-returns-nil () +(chime-deftest test-chime-timestamp-within-interval-p-one-minute-before-returns-nil () "Test that timestamp 1 minute before interval returns nil. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-timestamp-within-interval-p-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 0)) - ;; Timestamp at 14:09 (9 minutes from 14:00, not 10) - (timestamp (test-time-today-at 14 9)) - (interval 10)) - (with-test-time now - (let ((result (chime--timestamp-within-interval-p timestamp interval))) - (should-not result)))) - (test-chime-timestamp-within-interval-p-teardown))) - -(ert-deftest test-chime-timestamp-within-interval-p-one-minute-after-returns-nil () + (let* ((now (test-time-today-at 14 0)) + ;; Timestamp at 14:09 (9 minutes from 14:00, not 10) + (timestamp (test-time-today-at 14 9)) + (interval 10)) + (with-test-time now + (let ((result (chime--timestamp-within-interval-p timestamp interval))) + (should-not result))))) + +(chime-deftest test-chime-timestamp-within-interval-p-one-minute-after-returns-nil () "Test that timestamp 1 minute after interval returns nil. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-timestamp-within-interval-p-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 0)) - ;; Timestamp at 14:11 (11 minutes from 14:00, not 10) - (timestamp (test-time-today-at 14 11)) - (interval 10)) - (with-test-time now - (let ((result (chime--timestamp-within-interval-p timestamp interval))) - (should-not result)))) - (test-chime-timestamp-within-interval-p-teardown))) - -(ert-deftest test-chime-timestamp-within-interval-p-crossing-midnight-returns-t () + (let* ((now (test-time-today-at 14 0)) + ;; Timestamp at 14:11 (11 minutes from 14:00, not 10) + (timestamp (test-time-today-at 14 11)) + (interval 10)) + (with-test-time now + (let ((result (chime--timestamp-within-interval-p timestamp interval))) + (should-not result))))) + +(chime-deftest test-chime-timestamp-within-interval-p-crossing-midnight-returns-t () "Test that interval crossing midnight works correctly. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-timestamp-within-interval-p-setup) - (unwind-protect - (let* ((now (test-time-today-at 23 50)) - ;; Timestamp at 00:00 next day (10 minutes from 23:50) - ;; Add 600 seconds (10 minutes) to 23:50 to get 00:00 next day - ;; Convert to list format for compatibility - (timestamp (apply #'encode-time (decode-time (time-add now (seconds-to-time 600))))) - (interval 10)) - (with-test-time now - (let ((result (chime--timestamp-within-interval-p timestamp interval))) - (should result)))) - (test-chime-timestamp-within-interval-p-teardown))) - -(ert-deftest test-chime-timestamp-within-interval-p-crossing-day-boundary-returns-t () + (let* ((now (test-time-today-at 23 50)) + ;; Timestamp at 00:00 next day (10 minutes from 23:50) + ;; Add 600 seconds (10 minutes) to 23:50 to get 00:00 next day + ;; Convert to list format for compatibility + (timestamp (apply #'encode-time (decode-time (time-add now (seconds-to-time 600))))) + (interval 10)) + (with-test-time now + (let ((result (chime--timestamp-within-interval-p timestamp interval))) + (should result))))) + +(chime-deftest test-chime-timestamp-within-interval-p-crossing-day-boundary-returns-t () "Test that interval crossing to next day works correctly. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-timestamp-within-interval-p-setup) - (unwind-protect - (let* ((now (test-time-today-at 23 30)) - ;; Timestamp at 00:30 next day (60 minutes from 23:30) - ;; Add 3600 seconds (60 minutes) to 23:30 to get 00:30 next day - ;; Convert to list format for compatibility - (timestamp (apply #'encode-time (decode-time (time-add now (seconds-to-time 3600))))) - (interval 60)) - (with-test-time now - (let ((result (chime--timestamp-within-interval-p timestamp interval))) - (should result)))) - (test-chime-timestamp-within-interval-p-teardown))) - -(ert-deftest test-chime-timestamp-within-interval-p-week-interval-returns-t () + (let* ((now (test-time-today-at 23 30)) + ;; Timestamp at 00:30 next day (60 minutes from 23:30) + ;; Add 3600 seconds (60 minutes) to 23:30 to get 00:30 next day + ;; Convert to list format for compatibility + (timestamp (apply #'encode-time (decode-time (time-add now (seconds-to-time 3600))))) + (interval 60)) + (with-test-time now + (let ((result (chime--timestamp-within-interval-p timestamp interval))) + (should result))))) + +(chime-deftest test-chime-timestamp-within-interval-p-week-interval-returns-t () "Test that very large interval (1 week = 10080 minutes) works. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-timestamp-within-interval-p-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 0)) - ;; Timestamp at 14:00 one week later (10080 minutes = 7 days from now) - ;; Add 604800 seconds (10080 minutes = 7 days) to now - ;; Convert to list format for compatibility - (timestamp (apply #'encode-time (decode-time (time-add now (seconds-to-time 604800))))) - (interval 10080)) - (with-test-time now - (let ((result (chime--timestamp-within-interval-p timestamp interval))) - (should result)))) - (test-chime-timestamp-within-interval-p-teardown))) - -(ert-deftest test-chime-timestamp-within-interval-p-at-midnight-returns-t () + (let* ((now (test-time-today-at 14 0)) + ;; Timestamp at 14:00 one week later (10080 minutes = 7 days from now) + ;; Add 604800 seconds (10080 minutes = 7 days) to now + ;; Convert to list format for compatibility + (timestamp (apply #'encode-time (decode-time (time-add now (seconds-to-time 604800))))) + (interval 10080)) + (with-test-time now + (let ((result (chime--timestamp-within-interval-p timestamp interval))) + (should result))))) + +(chime-deftest test-chime-timestamp-within-interval-p-at-midnight-returns-t () "Test that timestamp at exact midnight works correctly. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-timestamp-within-interval-p-setup) - (unwind-protect - (let* ((now (test-time-today-at 23 50)) - ;; Timestamp at midnight (10 minutes from 23:50) - ;; Add 600 seconds (10 minutes) to 23:50 to get 00:00 next day - ;; Convert to list format for compatibility - (timestamp (apply #'encode-time (decode-time (time-add now (seconds-to-time 600))))) - (interval 10)) - (with-test-time now - (let ((result (chime--timestamp-within-interval-p timestamp interval))) - (should result)))) - (test-chime-timestamp-within-interval-p-teardown))) + (let* ((now (test-time-today-at 23 50)) + ;; Timestamp at midnight (10 minutes from 23:50) + ;; Add 600 seconds (10 minutes) to 23:50 to get 00:00 next day + ;; Convert to list format for compatibility + (timestamp (apply #'encode-time (decode-time (time-add now (seconds-to-time 600))))) + (interval 10)) + (with-test-time now + (let ((result (chime--timestamp-within-interval-p timestamp interval))) + (should result))))) ;;; Error Cases -(ert-deftest test-chime-timestamp-within-interval-p-nil-timestamp-returns-nil () +(chime-deftest test-chime-timestamp-within-interval-p-nil-timestamp-returns-nil () "Test that nil timestamp returns nil. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-timestamp-within-interval-p-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 0)) - (timestamp nil) - (interval 10)) - (with-test-time now - (let ((result (chime--timestamp-within-interval-p timestamp interval))) - (should-not result)))) - (test-chime-timestamp-within-interval-p-teardown))) - -(ert-deftest test-chime-timestamp-within-interval-p-nil-interval-returns-nil () + (let* ((now (test-time-today-at 14 0)) + (timestamp nil) + (interval 10)) + (with-test-time now + (let ((result (chime--timestamp-within-interval-p timestamp interval))) + (should-not result))))) + +(chime-deftest test-chime-timestamp-within-interval-p-nil-interval-returns-nil () "Test that nil interval returns nil. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-timestamp-within-interval-p-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 0)) - (timestamp (test-time-today-at 14 10)) - (interval nil)) - (with-test-time now - (let ((result (chime--timestamp-within-interval-p timestamp interval))) - (should-not result)))) - (test-chime-timestamp-within-interval-p-teardown))) - -(ert-deftest test-chime-timestamp-within-interval-p-negative-interval-returns-nil () + (let* ((now (test-time-today-at 14 0)) + (timestamp (test-time-today-at 14 10)) + (interval nil)) + (with-test-time now + (let ((result (chime--timestamp-within-interval-p timestamp interval))) + (should-not result))))) + +(chime-deftest test-chime-timestamp-within-interval-p-negative-interval-returns-nil () "Test that negative interval returns nil (past timestamps). REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-timestamp-within-interval-p-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 0)) - ;; Timestamp 10 minutes in the past (13:50) - (timestamp (test-time-today-at 13 50)) - (interval -10)) - (with-test-time now - (let ((result (chime--timestamp-within-interval-p timestamp interval))) - (should result)))) - (test-chime-timestamp-within-interval-p-teardown))) - -(ert-deftest test-chime-timestamp-within-interval-p-invalid-timestamp-returns-nil () + (let* ((now (test-time-today-at 14 0)) + ;; Timestamp 10 minutes in the past (13:50) + (timestamp (test-time-today-at 13 50)) + (interval -10)) + (with-test-time now + (let ((result (chime--timestamp-within-interval-p timestamp interval))) + (should result))))) + +(chime-deftest test-chime-timestamp-within-interval-p-invalid-timestamp-returns-nil () "Test that invalid timestamp format returns nil. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-timestamp-within-interval-p-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 0)) - (timestamp "not-a-timestamp") - (interval 10)) - (with-test-time now - (let ((result (chime--timestamp-within-interval-p timestamp interval))) - (should-not result)))) - (test-chime-timestamp-within-interval-p-teardown))) - -(ert-deftest test-chime-timestamp-within-interval-p-float-interval-works () + (let* ((now (test-time-today-at 14 0)) + (timestamp "not-a-timestamp") + (interval 10)) + (with-test-time now + (let ((result (chime--timestamp-within-interval-p timestamp interval))) + (should-not result))))) + +(chime-deftest test-chime-timestamp-within-interval-p-float-interval-works () "Test that float interval gets converted properly. REFACTORED: Uses dynamic timestamps and with-test-time" - (test-chime-timestamp-within-interval-p-setup) - (unwind-protect - (let* ((now (test-time-today-at 14 0)) - ;; Timestamp at 14:10 (10 minutes from 14:00) - (timestamp (test-time-today-at 14 10)) - (interval 10.5)) - (with-test-time now - (let ((result (chime--timestamp-within-interval-p timestamp interval))) - (should result)))) - (test-chime-timestamp-within-interval-p-teardown))) + (let* ((now (test-time-today-at 14 0)) + ;; Timestamp at 14:10 (10 minutes from 14:00) + (timestamp (test-time-today-at 14 10)) + (interval 10.5)) + (with-test-time now + (let ((result (chime--timestamp-within-interval-p timestamp interval))) + (should result))))) (provide 'test-chime-timestamp-within-interval-p) ;;; test-chime-timestamp-within-interval-p.el ends here diff --git a/tests/test-chime-tooltip-bugs.el b/tests/test-chime-tooltip-bugs.el index 8a11317..0d141b9 100644 --- a/tests/test-chime-tooltip-bugs.el +++ b/tests/test-chime-tooltip-bugs.el @@ -8,8 +8,6 @@ ;;; Code: (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) ;;; Setup and Teardown diff --git a/tests/test-chime-tooltip-day-calculation.el b/tests/test-chime-tooltip-day-calculation.el index 6e4f778..724ff9d 100644 --- a/tests/test-chime-tooltip-day-calculation.el +++ b/tests/test-chime-tooltip-day-calculation.el @@ -13,8 +13,6 @@ ;;; Code: (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) -(require 'testutil-general (expand-file-name "testutil-general.el")) (require 'testutil-events (expand-file-name "testutil-events.el")) (defmacro test-chime-tooltip-day-calculation--with-tooltip (now content &rest body) diff --git a/tests/test-chime-update-modeline-helpers.el b/tests/test-chime-update-modeline-helpers.el index 429265c..f28ad81 100644 --- a/tests/test-chime-update-modeline-helpers.el +++ b/tests/test-chime-update-modeline-helpers.el @@ -10,8 +10,6 @@ ;;; Code: (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) -(require 'testutil-general (expand-file-name "testutil-general.el")) (require 'testutil-events (expand-file-name "testutil-events.el")) ;;;; Tests for chime--find-soonest-time-in-window diff --git a/tests/test-chime-update-modeline.el b/tests/test-chime-update-modeline.el index 525e39e..7b1a809 100644 --- a/tests/test-chime-update-modeline.el +++ b/tests/test-chime-update-modeline.el @@ -26,10 +26,6 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) - ;;; Setup and Teardown (defun test-chime-update-modeline-setup () diff --git a/tests/test-chime-validation-retry.el b/tests/test-chime-validation-retry.el index a2765f4..ec5e2fe 100644 --- a/tests/test-chime-validation-retry.el +++ b/tests/test-chime-validation-retry.el @@ -20,8 +20,6 @@ ;;; Code: (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) (require 'testutil-events (expand-file-name "testutil-events.el")) ;;; Setup and Teardown diff --git a/tests/test-chime-whitelist-blacklist-conflicts.el b/tests/test-chime-whitelist-blacklist-conflicts.el index 18b6680..b2465c5 100644 --- a/tests/test-chime-whitelist-blacklist-conflicts.el +++ b/tests/test-chime-whitelist-blacklist-conflicts.el @@ -30,9 +30,6 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) - ;;; Setup and Teardown (defun test-chime-conflicts-setup () diff --git a/tests/test-integration-chime-mode.el b/tests/test-integration-chime-mode.el index 40436fb..229d877 100644 --- a/tests/test-integration-chime-mode.el +++ b/tests/test-integration-chime-mode.el @@ -28,8 +28,6 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) ;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) (require 'testutil-events (expand-file-name "testutil-events.el")) ;;; Tests diff --git a/tests/test-integration-per-event-override.el b/tests/test-integration-per-event-override.el index 8455590..119e345 100644 --- a/tests/test-integration-per-event-override.el +++ b/tests/test-integration-per-event-override.el @@ -32,7 +32,6 @@ ;;; Code: (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -(require 'testutil-general (expand-file-name "testutil-general.el")) (require 'cl-lib) (defun test-integration-per-event-override--events-from-agenda () diff --git a/tests/test-integration-recurring-events-tooltip.el b/tests/test-integration-recurring-events-tooltip.el index 810e3ee..c904d37 100644 --- a/tests/test-integration-recurring-events-tooltip.el +++ b/tests/test-integration-recurring-events-tooltip.el @@ -42,10 +42,6 @@ (setq chime-debug t) (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) - ;;; Setup and Teardown (defvar test-integration-recurring--orig-agenda-files nil diff --git a/tests/test-integration-startup.el b/tests/test-integration-startup.el index 1f60b54..952a975 100644 --- a/tests/test-integration-startup.el +++ b/tests/test-integration-startup.el @@ -45,8 +45,6 @@ (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) ;; Load test utilities -(require 'testutil-general (expand-file-name "testutil-general.el")) -(require 'testutil-time (expand-file-name "testutil-time.el")) (require 'testutil-events (expand-file-name "testutil-events.el")) ;;; Helper Functions diff --git a/tests/test-testutil-general.el b/tests/test-testutil-general.el index 7b4e445..c3c89f2 100644 --- a/tests/test-testutil-general.el +++ b/tests/test-testutil-general.el @@ -9,7 +9,6 @@ ;;; Code: (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) -(require 'testutil-general (expand-file-name "testutil-general.el")) (ert-deftest test-chime-test-default-base-dir-uses-env-override () "Normal: CHIME_TEST_TMPDIR selects an explicit test root." |
