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
|