events: per-occurrence overrides / reschedule (RECURRENCE-ID) + 6 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 41s

ev-with-override re-times/re-sizes a single instance of a series (keyed by
original start). ev-expand applies overrides after EXDATE/RDATE: agenda
re-sorts, instance moved out of window is dropped (slot vacated), no-op for a
non-occurring start. assoc for immutable event update. 254/254 green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-07 06:52:02 +00:00
parent 48f5b75cc2
commit b308effb9f
5 changed files with 121 additions and 13 deletions

View File

@@ -530,6 +530,54 @@
(len (ev-expand plain (ev-date 2026 6 1) (ev-date 2026 7 1)))
3)))))
;; ---- per-occurrence overrides (reschedule one instance) ----
(define
ev-cal-ov-run-all!
(fn
()
(let
((base (ev-event (quote standup) (ev-dt 2026 6 1 9 0) 30 {:freq :daily :count 4} 1)))
(do
;; reschedule one instance to a new time + duration
(let
((moved (ev-with-override base (ev-dt 2026 6 2 9 0) (ev-dt 2026 6 2 14 0) 45)))
(let
((occs (ev-expand moved (ev-date 2026 6 1) (ev-date 2026 6 5))))
(do
(ev-cal-check!
"override moves only the targeted instance"
(map (fn (o) (ev-dt-tod (get o :start))) occs)
(list 540 840 540 540))
(ev-cal-check!
"override applies the new duration"
(map (fn (o) (- (get o :end) (get o :start))) occs)
(list 30 45 30 30))
(ev-cal-check!
"override keeps the series length"
(len occs)
4))))
;; an instance moved out of the window vacates its slot
(let
((movedout (ev-with-override base (ev-dt 2026 6 2 9 0) (ev-dt 2026 6 20 9 0) 30)))
(ev-cal-check!
"instance moved out of window is dropped, slot vacated"
(ev-cal-starts (ev-expand movedout (ev-date 2026 6 1) (ev-date 2026 6 5)))
(list (list 2026 6 1) (list 2026 6 3) (list 2026 6 4))))
;; override for a non-existent original start is a no-op
(let
((noop (ev-with-override base (ev-dt 2026 6 9 9 0) (ev-dt 2026 6 9 14 0) 45)))
(ev-cal-check!
"override for a non-occurring start is a no-op"
(len (ev-expand noop (ev-date 2026 6 1) (ev-date 2026 6 5)))
4))
;; overrides re-sort the agenda when an instance moves earlier
(let
((early (ev-with-override base (ev-dt 2026 6 3 9 0) (ev-dt 2026 6 1 7 0) 30)))
(ev-cal-check!
"an instance moved earlier re-sorts into place"
(map (fn (o) (ev-dt-tod (get o :start))) (ev-expand early (ev-date 2026 6 1) (ev-date 2026 6 5)))
(list 420 540 540 540)))))))
(define
ev-calendar-tests-run!
(fn
@@ -540,4 +588,5 @@
(set! ev-cal-failures (list))
(ev-cal-run-all!)
(ev-cal-ex-run-all!)
(ev-cal-ov-run-all!)
{:failures ev-cal-failures :total (+ ev-cal-pass ev-cal-fail) :passed ev-cal-pass :failed ev-cal-fail})))