Fix wrong optimization in yearly recurrence calc

pull/249/head
Francis Lachapelle 2019-01-18 15:16:23 -05:00
parent 0186e6404f
commit ca9f83ec1f
3 changed files with 23 additions and 13 deletions

1
NEWS
View File

@ -8,6 +8,7 @@ Bug fixes
- [web] fixed all-day event dates with different timezone - [web] fixed all-day event dates with different timezone
- [web] fixed display of Bcc header (#4642) - [web] fixed display of Bcc header (#4642)
- [core] ignore transparent events in time conflict validation (#4539) - [core] ignore transparent events in time conflict validation (#4539)
- [core] fixed yearly recurrence calculator when starting from previous year
4.0.5 (2019-01-09) 4.0.5 (2019-01-09)
------------------ ------------------

View File

@ -227,8 +227,9 @@
} }
else else
{ {
// Year was skipped, added 12 months to the counter // Year was skipped, jump to following year
monthDiff += 12; monthDiff += (13 - currentMonth);
currentMonth = 1;
} }
} }

View File

@ -1,8 +1,6 @@
/* TestiCalRecurrenceCalculator.m - this file is part of SOGo /* TestiCalRecurrenceCalculator.m - this file is part of SOGo
* *
* Copyright (C) 2010 Inverse inc. * Copyright (C) 2010-2019 Inverse inc.
*
* Author: Francis Lachapelle <flachapelle@inverse.ca>
* *
* This file is free software; you can redistribute it and/or modify * This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -225,8 +223,16 @@
- (void) test_recurrenceRangesWithinCalendarDateRange_ - (void) test_recurrenceRangesWithinCalendarDateRange_
{ {
NSArray *rules = [NSArray arrayWithObjects: NSArray *rules = [NSArray arrayWithObjects:
[NSArray arrayWithObjects: @"20190104T090000Z",
@"20181201T000000Z",
@"FREQ=YEARLY;COUNT=0;UNTIL=20200123T090000Z;BYMONTH=1;BYDAY=4TH",
@"20190104T090000Z",
@"20190124T090000Z",
@"20200123T090000Z",
nil],
// Every other year on January, February, and March for 10 occurrences // Every other year on January, February, and March for 10 occurrences
[NSArray arrayWithObjects: @"19970310T090000Z", [NSArray arrayWithObjects: @"19970310T090000Z",
@"19970310T090000Z",
@"FREQ=YEARLY;INTERVAL=2;COUNT=10;BYMONTH=1,2,3", @"FREQ=YEARLY;INTERVAL=2;COUNT=10;BYMONTH=1,2,3",
@"19970310T090000Z", @"19970310T090000Z",
@"19990110T090000Z", @"19990110T090000Z",
@ -241,6 +247,7 @@
nil], nil],
// Everyday in January, for 3 years // Everyday in January, for 3 years
[NSArray arrayWithObjects: @"19980101T090000Z", [NSArray arrayWithObjects: @"19980101T090000Z",
@"19980101T090000Z",
@"FREQ=YEARLY;UNTIL=20000131T090000Z;BYMONTH=1;BYDAY=SU,MO,TU,WE,TH,FR,SA", @"FREQ=YEARLY;UNTIL=20000131T090000Z;BYMONTH=1;BYDAY=SU,MO,TU,WE,TH,FR,SA",
// RRULE:FREQ=DAILY;UNTIL=20000131T090000Z;BYMONTH=1 // RRULE:FREQ=DAILY;UNTIL=20000131T090000Z;BYMONTH=1
@"19980101T090000Z", @"19980101T090000Z",
@ -345,7 +352,7 @@
NSEnumerator *rulesList; NSEnumerator *rulesList;
NSArray *currentRule, *occurrences; NSArray *currentRule, *occurrences;
int i, j; int i, j;
NSCalendarDate *startDate, *endDate, *currentOccurrence; NSCalendarDate *startDate, *endDate, *rangeStartDate, *currentOccurrence;
iCalRecurrenceRule *recurrenceRule; iCalRecurrenceRule *recurrenceRule;
iCalRecurrenceCalculator *calculator; iCalRecurrenceCalculator *calculator;
@ -354,29 +361,30 @@
{ {
startDate = [[currentRule objectAtIndex: 0] asCalendarDate]; startDate = [[currentRule objectAtIndex: 0] asCalendarDate];
endDate = [startDate dateByAddingYears: 0 months: 0 days: 0 hours: 1 minutes: 0 seconds: 0]; endDate = [startDate dateByAddingYears: 0 months: 0 days: 0 hours: 1 minutes: 0 seconds: 0];
recurrenceRule = [iCalRecurrenceRule recurrenceRuleWithICalRepresentation: [currentRule objectAtIndex: 1]]; rangeStartDate = [[currentRule objectAtIndex: 1] asCalendarDate];
recurrenceRule = [iCalRecurrenceRule recurrenceRuleWithICalRepresentation: [currentRule objectAtIndex: 2]];
firRange = [NGCalendarDateRange calendarDateRangeWithStartDate: startDate firRange = [NGCalendarDateRange calendarDateRangeWithStartDate: startDate
endDate: endDate]; endDate: endDate];
calculator = [iCalRecurrenceCalculator recurrenceCalculatorForRecurrenceRule: recurrenceRule calculator = [iCalRecurrenceCalculator recurrenceCalculatorForRecurrenceRule: recurrenceRule
withFirstInstanceCalendarDateRange: firRange]; withFirstInstanceCalendarDateRange: firRange];
range = [NGCalendarDateRange calendarDateRangeWithStartDate: startDate range = [NGCalendarDateRange calendarDateRangeWithStartDate: rangeStartDate
endDate: [NSCalendarDate distantFuture]]; endDate: [NSCalendarDate distantFuture]];
occurrences = [calculator recurrenceRangesWithinCalendarDateRange: range]; occurrences = [calculator recurrenceRangesWithinCalendarDateRange: range];
for (i = 2, j = 0; i < [currentRule count] && j < [occurrences count]; i++, j++) for (i = 3, j = 0; i < [currentRule count] && j < [occurrences count]; i++, j++)
{ {
currentOccurrence = [[currentRule objectAtIndex: i] asCalendarDate]; currentOccurrence = [[currentRule objectAtIndex: i] asCalendarDate];
error = [NSString stringWithFormat: @"Invalid occurrence for recurrence rule %@: %@ (expected date was %@)", error = [NSString stringWithFormat: @"Invalid occurrence for recurrence rule %@: %@ (expected date was %@)",
[currentRule objectAtIndex: 1], [currentRule objectAtIndex: 2],
[[[occurrences objectAtIndex: j] startDate] descriptionWithCalendarFormat: dateFormat], [[[occurrences objectAtIndex: j] startDate] descriptionWithCalendarFormat: dateFormat],
[currentOccurrence descriptionWithCalendarFormat: dateFormat]]; [currentOccurrence descriptionWithCalendarFormat: dateFormat]];
testWithMessage([currentOccurrence isDateOnSameDay: [[occurrences objectAtIndex: j] startDate]], error); testWithMessage([currentOccurrence isDateOnSameDay: [[occurrences objectAtIndex: j] startDate]], error);
} }
error = [NSString stringWithFormat: @"Unexpected number of occurrences for recurrence rule %@ (found %ld, expected %ld)", error = [NSString stringWithFormat: @"Unexpected number of occurrences for recurrence rule %@ (found %ld, expected %ld)",
[currentRule objectAtIndex: 1], [currentRule objectAtIndex: 2],
[occurrences count], [occurrences count],
[currentRule count] - 2]; [currentRule count] - 3];
testWithMessage([currentRule count] - [occurrences count] == 2, error); testWithMessage([currentRule count] - [occurrences count] == 3, error);
} }
} }