Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Fix `Period` and `PeriodList` to work with `EXDATE` and `RDATE` Improve reliability and usability for `Period` and `PeriodList` to become less error-prone by enforcing timezones being used consistently Period - Make parameterless CTOR `internal` to ensure proper initialization by users - A period can be defined 1. by a start time and an end time, 2. by a start time and a duration, 3. by a start time only, with the duration unspecified. This is for EXDATE and RDATE date-only and date/time. - For cosistency, either the `EndTime` or the `Duration` can be set at a time. The last one set with a value not `null` will prevail, while the other will become `null`. - Timezones of `StartTime`and (optional) `EndTime` must be the same - `CompareTo` uses `AsUtc` for comparing the `StartTime` - Remove returning a "magic" duration of 1 day, if `EndTime` is null and `StartTime` is date-only. This broke `EXDATE` and `RDATE` of an event, when the only a start time exists. - Added `EffectiveEndTime` and `EffectiveDuration` properties to provide calculated values based on the set values. - Update the `EndTime` and `Duration` properties to directly return the set values. - Change the access modifiers of `GetEffectiveDuration()` and `GetEffectiveEndTime` methods from internal to private. PeriodList - `TzId`: `public` setter changed to `private` - `EnsureConsistentTimezones`: The first period determines the timezone of the `PeriodList` and all other `Period`s added must have the same timezone - Add `SetService(new PeriodListEvaluator(this))` for `StringReader` CTOR overload - Add `static PeriodList FromStringReader(StringReader)` - Add `static PeriodList FromDateTime(IDateTime)` - Add `PeriodList AddPeriod(Period)` for chaining - Add `PeriodList Add(IDateTime)` for chaining - nullable enable EventEvaluator: - `EventEvaluator.WithEndTime(Period)` only sets the `EndTime`, as `Period.EffectiveDuration` returns the duration. TodoEvaluator: - Remove method `PeriodWithDuration(Period)` as it became redudant with the refactored `Period` class. DataTypeSerializer and other serializers, CalendarObjectBase: - `Activator.CreateInstance(TargetType, true)` allows for not `public` CTORs, so that parameterless CTORs can be excluded from the public API, if proper initialization can't be assured (like with `Period`). PropertySerializer: - TBD: Never set the UTC timezone ID (use appending 'Z') - Resolves #590 - Resolves #591 - Resolves #614 - Resolves #676 * Add unit tests to `RecurrenceWithRDateTests` * Insert values about failure to Exception.Messages * Correct handling of iCalendar PERIOD PeriodKind - Add new enum Period: - Add internal `property string TzId` - Add internal method `PeriodKind GetPeriodKind()` - Ensure timeone consistence for setters of StartTime / EndTime PeriodList: - Add internal `property string TzId` - Add internal property ``PeriodKind PeriodListKind`m - Ensure added `Period`s have the same `TzId`and `PeriodKind` as the first one added PeriodListSerialilzer - Serializes TZID - Serializes value type PERIOD * Add abstraction layer to create EXDATE and RDATE - Introduced `ExceptionDateCollection`, `RecurrencePeriodCollection` and PeriodCollectionBase` classes. - Updated serializers to handle the modified `PeriodList` implementation. These classes are an abstraction layer for creating `List<PeriodList>` objects. `Period`s and `CalDateTime`s are accepted without having to care for RFC 5545 rules regarding serialization: `ToRecurrenceDates` and `ToRecurrenceDates` methods aggregate and convert the exception or recurrence `CalDateTime` and `Period` objects into a list of `PeriodList` objects. Periods are grouped by their timezone IDs and period kinds in a way, that each `PeriodList` contains only distinct periods ready to serialize. * `Period` StartTime, EndTime and Duration properties are immutable - Adjust code in ' EventEvaluator` and `PeriodSerializer` - Method `GetPeriodKind()` is replace with internal property `PeriodKind` - Add internal `Period.Create` to centralize logic if end time and duration exist - Modified unit test * Remove source and test files related to RDATE/EXDATEcollections Remove solution for RDATE/ESDATE introduced earlier in this PE The commit removes several test and source files related to period and exception date collections in calendar events. Specifically, the following files have been completely removed: - `PeriodCollectionBase.cs` - `ExceptionDateCollection.cs` - `RecurrencePeriodCollection.cs` - `PeriodCollectionTests.cs` - `RecurrenceWithExDateTests.cs` - `RecurrenceWithRDateTests.cs` * Add wrapper classes for `ExceptionDates` and `RecurrenceDates` - Add internal properties `PeriodKind` and `TzId` to `PeriodList`. - Modify `Period` indexer and `Insert` to ensure consistency for timezone and `PeriodKind` - Prepare for `PeriodList` to become `internal` - Update `PeriodListSerializer` and `PeriodSerializer` classes for `Period` serialization - Introduce `ExceptionDates`, `RecurrenceDates`, and `PeriodListWrapperBase` to become wrappers around these properties of `RecurringComponent` - Add unit tests in `PeriodListWrapperTests` for `ExceptionDates` and `RecurrenceDates`. Note: The wrappers are not yet implemented for `IRecurringComponent`s. * Migrate usage of `IList<PeriodList>` to `ExceptionDates` and `RecurrenceDates` `IRecurrable` - Change the type of `ExceptionDates` from `IList<PeriodList>` to `ExceptionDates`. - Change the type of `RecurrenceDates` from `IList<PeriodList>` to `RecurrenceDates`. `RecurringComponent`, `VTimeZoneInfo` - Rename `IList<PeriodList> ExceptionDates` to `ExceptionDatesPeriodLists`. This serves as the backing storage for the new `ExceptionDates` class/property. - Rename `IList<PeriodList> RecurrenceDates` to `RecurrenceDatesPeriodLists`. This serves as the backing storage for the new `RecurrenceDates` class/property. - Add the creation of instances of `ExceptionDates` and `RecurrenceDates` to the `Initialize()` method. `PeriodList` and `PeriodListEvaluator` - Change the access modifier to `internal`. `RecurringEvaluator` and `TodoEvaluator` - Implement the new `ExceptionDates` and `RecurrenceDates` classes. `VTimeZone` - Enhanced serialization: - Before: Each `RDATE` date/time was serialized as a separate `RDATE` propery - Now: `RDATE` date/times which can be clustered go into one single `RDATE` property Unit tests - Refactor tests, using `ExceptionDates` and `RecurrenceDates` instead of `IList<PeriodList>` - Remove the duplicate `SimpleDeserializationTests.RecurrenceDates1()` method, which exists in `DeserializationTests.RecurrenceDates1()`. Todo: - Replace the use of `PeriodList.GetGroupedPeriods` in `CalendarEvent.Equals()`. * Add `PeriodListWrapperBase.GetAllPeriodsByKind` Using this internal method stops recreating `Period`s from `IDateTime` Update comments in PropertySerializer * Replace method `PeriodList.GetGroupedPeriods` - No duplicate `Period` instances can be added or inserted into the `PeriodList`. - `RecurrenceDates.GetAllDates()`, `PeriodListWrapperBase.GetAllDates()` and `PeriodListWrapperBase.GetAllPeriodsByKind` return a flattened and ordered list of distinct objects - Update `CalendarEvent.Equals` and `CalendarEvent.GetHashCode` using `ExceptionDates` and `RecurrenceDates` instead of `PeriodList.GetGroupedPeriods` - Remove `PeriodList.GetGroupedPeriods` * Add EXDATE and RDATE unit tests mentioned in issues * Updates after revview 2025-01-16
- Loading branch information