diff options
Diffstat (limited to 'tests/test-calendar-sync--collect-exdates.el')
| -rw-r--r-- | tests/test-calendar-sync--collect-exdates.el | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/tests/test-calendar-sync--collect-exdates.el b/tests/test-calendar-sync--collect-exdates.el new file mode 100644 index 00000000..b70277e1 --- /dev/null +++ b/tests/test-calendar-sync--collect-exdates.el @@ -0,0 +1,147 @@ +;;; test-calendar-sync--collect-exdates.el --- Tests for EXDATE collection -*- lexical-binding: t; -*- + +;;; Commentary: +;; Unit tests for calendar-sync--collect-exdates function. +;; Tests collection of all excluded dates from an event, handling timezone conversion. +;; Following quality-engineer.org guidelines: one function per file. + +;;; Code: + +(require 'ert) +(add-to-list 'load-path (expand-file-name "." (file-name-directory load-file-name))) +(add-to-list 'load-path (expand-file-name "../modules" (file-name-directory load-file-name))) +(require 'testutil-calendar-sync) +(require 'calendar-sync) + +;;; Normal Cases + +(ert-deftest test-calendar-sync--collect-exdates-normal-single-returns-list () + "Test collecting single EXDATE returns list with one parsed value." + (let ((event "BEGIN:VEVENT +DTSTART:20260203T130000 +RRULE:FREQ=WEEKLY;BYDAY=TU +EXDATE:20260210T130000 +SUMMARY:Weekly Meeting +END:VEVENT")) + (let ((result (calendar-sync--collect-exdates event))) + (should (listp result)) + (should (= 1 (length result))) + (should (equal '(2026 2 10 13 0) (car result)))))) + +(ert-deftest test-calendar-sync--collect-exdates-normal-multiple-returns-all () + "Test collecting multiple EXDATEs returns all parsed values." + (let ((event "BEGIN:VEVENT +DTSTART:20260203T130000 +RRULE:FREQ=WEEKLY;BYDAY=TU +EXDATE:20260210T130000 +EXDATE:20260217T130000 +EXDATE:20260224T130000 +SUMMARY:Weekly Meeting +END:VEVENT")) + (let ((result (calendar-sync--collect-exdates event))) + (should (= 3 (length result))) + (should (member '(2026 2 10 13 0) result)) + (should (member '(2026 2 17 13 0) result)) + (should (member '(2026 2 24 13 0) result))))) + +(ert-deftest test-calendar-sync--collect-exdates-normal-tzid-converts-to-local () + "Test that TZID-qualified EXDATEs are converted to local time." + ;; Use a timezone different from local to verify conversion + ;; We'll use Europe/London and check that conversion happens + (let ((event "BEGIN:VEVENT +DTSTART;TZID=Europe/London:20260203T130000 +RRULE:FREQ=WEEKLY;BYDAY=TU +EXDATE;TZID=Europe/London:20260210T130000 +SUMMARY:London Meeting +END:VEVENT")) + (let ((result (calendar-sync--collect-exdates event))) + (should (= 1 (length result))) + ;; Result should be a valid datetime list (conversion may differ based on local TZ) + (let ((parsed (car result))) + (should (= 5 (length parsed))) + (should (numberp (nth 0 parsed))) ; year + (should (numberp (nth 1 parsed))) ; month + (should (numberp (nth 2 parsed))) ; day + (should (numberp (nth 3 parsed))) ; hour + (should (numberp (nth 4 parsed))))))) ; minute + +;;; Boundary Cases + +(ert-deftest test-calendar-sync--collect-exdates-boundary-no-exdates-returns-empty () + "Test that event without EXDATE returns empty list." + (let ((event "BEGIN:VEVENT +DTSTART:20260203T130000 +RRULE:FREQ=WEEKLY;BYDAY=TU +SUMMARY:Weekly Meeting +END:VEVENT")) + (let ((result (calendar-sync--collect-exdates event))) + (should (listp result)) + (should (= 0 (length result)))))) + +(ert-deftest test-calendar-sync--collect-exdates-boundary-utc-converts-to-local () + "Test that UTC (Z suffix) EXDATEs are converted to local time." + (let ((event "BEGIN:VEVENT +DTSTART:20260203T180000Z +RRULE:FREQ=WEEKLY;BYDAY=TU +EXDATE:20260210T180000Z +SUMMARY:UTC Meeting +END:VEVENT")) + (let ((result (calendar-sync--collect-exdates event))) + (should (= 1 (length result))) + ;; Result should be converted to local time + (let ((parsed (car result))) + (should (= 5 (length parsed))) + ;; Date should be valid + (should (numberp (nth 0 parsed))))))) + +(ert-deftest test-calendar-sync--collect-exdates-boundary-mixed-formats-handles-all () + "Test handling mix of TZID, UTC, and local time EXDATEs." + (let ((event "BEGIN:VEVENT +DTSTART:20260203T130000 +RRULE:FREQ=WEEKLY;BYDAY=TU +EXDATE:20260210T130000 +EXDATE:20260217T180000Z +SUMMARY:Mixed Meeting +END:VEVENT")) + (let ((result (calendar-sync--collect-exdates event))) + (should (= 2 (length result))) + ;; Both should be valid parsed datetimes + (dolist (parsed result) + (should (= 5 (length parsed))) + (should (numberp (nth 0 parsed))))))) + +(ert-deftest test-calendar-sync--collect-exdates-boundary-date-only-returns-date () + "Test collecting all-day EXDATE returns date with nil for time." + (let ((event "BEGIN:VEVENT +DTSTART;VALUE=DATE:20260203 +RRULE:FREQ=WEEKLY;BYDAY=TU +EXDATE;VALUE=DATE:20260210 +SUMMARY:All Day Event +END:VEVENT")) + (let ((result (calendar-sync--collect-exdates event))) + (should (= 1 (length result))) + (let ((parsed (car result))) + (should (equal '(2026 2 10 nil nil) parsed)))))) + +;;; Error Cases + +(ert-deftest test-calendar-sync--collect-exdates-error-empty-string-returns-empty () + "Test that empty string returns empty list." + (let ((result (calendar-sync--collect-exdates ""))) + (should (listp result)) + (should (= 0 (length result))))) + +(ert-deftest test-calendar-sync--collect-exdates-error-nil-returns-empty () + "Test that nil input returns empty list." + (let ((result (calendar-sync--collect-exdates nil))) + (should (listp result)) + (should (= 0 (length result))))) + +(ert-deftest test-calendar-sync--collect-exdates-error-malformed-returns-empty () + "Test that malformed event returns empty list." + (let ((result (calendar-sync--collect-exdates "not a vevent"))) + (should (listp result)) + (should (= 0 (length result))))) + +(provide 'test-calendar-sync--collect-exdates) +;;; test-calendar-sync--collect-exdates.el ends here |
