diff options
| author | Craig Jennings <c@cjennings.net> | 2026-05-10 16:36:47 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-05-10 16:36:47 -0500 |
| commit | 3c64dac1b98049d475be838294349326c32248ae (patch) | |
| tree | 626917ca3660d34b48195a77123b1def3d418282 /tests/test-chime-tooltip-day-calculation.el | |
| parent | 0772736d2bca36472f623d5258784f41db9b4f9a (diff) | |
| download | chime-3c64dac1b98049d475be838294349326c32248ae.tar.gz chime-3c64dac1b98049d475be838294349326c32248ae.zip | |
feat: tighten chime runtime validation and tooltip behavior
Diffstat (limited to 'tests/test-chime-tooltip-day-calculation.el')
| -rw-r--r-- | tests/test-chime-tooltip-day-calculation.el | 358 |
1 files changed, 110 insertions, 248 deletions
diff --git a/tests/test-chime-tooltip-day-calculation.el b/tests/test-chime-tooltip-day-calculation.el index 1a25767..6e4f778 100644 --- a/tests/test-chime-tooltip-day-calculation.el +++ b/tests/test-chime-tooltip-day-calculation.el @@ -15,6 +15,18 @@ (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) + "Bind tooltip for CONTENT at NOW and run BODY with common test config." + (declare (indent 2)) + `(with-test-setup + (with-chime-config + chime-modeline-lookahead-minutes 10080 + chime-tooltip-lookahead-hours 168 + (with-test-time ,now + (with-chime-tooltip-from-content ,content tooltip + ,@body))))) (ert-deftest test-chime-tooltip-day-calculation-fractional-days () "Test that fractional days show both days and hours correctly. @@ -24,65 +36,36 @@ User scenario: Viewing tooltip on Sunday 9pm, sees: - Wednesday 2pm event: 65 hours = 2.7 days → 'in 2 days 17 hours' This test prevents regression of the integer division truncation bug." - (chime-create-test-base-dir) - (unwind-protect - (let* ((now (test-time-today-at 21 0)) ; Sunday 9pm - ;; Create events at specific future times - (tuesday-9pm (time-add now (seconds-to-time (* 48 3600)))) ; +48 hours - (wednesday-2pm (time-add now (seconds-to-time (* 65 3600)))) ; +65 hours - (content (format "* Tuesday Event\n<%s>\n* Wednesday Event\n<%s>\n" - (format-time-string "<%Y-%m-%d %a %H:%M>" tuesday-9pm) - (format-time-string "<%Y-%m-%d %a %H:%M>" wednesday-2pm))) - (test-file (chime-create-temp-test-file-with-content content)) - (test-buffer (find-file-noselect test-file)) - (events nil)) - - ;; Gather events - (with-current-buffer test-buffer - (org-mode) - (goto-char (point-min)) - (while (re-search-forward "^\\*+ " nil t) - (beginning-of-line) - (push (chime--gather-info (point-marker)) events) - (forward-line 1))) - (kill-buffer test-buffer) - (setq events (nreverse events)) - - ;; Set lookahead to cover events (7 days) - (setq chime-modeline-lookahead-minutes 10080) - (setq chime-tooltip-lookahead-hours 168) - - (with-test-time now - ;; Update modeline and get tooltip - (chime--update-modeline events) - (let ((tooltip (chime--make-tooltip chime--upcoming-events))) - - ;; Verify tooltip contains both events - (should (string-match-p "Tuesday Event" tooltip)) - (should (string-match-p "Wednesday Event" tooltip)) - - ;; Print tooltip for manual inspection - (message "TOOLTIP CONTENT:\n%s" tooltip) - - ;; AFTER FIX: Tuesday shows "in 2 days", Wednesday shows "in 2 days 17 hours" - ;; Verify Tuesday shows exactly 2 days (no "hours" in countdown) - (should (string-match-p "Tuesday Event.*(in 2 days)" tooltip)) - ;; Make sure Tuesday doesn't have hours - (should-not (string-match-p "Tuesday Event.*hours" tooltip)) - - ;; Verify Wednesday shows 2 days AND 17 hours - (should (string-match-p "Wednesday Event.*(in 2 days 17 hours)" tooltip)) - - ;; Verify they show DIFFERENT countdowns - (let ((tuesday-line (progn - (string-match "Tuesday Event[^\n]*" tooltip) - (match-string 0 tooltip))) - (wednesday-line (progn - (string-match "Wednesday Event[^\n]*" tooltip) - (match-string 0 tooltip)))) - (should-not (string= tuesday-line wednesday-line)))))) - - (chime-delete-test-base-dir))) + (let* ((now (test-time-today-at 21 0)) ; Sunday 9pm + ;; Create events at specific future times + (tuesday-9pm (time-add now (seconds-to-time (* 48 3600)))) ; +48 hours + (wednesday-2pm (time-add now (seconds-to-time (* 65 3600)))) ; +65 hours + (content (format "* Tuesday Event\n<%s>\n* Wednesday Event\n<%s>\n" + (format-time-string "<%Y-%m-%d %a %H:%M>" tuesday-9pm) + (format-time-string "<%Y-%m-%d %a %H:%M>" wednesday-2pm)))) + (test-chime-tooltip-day-calculation--with-tooltip now content + (ert-info ((format "Tooltip content:\n%s" tooltip)) + ;; Verify tooltip contains both events + (should (string-match-p "Tuesday Event" tooltip)) + (should (string-match-p "Wednesday Event" tooltip)) + + ;; AFTER FIX: Tuesday shows "in 2 days", Wednesday shows "in 2 days 17 hours" + ;; Verify Tuesday shows exactly 2 days (no "hours" in countdown) + (should (string-match-p "Tuesday Event.*(in 2 days)" tooltip)) + ;; Make sure Tuesday doesn't have hours + (should-not (string-match-p "Tuesday Event.*hours" tooltip)) + + ;; Verify Wednesday shows 2 days AND 17 hours + (should (string-match-p "Wednesday Event.*(in 2 days 17 hours)" tooltip)) + + ;; Verify they show DIFFERENT countdowns + (let ((tuesday-line (progn + (string-match "Tuesday Event[^\n]*" tooltip) + (match-string 0 tooltip))) + (wednesday-line (progn + (string-match "Wednesday Event[^\n]*" tooltip) + (match-string 0 tooltip)))) + (should-not (string= tuesday-line wednesday-line))))))) ;;; Helper function for creating test events @@ -103,116 +86,47 @@ Returns formatted org content string." (ert-deftest test-chime-tooltip-day-calculation-boundary-exactly-24-hours () "Test event exactly 24 hours away shows 'in 1 day' not hours." - (chime-create-test-base-dir) - (unwind-protect - (let* ((now (test-time-today-at 12 0)) - (content (test-chime-tooltip-day-calculation--create-event-at-hours now "Tomorrow Same Time" 24)) - (test-file (chime-create-temp-test-file-with-content content)) - (events (with-current-buffer (find-file-noselect test-file) - (org-mode) - (goto-char (point-min)) - (let ((evs nil)) - (while (re-search-forward "^\\*+ " nil t) - (push (chime--gather-info (point-marker)) evs)) - (nreverse evs))))) - (kill-buffer (get-file-buffer test-file)) - - (setq chime-modeline-lookahead-minutes 10080) - (setq chime-tooltip-lookahead-hours 168) - - (with-test-time now - (chime--update-modeline events) - (let ((tooltip (chime--make-tooltip chime--upcoming-events))) - ;; Should show "in 1 day" not hours - (should (string-match-p "(in 1 day)" tooltip)) - (should-not (string-match-p "hours" tooltip))))) - (chime-delete-test-base-dir))) + (let* ((now (test-time-today-at 12 0)) + (content (test-chime-tooltip-day-calculation--create-event-at-hours + now "Tomorrow Same Time" 24))) + (test-chime-tooltip-day-calculation--with-tooltip now content + ;; Should show "in 1 day" not hours + (should (string-match-p "(in 1 day)" tooltip)) + (should-not (string-match-p "hours" tooltip))))) (ert-deftest test-chime-tooltip-day-calculation-boundary-23-hours-59-minutes () "Test event 23h59m away shows hours, not days (just under 24h threshold)." - (chime-create-test-base-dir) - (unwind-protect - (let* ((now (test-time-today-at 12 0)) - ;; 23 hours 59 minutes = 1439 minutes = just under 1440 - (event-time (time-add now (seconds-to-time (* 1439 60)))) - (content (format "* Almost Tomorrow\n<%s>\n" - (format-time-string "%Y-%m-%d %a %H:%M" event-time))) - (test-file (chime-create-temp-test-file-with-content content)) - (events (with-current-buffer (find-file-noselect test-file) - (org-mode) - (goto-char (point-min)) - (let ((evs nil)) - (while (re-search-forward "^\\*+ " nil t) - (push (chime--gather-info (point-marker)) evs)) - (nreverse evs))))) - (kill-buffer (get-file-buffer test-file)) - - (setq chime-modeline-lookahead-minutes 10080) - (setq chime-tooltip-lookahead-hours 168) - - (with-test-time now - (chime--update-modeline events) - (let ((tooltip (chime--make-tooltip chime--upcoming-events))) - ;; Should show hours format (< 24 hours) - (should (string-match-p "hours" tooltip)) - (should-not (string-match-p "days?" tooltip))))) - (chime-delete-test-base-dir))) + (let* ((now (test-time-today-at 12 0)) + ;; 23 hours 59 minutes = 1439 minutes = just under 1440 + (event-time (time-add now (seconds-to-time (* 1439 60)))) + (content (format "* Almost Tomorrow\n<%s>\n" + (format-time-string "%Y-%m-%d %a %H:%M" event-time)))) + (test-chime-tooltip-day-calculation--with-tooltip now content + ;; Should show hours format (< 24 hours) + (should (string-match-p "hours" tooltip)) + (should-not (string-match-p "days?" tooltip))))) (ert-deftest test-chime-tooltip-day-calculation-boundary-25-hours () "Test event 25 hours away shows 'in 1 day 1 hour'." - (chime-create-test-base-dir) - (unwind-protect - (let* ((now (test-time-today-at 12 0)) - (content (test-chime-tooltip-day-calculation--create-event-at-hours now "Day Plus One" 25)) - (test-file (chime-create-temp-test-file-with-content content)) - (events (with-current-buffer (find-file-noselect test-file) - (org-mode) - (goto-char (point-min)) - (let ((evs nil)) - (while (re-search-forward "^\\*+ " nil t) - (push (chime--gather-info (point-marker)) evs)) - (nreverse evs))))) - (kill-buffer (get-file-buffer test-file)) - - (setq chime-modeline-lookahead-minutes 10080) - (setq chime-tooltip-lookahead-hours 168) - - (with-test-time now - (chime--update-modeline events) - (let ((tooltip (chime--make-tooltip chime--upcoming-events))) - ;; Should show "in 1 day 1 hour" - (should (string-match-p "(in 1 day 1 hour)" tooltip))))) - (chime-delete-test-base-dir))) + (let* ((now (test-time-today-at 12 0)) + (content (test-chime-tooltip-day-calculation--create-event-at-hours + now "Day Plus One" 25))) + (test-chime-tooltip-day-calculation--with-tooltip now content + ;; Should show "in 1 day 1 hour" + (should (string-match-p "(in 1 day 1 hour)" tooltip))))) (ert-deftest test-chime-tooltip-day-calculation-boundary-exactly-48-hours () "Test event exactly 48 hours away shows 'in 2 days' without hours." - (chime-create-test-base-dir) - (unwind-protect - (let* ((now (test-time-today-at 12 0)) - (content (test-chime-tooltip-day-calculation--create-event-at-hours now "Two Days Exact" 48)) - (test-file (chime-create-temp-test-file-with-content content)) - (events (with-current-buffer (find-file-noselect test-file) - (org-mode) - (goto-char (point-min)) - (let ((evs nil)) - (while (re-search-forward "^\\*+ " nil t) - (push (chime--gather-info (point-marker)) evs)) - (nreverse evs))))) - (kill-buffer (get-file-buffer test-file)) - - (setq chime-modeline-lookahead-minutes 10080) - (setq chime-tooltip-lookahead-hours 168) - - (with-test-time now - (chime--update-modeline events) - (let ((tooltip (chime--make-tooltip chime--upcoming-events)) - (line (test-chime-tooltip-day-calculation--get-formatted-line - (chime--make-tooltip chime--upcoming-events) "Two Days Exact"))) - ;; Should show exactly "in 2 days" with NO hours - (should (string-match-p "(in 2 days)" tooltip)) - ;; Verify the line doesn't contain "hour" (would be "2 days 0 hours") - (should-not (string-match-p "hour" line))))) - (chime-delete-test-base-dir))) + (let* ((now (test-time-today-at 12 0)) + (content (test-chime-tooltip-day-calculation--create-event-at-hours + now "Two Days Exact" 48))) + (test-chime-tooltip-day-calculation--with-tooltip now content + (let ((line (test-chime-tooltip-day-calculation--get-formatted-line + tooltip "Two Days Exact"))) + ;; Should show exactly "in 2 days" with NO hours + (should (string-match-p "(in 2 days)" tooltip)) + ;; Verify the line doesn't contain "hour" (would be "2 days 0 hours") + (should-not (string-match-p "hour" line)))))) ;;; Midnight Boundaries @@ -221,102 +135,50 @@ Returns formatted org content string." Scenario: 11pm now, event at 2am (3 hours later, next calendar day) Should show hours, not '1 day' since it's only 3 hours away." - (chime-create-test-base-dir) - (unwind-protect - (let* ((now (test-time-today-at 23 0)) ; 11pm - ;; 3 hours later = 2am next day - (content (test-chime-tooltip-day-calculation--create-event-at-hours now "Early Morning" 3)) - (test-file (chime-create-temp-test-file-with-content content)) - (events (with-current-buffer (find-file-noselect test-file) - (org-mode) - (goto-char (point-min)) - (let ((evs nil)) - (while (re-search-forward "^\\*+ " nil t) - (push (chime--gather-info (point-marker)) evs)) - (nreverse evs))))) - (kill-buffer (get-file-buffer test-file)) - - (setq chime-modeline-lookahead-minutes 10080) - (setq chime-tooltip-lookahead-hours 168) - - (with-test-time now - (chime--update-modeline events) - (let ((tooltip (chime--make-tooltip chime--upcoming-events))) - ;; Should show "in 3 hours" not "in 1 day" - (should (string-match-p "3 hours" tooltip)) - (should-not (string-match-p "days?" tooltip))))) - (chime-delete-test-base-dir))) + (let* ((now (test-time-today-at 23 0)) ; 11pm + ;; 3 hours later = 2am next day + (content (test-chime-tooltip-day-calculation--create-event-at-hours + now "Early Morning" 3))) + (test-chime-tooltip-day-calculation--with-tooltip now content + ;; Should show "in 3 hours" not "in 1 day" + (should (string-match-p "3 hours" tooltip)) + (should-not (string-match-p "days?" tooltip))))) (ert-deftest test-chime-tooltip-day-calculation-midnight-plus-one-day () "Test event at midnight tomorrow (24h exactly) shows '1 day'." - (chime-create-test-base-dir) - (unwind-protect - (let* ((now (test-time-today-at 0 0)) ; Midnight today - (content (test-chime-tooltip-day-calculation--create-event-at-hours now "Midnight Tomorrow" 24)) - (test-file (chime-create-temp-test-file-with-content content)) - (events (with-current-buffer (find-file-noselect test-file) - (org-mode) - (goto-char (point-min)) - (let ((evs nil)) - (while (re-search-forward "^\\*+ " nil t) - (push (chime--gather-info (point-marker)) evs)) - (nreverse evs))))) - (kill-buffer (get-file-buffer test-file)) - - (setq chime-modeline-lookahead-minutes 10080) - (setq chime-tooltip-lookahead-hours 168) - - (with-test-time now - (chime--update-modeline events) - (let ((tooltip (chime--make-tooltip chime--upcoming-events))) - (should (string-match-p "(in 1 day)" tooltip)) - (should-not (string-match-p "hour" tooltip))))) - (chime-delete-test-base-dir))) + (let* ((now (test-time-today-at 0 0)) ; Midnight today + (content (test-chime-tooltip-day-calculation--create-event-at-hours + now "Midnight Tomorrow" 24))) + (test-chime-tooltip-day-calculation--with-tooltip now content + (should (string-match-p "(in 1 day)" tooltip)) + (should-not (string-match-p "hour" tooltip))))) ;;; Multiple Events - Verify distinct formatting (ert-deftest test-chime-tooltip-day-calculation-multiple-events-distinct () "Test multiple events at different fractional-day offsets show distinct times." - (chime-create-test-base-dir) - (unwind-protect - (let* ((now (test-time-today-at 12 0)) - (content (concat - (test-chime-tooltip-day-calculation--create-event-at-hours now "Event 1 Day" 24) - (test-chime-tooltip-day-calculation--create-event-at-hours now "Event 1.5 Days" 36) - (test-chime-tooltip-day-calculation--create-event-at-hours now "Event 2 Days" 48) - (test-chime-tooltip-day-calculation--create-event-at-hours now "Event 2.75 Days" 66))) - (test-file (chime-create-temp-test-file-with-content content)) - (events (with-current-buffer (find-file-noselect test-file) - (org-mode) - (goto-char (point-min)) - (let ((evs nil)) - (while (re-search-forward "^\\*+ " nil t) - (push (chime--gather-info (point-marker)) evs)) - (nreverse evs))))) - (kill-buffer (get-file-buffer test-file)) - - (setq chime-modeline-lookahead-minutes 10080) - (setq chime-tooltip-lookahead-hours 168) - - (with-test-time now - (chime--update-modeline events) - (let ((tooltip (chime--make-tooltip chime--upcoming-events))) - ;; Verify each event shows correctly - (should (string-match-p "Event 1 Day.*(in 1 day)" tooltip)) - (should (string-match-p "Event 1.5 Days.*(in 1 day 12 hours)" tooltip)) - (should (string-match-p "Event 2 Days.*(in 2 days)" tooltip)) - (should (string-match-p "Event 2.75 Days.*(in 2 days 18 hours)" tooltip)) - - ;; Verify they're all different - (let ((lines (split-string tooltip "\n"))) - (let ((countdowns (cl-remove-if-not - (lambda (line) (string-match-p "Event.*day" line)) - lines))) - ;; Should have 4 distinct countdown lines - (should (= 4 (length countdowns))) - ;; All should be unique - (should (= 4 (length (delete-dups (copy-sequence countdowns)))))))))) - (chime-delete-test-base-dir))) + (let* ((now (test-time-today-at 12 0)) + (content (concat + (test-chime-tooltip-day-calculation--create-event-at-hours now "Event 1 Day" 24) + (test-chime-tooltip-day-calculation--create-event-at-hours now "Event 1.5 Days" 36) + (test-chime-tooltip-day-calculation--create-event-at-hours now "Event 2 Days" 48) + (test-chime-tooltip-day-calculation--create-event-at-hours now "Event 2.75 Days" 66)))) + (test-chime-tooltip-day-calculation--with-tooltip now content + ;; Verify each event shows correctly + (should (string-match-p "Event 1 Day.*(in 1 day)" tooltip)) + (should (string-match-p "Event 1.5 Days.*(in 1 day 12 hours)" tooltip)) + (should (string-match-p "Event 2 Days.*(in 2 days)" tooltip)) + (should (string-match-p "Event 2.75 Days.*(in 2 days 18 hours)" tooltip)) + + ;; Verify they're all different + (let ((lines (split-string tooltip "\n"))) + (let ((countdowns (cl-remove-if-not + (lambda (line) (string-match-p "Event.*day" line)) + lines))) + ;; Should have 4 distinct countdown lines + (should (= 4 (length countdowns))) + ;; All should be unique + (should (= 4 (length (delete-dups (copy-sequence countdowns)))))))))) (provide 'test-chime-tooltip-day-calculation) ;;; test-chime-tooltip-day-calculation.el ends here |
