a42a5c0d

By: Tom Sydney Kerckhove <syd@cs-syd.eu>

ical-recurrence: reconcile the components that share a UID

An overriding component now replaces the instance its RECURRENCE-ID names
instead of appearing as an extra occurrence beside it, which is what the
previous commit's test asked for.

Within a UID group the component without a RECURRENCE-ID is the series and
each component with one replaces the instance it names.  Matching is an
exact comparison of the property value against the generated instance's
start, which is what section 3.8.4.4 makes possible:

@
This property MUST have the same
value type as the "DTSTART" property contained within the
recurring component.  Furthermore, this property MUST be specified
as a date with local time if and only if the "DTSTART" property
contained within the recurring component is specified as a date
with local time.
@

so a RECURRENCE-ID that matches none of them exactly is non-conforming
input rather than a near miss to be resolved.  The RANGE parameter is not
part of the value, and RANGE=THISANDFUTURE is not handled yet.

Three fixable errors for the cases the spec does not define, each keeping
what the calendar said rather than dropping it:

* RecurrenceIdentifierUnmatched, for an override that names no instance
  the series generates.  It contributes its own instance.
* RecurrenceIdentifierDuplicate, for two overrides of one instance at the
  same SEQUENCE.  A higher SEQUENCE is the later revision and wins
  outright; a tie contradicts that, so 'Ord' settles it rather than the
  order the components happen to appear in the file, following the
  colliding-observances precedent.
* RecurrenceMultipleSeries, for two components of one UID with no
  RECURRENCE-ID between them.  Both are expanded.

A fixable error must halt a conforming run and succeed leniently, and
these are the errors that only a group of components can have, so they
need a whole calendar rather than the single component that
test_resources/event/fixable holds.  Hence test_resources/calendar/fixable,
with the same two tests per file.  'scenarioDir' does not recur into
subdirectories, so test_resources/calendar does not also pick them up.

Each of those four goldens was derived by hand rather than generated, and
each fixture's overriding component starts at a different time from the
instance it replaces, so the golden shows which component won without the
format having to name it.

Every pre-existing .occ and .res golden is still byte-identical.

Suite timing

Time to Start Worker time Duration Time to finish Idle
Config 0s 1s 1s 1s 0s
Eval 1s 10s 10s 11s 0s
Build 11s 1m14s 1m14s 1m25s 0s
Suite 0s 1m26s 1m25s 1m25s 0s

Timeline

0s10s20s30s40s50s1m1m10s1m20s