summaryrefslogtreecommitdiff
path: root/tests/test-calendar-sync--filter-exdates.el
blob: b0f2d6a4567710ddffb2be0f41127b069841a8c9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
;;; test-calendar-sync--filter-exdates.el --- Tests for EXDATE filtering  -*- lexical-binding: t; -*-

;;; Commentary:
;; Unit tests for calendar-sync--filter-exdates function.
;; Tests filtering occurrences list to remove EXDATE matches.
;; 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--filter-exdates-normal-single-match-removes-one ()
  "Test that single matching EXDATE removes one occurrence."
  (let ((occurrences (list (list :start '(2026 2 3 13 0) :summary "Meeting")
                           (list :start '(2026 2 10 13 0) :summary "Meeting")
                           (list :start '(2026 2 17 13 0) :summary "Meeting")))
        (exdates '((2026 2 10 13 0))))
    (let ((result (calendar-sync--filter-exdates occurrences exdates)))
      (should (= 2 (length result)))
      ;; Feb 10 should be removed
      (should-not (cl-find-if (lambda (occ)
                                (equal '(2026 2 10 13 0) (plist-get occ :start)))
                              result))
      ;; Feb 3 and Feb 17 should remain
      (should (cl-find-if (lambda (occ)
                            (equal '(2026 2 3 13 0) (plist-get occ :start)))
                          result))
      (should (cl-find-if (lambda (occ)
                            (equal '(2026 2 17 13 0) (plist-get occ :start)))
                          result)))))

(ert-deftest test-calendar-sync--filter-exdates-normal-multiple-matches-removes-all ()
  "Test that multiple EXDATEs remove all matching occurrences."
  (let ((occurrences (list (list :start '(2026 2 3 13 0) :summary "Meeting")
                           (list :start '(2026 2 10 13 0) :summary "Meeting")
                           (list :start '(2026 2 17 13 0) :summary "Meeting")
                           (list :start '(2026 2 24 13 0) :summary "Meeting")))
        (exdates '((2026 2 10 13 0) (2026 2 24 13 0))))
    (let ((result (calendar-sync--filter-exdates occurrences exdates)))
      (should (= 2 (length result)))
      ;; Feb 10 and Feb 24 should be removed
      (should-not (cl-find-if (lambda (occ)
                                (equal '(2026 2 10 13 0) (plist-get occ :start)))
                              result))
      (should-not (cl-find-if (lambda (occ)
                                (equal '(2026 2 24 13 0) (plist-get occ :start)))
                              result)))))

(ert-deftest test-calendar-sync--filter-exdates-normal-preserves-non-matches ()
  "Test that non-matching occurrences are preserved."
  (let ((occurrences (list (list :start '(2026 2 3 13 0) :summary "Meeting")
                           (list :start '(2026 2 10 13 0) :summary "Meeting")))
        (exdates '((2026 3 15 13 0))))  ; No match
    (let ((result (calendar-sync--filter-exdates occurrences exdates)))
      (should (= 2 (length result)))
      ;; Both should remain
      (should (cl-find-if (lambda (occ)
                            (equal '(2026 2 3 13 0) (plist-get occ :start)))
                          result))
      (should (cl-find-if (lambda (occ)
                            (equal '(2026 2 10 13 0) (plist-get occ :start)))
                          result)))))

;;; Boundary Cases

(ert-deftest test-calendar-sync--filter-exdates-boundary-empty-exdates-returns-all ()
  "Test that empty exdates list returns all occurrences."
  (let ((occurrences (list (list :start '(2026 2 3 13 0) :summary "Meeting")
                           (list :start '(2026 2 10 13 0) :summary "Meeting")))
        (exdates '()))
    (let ((result (calendar-sync--filter-exdates occurrences exdates)))
      (should (= 2 (length result))))))

(ert-deftest test-calendar-sync--filter-exdates-boundary-empty-occurrences-returns-empty ()
  "Test that empty occurrences list returns empty."
  (let ((occurrences '())
        (exdates '((2026 2 10 13 0))))
    (let ((result (calendar-sync--filter-exdates occurrences exdates)))
      (should (= 0 (length result))))))

(ert-deftest test-calendar-sync--filter-exdates-boundary-all-excluded-returns-empty ()
  "Test that when all occurrences are excluded, returns empty."
  (let ((occurrences (list (list :start '(2026 2 3 13 0) :summary "Meeting")
                           (list :start '(2026 2 10 13 0) :summary "Meeting")))
        (exdates '((2026 2 3 13 0) (2026 2 10 13 0))))
    (let ((result (calendar-sync--filter-exdates occurrences exdates)))
      (should (= 0 (length result))))))

(ert-deftest test-calendar-sync--filter-exdates-boundary-date-only-matches-any-time ()
  "Test that date-only EXDATE (nil hour/minute) matches any time on that day."
  (let ((occurrences (list (list :start '(2026 2 3 9 0) :summary "Morning")
                           (list :start '(2026 2 3 13 0) :summary "Afternoon")
                           (list :start '(2026 2 10 13 0) :summary "Next Week")))
        (exdates '((2026 2 3 nil nil))))  ; Date-only exclusion
    (let ((result (calendar-sync--filter-exdates occurrences exdates)))
      ;; Both Feb 3 occurrences should be removed
      (should (= 1 (length result)))
      (should (equal '(2026 2 10 13 0) (plist-get (car result) :start))))))

;;; Error Cases

(ert-deftest test-calendar-sync--filter-exdates-error-nil-occurrences-handles-gracefully ()
  "Test that nil occurrences handles gracefully."
  (let ((result (calendar-sync--filter-exdates nil '((2026 2 10 13 0)))))
    (should (listp result))
    (should (= 0 (length result)))))

(ert-deftest test-calendar-sync--filter-exdates-error-nil-exdates-returns-occurrences ()
  "Test that nil exdates returns original occurrences."
  (let ((occurrences (list (list :start '(2026 2 3 13 0) :summary "Meeting"))))
    (let ((result (calendar-sync--filter-exdates occurrences nil)))
      (should (= 1 (length result))))))

(provide 'test-calendar-sync--filter-exdates)
;;; test-calendar-sync--filter-exdates.el ends here