From 4f5c2d6845db2f418761525fba32eb5beaa040f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B8=D0=BB=D1=8F=D0=BD=20=D0=9F=D0=B0=D0=BB=D0=B0?= =?UTF-8?q?=D1=83=D0=B7=D0=BE=D0=B2?= Date: Fri, 16 Sep 2022 17:51:09 +0300 Subject: [PATCH] recur_expansion.js: fix iterator with RDATE-only recurrence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When iterating with e is an event-component if (e.isRecurring() { let i = e.iterator(); while (n = i.next()) { o = g.getOccurrenceDetails(obj) … } } on the first iteration the DTSTART instance shall be returned. It is returned, when there is RRULE. In the lack of this change, on the first iteration, when RDATE is present without RRULE, the first RDATE instance is returned. --- lib/ical/recur_expansion.js | 17 ++++++++++++----- test/recur_expansion_test.js | 23 +++++++++++++++++++++++ 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/lib/ical/recur_expansion.js b/lib/ical/recur_expansion.js index 903906df..7222a4a7 100644 --- a/lib/ical/recur_expansion.js +++ b/lib/ical/recur_expansion.js @@ -121,7 +121,7 @@ ICAL.RecurExpansion = (function() { * @type {Number} * @private */ - ruleDateInc: 0, + ruleDateInc: -1, /** * Current position in exDates array @@ -241,6 +241,14 @@ ICAL.RecurExpansion = (function() { // _after_ we choose a value this should be // the only spot where we need to worry about the // end of events. + if (this.ruleDateInc == -1) { + this._nextRuleDay(); + if (!iter) { + // on the first iteration return DTSTART + return this.last; + } + } + if (!next && !iter) { // there are no more iterators or rdates this.complete = true; @@ -278,7 +286,7 @@ ICAL.RecurExpansion = (function() { } //XXX: The spec states that after we resolve the final - // list of dates we execute exdate this seems somewhat counter + // list of dates we execute exdate. This seems somewhat counter // intuitive to what I have seen most servers do so for now // I exclude based on the original date not the one that may // have been modified by the exception. @@ -384,15 +392,14 @@ ICAL.RecurExpansion = (function() { this.ruleDateInc = 0; this.last = this.ruleDates[0].clone(); + this.ruleDate = this.ruleDates[0]; } else { this.ruleDateInc = ICAL.helpers.binsearchInsert( this.ruleDates, this.last, compareTime - ); + ) - 1; } - - this.ruleDate = this.ruleDates[this.ruleDateInc]; } if (component.hasProperty('rrule')) { diff --git a/test/recur_expansion_test.js b/test/recur_expansion_test.js index 877c5656..3dfcacab 100644 --- a/test/recur_expansion_test.js +++ b/test/recur_expansion_test.js @@ -61,6 +61,29 @@ suite('recur_expansion', function() { }, ".ruleIterators or .component must be given"); }); + test('only rdate without rrule', function() { + var component = primary.component.toJSON(); + component = new ICAL.Component(component); + component.removeAllProperties('rrule'); + + var subject = new ICAL.RecurExpansion({ + component, + dtstart: primary.startDate + }); + var expected = [ + new Date(2012, 09, 02, 10), + new Date(2012, 10, 05, 10), + new Date(2012, 10, 10, 10), + new Date(2012, 10, 30, 10) + ], dates = [], next; + + while (next = subject.next() ) { + dates.push(next.toJSDate()); + } + + assert.deepEqual(dates, expected); + }); + test('default', function() { var dtstart = ICAL.Time.fromData({ year: 2012,