Skip to content

Commit

Permalink
Migrate usage of IList<PeriodList> to ExceptionDates and `Recurre…
Browse files Browse the repository at this point in the history
…nceDates`

`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()`.
  • Loading branch information
axunonb committed Jan 10, 2025
1 parent 3800f1c commit 3817d85
Show file tree
Hide file tree
Showing 16 changed files with 209 additions and 202 deletions.
15 changes: 7 additions & 8 deletions Ical.Net.Tests/CalendarEventTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -249,29 +249,29 @@ public void RrulesAreSignificantTests()
Assert.That(testRrule.GetHashCode(), Is.Not.EqualTo(simpleEvent.GetHashCode()));

var testRdate = GetSimpleEvent();
testRdate.RecurrenceDates = new List<PeriodList> { new PeriodList { new Period(new CalDateTime(_now)) } };
testRdate.RecurrenceDatesPeriodLists = new List<PeriodList> { new PeriodList { new Period(new CalDateTime(_now)) } };
Assert.That(testRdate, Is.Not.EqualTo(simpleEvent));
Assert.That(testRdate.GetHashCode(), Is.Not.EqualTo(simpleEvent.GetHashCode()));
}

private static List<RecurrencePattern> GetSimpleRecurrenceList()
=> new List<RecurrencePattern> { new RecurrencePattern(FrequencyType.Daily, 1) { Count = 5 } };
private static List<PeriodList> GetExceptionDates()
=> new List<PeriodList> { new PeriodList { new Period(new CalDateTime(_now.AddDays(1).Date)) } };
private static List<IDateTime> GetExceptionDates()
=> new List<IDateTime> { new CalDateTime(_now.AddDays(1).Date) };

[Test]
public void EventWithRecurrenceAndExceptionComparison()
{
var vEvent = GetSimpleEvent();
vEvent.RecurrenceRules = GetSimpleRecurrenceList();
vEvent.ExceptionDates = GetExceptionDates();
vEvent.ExceptionDates.AddRange(GetExceptionDates());

var calendar = new Calendar();
calendar.Events.Add(vEvent);

var vEvent2 = GetSimpleEvent();
vEvent2.RecurrenceRules = GetSimpleRecurrenceList();
vEvent2.ExceptionDates = GetExceptionDates();
vEvent2.ExceptionDates.AddRange(GetExceptionDates());

var cal2 = new Calendar();
cal2.Events.Add(vEvent2);
Expand All @@ -283,8 +283,7 @@ public void EventWithRecurrenceAndExceptionComparison()
{
Assert.That(eventB.RecurrenceRules.First(), Is.EqualTo(eventA.RecurrenceRules.First()));
Assert.That(eventB.RecurrenceRules.First().GetHashCode(), Is.EqualTo(eventA.RecurrenceRules.First().GetHashCode()));
Assert.That(eventB.ExceptionDates.First(), Is.EqualTo(eventA.ExceptionDates.First()));
Assert.That(eventB.ExceptionDates.First().GetHashCode(), Is.EqualTo(eventA.ExceptionDates.First().GetHashCode()));
Assert.That(eventB.ExceptionDates.GetAllDates().First(), Is.EqualTo(eventA.ExceptionDates.GetAllDates().First()));
Assert.That(eventB.GetHashCode(), Is.EqualTo(eventA.GetHashCode()));
Assert.That(eventB, Is.EqualTo(eventA));
Assert.That(cal2, Is.EqualTo(calendar));
Expand All @@ -309,7 +308,7 @@ public void AddingExdateToEventShouldNotBeEqualToOriginal()
var deserializedNoExDate = Calendar.Load(serialized);
Assert.That(deserializedNoExDate, Is.EqualTo(cal1));

vEvent.ExceptionDates = GetExceptionDates();
vEvent.ExceptionDates.AddRange(GetExceptionDates());
serialized = serializer.SerializeToString(cal1);
var deserializedWithExDate = Calendar.Load(serialized);

Expand Down
129 changes: 76 additions & 53 deletions Ical.Net.Tests/DeserializationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -267,36 +267,37 @@ public void Encoding3()
[Test]
public void Event8()
{
var sr = @"BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Apple Computer\, Inc//iCal 1.0//EN
CALSCALE:GREGORIAN
BEGIN:VEVENT
CREATED:20070404T211714Z
DTEND:20070407T010000Z
DTSTAMP:20070404T211714Z
DTSTART:20070406T230000Z
DURATION:PT2H
RRULE:FREQ=WEEKLY;UNTIL=20070801T070000Z;BYDAY=FR
SUMMARY:Friday Meetings
DTSTAMP:20040103T033800Z
SEQUENCE:1
UID:fd940618-45e2-4d19-b118-37fd7a8e3906
END:VEVENT
BEGIN:VEVENT
CREATED:20070404T204310Z
DTEND:20070416T030000Z
DTSTAMP:20070404T204310Z
DTSTART:20070414T200000Z
DURATION:P1DT7H
RRULE:FREQ=DAILY;COUNT=12;BYDAY=SA,SU
SUMMARY:Weekend Yea!
DTSTAMP:20040103T033800Z
SEQUENCE:1
UID:ebfbd3e3-cc1e-4a64-98eb-ced2598b3908
END:VEVENT
END:VCALENDAR
";
var sr = """
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Apple Computer\, Inc//iCal 1.0//EN
CALSCALE:GREGORIAN
BEGIN:VEVENT
CREATED:20070404T211714Z
DTEND:20070407T010000Z
DTSTAMP:20070404T211714Z
DTSTART:20070406T230000Z
DURATION:PT2H
RRULE:FREQ=WEEKLY;UNTIL=20070801T070000Z;BYDAY=FR
SUMMARY:Friday Meetings
DTSTAMP:20040103T033800Z
SEQUENCE:1
UID:fd940618-45e2-4d19-b118-37fd7a8e3906
END:VEVENT
BEGIN:VEVENT
CREATED:20070404T204310Z
DTEND:20070416T030000Z
DTSTAMP:20070404T204310Z
DTSTART:20070414T200000Z
DURATION:P1DT7H
RRULE:FREQ=DAILY;COUNT=12;BYDAY=SA,SU
SUMMARY:Weekend Yea!
DTSTAMP:20040103T033800Z
SEQUENCE:1
UID:ebfbd3e3-cc1e-4a64-98eb-ced2598b3908
END:VEVENT
END:VCALENDAR
""";
var iCal = Calendar.Load(sr);
Assert.That(iCal.Events.Count == 2, Is.True, "There should be 2 events in the parsed calendar");
Assert.That(iCal.Events["fd940618-45e2-4d19-b118-37fd7a8e3906"], Is.Not.Null, "Event fd940618-45e2-4d19-b118-37fd7a8e3906 should exist in the calendar");
Expand Down Expand Up @@ -351,25 +352,46 @@ public void Google1()
public void RecurrenceDates1()
{
var iCal = Calendar.Load(IcsFiles.RecurrenceDates1);
Assert.That(iCal.Events, Has.Count.EqualTo(1));
Assert.That(iCal.Events.First().RecurrenceDates, Has.Count.EqualTo(3));

var expectedStartTimes = new List<CalDateTime>
{
// date are unique
new CalDateTime(1997, 7, 14, 12, 30, 0, CalDateTime.UtcTzId),
new CalDateTime(1996, 4, 3, 2, 0, 0, CalDateTime.UtcTzId),
new CalDateTime(1996, 4, 4, 1, 0, 0, CalDateTime.UtcTzId),
new CalDateTime(1997, 1, 1),
new CalDateTime(1997, 1, 20),
new CalDateTime(1997, 2, 17),
new CalDateTime(1997, 4, 21),
new CalDateTime(1997, 5, 26),
new CalDateTime(1997, 7, 4),
new CalDateTime(1997, 9, 1),
new CalDateTime(1997, 10, 14),
new CalDateTime(1997, 11, 28),
new CalDateTime(1997, 11, 29),
new CalDateTime(1997, 12, 25)
};

var expectedEndTime = new CalDateTime(new DateTime(1996, 4, 3, 4, 0, 0, DateTimeKind.Utc));

var actualStartTimes = iCal.Events[0].RecurrenceDates.GetAllPeriods()
.Select(p => p.StartTime)
.Union(iCal.Events[0].RecurrenceDates.GetAllDates())
.ToList();

Assert.Multiple(() =>
{
Assert.That(iCal.Events.First().RecurrenceDates[0][0].StartTime, Is.EqualTo((CalDateTime)new DateTime(1997, 7, 14, 12, 30, 0, DateTimeKind.Utc)));
Assert.That(iCal.Events.First().RecurrenceDates[1][0].StartTime, Is.EqualTo((CalDateTime)new DateTime(1996, 4, 3, 2, 0, 0, DateTimeKind.Utc)));
Assert.That(iCal.Events.First().RecurrenceDates[1][0].EndTime, Is.EqualTo((CalDateTime)new DateTime(1996, 4, 3, 4, 0, 0, DateTimeKind.Utc)));
Assert.That(iCal.Events.First().RecurrenceDates[2][0].StartTime, Is.EqualTo(new CalDateTime(1997, 1, 1)));
Assert.That(iCal.Events.First().RecurrenceDates[2][1].StartTime, Is.EqualTo(new CalDateTime(1997, 1, 20)));
Assert.That(iCal.Events.First().RecurrenceDates[2][2].StartTime, Is.EqualTo(new CalDateTime(1997, 2, 17)));
Assert.That(iCal.Events.First().RecurrenceDates[2][3].StartTime, Is.EqualTo(new CalDateTime(1997, 4, 21)));
Assert.That(iCal.Events.First().RecurrenceDates[2][4].StartTime, Is.EqualTo(new CalDateTime(1997, 5, 26)));
Assert.That(iCal.Events.First().RecurrenceDates[2][5].StartTime, Is.EqualTo(new CalDateTime(1997, 7, 4)));
Assert.That(iCal.Events.First().RecurrenceDates[2][6].StartTime, Is.EqualTo(new CalDateTime(1997, 9, 1)));
Assert.That(iCal.Events.First().RecurrenceDates[2][7].StartTime, Is.EqualTo(new CalDateTime(1997, 10, 14)));
Assert.That(iCal.Events.First().RecurrenceDates[2][8].StartTime, Is.EqualTo(new CalDateTime(1997, 11, 28)));
Assert.That(iCal.Events.First().RecurrenceDates[2][9].StartTime, Is.EqualTo(new CalDateTime(1997, 11, 29)));
Assert.That(iCal.Events.First().RecurrenceDates[2][10].StartTime, Is.EqualTo(new CalDateTime(1997, 12, 25)));
Assert.That(iCal.Events, Has.Count.EqualTo(1));
Assert.That(iCal.Events[0].RecurrenceDatesPeriodLists, Has.Count.EqualTo(3));
Assert.That(actualStartTimes, Has.Count.EqualTo(expectedStartTimes.Count));

foreach (var date in expectedStartTimes)
{
Assert.That(actualStartTimes.Single(dt => dt.Equals(date)),
Is.EqualTo(date), "Should contain " + date);
}

Assert.That(iCal.Events[0].RecurrenceDates.Contains(new Period(expectedStartTimes[1], expectedEndTime)));
});
}

Expand Down Expand Up @@ -549,13 +571,14 @@ public void Property1()
[TestCase(false)]
public void KeepApartDtEndAndDuration_Tests(bool useDtEnd)
{
var calStr = $@"BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART:20070406T230000Z
{(useDtEnd ? "DTEND:20070407T010000Z" : "DURATION:PT1H")}
END:VEVENT
END:VCALENDAR
";
var calStr = $"""
BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART:20070406T230000Z
{(useDtEnd ? "DTEND:20070407T010000Z" : "DURATION:PT1H")}
END:VEVENT
END:VCALENDAR
""";

var calendar = Calendar.Load(calStr);

Expand Down
Loading

0 comments on commit 3817d85

Please sign in to comment.