Parsing goes through icalendar's low-level parser, which keeps properties in order and keeps repeated ones. Writing is ours: that crate's writer escapes a whole property value as text, so CATEGORIES:Work,Personal would go out as one category named "Work,Personal" to every other client. Anything the model does not interpret is carried rather than dropped -- X-MOZ-LASTACK, X-EVOLUTION-ALARM-UID, ACKNOWLEDGED, the X-MICROSOFT-CDO set, unrecognised ATTENDEE parameters, and whole VTODO/VJOURNAL components. A calendar has several clients writing to it and this one is not the authority on which properties matter. VTIMEZONE is modelled properly, and TZID is stored exactly as written: Exchange names its zones "Pacific Standard Time", which no IANA lookup resolves, and normalising at parse time would make the document unrepresentable. Mapping to a real zone belongs at the point of use. Tested against a golden corpus captured from the live Baikal (seven producing clients over five years) and a published Outlook feed, scrubbed of private content with the structure left byte-for-byte. Eight hand-written fixtures cover what neither server had: DURATION, floating times, RDATE, DST boundaries, leap day, and the full escape set. The contract is that parse -> write -> parse is stable, plus a check that no property name loses occurrences across the trip, since a parser that dropped ATTENDEE entirely would round-trip perfectly and still be wrong.
3.4 KiB
Golden-file corpus
Every file here is real iCalendar data unless it sits under synthetic/. The point of the corpus
is that runway-core is tested against what servers and clients actually emit, not against what
the RFC says they should.
The contract each file must satisfy is in tests/ical.rs: parse → serialise → parse must be
stable, and the second parse must equal the first. A file that cannot round-trip is a bug in the
parser or the writer, never a reason to edit the file.
Provenance
baikal/ — captured from a live Baikal (SabreDAV) server holding six calendars written by seven
different clients over five years. One file per CalDAV resource, exactly as the server returned it
in a calendar-query REPORT.
| File | What it covers |
|---|---|
davx5-allday-weekly-alarm.ics |
VALUE=DATE all-day series, RRULE, one VALARM |
davx5-zoned-two-alarms-vtimezone.ics |
TZID=America/New_York, two VALARMs, VTIMEZONE emitted after the VEVENT |
evolution-x-lic-error.ics |
X-LIC-ERROR baked in by libical, ACKNOWLEDGED, X-EVOLUTION-ALARM-UID, TRIGGER;RELATED=START |
thunderbird-google-invite-attendees.ics |
three ATTENDEEs with CUTYPE/PARTSTAT/X-NUM-GUESTS, RRULE with COUNT, Europe/Zurich |
thunderbird-x-moz-props.ics |
X-MOZ-GENERATION, X-MOZ-LASTACK — vendor state that must survive a round-trip |
outlook-invite-quoted-cn.ics |
ORGANIZER/ATTENDEE with a quoted CN containing a comma, LANGUAGE parameters, X-MICROSOFT-CDO-* |
runway-v1-unfolded-line.ics |
v1's own broken output, still stored on the server: a 248-octet unfolded DESCRIPTION (RFC violation) and CREATED with no Z |
outlook/ — captured from a published Outlook/Exchange .ics feed (252 events, 103 UIDs), trimmed
to seven components that carry the interesting structure.
| Covers |
|---|
Windows timezone names (TZID=Pacific Standard Time), not IANA — with the matching VTIMEZONE definitions, whose DTSTART:16010101T020000 is year 1601 |
A master with four RECURRENCE-ID overrides, one of which moves the occurrence to a different day |
An orphan override: a RECURRENCE-ID whose master lies outside the feed window and must still render |
EXDATE with many comma-separated values on one line |
METHOD:PUBLISH, X-WR-CALNAME, and the full X-MICROSOFT-* set |
synthetic/ — hand-authored, because nothing in the real corpus exercises these: DURATION
instead of DTEND, floating (zoneless) times, RDATE on an event, a CalDAV resource bundling a
master with its override, a DST spring-forward series, a leap-day series, and the complete set of
RFC 5545 text escapes with non-ASCII.
Scrubbing
The real files have been scrubbed. Structure is preserved exactly — property names, parameters,
property order, component nesting, every datetime, TZID, RRULE, EXDATE, RECURRENCE-ID,
SEQUENCE and X- property is byte-for-byte what the server sent. Only human-readable content was
replaced: SUMMARY, DESCRIPTION, LOCATION, display names, email addresses and URLs, each with
synthetic text of comparable shape that keeps the RFC 5545 escaping in play. UIDs were replaced by
a stable hash that preserves their original format, so master/override linkage inside a series
still holds.
runway-v1-unfolded-line.ics is deliberately not refolded: its over-long line is the defect
under test.