]> git.mxchange.org Git - friendica-addons.git/blob - dav/SabreDAV/tests/Sabre/VObject/RecurrenceIteratorTest.php
d1ef2da6048efd7ce7b8f6e9d43fbc8d9352dce3
[friendica-addons.git] / dav / SabreDAV / tests / Sabre / VObject / RecurrenceIteratorTest.php
1 <?php
2
3 class Sabre_VObject_RecurrenceIteratorTest extends PHPUnit_Framework_TestCase {
4
5     function testValues() {
6
7         $ev = new Sabre_VObject_Component('VEVENT');
8         $ev->UID = 'bla';
9         $ev->RRULE = 'FREQ=DAILY;BYHOUR=10;BYMINUTE=5;BYSECOND=16;BYWEEKNO=32;BYYEARDAY=100,200';
10         $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
11         $dtStart->setDateTime(new DateTime('2011-10-07'),Sabre_VObject_Property_DateTime::UTC);
12
13         $ev->add($dtStart);
14
15         $vcal = Sabre_VObject_Component::create('VCALENDAR');
16         $vcal->add($ev);
17
18         $it = new Sabre_VObject_RecurrenceIterator($vcal,(string)$ev->uid);
19
20         $this->assertEquals(array(10), $it->byHour);
21         $this->assertEquals(array(5), $it->byMinute);
22         $this->assertEquals(array(16), $it->bySecond);
23         $this->assertEquals(array(32), $it->byWeekNo);
24         $this->assertEquals(array(100,200), $it->byYearDay);
25
26     }
27
28     /**
29      * @expectedException InvalidArgumentException
30      * @depends testValues
31      */
32     function testInvalidFreq() {
33
34         $ev = new Sabre_VObject_Component('VEVENT');
35         $ev->RRULE = 'FREQ=SMONTHLY;INTERVAL=3;UNTIL=20111025T000000Z';
36         $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
37         $dtStart->setDateTime(new DateTime('2011-10-07'),Sabre_VObject_Property_DateTime::UTC);
38
39         $ev->add($dtStart);
40
41         $vcal = Sabre_VObject_Component::create('VCALENDAR');
42         $vcal->add($ev);
43
44         $it = new Sabre_VObject_RecurrenceIterator($vcal,(string)$ev->uid);
45
46     }
47
48     /**
49      * @expectedException InvalidArgumentException
50      */
51     function testVCalendarNoUID() {
52
53         $vcal = new Sabre_VObject_Component('VCALENDAR');
54         $it = new Sabre_VObject_RecurrenceIterator($vcal);
55
56     }
57
58     /**
59      * @expectedException InvalidArgumentException
60      */
61     function testVCalendarInvalidUID() {
62
63         $vcal = new Sabre_VObject_Component('VCALENDAR');
64         $it = new Sabre_VObject_RecurrenceIterator($vcal,'foo');
65
66     }
67
68     /**
69      * @depends testValues
70      */
71     function testDaily() {
72
73         $ev = new Sabre_VObject_Component('VEVENT');
74         $ev->UID = 'bla';
75         $ev->RRULE = 'FREQ=DAILY;INTERVAL=3;UNTIL=20111025T000000Z';
76         $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
77         $dtStart->setDateTime(new DateTime('2011-10-07'),Sabre_VObject_Property_DateTime::UTC);
78
79         $ev->add($dtStart);
80
81         $vcal = Sabre_VObject_Component::create('VCALENDAR');
82         $vcal->add($ev);
83
84         $it = new Sabre_VObject_RecurrenceIterator($vcal,$ev->uid);
85
86         $this->assertEquals('daily', $it->frequency);
87         $this->assertEquals(3, $it->interval);
88         $this->assertEquals(new DateTime('2011-10-25', new DateTimeZone('UTC')), $it->until);
89
90         // Max is to prevent overflow
91         $max = 12;
92         $result = array();
93         foreach($it as $item) {
94
95             $result[] = $item;
96             $max--;
97
98             if (!$max) break;
99
100         }
101
102         $tz = new DateTimeZone('UTC');
103
104         $this->assertEquals(
105             array(
106                 new DateTime('2011-10-07', $tz),
107                 new DateTime('2011-10-10', $tz),
108                 new DateTime('2011-10-13', $tz),
109                 new DateTime('2011-10-16', $tz),
110                 new DateTime('2011-10-19', $tz),
111                 new DateTime('2011-10-22', $tz),
112                 new DateTime('2011-10-25', $tz),
113             ),
114             $result
115         );
116
117     }
118
119     /**
120      * @depends testValues
121      */
122     function testNoRRULE() {
123
124         $ev = new Sabre_VObject_Component('VEVENT');
125         $ev->UID = 'bla';
126         $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
127         $dtStart->setDateTime(new DateTime('2011-10-07'),Sabre_VObject_Property_DateTime::UTC);
128
129         $ev->add($dtStart);
130
131         $vcal = Sabre_VObject_Component::create('VCALENDAR');
132         $vcal->add($ev);
133
134         $it = new Sabre_VObject_RecurrenceIterator($vcal,$ev->uid);
135
136         $this->assertEquals('daily', $it->frequency);
137         $this->assertEquals(1, $it->interval);
138
139         // Max is to prevent overflow
140         $max = 12;
141         $result = array();
142         foreach($it as $item) {
143
144             $result[] = $item;
145             $max--;
146
147             if (!$max) break;
148
149         }
150
151         $tz = new DateTimeZone('UTC');
152
153         $this->assertEquals(
154             array(
155                 new DateTime('2011-10-07', $tz),
156             ),
157             $result
158         );
159
160     }
161
162     /**
163      * @depends testValues
164      */
165     function testDailyByDay() {
166
167         $ev = new Sabre_VObject_Component('VEVENT');
168         $ev->UID = 'bla';
169         $ev->RRULE = 'FREQ=DAILY;INTERVAL=2;BYDAY=TU,WE,FR';
170         $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
171         $dtStart->setDateTime(new DateTime('2011-10-07'),Sabre_VObject_Property_DateTime::UTC);
172
173         $ev->add($dtStart);
174
175         $vcal = Sabre_VObject_Component::create('VCALENDAR');
176         $vcal->add($ev);
177
178         $it = new Sabre_VObject_RecurrenceIterator($vcal,(string)$ev->uid);
179
180         $this->assertEquals('daily', $it->frequency);
181         $this->assertEquals(2, $it->interval);
182         $this->assertEquals(array('TU','WE','FR'), $it->byDay);
183
184         // Grabbing the next 12 items
185         $max = 12;
186         $result = array();
187         foreach($it as $item) {
188
189             $result[] = $item;
190             $max--;
191
192             if (!$max) break;
193
194         }
195
196         $tz = new DateTimeZone('UTC');
197
198         $this->assertEquals(
199             array(
200                 new DateTime('2011-10-07', $tz),
201                 new DateTime('2011-10-11', $tz),
202                 new DateTime('2011-10-19', $tz),
203                 new DateTime('2011-10-21', $tz),
204                 new DateTime('2011-10-25', $tz),
205                 new DateTime('2011-11-02', $tz),
206                 new DateTime('2011-11-04', $tz),
207                 new DateTime('2011-11-08', $tz),
208                 new DateTime('2011-11-16', $tz),
209                 new DateTime('2011-11-18', $tz),
210                 new DateTime('2011-11-22', $tz),
211                 new DateTime('2011-11-30', $tz),
212             ),
213             $result
214         );
215
216     }
217
218     /**
219      * @depends testValues
220      */
221     function testWeekly() {
222
223         $ev = new Sabre_VObject_Component('VEVENT');
224         $ev->UID = 'bla';
225         $ev->RRULE = 'FREQ=WEEKLY;INTERVAL=2;COUNT=10';
226         $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
227         $dtStart->setDateTime(new DateTime('2011-10-07'),Sabre_VObject_Property_DateTime::UTC);
228
229         $ev->add($dtStart);
230
231         $vcal = Sabre_VObject_Component::create('VCALENDAR');
232         $vcal->add($ev);
233
234         $it = new Sabre_VObject_RecurrenceIterator($vcal,(string)$ev->uid);
235
236         $this->assertEquals('weekly', $it->frequency);
237         $this->assertEquals(2, $it->interval);
238         $this->assertEquals(10, $it->count);
239
240         // Max is to prevent overflow
241         $max = 12;
242         $result = array();
243         foreach($it as $item) {
244
245             $result[] = $item;
246             $max--;
247
248             if (!$max) break;
249
250         }
251
252         $tz = new DateTimeZone('UTC');
253
254         $this->assertEquals(
255             array(
256                 new DateTime('2011-10-07', $tz),
257                 new DateTime('2011-10-21', $tz),
258                 new DateTime('2011-11-04', $tz),
259                 new DateTime('2011-11-18', $tz),
260                 new DateTime('2011-12-02', $tz),
261                 new DateTime('2011-12-16', $tz),
262                 new DateTime('2011-12-30', $tz),
263                 new DateTime('2012-01-13', $tz),
264                 new DateTime('2012-01-27', $tz),
265                 new DateTime('2012-02-10', $tz),
266             ),
267             $result
268         );
269
270     }
271
272     /**
273      * @depends testValues
274      */
275     function testWeeklyByDay() {
276
277         $ev = new Sabre_VObject_Component('VEVENT');
278         $ev->UID = 'bla';
279         $ev->RRULE = 'FREQ=WEEKLY;INTERVAL=2;BYDAY=TU,WE,FR;WKST=SU';
280         $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
281         $dtStart->setDateTime(new DateTime('2011-10-07'),Sabre_VObject_Property_DateTime::UTC);
282
283         $ev->add($dtStart);
284
285         $vcal = Sabre_VObject_Component::create('VCALENDAR');
286         $vcal->add($ev);
287
288         $it = new Sabre_VObject_RecurrenceIterator($vcal,(string)$ev->uid);
289
290         $this->assertEquals('weekly', $it->frequency);
291         $this->assertEquals(2, $it->interval);
292         $this->assertEquals(array('TU','WE','FR'), $it->byDay);
293         $this->assertEquals('SU', $it->weekStart);
294
295         // Grabbing the next 12 items
296         $max = 12;
297         $result = array();
298         foreach($it as $item) {
299
300             $result[] = $item;
301             $max--;
302
303             if (!$max) break;
304
305         }
306
307         $tz = new DateTimeZone('UTC');
308
309         $this->assertEquals(
310             array(
311                 new DateTime('2011-10-07', $tz),
312                 new DateTime('2011-10-18', $tz),
313                 new DateTime('2011-10-19', $tz),
314                 new DateTime('2011-10-21', $tz),
315                 new DateTime('2011-11-01', $tz),
316                 new DateTime('2011-11-02', $tz),
317                 new DateTime('2011-11-04', $tz),
318                 new DateTime('2011-11-15', $tz),
319                 new DateTime('2011-11-16', $tz),
320                 new DateTime('2011-11-18', $tz),
321                 new DateTime('2011-11-29', $tz),
322                 new DateTime('2011-11-30', $tz),
323             ),
324             $result
325         );
326
327     }
328
329     /**
330      * @depends testValues
331      */
332     function testMonthly() {
333
334         $ev = new Sabre_VObject_Component('VEVENT');
335         $ev->UID = 'bla';
336         $ev->RRULE = 'FREQ=MONTHLY;INTERVAL=3;COUNT=5';
337         $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
338         $dtStart->setDateTime(new DateTime('2011-12-05'),Sabre_VObject_Property_DateTime::UTC);
339
340         $ev->add($dtStart);
341
342         $vcal = Sabre_VObject_Component::create('VCALENDAR');
343         $vcal->add($ev);
344
345         $it = new Sabre_VObject_RecurrenceIterator($vcal,(string)$ev->uid);
346
347         $this->assertEquals('monthly', $it->frequency);
348         $this->assertEquals(3, $it->interval);
349         $this->assertEquals(5, $it->count);
350
351         $max = 14;
352         $result = array();
353         foreach($it as $item) {
354
355             $result[] = $item;
356             $max--;
357
358             if (!$max) break;
359
360         }
361
362         $tz = new DateTimeZone('UTC');
363
364         $this->assertEquals(
365             array(
366                 new DateTime('2011-12-05', $tz),
367                 new DateTime('2012-03-05', $tz),
368                 new DateTime('2012-06-05', $tz),
369                 new DateTime('2012-09-05', $tz),
370                 new DateTime('2012-12-05', $tz),
371             ),
372             $result
373         );
374
375
376     }
377
378     /**
379      * @depends testValues
380      */
381     function testMonthlyEndOfMonth() {
382
383         $ev = new Sabre_VObject_Component('VEVENT');
384         $ev->UID = 'bla';
385         $ev->RRULE = 'FREQ=MONTHLY;INTERVAL=2;COUNT=12';
386         $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
387         $dtStart->setDateTime(new DateTime('2011-12-31'),Sabre_VObject_Property_DateTime::UTC);
388
389         $ev->add($dtStart);
390
391         $vcal = Sabre_VObject_Component::create('VCALENDAR');
392         $vcal->add($ev);
393
394         $it = new Sabre_VObject_RecurrenceIterator($vcal,(string)$ev->uid);
395
396         $this->assertEquals('monthly', $it->frequency);
397         $this->assertEquals(2, $it->interval);
398         $this->assertEquals(12, $it->count);
399
400         $max = 14;
401         $result = array();
402         foreach($it as $item) {
403
404             $result[] = $item;
405             $max--;
406
407             if (!$max) break;
408
409         }
410
411         $tz = new DateTimeZone('UTC');
412
413         $this->assertEquals(
414             array(
415                 new DateTime('2011-12-31', $tz),
416                 new DateTime('2012-08-31', $tz),
417                 new DateTime('2012-10-31', $tz),
418                 new DateTime('2012-12-31', $tz),
419                 new DateTime('2013-08-31', $tz),
420                 new DateTime('2013-10-31', $tz),
421                 new DateTime('2013-12-31', $tz),
422                 new DateTime('2014-08-31', $tz),
423                 new DateTime('2014-10-31', $tz),
424                 new DateTime('2014-12-31', $tz),
425                 new DateTime('2015-08-31', $tz),
426                 new DateTime('2015-10-31', $tz),
427             ),
428             $result
429         );
430
431
432     }
433
434     /**
435      * @depends testValues
436      */
437     function testMonthlyByMonthDay() {
438
439         $ev = new Sabre_VObject_Component('VEVENT');
440         $ev->UID = 'bla';
441         $ev->RRULE = 'FREQ=MONTHLY;INTERVAL=5;COUNT=9;BYMONTHDAY=1,31,-7';
442         $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
443         $dtStart->setDateTime(new DateTime('2011-01-01'),Sabre_VObject_Property_DateTime::UTC);
444
445         $ev->add($dtStart);
446
447         $vcal = Sabre_VObject_Component::create('VCALENDAR');
448         $vcal->add($ev);
449
450         $it = new Sabre_VObject_RecurrenceIterator($vcal,(string)$ev->uid);
451
452         $this->assertEquals('monthly', $it->frequency);
453         $this->assertEquals(5, $it->interval);
454         $this->assertEquals(9, $it->count);
455         $this->assertEquals(array(1, 31, -7), $it->byMonthDay);
456
457         $max = 14;
458         $result = array();
459         foreach($it as $item) {
460
461             $result[] = $item;
462             $max--;
463
464             if (!$max) break;
465
466         }
467
468         $tz = new DateTimeZone('UTC');
469
470         $this->assertEquals(
471             array(
472                 new DateTime('2011-01-01', $tz),
473                 new DateTime('2011-01-25', $tz),
474                 new DateTime('2011-01-31', $tz),
475                 new DateTime('2011-06-01', $tz),
476                 new DateTime('2011-06-24', $tz),
477                 new DateTime('2011-11-01', $tz),
478                 new DateTime('2011-11-24', $tz),
479                 new DateTime('2012-04-01', $tz),
480                 new DateTime('2012-04-24', $tz),
481             ),
482             $result
483         );
484
485     }
486
487     /**
488      * @depends testValues
489      */
490     function testMonthlyByDay() {
491
492         $ev = new Sabre_VObject_Component('VEVENT');
493         $ev->UID = 'bla';
494         $ev->RRULE = 'FREQ=MONTHLY;INTERVAL=2;COUNT=16;BYDAY=MO,-2TU,+1WE,3TH';
495         $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
496         $dtStart->setDateTime(new DateTime('2011-01-03'),Sabre_VObject_Property_DateTime::UTC);
497
498         $ev->add($dtStart);
499
500         $vcal = Sabre_VObject_Component::create('VCALENDAR');
501         $vcal->add($ev);
502
503         $it = new Sabre_VObject_RecurrenceIterator($vcal,(string)$ev->uid);
504
505         $this->assertEquals('monthly', $it->frequency);
506         $this->assertEquals(2, $it->interval);
507         $this->assertEquals(16, $it->count);
508         $this->assertEquals(array('MO','-2TU','+1WE','3TH'), $it->byDay);
509
510         $max = 20;
511         $result = array();
512         foreach($it as $k=>$item) {
513
514             $result[] = $item;
515             $max--;
516
517             if (!$max) break;
518
519         }
520
521         $tz = new DateTimeZone('UTC');
522
523         $this->assertEquals(
524             array(
525                 new DateTime('2011-01-03', $tz),
526                 new DateTime('2011-01-05', $tz),
527                 new DateTime('2011-01-10', $tz),
528                 new DateTime('2011-01-17', $tz),
529                 new DateTime('2011-01-18', $tz),
530                 new DateTime('2011-01-20', $tz),
531                 new DateTime('2011-01-24', $tz),
532                 new DateTime('2011-01-31', $tz),
533                 new DateTime('2011-03-02', $tz),
534                 new DateTime('2011-03-07', $tz),
535                 new DateTime('2011-03-14', $tz),
536                 new DateTime('2011-03-17', $tz),
537                 new DateTime('2011-03-21', $tz),
538                 new DateTime('2011-03-22', $tz),
539                 new DateTime('2011-03-28', $tz),
540                 new DateTime('2011-05-02', $tz),
541             ),
542             $result
543         );
544
545     }
546
547     /**
548      * @depends testValues
549      */
550     function testMonthlyByDayByMonthDay() {
551
552         $ev = new Sabre_VObject_Component('VEVENT');
553         $ev->UID = 'bla';
554         $ev->RRULE = 'FREQ=MONTHLY;COUNT=10;BYDAY=MO;BYMONTHDAY=1';
555         $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
556         $dtStart->setDateTime(new DateTime('2011-08-01'),Sabre_VObject_Property_DateTime::UTC);
557
558         $ev->add($dtStart);
559
560         $vcal = Sabre_VObject_Component::create('VCALENDAR');
561         $vcal->add($ev);
562
563         $it = new Sabre_VObject_RecurrenceIterator($vcal,(string)$ev->uid);
564
565         $this->assertEquals('monthly', $it->frequency);
566         $this->assertEquals(1, $it->interval);
567         $this->assertEquals(10, $it->count);
568         $this->assertEquals(array('MO'), $it->byDay);
569         $this->assertEquals(array(1), $it->byMonthDay);
570
571         $max = 20;
572         $result = array();
573         foreach($it as $k=>$item) {
574
575             $result[] = $item;
576             $max--;
577
578             if (!$max) break;
579
580         }
581
582         $tz = new DateTimeZone('UTC');
583
584         $this->assertEquals(
585             array(
586                 new DateTime('2011-08-01', $tz),
587                 new DateTime('2012-10-01', $tz),
588                 new DateTime('2013-04-01', $tz),
589                 new DateTime('2013-07-01', $tz),
590                 new DateTime('2014-09-01', $tz),
591                 new DateTime('2014-12-01', $tz),
592                 new DateTime('2015-06-01', $tz),
593                 new DateTime('2016-02-01', $tz),
594                 new DateTime('2016-08-01', $tz),
595                 new DateTime('2017-05-01', $tz),
596             ),
597             $result
598         );
599
600     }
601
602     /**
603      * @depends testValues
604      */
605     function testMonthlyByDayBySetPos() {
606
607         $ev = new Sabre_VObject_Component('VEVENT');
608         $ev->UID = 'bla';
609         $ev->RRULE = 'FREQ=MONTHLY;COUNT=10;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=1,-1';
610         $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
611         $dtStart->setDateTime(new DateTime('2011-01-03'),Sabre_VObject_Property_DateTime::UTC);
612
613         $ev->add($dtStart);
614
615         $vcal = Sabre_VObject_Component::create('VCALENDAR');
616         $vcal->add($ev);
617
618         $it = new Sabre_VObject_RecurrenceIterator($vcal,(string)$ev->uid);
619
620         $this->assertEquals('monthly', $it->frequency);
621         $this->assertEquals(1, $it->interval);
622         $this->assertEquals(10, $it->count);
623         $this->assertEquals(array('MO','TU','WE','TH','FR'), $it->byDay);
624         $this->assertEquals(array(1,-1), $it->bySetPos);
625
626         $max = 20;
627         $result = array();
628         foreach($it as $k=>$item) {
629
630             $result[] = $item;
631             $max--;
632
633             if (!$max) break;
634
635         }
636
637         $tz = new DateTimeZone('UTC');
638
639         $this->assertEquals(
640             array(
641                 new DateTime('2011-01-03', $tz),
642                 new DateTime('2011-01-31', $tz),
643                 new DateTime('2011-02-01', $tz),
644                 new DateTime('2011-02-28', $tz),
645                 new DateTime('2011-03-01', $tz),
646                 new DateTime('2011-03-31', $tz),
647                 new DateTime('2011-04-01', $tz),
648                 new DateTime('2011-04-29', $tz),
649                 new DateTime('2011-05-02', $tz),
650                 new DateTime('2011-05-31', $tz),
651             ),
652             $result
653         );
654
655     }
656
657     /**
658      * @depends testValues
659      */
660     function testYearly() {
661
662         $ev = new Sabre_VObject_Component('VEVENT');
663         $ev->UID = 'bla';
664         $ev->RRULE = 'FREQ=YEARLY;COUNT=10;INTERVAL=3';
665         $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
666         $dtStart->setDateTime(new DateTime('2011-01-01'),Sabre_VObject_Property_DateTime::UTC);
667
668         $ev->add($dtStart);
669
670         $vcal = Sabre_VObject_Component::create('VCALENDAR');
671         $vcal->add($ev);
672
673         $it = new Sabre_VObject_RecurrenceIterator($vcal,(string)$ev->uid);
674
675         $this->assertEquals('yearly', $it->frequency);
676         $this->assertEquals(3, $it->interval);
677         $this->assertEquals(10, $it->count);
678
679         $max = 20;
680         $result = array();
681         foreach($it as $k=>$item) {
682
683             $result[] = $item;
684             $max--;
685
686             if (!$max) break;
687
688         }
689
690         $tz = new DateTimeZone('UTC');
691
692         $this->assertEquals(
693             array(
694                 new DateTime('2011-01-01', $tz),
695                 new DateTime('2014-01-01', $tz),
696                 new DateTime('2017-01-01', $tz),
697                 new DateTime('2020-01-01', $tz),
698                 new DateTime('2023-01-01', $tz),
699                 new DateTime('2026-01-01', $tz),
700                 new DateTime('2029-01-01', $tz),
701                 new DateTime('2032-01-01', $tz),
702                 new DateTime('2035-01-01', $tz),
703                 new DateTime('2038-01-01', $tz),
704             ),
705             $result
706         );
707
708     }
709
710     /**
711      * @depends testValues
712      */
713     function testYearlyByMonth() {
714
715         $ev = new Sabre_VObject_Component('VEVENT');
716         $ev->UID = 'bla';
717         $ev->RRULE = 'FREQ=YEARLY;COUNT=8;INTERVAL=4;BYMONTH=4,10';
718         $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
719         $dtStart->setDateTime(new DateTime('2011-04-07'),Sabre_VObject_Property_DateTime::UTC);
720
721         $ev->add($dtStart);
722
723         $vcal = Sabre_VObject_Component::create('VCALENDAR');
724         $vcal->add($ev);
725
726         $it = new Sabre_VObject_RecurrenceIterator($vcal,(string)$ev->uid);
727
728         $this->assertEquals('yearly', $it->frequency);
729         $this->assertEquals(4, $it->interval);
730         $this->assertEquals(8, $it->count);
731         $this->assertEquals(array(4,10), $it->byMonth);
732
733         $max = 20;
734         $result = array();
735         foreach($it as $k=>$item) {
736
737             $result[] = $item;
738             $max--;
739
740             if (!$max) break;
741
742         }
743
744         $tz = new DateTimeZone('UTC');
745
746         $this->assertEquals(
747             array(
748                 new DateTime('2011-04-07', $tz),
749                 new DateTime('2011-10-07', $tz),
750                 new DateTime('2015-04-07', $tz),
751                 new DateTime('2015-10-07', $tz),
752                 new DateTime('2019-04-07', $tz),
753                 new DateTime('2019-10-07', $tz),
754                 new DateTime('2023-04-07', $tz),
755                 new DateTime('2023-10-07', $tz),
756             ),
757             $result
758         );
759
760     }
761
762     /**
763      * @depends testValues
764      */
765     function testYearlyByMonthByDay() {
766
767         $ev = new Sabre_VObject_Component('VEVENT');
768         $ev->UID = 'bla';
769         $ev->RRULE = 'FREQ=YEARLY;COUNT=8;INTERVAL=5;BYMONTH=4,10;BYDAY=1MO,-1SU';
770         $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
771         $dtStart->setDateTime(new DateTime('2011-04-04'),Sabre_VObject_Property_DateTime::UTC);
772
773         $ev->add($dtStart);
774
775         $vcal = Sabre_VObject_Component::create('VCALENDAR');
776         $vcal->add($ev);
777
778         $it = new Sabre_VObject_RecurrenceIterator($vcal,(string)$ev->uid);
779
780         $this->assertEquals('yearly', $it->frequency);
781         $this->assertEquals(5, $it->interval);
782         $this->assertEquals(8, $it->count);
783         $this->assertEquals(array(4,10), $it->byMonth);
784         $this->assertEquals(array('1MO','-1SU'), $it->byDay);
785
786         $max = 20;
787         $result = array();
788         foreach($it as $k=>$item) {
789
790             $result[] = $item;
791             $max--;
792
793             if (!$max) break;
794
795         }
796
797         $tz = new DateTimeZone('UTC');
798
799         $this->assertEquals(
800             array(
801                 new DateTime('2011-04-04', $tz),
802                 new DateTime('2011-04-24', $tz),
803                 new DateTime('2011-10-03', $tz),
804                 new DateTime('2011-10-30', $tz),
805                 new DateTime('2016-04-04', $tz),
806                 new DateTime('2016-04-24', $tz),
807                 new DateTime('2016-10-03', $tz),
808                 new DateTime('2016-10-30', $tz),
809             ),
810             $result
811         );
812
813     }
814
815     /**
816      * @depends testValues
817      */
818     function testFastForward() {
819
820         $ev = new Sabre_VObject_Component('VEVENT');
821         $ev->UID = 'bla';
822         $ev->RRULE = 'FREQ=YEARLY;COUNT=8;INTERVAL=5;BYMONTH=4,10;BYDAY=1MO,-1SU';
823         $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
824         $dtStart->setDateTime(new DateTime('2011-04-04'),Sabre_VObject_Property_DateTime::UTC);
825
826         $ev->add($dtStart);
827
828         $vcal = Sabre_VObject_Component::create('VCALENDAR');
829         $vcal->add($ev);
830
831         $it = new Sabre_VObject_RecurrenceIterator($vcal,(string)$ev->uid);
832
833         // The idea is that we're fast-forwarding too far in the future, so
834         // there will be no results left.
835         $it->fastForward(new DateTime('2020-05-05'));
836
837         $max = 20;
838         $result = array();
839         while($item = $it->current()) {
840
841             $result[] = $item;
842             $max--;
843
844             if (!$max) break;
845             $it->next();
846
847         }
848
849         $tz = new DateTimeZone('UTC');
850         $this->assertEquals(array(), $result);
851
852     }
853
854     /**
855      * @depends testValues
856      */
857     function testComplexExclusions() {
858
859         $ev = new Sabre_VObject_Component('VEVENT');
860         $ev->UID = 'bla';
861         $ev->RRULE = 'FREQ=YEARLY;COUNT=10';
862         $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
863
864         $tz = new DateTimeZone('Canada/Eastern');
865         $dtStart->setDateTime(new DateTime('2011-01-01 13:50:20', $tz),Sabre_VObject_Property_DateTime::LOCALTZ);
866
867         $exDate1 = new Sabre_VObject_Property_MultiDateTime('EXDATE');
868         $exDate1->setDateTimes(array(new DateTime('2012-01-01 13:50:20', $tz), new DateTime('2014-01-01 13:50:20', $tz)), Sabre_VObject_Property_DateTime::LOCALTZ);
869         $exDate2 = new Sabre_VObject_Property_MultiDateTime('EXDATE');
870         $exDate2->setDateTimes(array(new DateTime('2016-01-01 13:50:20', $tz)), Sabre_VObject_Property_DateTime::LOCALTZ);
871
872         $ev->add($dtStart);
873         $ev->add($exDate1);
874         $ev->add($exDate2);
875
876         $vcal = Sabre_VObject_Component::create('VCALENDAR');
877         $vcal->add($ev);
878
879         $it = new Sabre_VObject_RecurrenceIterator($vcal,(string)$ev->uid);
880
881         $this->assertEquals('yearly', $it->frequency);
882         $this->assertEquals(1, $it->interval);
883         $this->assertEquals(10, $it->count);
884
885         $max = 20;
886         $result = array();
887         foreach($it as $k=>$item) {
888
889             $result[] = $item;
890             $max--;
891
892             if (!$max) break;
893
894         }
895
896         $this->assertEquals(
897             array(
898                 new DateTime('2011-01-01 13:50:20', $tz),
899                 new DateTime('2013-01-01 13:50:20', $tz),
900                 new DateTime('2015-01-01 13:50:20', $tz),
901                 new DateTime('2017-01-01 13:50:20', $tz),
902                 new DateTime('2018-01-01 13:50:20', $tz),
903                 new DateTime('2019-01-01 13:50:20', $tz),
904                 new DateTime('2020-01-01 13:50:20', $tz),
905             ),
906             $result
907         );
908
909     }
910
911     /**
912      * @depends testValues
913      */
914     function testOverridenEvent() {
915
916         $vcal = Sabre_VObject_Component::create('VCALENDAR');
917
918         $ev1 = Sabre_VObject_Component::create('VEVENT');
919         $ev1->UID = 'overridden';
920         $ev1->RRULE = 'FREQ=DAILY;COUNT=10';
921         $ev1->DTSTART = '20120107T120000Z';
922         $ev1->SUMMARY = 'baseEvent';
923
924         $vcal->add($ev1);
925
926         // ev2 overrides an event, and puts it on 2pm instead.
927         $ev2 = Sabre_VObject_Component::create('VEVENT');
928         $ev2->UID = 'overridden';
929         $ev2->{'RECURRENCE-ID'} = '20120110T120000Z';
930         $ev2->DTSTART = '20120110T140000Z';
931         $ev2->SUMMARY = 'Event 2';
932
933         $vcal->add($ev2);
934
935         // ev3 overrides an event, and puts it 2 days and 2 hours later 
936         $ev3 = Sabre_VObject_Component::create('VEVENT');
937         $ev3->UID = 'overridden';
938         $ev3->{'RECURRENCE-ID'} = '20120113T120000Z';
939         $ev3->DTSTART = '20120115T140000Z';
940         $ev3->SUMMARY = 'Event 3';
941
942         $vcal->add($ev3);
943
944         $it = new Sabre_VObject_RecurrenceIterator($vcal,'overridden');
945
946         $dates = array();
947         $summaries = array();
948         while($it->valid()) {
949
950             $dates[] = $it->getDTStart();
951             $summaries[] = (string)$it->getEventObject()->SUMMARY;
952             $it->next();
953
954         }
955
956         $tz = new DateTimeZone('GMT');
957         $this->assertEquals(array(
958             new DateTime('2012-01-07 12:00:00',$tz),
959             new DateTime('2012-01-08 12:00:00',$tz),
960             new DateTime('2012-01-09 12:00:00',$tz),
961             new DateTime('2012-01-10 14:00:00',$tz),
962             new DateTime('2012-01-11 12:00:00',$tz),
963             new DateTime('2012-01-12 12:00:00',$tz),
964             new DateTime('2012-01-14 12:00:00',$tz),
965             new DateTime('2012-01-15 12:00:00',$tz),
966             new DateTime('2012-01-15 14:00:00',$tz),
967             new DateTime('2012-01-16 12:00:00',$tz),
968         ), $dates);
969
970         $this->assertEquals(array(
971             'baseEvent',
972             'baseEvent',
973             'baseEvent',
974             'Event 2',
975             'baseEvent',
976             'baseEvent',
977             'baseEvent',
978             'baseEvent',
979             'Event 3',
980             'baseEvent',
981         ), $summaries);
982
983     }
984
985     /**
986      * @depends testValues
987      */
988     function testOverridenEvent2() {
989
990         $vcal = Sabre_VObject_Component::create('VCALENDAR');
991
992         $ev1 = Sabre_VObject_Component::create('VEVENT');
993         $ev1->UID = 'overridden';
994         $ev1->RRULE = 'FREQ=WEEKLY;COUNT=3';
995         $ev1->DTSTART = '20120112T120000Z';
996         $ev1->SUMMARY = 'baseEvent';
997
998         $vcal->add($ev1);
999
1000         // ev2 overrides an event, and puts it 6 days earlier instead.
1001         $ev2 = Sabre_VObject_Component::create('VEVENT');
1002         $ev2->UID = 'overridden';
1003         $ev2->{'RECURRENCE-ID'} = '20120119T120000Z';
1004         $ev2->DTSTART = '20120113T120000Z';
1005         $ev2->SUMMARY = 'Override!';
1006
1007         $vcal->add($ev2);
1008
1009         $it = new Sabre_VObject_RecurrenceIterator($vcal,'overridden');
1010
1011         $dates = array();
1012         $summaries = array();
1013         while($it->valid()) {
1014
1015             $dates[] = $it->getDTStart();
1016             $summaries[] = (string)$it->getEventObject()->SUMMARY;
1017             $it->next();
1018
1019         }
1020
1021         $tz = new DateTimeZone('GMT');
1022         $this->assertEquals(array(
1023             new DateTime('2012-01-12 12:00:00',$tz),
1024             new DateTime('2012-01-13 12:00:00',$tz),
1025             new DateTime('2012-01-26 12:00:00',$tz),
1026
1027         ), $dates);
1028
1029         $this->assertEquals(array(
1030             'baseEvent',
1031             'Override!',
1032             'baseEvent',
1033         ), $summaries);
1034
1035     }
1036
1037     /**
1038      * @depends testValues
1039      */
1040     function testOverridenEventNoValuesExpected() {
1041
1042         $vcal = Sabre_VObject_Component::create('VCALENDAR');
1043
1044         $ev1 = Sabre_VObject_Component::create('VEVENT');
1045         $ev1->UID = 'overridden';
1046         $ev1->RRULE = 'FREQ=WEEKLY;COUNT=3';
1047         $ev1->DTSTART = '20120124T120000Z';
1048         $ev1->SUMMARY = 'baseEvent';
1049
1050         $vcal->add($ev1);
1051
1052         // ev2 overrides an event, and puts it 6 days earlier instead.
1053         $ev2 = Sabre_VObject_Component::create('VEVENT');
1054         $ev2->UID = 'overridden';
1055         $ev2->{'RECURRENCE-ID'} = '20120131T120000Z';
1056         $ev2->DTSTART = '20120125T120000Z';
1057         $ev2->SUMMARY = 'Override!';
1058
1059         $vcal->add($ev2);
1060
1061         $it = new Sabre_VObject_RecurrenceIterator($vcal,'overridden');
1062
1063         $dates = array();
1064         $summaries = array();
1065
1066         // The reported problem was specifically related to the VCALENDAR 
1067         // expansion. In this parcitular case, we had to forward to the 28th of 
1068         // january.
1069         $it->fastForward(new DateTime('2012-01-28 23:00:00'));
1070
1071         // We stop the loop when it hits the 6th of februari. Normally this 
1072         // iterator would hit 24, 25 (overriden from 31) and 7 feb but because 
1073         // we 'filter' from the 28th till the 6th, we should get 0 results.
1074         while($it->valid() && $it->getDTSTart() < new DateTime('2012-02-06 23:00:00')) {
1075
1076             $dates[] = $it->getDTStart();
1077             $summaries[] = (string)$it->getEventObject()->SUMMARY;
1078             $it->next();
1079
1080         }
1081
1082         $this->assertEquals(array(), $dates);
1083         $this->assertEquals(array(), $summaries);
1084
1085     }
1086 }
1087