From 6abc243e5d40bd60174a3fb1affc9517b0ac5617 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Wed, 19 Aug 2026 09:09:36 +0200 Subject: feat(render): iCalendar emitter, RFC 5545 Not a template job: folding, escaping, exclusive DTEND and stable UIDs are rules a logic-less template cannot enforce, and each fails silently in a subscriber's client rather than loudly at generation. DTEND is EXCLUSIVE for an all-day event (section 3.6.1). Wrong here shows every event a day short, everywhere. UIDs are YYYYMMDD-@colitur and stable across regenerations (section 3.8.4.7). Wrong here duplicates the whole year in every subscriber's phone, months later. Every line is CRLF-terminated and folded at 75 octets (section 3.1). No RRULE: a liturgical calendar is not a recurrence rule. Asserted, so nobody optimises it later. DTSTAMP is a parameter, not a clock read. RFC 5545 requires it and the obvious implementation reads the wall clock -- which violates the kernel's determinism rule and would make two feeds from identical data differ byte-for-byte, defeating reproducible builds and any reviewable diff on a published tree. Corrected one test literal against real engine output: DTSTAMP is a per-VEVENT property (section 3.8.7.2), not calendar-level, so the default-value line count is 365 (every event), not 1. Mutation-tested: a non-exclusive DTEND reddens the suite. --- test/test_colitur.ml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'test/test_colitur.ml') diff --git a/test/test_colitur.ml b/test/test_colitur.ml index ca61415..d4ba6d3 100644 --- a/test/test_colitur.ml +++ b/test/test_colitur.ml @@ -12,4 +12,5 @@ let () = Test_template.render_suite; Test_view.suite; Test_emit.suite; - Test_emit.xml_suite ] + Test_emit.xml_suite; + Test_ics.suite ] -- cgit v1.3