comparison vendor/sabre/vobject/tests/VObject/Recur/RRuleIteratorTest.php @ 7:430dbd5346f7

vendor sabre as distributed
author Charlie Root
date Sat, 13 Jan 2018 09:06:10 -0500
parents
children
comparison
equal deleted inserted replaced
6:cec75ba50afc 7:430dbd5346f7
1 <?php
2
3 namespace Sabre\VObject\Recur;
4
5 use DateTime;
6 use DateTimeZone;
7
8 class RRuleIteratorTest extends \PHPUnit_Framework_TestCase {
9
10 function testHourly() {
11
12 $this->parse(
13 'FREQ=HOURLY;INTERVAL=3;COUNT=12',
14 '2011-10-07 12:00:00',
15 array(
16 '2011-10-07 12:00:00',
17 '2011-10-07 15:00:00',
18 '2011-10-07 18:00:00',
19 '2011-10-07 21:00:00',
20 '2011-10-08 00:00:00',
21 '2011-10-08 03:00:00',
22 '2011-10-08 06:00:00',
23 '2011-10-08 09:00:00',
24 '2011-10-08 12:00:00',
25 '2011-10-08 15:00:00',
26 '2011-10-08 18:00:00',
27 '2011-10-08 21:00:00',
28 )
29 );
30
31 }
32
33 function testDaily() {
34
35 $this->parse(
36 'FREQ=DAILY;INTERVAL=3;UNTIL=20111025T000000Z',
37 '2011-10-07',
38 array(
39 '2011-10-07 00:00:00',
40 '2011-10-10 00:00:00',
41 '2011-10-13 00:00:00',
42 '2011-10-16 00:00:00',
43 '2011-10-19 00:00:00',
44 '2011-10-22 00:00:00',
45 '2011-10-25 00:00:00',
46 )
47 );
48
49 }
50
51 function testDailyByDayByHour() {
52
53 $this->parse(
54 'FREQ=DAILY;BYDAY=SA,SU;BYHOUR=6,7',
55 '2011-10-08 06:00:00',
56 array(
57 '2011-10-08 06:00:00',
58 '2011-10-08 07:00:00',
59 '2011-10-09 06:00:00',
60 '2011-10-09 07:00:00',
61 '2011-10-15 06:00:00',
62 '2011-10-15 07:00:00',
63 '2011-10-16 06:00:00',
64 '2011-10-16 07:00:00',
65 '2011-10-22 06:00:00',
66 '2011-10-22 07:00:00',
67 '2011-10-23 06:00:00',
68 '2011-10-23 07:00:00',
69 )
70 );
71
72 }
73
74 function testDailyByHour() {
75
76 $this->parse(
77 'FREQ=DAILY;INTERVAL=2;BYHOUR=10,11,12,13,14,15',
78 '2012-10-11 12:00:00',
79 array(
80 '2012-10-11 12:00:00',
81 '2012-10-11 13:00:00',
82 '2012-10-11 14:00:00',
83 '2012-10-11 15:00:00',
84 '2012-10-13 10:00:00',
85 '2012-10-13 11:00:00',
86 '2012-10-13 12:00:00',
87 '2012-10-13 13:00:00',
88 '2012-10-13 14:00:00',
89 '2012-10-13 15:00:00',
90 '2012-10-15 10:00:00',
91 '2012-10-15 11:00:00',
92 )
93 );
94
95 }
96
97 function testDailyByDay() {
98
99 $this->parse(
100 'FREQ=DAILY;INTERVAL=2;BYDAY=TU,WE,FR',
101 '2011-10-07 12:00:00',
102 array(
103 '2011-10-07 12:00:00',
104 '2011-10-11 12:00:00',
105 '2011-10-19 12:00:00',
106 '2011-10-21 12:00:00',
107 '2011-10-25 12:00:00',
108 '2011-11-02 12:00:00',
109 '2011-11-04 12:00:00',
110 '2011-11-08 12:00:00',
111 '2011-11-16 12:00:00',
112 '2011-11-18 12:00:00',
113 '2011-11-22 12:00:00',
114 '2011-11-30 12:00:00',
115 )
116 );
117
118 }
119
120 function testDailyCount() {
121
122 $this->parse(
123 'FREQ=DAILY;COUNT=5',
124 '2014-08-01 18:03:00',
125 array(
126 '2014-08-01 18:03:00',
127 '2014-08-02 18:03:00',
128 '2014-08-03 18:03:00',
129 '2014-08-04 18:03:00',
130 '2014-08-05 18:03:00',
131 )
132 );
133
134 }
135
136 function testDailyByMonth() {
137
138 $this->parse(
139 'FREQ=DAILY;BYMONTH=9,10;BYDAY=SU',
140 '2007-10-04 16:00:00',
141 array(
142 "2013-09-29 16:00:00",
143 "2013-10-06 16:00:00",
144 "2013-10-13 16:00:00",
145 "2013-10-20 16:00:00",
146 "2013-10-27 16:00:00",
147 "2014-09-07 16:00:00"
148 ),
149 '2013-09-28'
150 );
151
152 }
153
154 function testWeekly() {
155
156 $this->parse(
157 'FREQ=WEEKLY;INTERVAL=2;COUNT=10',
158 '2011-10-07 00:00:00',
159 array(
160 '2011-10-07 00:00:00',
161 '2011-10-21 00:00:00',
162 '2011-11-04 00:00:00',
163 '2011-11-18 00:00:00',
164 '2011-12-02 00:00:00',
165 '2011-12-16 00:00:00',
166 '2011-12-30 00:00:00',
167 '2012-01-13 00:00:00',
168 '2012-01-27 00:00:00',
169 '2012-02-10 00:00:00',
170 )
171 );
172
173 }
174
175 function testWeeklyByDay() {
176
177 $this->parse(
178 'FREQ=WEEKLY;INTERVAL=1;COUNT=4;BYDAY=MO;WKST=SA',
179 '2014-08-01 00:00:00',
180 array(
181 '2014-08-01 00:00:00',
182 '2014-08-04 00:00:00',
183 '2014-08-11 00:00:00',
184 '2014-08-18 00:00:00',
185 )
186 );
187
188 }
189
190 function testWeeklyByDay2() {
191
192 $this->parse(
193 'FREQ=WEEKLY;INTERVAL=2;BYDAY=TU,WE,FR;WKST=SU',
194 '2011-10-07 00:00:00',
195 array(
196 '2011-10-07 00:00:00',
197 '2011-10-18 00:00:00',
198 '2011-10-19 00:00:00',
199 '2011-10-21 00:00:00',
200 '2011-11-01 00:00:00',
201 '2011-11-02 00:00:00',
202 '2011-11-04 00:00:00',
203 '2011-11-15 00:00:00',
204 '2011-11-16 00:00:00',
205 '2011-11-18 00:00:00',
206 '2011-11-29 00:00:00',
207 '2011-11-30 00:00:00',
208 )
209 );
210
211 }
212
213 function testWeeklyByDayByHour() {
214
215 $this->parse(
216 'FREQ=WEEKLY;INTERVAL=2;BYDAY=TU,WE,FR;WKST=MO;BYHOUR=8,9,10',
217 '2011-10-07 08:00:00',
218 array(
219 '2011-10-07 08:00:00',
220 '2011-10-07 09:00:00',
221 '2011-10-07 10:00:00',
222 '2011-10-18 08:00:00',
223 '2011-10-18 09:00:00',
224 '2011-10-18 10:00:00',
225 '2011-10-19 08:00:00',
226 '2011-10-19 09:00:00',
227 '2011-10-19 10:00:00',
228 '2011-10-21 08:00:00',
229 '2011-10-21 09:00:00',
230 '2011-10-21 10:00:00',
231 '2011-11-01 08:00:00',
232 '2011-11-01 09:00:00',
233 '2011-11-01 10:00:00',
234 )
235 );
236
237 }
238
239 function testWeeklyByDaySpecificHour() {
240
241 $this->parse(
242 'FREQ=WEEKLY;INTERVAL=2;BYDAY=TU,WE,FR;WKST=SU',
243 '2011-10-07 18:00:00',
244 array(
245 '2011-10-07 18:00:00',
246 '2011-10-18 18:00:00',
247 '2011-10-19 18:00:00',
248 '2011-10-21 18:00:00',
249 '2011-11-01 18:00:00',
250 '2011-11-02 18:00:00',
251 '2011-11-04 18:00:00',
252 '2011-11-15 18:00:00',
253 '2011-11-16 18:00:00',
254 '2011-11-18 18:00:00',
255 '2011-11-29 18:00:00',
256 '2011-11-30 18:00:00',
257 )
258 );
259
260 }
261
262 function testMonthly() {
263
264 $this->parse(
265 'FREQ=MONTHLY;INTERVAL=3;COUNT=5',
266 '2011-12-05 00:00:00',
267 array(
268 '2011-12-05 00:00:00',
269 '2012-03-05 00:00:00',
270 '2012-06-05 00:00:00',
271 '2012-09-05 00:00:00',
272 '2012-12-05 00:00:00',
273 )
274 );
275
276 }
277
278 function testMonlthyEndOfMonth() {
279
280 $this->parse(
281 'FREQ=MONTHLY;INTERVAL=2;COUNT=12',
282 '2011-12-31 00:00:00',
283 array(
284 '2011-12-31 00:00:00',
285 '2012-08-31 00:00:00',
286 '2012-10-31 00:00:00',
287 '2012-12-31 00:00:00',
288 '2013-08-31 00:00:00',
289 '2013-10-31 00:00:00',
290 '2013-12-31 00:00:00',
291 '2014-08-31 00:00:00',
292 '2014-10-31 00:00:00',
293 '2014-12-31 00:00:00',
294 '2015-08-31 00:00:00',
295 '2015-10-31 00:00:00',
296 )
297 );
298
299 }
300
301 function testMonthlyByMonthDay() {
302
303 $this->parse(
304 'FREQ=MONTHLY;INTERVAL=5;COUNT=9;BYMONTHDAY=1,31,-7',
305 '2011-01-01 00:00:00',
306 array(
307 '2011-01-01 00:00:00',
308 '2011-01-25 00:00:00',
309 '2011-01-31 00:00:00',
310 '2011-06-01 00:00:00',
311 '2011-06-24 00:00:00',
312 '2011-11-01 00:00:00',
313 '2011-11-24 00:00:00',
314 '2012-04-01 00:00:00',
315 '2012-04-24 00:00:00',
316 )
317 );
318
319 }
320
321 function testMonthlyByDay() {
322
323 $this->parse(
324 'FREQ=MONTHLY;INTERVAL=2;COUNT=16;BYDAY=MO,-2TU,+1WE,3TH',
325 '2011-01-03 00:00:00',
326 array(
327 '2011-01-03 00:00:00',
328 '2011-01-05 00:00:00',
329 '2011-01-10 00:00:00',
330 '2011-01-17 00:00:00',
331 '2011-01-18 00:00:00',
332 '2011-01-20 00:00:00',
333 '2011-01-24 00:00:00',
334 '2011-01-31 00:00:00',
335 '2011-03-02 00:00:00',
336 '2011-03-07 00:00:00',
337 '2011-03-14 00:00:00',
338 '2011-03-17 00:00:00',
339 '2011-03-21 00:00:00',
340 '2011-03-22 00:00:00',
341 '2011-03-28 00:00:00',
342 '2011-05-02 00:00:00',
343 )
344 );
345
346 }
347
348 function testMonthlyByDayByMonthDay() {
349
350 $this->parse(
351 'FREQ=MONTHLY;COUNT=10;BYDAY=MO;BYMONTHDAY=1',
352 '2011-08-01 00:00:00',
353 array(
354 '2011-08-01 00:00:00',
355 '2012-10-01 00:00:00',
356 '2013-04-01 00:00:00',
357 '2013-07-01 00:00:00',
358 '2014-09-01 00:00:00',
359 '2014-12-01 00:00:00',
360 '2015-06-01 00:00:00',
361 '2016-02-01 00:00:00',
362 '2016-08-01 00:00:00',
363 '2017-05-01 00:00:00',
364 )
365 );
366
367 }
368
369 function testMonthlyByDayBySetPos() {
370
371 $this->parse(
372 'FREQ=MONTHLY;COUNT=10;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=1,-1',
373 '2011-01-03 00:00:00',
374 array(
375 '2011-01-03 00:00:00',
376 '2011-01-31 00:00:00',
377 '2011-02-01 00:00:00',
378 '2011-02-28 00:00:00',
379 '2011-03-01 00:00:00',
380 '2011-03-31 00:00:00',
381 '2011-04-01 00:00:00',
382 '2011-04-29 00:00:00',
383 '2011-05-02 00:00:00',
384 '2011-05-31 00:00:00',
385 )
386 );
387
388 }
389
390 function testYearly() {
391
392 $this->parse(
393 'FREQ=YEARLY;COUNT=10;INTERVAL=3',
394 '2011-01-01 00:00:00',
395 array(
396 '2011-01-01 00:00:00',
397 '2014-01-01 00:00:00',
398 '2017-01-01 00:00:00',
399 '2020-01-01 00:00:00',
400 '2023-01-01 00:00:00',
401 '2026-01-01 00:00:00',
402 '2029-01-01 00:00:00',
403 '2032-01-01 00:00:00',
404 '2035-01-01 00:00:00',
405 '2038-01-01 00:00:00',
406 )
407 );
408 }
409
410 function testYearlyLeapYear() {
411
412 $this->parse(
413 'FREQ=YEARLY;COUNT=3',
414 '2012-02-29 00:00:00',
415 array(
416 '2012-02-29 00:00:00',
417 '2016-02-29 00:00:00',
418 '2020-02-29 00:00:00',
419 )
420 );
421 }
422
423 function testYearlyByMonth() {
424
425 $this->parse(
426 'FREQ=YEARLY;COUNT=8;INTERVAL=4;BYMONTH=4,10',
427 '2011-04-07 00:00:00',
428 array(
429 '2011-04-07 00:00:00',
430 '2011-10-07 00:00:00',
431 '2015-04-07 00:00:00',
432 '2015-10-07 00:00:00',
433 '2019-04-07 00:00:00',
434 '2019-10-07 00:00:00',
435 '2023-04-07 00:00:00',
436 '2023-10-07 00:00:00',
437 )
438 );
439
440 }
441
442 function testYearlyByMonthByDay() {
443
444 $this->parse(
445 'FREQ=YEARLY;COUNT=8;INTERVAL=5;BYMONTH=4,10;BYDAY=1MO,-1SU',
446 '2011-04-04 00:00:00',
447 array(
448 '2011-04-04 00:00:00',
449 '2011-04-24 00:00:00',
450 '2011-10-03 00:00:00',
451 '2011-10-30 00:00:00',
452 '2016-04-04 00:00:00',
453 '2016-04-24 00:00:00',
454 '2016-10-03 00:00:00',
455 '2016-10-30 00:00:00',
456 )
457 );
458
459 }
460
461 function testFastForward() {
462
463 // The idea is that we're fast-forwarding too far in the future, so
464 // there will be no results left.
465 $this->parse(
466 'FREQ=YEARLY;COUNT=8;INTERVAL=5;BYMONTH=4,10;BYDAY=1MO,-1SU',
467 '2011-04-04 00:00:00',
468 array(),
469 '2020-05-05 00:00:00'
470 );
471
472 }
473
474 /**
475 * The bug that was in the
476 * system before would fail on the 5th tuesday of the month, if the 5th
477 * tuesday did not exist.
478 *
479 * A pretty slow test. Had to be marked as 'medium' for phpunit to not die
480 * after 1 second. Would be good to optimize later.
481 *
482 * @medium
483 */
484 function testFifthTuesdayProblem() {
485
486 $this->parse(
487 'FREQ=MONTHLY;INTERVAL=1;UNTIL=20071030T035959Z;BYDAY=5TU',
488 '2007-10-04 14:46:42',
489 array(
490 "2007-10-04 14:46:42",
491 )
492 );
493
494 }
495
496 /**
497 * This bug came from a Fruux customer. This would result in a never-ending
498 * request.
499 */
500 function testFastFowardTooFar() {
501
502 $this->parse(
503 'FREQ=WEEKLY;BYDAY=MO;UNTIL=20090704T205959Z;INTERVAL=1',
504 '2009-04-20 18:00:00',
505 array(
506 '2009-04-20 18:00:00',
507 '2009-04-27 18:00:00',
508 '2009-05-04 18:00:00',
509 '2009-05-11 18:00:00',
510 '2009-05-18 18:00:00',
511 '2009-05-25 18:00:00',
512 '2009-06-01 18:00:00',
513 '2009-06-08 18:00:00',
514 '2009-06-15 18:00:00',
515 '2009-06-22 18:00:00',
516 '2009-06-29 18:00:00',
517 )
518 );
519
520 }
521
522 /**
523 * This also at one point caused an infinite loop. We're keeping the test.
524 */
525 function testYearlyByMonthLoop() {
526
527 $this->parse(
528 'FREQ=YEARLY;INTERVAL=1;UNTIL=20120203T225959Z;BYMONTH=2;BYSETPOS=1;BYDAY=SU,MO,TU,WE,TH,FR,SA',
529 '2012-01-01 15:45:00',
530 array(
531 '2012-02-01 15:45:00',
532 ),
533 '2012-01-29 23:00:00'
534 );
535
536
537 }
538
539 /**
540 * Something, somewhere produced an ics with an interval set to 0. Because
541 * this means we increase the current day (or week, month) by 0, this also
542 * results in an infinite loop.
543 *
544 * @expectedException InvalidArgumentException
545 */
546 function testZeroInterval() {
547
548 $this->parse(
549 'FREQ=YEARLY;INTERVAL=0',
550 '2012-08-24 14:57:00',
551 array(),
552 '2013-01-01 23:00:00'
553 );
554
555 }
556
557 /**
558 * @expectedException InvalidArgumentException
559 */
560 function testInvalidFreq() {
561
562 $this->parse(
563 'FREQ=SMONTHLY;INTERVAL=3;UNTIL=20111025T000000Z',
564 '2011-10-07',
565 array()
566 );
567
568 }
569
570 /**
571 * @expectedException InvalidArgumentException
572 */
573 function testByDayBadOffset() {
574
575 $this->parse(
576 'FREQ=WEEKLY;INTERVAL=1;COUNT=4;BYDAY=0MO;WKST=SA',
577 '2014-08-01 00:00:00',
578 array()
579 );
580
581 }
582
583 function testUntilBeginHAsTimezone() {
584
585 $this->parse(
586 'FREQ=WEEKLY;UNTIL=20131118T183000',
587 '2013-09-23 18:30:00',
588 array(
589 '2013-09-23 18:30:00',
590 '2013-09-30 18:30:00',
591 '2013-10-07 18:30:00',
592 '2013-10-14 18:30:00',
593 '2013-10-21 18:30:00',
594 '2013-10-28 18:30:00',
595 '2013-11-04 18:30:00',
596 '2013-11-11 18:30:00',
597 '2013-11-18 18:30:00',
598 ),
599 null,
600 'America/New_York'
601 );
602
603 }
604
605 function testUntilBeforeDtStart() {
606
607 $this->parse(
608 'FREQ=DAILY;UNTIL=20140101T000000Z',
609 '2014-08-02 00:15:00',
610 array(
611 '2014-08-02 00:15:00',
612 )
613 );
614
615 }
616
617 function testIgnoredStuff() {
618
619 $this->parse(
620 'FREQ=DAILY;BYSECOND=1;BYMINUTE=1;BYYEARDAY=1;BYWEEKNO=1;COUNT=2',
621 '2014-08-02 00:15:00',
622 array(
623 '2014-08-02 00:15:00',
624 '2014-08-03 00:15:00',
625 )
626 );
627
628 }
629
630 /**
631 * @expectedException InvalidArgumentException
632 */
633 function testUnsupportedPart() {
634
635 $this->parse(
636 'FREQ=DAILY;BYWODAN=1',
637 '2014-08-02 00:15:00',
638 array()
639 );
640
641 }
642
643 function testIteratorFunctions() {
644
645 $parser = new RRuleIterator('FREQ=DAILY', new DateTime('2014-08-02 00:00:13'));
646 $parser->next();
647 $this->assertEquals(
648 new DateTime('2014-08-03 00:00:13'),
649 $parser->current()
650 );
651 $this->assertEquals(
652 1,
653 $parser->key()
654 );
655
656 $parser->rewind();
657
658 $this->assertEquals(
659 new DateTime('2014-08-02 00:00:13'),
660 $parser->current()
661 );
662 $this->assertEquals(
663 0,
664 $parser->key()
665 );
666
667 }
668
669 function parse($rule, $start, $expected, $fastForward = null, $tz = 'UTC') {
670
671 $dt = new DateTime($start, new DateTimeZone($tz));
672 $parser = new RRuleIterator($rule, $dt);
673
674 if ($fastForward) {
675 $parser->fastForward(new DateTime($fastForward));
676 }
677
678 $result = array();
679 while($parser->valid()) {
680
681 $item = $parser->current();
682 $result[] = $item->format('Y-m-d H:i:s');
683
684 if ($parser->isInfinite() && count($result) >= count($expected)) {
685 break;
686 }
687 $parser->next();
688
689 }
690
691 $this->assertEquals(
692 $expected,
693 $result
694 );
695
696 }
697
698 }