This commit is contained in:
Xes
2025-08-14 22:41:49 +02:00
parent 2de81ccc46
commit 8ce45119b6
39774 changed files with 4309466 additions and 0 deletions

View File

@@ -0,0 +1,59 @@
<?php
namespace Sabre\VObject\Recur;
use
Sabre\VObject\Reader,
DateTime;
class ByMonthInDailyTest extends \PHPUnit_Framework_TestCase {
/**
* This tests the expansion of dates with DAILY frequency in RRULE with BYMONTH restrictions
*/
function testExpand() {
$ics = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Apple Inc.//iCal 4.0.4//EN
CALSCALE:GREGORIAN
BEGIN:VEVENT
TRANSP:OPAQUE
DTEND:20070925T183000Z
UID:uuid
DTSTAMP:19700101T000000Z
LOCATION:
DESCRIPTION:
STATUS:CONFIRMED
SEQUENCE:18
SUMMARY:Stuff
DTSTART:20070925T160000Z
CREATED:20071004T144642Z
RRULE:FREQ=DAILY;BYMONTH=9,10;BYDAY=SU
END:VEVENT
END:VCALENDAR
ICS;
$vcal = Reader::read($ics);
$this->assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal);
$vcal->expand(new DateTime('2013-09-28'), new DateTime('2014-09-11'));
foreach ($vcal->VEVENT as $event) {
$dates[] = $event->DTSTART->getValue();
}
$expectedDates = array(
"20130929T160000Z",
"20131006T160000Z",
"20131013T160000Z",
"20131020T160000Z",
"20131027T160000Z",
"20140907T160000Z"
);
$this->assertEquals($expectedDates, $dates, 'Recursed dates are restricted by month');
}
}

View File

@@ -0,0 +1,61 @@
<?php
namespace Sabre\VObject\Recur;
use
Sabre\VObject\Reader,
DateTime;
class BySetPosHangTest extends \PHPUnit_Framework_TestCase {
/**
* Using this iCalendar object, including BYSETPOS=-2 causes the iterator
* to hang, as reported in ticket #212.
*
* See: https://github.com/fruux/sabre-vobject/issues/212
*/
function testExpand() {
$ics = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Sabre//Sabre VObject 3.4.2//EN
CALSCALE:GREGORIAN
BEGIN:VEVENT
SUMMARY:Test event 1
DTSTART;TZID=Europe/Copenhagen:20150101T170000
RRULE:FREQ=MONTHLY;BYDAY=TH;BYSETPOS=-2
UID:b4071499-6fe4-418a-83b8-2b8d5ebb38e4
END:VEVENT
END:VCALENDAR
ICS;
$vcal = Reader::read($ics);
$this->assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal);
$vcal->expand(new DateTime('2015-01-01'), new DateTime('2016-01-01'));
foreach ($vcal->VEVENT as $event) {
$dates[] = $event->DTSTART->getValue();
}
$expectedDates = array(
"20150101T160000Z",
"20150122T160000Z",
"20150219T160000Z",
"20150319T160000Z",
"20150423T150000Z",
"20150521T150000Z",
"20150618T150000Z",
"20150723T150000Z",
"20150820T150000Z",
"20150917T150000Z",
"20151022T150000Z",
"20151119T160000Z",
"20151224T160000Z",
);
$this->assertEquals($expectedDates, $dates);
}
}

View File

@@ -0,0 +1,122 @@
<?php
namespace Sabre\VObject\Recur\EventIterator;
use
DateTime,
DateTimeZone,
Sabre\VObject\Reader;
class ExpandFloatingTimesTest extends \PHPUnit_Framework_TestCase {
function testExpand() {
$input = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:foo
DTSTART:20150109T090000
DTEND:20150109T100000
RRULE:FREQ=WEEKLY;INTERVAL=1;UNTIL=20191002T070000Z;BYDAY=FR
END:VEVENT
END:VCALENDAR
ICS;
$vcal = Reader::read($input);
$this->assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal);
$vcal->expand(new DateTime('2015-01-01'), new DateTime('2015-01-31'));
$result = $vcal->serialize();
$output = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:foo
DTSTART:20150109T090000Z
DTEND:20150109T100000Z
RECURRENCE-ID:20150109T090000Z
END:VEVENT
BEGIN:VEVENT
UID:foo
DTSTART:20150116T090000Z
DTEND:20150116T100000Z
RECURRENCE-ID:20150116T090000Z
END:VEVENT
BEGIN:VEVENT
UID:foo
DTSTART:20150123T090000Z
DTEND:20150123T100000Z
RECURRENCE-ID:20150123T090000Z
END:VEVENT
BEGIN:VEVENT
UID:foo
DTSTART:20150130T090000Z
DTEND:20150130T100000Z
RECURRENCE-ID:20150130T090000Z
END:VEVENT
END:VCALENDAR
ICS;
$this->assertEquals($output, str_replace("\r", "", $result));
}
function testExpandWithReferenceTimezone() {
$input = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:foo
DTSTART:20150109T090000
DTEND:20150109T100000
RRULE:FREQ=WEEKLY;INTERVAL=1;UNTIL=20191002T070000Z;BYDAY=FR
END:VEVENT
END:VCALENDAR
ICS;
$vcal = Reader::read($input);
$this->assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal);
$vcal->expand(new DateTime('2015-01-01'), new DateTime('2015-01-31'), new \DateTimeZone('Europe/Berlin'));
$result = $vcal->serialize();
$output = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:foo
DTSTART:20150109T080000Z
DTEND:20150109T090000Z
RECURRENCE-ID:20150109T080000Z
END:VEVENT
BEGIN:VEVENT
UID:foo
DTSTART:20150116T080000Z
DTEND:20150116T090000Z
RECURRENCE-ID:20150116T080000Z
END:VEVENT
BEGIN:VEVENT
UID:foo
DTSTART:20150123T080000Z
DTEND:20150123T090000Z
RECURRENCE-ID:20150123T080000Z
END:VEVENT
BEGIN:VEVENT
UID:foo
DTSTART:20150130T080000Z
DTEND:20150130T090000Z
RECURRENCE-ID:20150130T080000Z
END:VEVENT
END:VCALENDAR
ICS;
$this->assertEquals($output, str_replace("\r", "", $result));
}
}

View File

@@ -0,0 +1,54 @@
<?php
namespace Sabre\VObject\Recur\EventIterator;
use Sabre\VObject\Recur;
use Sabre\VObject\Reader;
class FifthTuesdayProblemTest extends \PHPUnit_Framework_TestCase {
/**
* A pretty slow test. Had to be marked as 'medium' for phpunit to not die
* after 1 second. Would be good to optimize later.
*
* @medium
*/
function testGetDTEnd() {
$ics = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Apple Inc.//iCal 4.0.4//EN
CALSCALE:GREGORIAN
BEGIN:VEVENT
TRANSP:OPAQUE
DTEND;TZID=America/New_York:20070925T170000
UID:uuid
DTSTAMP:19700101T000000Z
LOCATION:
DESCRIPTION:
STATUS:CONFIRMED
SEQUENCE:18
SUMMARY:Stuff
DTSTART;TZID=America/New_York:20070925T160000
CREATED:20071004T144642Z
RRULE:FREQ=MONTHLY;INTERVAL=1;UNTIL=20071030T035959Z;BYDAY=5TU
END:VEVENT
END:VCALENDAR
ICS;
$vObject = Reader::read($ics);
$it = new Recur\EventIterator($vObject, (string)$vObject->VEVENT->UID);
while($it->valid()) {
$it->next();
}
// If we got here, it means we were successful. The bug that was in the
// system before would fail on the 5th tuesday of the month, if the 5th
// tuesday did not exist.
$this->assertTrue(true);
}
}

View File

@@ -0,0 +1,64 @@
<?php
namespace Sabre\VObject\Recur\EventIterator;
use
DateTime,
DateTimeZone,
Sabre\VObject\Reader;
/**
* This is a unittest for Issue #53.
*/
class RecurrenceIteratorIncorrectExpandTest extends \PHPUnit_Framework_TestCase {
function testExpand() {
$input = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:foo
DTSTART:20130711T050000Z
DTEND:20130711T053000Z
RRULE:FREQ=DAILY;INTERVAL=1;COUNT=2
END:VEVENT
BEGIN:VEVENT
UID:foo
DTSTART:20130719T050000Z
DTEND:20130719T053000Z
RECURRENCE-ID:20130712T050000Z
END:VEVENT
END:VCALENDAR
ICS;
$vcal = Reader::read($input);
$this->assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal);
$vcal->expand(new DateTime('2011-01-01'), new DateTime('2014-01-01'));
$result = $vcal->serialize();
$output = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:foo
DTSTART:20130711T050000Z
DTEND:20130711T053000Z
RECURRENCE-ID:20130711T050000Z
END:VEVENT
BEGIN:VEVENT
UID:foo
DTSTART:20130719T050000Z
DTEND:20130719T053000Z
RECURRENCE-ID:20130712T050000Z
END:VEVENT
END:VCALENDAR
ICS;
$this->assertEquals($output, str_replace("\r", "", $result));
}
}

View File

@@ -0,0 +1,99 @@
<?php
namespace Sabre\VObject\Recur\EventIterator;
use
DateTime,
DateTimeZone,
Sabre\VObject\Component\VCalendar,
Sabre\VObject\Recur;
class EventIteratorInfiniteLoopProblemTest extends \PHPUnit_Framework_TestCase {
public function setUp() {
$this->vcal = new VCalendar();
}
/**
* This bug came from a Fruux customer. This would result in a never-ending
* request.
*/
function testFastForwardTooFar() {
$ev = $this->vcal->createComponent('VEVENT');
$ev->UID = 'foobar';
$ev->DTSTART = '20090420T180000Z';
$ev->RRULE = 'FREQ=WEEKLY;BYDAY=MO;UNTIL=20090704T205959Z;INTERVAL=1';
$this->assertFalse($ev->isInTimeRange(new DateTime('2012-01-01 12:00:00'),new DateTime('3000-01-01 00:00:00')));
}
/**
* Different bug, also likely an infinite loop.
*/
function testYearlyByMonthLoop() {
$ev = $this->vcal->createComponent('VEVENT');
$ev->UID = 'uuid';
$ev->DTSTART = '20120101T154500';
$ev->DTSTART['TZID'] = 'Europe/Berlin';
$ev->RRULE = 'FREQ=YEARLY;INTERVAL=1;UNTIL=20120203T225959Z;BYMONTH=2;BYSETPOS=1;BYDAY=SU,MO,TU,WE,TH,FR,SA';
$ev->DTEND = '20120101T164500';
$ev->DTEND['TZID'] = 'Europe/Berlin';
// This recurrence rule by itself is a yearly rule that should happen
// every february.
//
// The BYDAY part expands this to every day of the month, but the
// BYSETPOS limits this to only the 1st day of the month. Very crazy
// way to specify this, and could have certainly been a lot easier.
$this->vcal->add($ev);
$it = new Recur\EventIterator($this->vcal,'uuid');
$it->fastForward(new DateTime('2012-01-29 23:00:00', new DateTimeZone('UTC')));
$collect = array();
while($it->valid()) {
$collect[] = $it->getDTSTART();
if ($it->getDTSTART() > new DateTime('2013-02-05 22:59:59', new DateTimeZone('UTC'))) {
break;
}
$it->next();
}
$this->assertEquals(
array(new DateTime('2012-02-01 15:45:00', new DateTimeZone('Europe/Berlin'))),
$collect
);
}
/**
* Something, somewhere produced an ics with an interval set to 0. Because
* this means we increase the current day (or week, month) by 0, this also
* results in an infinite loop.
*
* @expectedException InvalidArgumentException
* @return void
*/
function testZeroInterval() {
$ev = $this->vcal->createComponent('VEVENT');
$ev->UID = 'uuid';
$ev->DTSTART = '20120824T145700Z';
$ev->RRULE = 'FREQ=YEARLY;INTERVAL=0';
$this->vcal->add($ev);
$it = new Recur\EventIterator($this->vcal,'uuid');
$it->fastForward(new DateTime('2013-01-01 23:00:00', new DateTimeZone('UTC')));
// if we got this far.. it means we are no longer infinitely looping
}
}

View File

@@ -0,0 +1,49 @@
<?php
namespace Sabre\VObject;
use
DateTime,
DateTimeZone;
class Issue48Test extends \PHPUnit_Framework_TestCase {
function testExpand() {
$input = <<<ICS
BEGIN:VCALENDAR
BEGIN:VEVENT
UID:foo
DTEND;TZID=Europe/Moscow:20130710T120000
DTSTART;TZID=Europe/Moscow:20130710T110000
RRULE:FREQ=DAILY;UNTIL=20130712T195959Z
END:VEVENT
BEGIN:VEVENT
UID:foo
DTEND;TZID=Europe/Moscow:20130713T120000
DTSTART;TZID=Europe/Moscow:20130713T110000
RECURRENCE-ID;TZID=Europe/Moscow:20130711T110000
END:VEVENT
END:VCALENDAR
ICS;
$vcal = Reader::read($input);
$this->assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal);
$it = new Recur\EventIterator($vcal, 'foo');
$result = iterator_to_array($it);
$tz = new DateTimeZone('Europe/Moscow');
$expected = array(
new DateTime('2013-07-10 11:00:00', $tz),
new DateTime('2013-07-12 11:00:00', $tz),
new DateTime('2013-07-13 11:00:00', $tz),
);
$this->assertEquals($expected, $result);
}
}

View File

@@ -0,0 +1,128 @@
<?php
namespace Sabre\VObject;
use
DateTime,
DateTimeZone;
class Issue50Test extends \PHPUnit_Framework_TestCase {
function testExpand() {
$input = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN
BEGIN:VTIMEZONE
TZID:Europe/Brussels
X-LIC-LOCATION:Europe/Brussels
BEGIN:DAYLIGHT
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
TZNAME:CEST
DTSTART:19700329T020000
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
TZNAME:CET
DTSTART:19701025T030000
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
CREATED:20130705T142510Z
LAST-MODIFIED:20130715T132556Z
DTSTAMP:20130715T132556Z
UID:1aef0b27-3d92-4581-829a-11999dd36724
SUMMARY:Werken
RRULE:FREQ=DAILY;COUNT=5
DTSTART;TZID=Europe/Brussels:20130715T090000
DTEND;TZID=Europe/Brussels:20130715T170000
LOCATION:Job
DESCRIPTION:Vrij
X-MOZ-GENERATION:9
END:VEVENT
BEGIN:VEVENT
CREATED:20130715T081654Z
LAST-MODIFIED:20130715T110931Z
DTSTAMP:20130715T110931Z
UID:1aef0b27-3d92-4581-829a-11999dd36724
SUMMARY:Werken
RECURRENCE-ID;TZID=Europe/Brussels:20130719T090000
DTSTART;TZID=Europe/Brussels:20130719T070000
DTEND;TZID=Europe/Brussels:20130719T150000
SEQUENCE:1
LOCATION:Job
DESCRIPTION:Vrij
X-MOZ-GENERATION:1
END:VEVENT
BEGIN:VEVENT
CREATED:20130715T111654Z
LAST-MODIFIED:20130715T132556Z
DTSTAMP:20130715T132556Z
UID:1aef0b27-3d92-4581-829a-11999dd36724
SUMMARY:Werken
RECURRENCE-ID;TZID=Europe/Brussels:20130716T090000
DTSTART;TZID=Europe/Brussels:20130716T070000
DTEND;TZID=Europe/Brussels:20130716T150000
SEQUENCE:1
LOCATION:Job
X-MOZ-GENERATION:2
END:VEVENT
BEGIN:VEVENT
CREATED:20130715T125942Z
LAST-MODIFIED:20130715T130023Z
DTSTAMP:20130715T130023Z
UID:1aef0b27-3d92-4581-829a-11999dd36724
SUMMARY:Werken
RECURRENCE-ID;TZID=Europe/Brussels:20130717T090000
DTSTART;TZID=Europe/Brussels:20130717T070000
DTEND;TZID=Europe/Brussels:20130717T150000
SEQUENCE:1
LOCATION:Job
X-MOZ-GENERATION:3
END:VEVENT
BEGIN:VEVENT
CREATED:20130715T130024Z
LAST-MODIFIED:20130715T130034Z
DTSTAMP:20130715T130034Z
UID:1aef0b27-3d92-4581-829a-11999dd36724
SUMMARY:Werken
RECURRENCE-ID;TZID=Europe/Brussels:20130718T090000
DTSTART;TZID=Europe/Brussels:20130718T090000
DTEND;TZID=Europe/Brussels:20130718T170000
LOCATION:Job
X-MOZ-GENERATION:5
DESCRIPTION:Vrij
END:VEVENT
END:VCALENDAR
ICS;
$vcal = Reader::read($input);
$this->assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal);
$it = new Recur\EventIterator($vcal, '1aef0b27-3d92-4581-829a-11999dd36724');
$result = array();
foreach($it as $instance) {
$result[] = $instance;
}
$tz = new DateTimeZone('Europe/Brussels');
$this->assertEquals(array(
new DateTime('2013-07-15 09:00:00', $tz),
new DateTime('2013-07-16 07:00:00', $tz),
new DateTime('2013-07-17 07:00:00', $tz),
new DateTime('2013-07-18 09:00:00', $tz),
new DateTime('2013-07-19 07:00:00', $tz),
), $result);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,65 @@
<?php
namespace Sabre\VObject\Recur\EventIterator;
use
DateTime,
DateTimeZone,
Sabre\VObject\Reader;
class RecurrenceIteratorMissingOverriddenTest extends \PHPUnit_Framework_TestCase {
function testExpand() {
$input = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:foo
DTSTART:20130727T120000Z
DURATION:PT1H
RRULE:FREQ=DAILY;COUNT=2
SUMMARY:A
END:VEVENT
BEGIN:VEVENT
RECURRENCE-ID:20130728T120000Z
UID:foo
DTSTART:20140101T120000Z
DURATION:PT1H
SUMMARY:B
END:VEVENT
END:VCALENDAR
ICS;
$vcal = Reader::read($input);
$this->assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal);
$vcal->expand(new DateTime('2011-01-01'), new DateTime('2015-01-01'));
$result = $vcal->serialize();
$output = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:foo
DTSTART:20130727T120000Z
DURATION:PT1H
SUMMARY:A
RECURRENCE-ID:20130727T120000Z
END:VEVENT
BEGIN:VEVENT
RECURRENCE-ID:20130728T120000Z
UID:foo
DTSTART:20140101T120000Z
DURATION:PT1H
SUMMARY:B
END:VEVENT
END:VCALENDAR
ICS;
$this->assertEquals($output, str_replace("\r","",$result));
}
}

View File

@@ -0,0 +1,40 @@
<?php
namespace Sabre\VObject\Recur;
use
Sabre\VObject\Reader;
class IssueEXDATETest extends \PHPUnit_Framework_TestCase {
/**
* @expectedException \Sabre\VObject\Recur\NoInstancesException
*/
function testRecurrence() {
$input = <<<ICS
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
BEGIN:VEVENT
DTSTART;TZID=Europe/Berlin:20130329T140000
DTEND;TZID=Europe/Berlin:20130329T153000
RRULE:FREQ=WEEKLY;BYDAY=FR;UNTIL=20130412T115959Z
EXDATE;TZID=Europe/Berlin:20130405T140000
EXDATE;TZID=Europe/Berlin:20130329T140000
DTSTAMP:20140916T201215Z
UID:foo
SEQUENCE:1
SUMMARY:foo
END:VEVENT
END:VCALENDAR
ICS;
$vcal = Reader::read($input);
$this->assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal);
$it = new EventIterator($vcal, 'foo');
}
}

View File

@@ -0,0 +1,122 @@
<?php
namespace Sabre\VObject\RecurrenceIterator;
use Sabre\VObject\Reader;
use DateTime;
class OverrideFirstEventTest extends \PHPUnit_Framework_TestCase {
function testOverrideFirstEvent() {
$input = <<<ICS
BEGIN:VCALENDAR
BEGIN:VEVENT
UID:foobar
DTSTART:20140803T120000Z
RRULE:FREQ=WEEKLY
SUMMARY:Original
END:VEVENT
BEGIN:VEVENT
UID:foobar
RECURRENCE-ID:20140803T120000Z
DTSTART:20140803T120000Z
SUMMARY:Overridden
END:VEVENT
END:VCALENDAR
ICS;
$vcal = Reader::read($input);
$vcal->expand(new DateTime('2014-08-01'), new DateTime('2014-09-01'));
$expected = <<<ICS
BEGIN:VCALENDAR
BEGIN:VEVENT
UID:foobar
RECURRENCE-ID:20140803T120000Z
DTSTART:20140803T120000Z
SUMMARY:Overridden
END:VEVENT
BEGIN:VEVENT
UID:foobar
DTSTART:20140810T120000Z
SUMMARY:Original
RECURRENCE-ID:20140810T120000Z
END:VEVENT
BEGIN:VEVENT
UID:foobar
DTSTART:20140817T120000Z
SUMMARY:Original
RECURRENCE-ID:20140817T120000Z
END:VEVENT
BEGIN:VEVENT
UID:foobar
DTSTART:20140824T120000Z
SUMMARY:Original
RECURRENCE-ID:20140824T120000Z
END:VEVENT
BEGIN:VEVENT
UID:foobar
DTSTART:20140831T120000Z
SUMMARY:Original
RECURRENCE-ID:20140831T120000Z
END:VEVENT
END:VCALENDAR
ICS;
$newIcs = $vcal->serialize();
$newIcs = str_replace("\r\n","\n", $newIcs);
$this->assertEquals(
$expected,
$newIcs
);
}
function testRemoveFirstEvent() {
$input = <<<ICS
BEGIN:VCALENDAR
BEGIN:VEVENT
UID:foobar
DTSTART:20140803T120000Z
RRULE:FREQ=WEEKLY
EXDATE:20140803T120000Z
SUMMARY:Original
END:VEVENT
END:VCALENDAR
ICS;
$vcal = Reader::read($input);
$vcal->expand(new DateTime('2014-08-01'), new DateTime('2014-08-19'));
$expected = <<<ICS
BEGIN:VCALENDAR
BEGIN:VEVENT
UID:foobar
DTSTART:20140810T120000Z
SUMMARY:Original
RECURRENCE-ID:20140810T120000Z
END:VEVENT
BEGIN:VEVENT
UID:foobar
DTSTART:20140817T120000Z
SUMMARY:Original
RECURRENCE-ID:20140817T120000Z
END:VEVENT
END:VCALENDAR
ICS;
$newIcs = $vcal->serialize();
$newIcs = str_replace("\r\n","\n", $newIcs);
$this->assertEquals(
$expected,
$newIcs
);
}
}

View File

@@ -0,0 +1,56 @@
<?php
namespace Sabre\VObject\Recur;
use Sabre\VObject\Recur\EventIterator;
use Sabre\VObject\Reader;
/**
* Testing case when overridden recurring events have same start date.
*
* Class SameDateForRecurringEventsTest
*/
class SameDateForRecurringEventsTest extends \PHPUnit_Framework_TestCase
{
/**
* Checking is all events iterated by EventIterator.
*/
public function testAllEventsArePresentInIterator()
{
$ics = <<<ICS
BEGIN:VCALENDAR
BEGIN:VEVENT
UID:1
DTSTART;TZID=Europe/Kiev:20160713T110000
DTEND;TZID=Europe/Kiev:20160713T113000
RRULE:FREQ=DAILY;INTERVAL=1;COUNT=3
END:VEVENT
BEGIN:VEVENT
UID:2
DTSTART;TZID=Europe/Kiev:20160713T110000
DTEND;TZID=Europe/Kiev:20160713T113000
RECURRENCE-ID;TZID=Europe/Kiev:20160714T110000
END:VEVENT
BEGIN:VEVENT
UID:3
DTSTART;TZID=Europe/Kiev:20160713T110000
DTEND;TZID=Europe/Kiev:20160713T113000
RECURRENCE-ID;TZID=Europe/Kiev:20160715T110000
END:VEVENT
BEGIN:VEVENT
UID:4
DTSTART;TZID=Europe/Kiev:20160713T110000
DTEND;TZID=Europe/Kiev:20160713T113000
RECURRENCE-ID;TZID=Europe/Kiev:20160716T110000
END:VEVENT
END:VCALENDAR
ICS;
$vCalendar = Reader::read($ics);
$eventIterator = new EventIterator($vCalendar->getComponents());
$this->assertEquals(4, iterator_count($eventIterator), 'in ICS 4 events');
}
}

View File

@@ -0,0 +1,56 @@
<?php
namespace Sabre\VObject\Recur;
use DateTime;
use DateTimeZone;
class RDateIteratorTest extends \PHPUnit_Framework_TestCase {
function testSimple() {
$utc = new DateTimeZone('UTC');
$it = new RDateIterator('20140901T000000Z,20141001T000000Z', new DateTime('2014-08-01 00:00:00', $utc));
$expected = array(
new DateTime('2014-08-01 00:00:00', $utc),
new DateTime('2014-09-01 00:00:00', $utc),
new DateTime('2014-10-01 00:00:00', $utc),
);
$this->assertEquals(
$expected,
iterator_to_array($it)
);
$this->assertFalse($it->isInfinite());
}
function testFastForward() {
$utc = new DateTimeZone('UTC');
$it = new RDateIterator('20140901T000000Z,20141001T000000Z', new DateTime('2014-08-01 00:00:00', $utc));
$it->fastForward(new DateTime('2014-08-15 00:00:00'));
$result = array();
while($it->valid()) {
$result[] = $it->current();
$it->next();
}
$expected = array(
new DateTime('2014-09-01 00:00:00', $utc),
new DateTime('2014-10-01 00:00:00', $utc),
);
$this->assertEquals(
$expected,
$result
);
$this->assertFalse($it->isInfinite());
}
}

View File

@@ -0,0 +1,713 @@
<?php
namespace Sabre\VObject\Recur;
use DateTime;
use DateTimeZone;
class RRuleIteratorTest extends \PHPUnit_Framework_TestCase {
function testHourly() {
$this->parse(
'FREQ=HOURLY;INTERVAL=3;COUNT=12',
'2011-10-07 12:00:00',
array(
'2011-10-07 12:00:00',
'2011-10-07 15:00:00',
'2011-10-07 18:00:00',
'2011-10-07 21:00:00',
'2011-10-08 00:00:00',
'2011-10-08 03:00:00',
'2011-10-08 06:00:00',
'2011-10-08 09:00:00',
'2011-10-08 12:00:00',
'2011-10-08 15:00:00',
'2011-10-08 18:00:00',
'2011-10-08 21:00:00',
)
);
}
function testDaily() {
$this->parse(
'FREQ=DAILY;INTERVAL=3;UNTIL=20111025T000000Z',
'2011-10-07',
array(
'2011-10-07 00:00:00',
'2011-10-10 00:00:00',
'2011-10-13 00:00:00',
'2011-10-16 00:00:00',
'2011-10-19 00:00:00',
'2011-10-22 00:00:00',
'2011-10-25 00:00:00',
)
);
}
function testDailyByDayByHour() {
$this->parse(
'FREQ=DAILY;BYDAY=SA,SU;BYHOUR=6,7',
'2011-10-08 06:00:00',
array(
'2011-10-08 06:00:00',
'2011-10-08 07:00:00',
'2011-10-09 06:00:00',
'2011-10-09 07:00:00',
'2011-10-15 06:00:00',
'2011-10-15 07:00:00',
'2011-10-16 06:00:00',
'2011-10-16 07:00:00',
'2011-10-22 06:00:00',
'2011-10-22 07:00:00',
'2011-10-23 06:00:00',
'2011-10-23 07:00:00',
)
);
}
function testDailyByHour() {
$this->parse(
'FREQ=DAILY;INTERVAL=2;BYHOUR=10,11,12,13,14,15',
'2012-10-11 12:00:00',
array(
'2012-10-11 12:00:00',
'2012-10-11 13:00:00',
'2012-10-11 14:00:00',
'2012-10-11 15:00:00',
'2012-10-13 10:00:00',
'2012-10-13 11:00:00',
'2012-10-13 12:00:00',
'2012-10-13 13:00:00',
'2012-10-13 14:00:00',
'2012-10-13 15:00:00',
'2012-10-15 10:00:00',
'2012-10-15 11:00:00',
)
);
}
function testDailyByDay() {
$this->parse(
'FREQ=DAILY;INTERVAL=2;BYDAY=TU,WE,FR',
'2011-10-07 12:00:00',
array(
'2011-10-07 12:00:00',
'2011-10-11 12:00:00',
'2011-10-19 12:00:00',
'2011-10-21 12:00:00',
'2011-10-25 12:00:00',
'2011-11-02 12:00:00',
'2011-11-04 12:00:00',
'2011-11-08 12:00:00',
'2011-11-16 12:00:00',
'2011-11-18 12:00:00',
'2011-11-22 12:00:00',
'2011-11-30 12:00:00',
)
);
}
function testDailyCount() {
$this->parse(
'FREQ=DAILY;COUNT=5',
'2014-08-01 18:03:00',
array(
'2014-08-01 18:03:00',
'2014-08-02 18:03:00',
'2014-08-03 18:03:00',
'2014-08-04 18:03:00',
'2014-08-05 18:03:00',
)
);
}
function testDailyByMonth() {
$this->parse(
'FREQ=DAILY;BYMONTH=9,10;BYDAY=SU',
'2007-10-04 16:00:00',
array(
"2013-09-29 16:00:00",
"2013-10-06 16:00:00",
"2013-10-13 16:00:00",
"2013-10-20 16:00:00",
"2013-10-27 16:00:00",
"2014-09-07 16:00:00"
),
'2013-09-28'
);
}
function testWeekly() {
$this->parse(
'FREQ=WEEKLY;INTERVAL=2;COUNT=10',
'2011-10-07 00:00:00',
array(
'2011-10-07 00:00:00',
'2011-10-21 00:00:00',
'2011-11-04 00:00:00',
'2011-11-18 00:00:00',
'2011-12-02 00:00:00',
'2011-12-16 00:00:00',
'2011-12-30 00:00:00',
'2012-01-13 00:00:00',
'2012-01-27 00:00:00',
'2012-02-10 00:00:00',
)
);
}
function testWeeklyByDay() {
$this->parse(
'FREQ=WEEKLY;INTERVAL=1;COUNT=4;BYDAY=MO;WKST=SA',
'2014-08-01 00:00:00',
array(
'2014-08-01 00:00:00',
'2014-08-04 00:00:00',
'2014-08-11 00:00:00',
'2014-08-18 00:00:00',
)
);
}
function testWeeklyByDay2() {
$this->parse(
'FREQ=WEEKLY;INTERVAL=2;BYDAY=TU,WE,FR;WKST=SU',
'2011-10-07 00:00:00',
array(
'2011-10-07 00:00:00',
'2011-10-18 00:00:00',
'2011-10-19 00:00:00',
'2011-10-21 00:00:00',
'2011-11-01 00:00:00',
'2011-11-02 00:00:00',
'2011-11-04 00:00:00',
'2011-11-15 00:00:00',
'2011-11-16 00:00:00',
'2011-11-18 00:00:00',
'2011-11-29 00:00:00',
'2011-11-30 00:00:00',
)
);
}
function testWeeklyByDayByHour() {
$this->parse(
'FREQ=WEEKLY;INTERVAL=2;BYDAY=TU,WE,FR;WKST=MO;BYHOUR=8,9,10',
'2011-10-07 08:00:00',
array(
'2011-10-07 08:00:00',
'2011-10-07 09:00:00',
'2011-10-07 10:00:00',
'2011-10-18 08:00:00',
'2011-10-18 09:00:00',
'2011-10-18 10:00:00',
'2011-10-19 08:00:00',
'2011-10-19 09:00:00',
'2011-10-19 10:00:00',
'2011-10-21 08:00:00',
'2011-10-21 09:00:00',
'2011-10-21 10:00:00',
'2011-11-01 08:00:00',
'2011-11-01 09:00:00',
'2011-11-01 10:00:00',
)
);
}
function testWeeklyByDaySpecificHour() {
$this->parse(
'FREQ=WEEKLY;INTERVAL=2;BYDAY=TU,WE,FR;WKST=SU',
'2011-10-07 18:00:00',
array(
'2011-10-07 18:00:00',
'2011-10-18 18:00:00',
'2011-10-19 18:00:00',
'2011-10-21 18:00:00',
'2011-11-01 18:00:00',
'2011-11-02 18:00:00',
'2011-11-04 18:00:00',
'2011-11-15 18:00:00',
'2011-11-16 18:00:00',
'2011-11-18 18:00:00',
'2011-11-29 18:00:00',
'2011-11-30 18:00:00',
)
);
}
function testMonthly() {
$this->parse(
'FREQ=MONTHLY;INTERVAL=3;COUNT=5',
'2011-12-05 00:00:00',
array(
'2011-12-05 00:00:00',
'2012-03-05 00:00:00',
'2012-06-05 00:00:00',
'2012-09-05 00:00:00',
'2012-12-05 00:00:00',
)
);
}
function testMonlthyEndOfMonth() {
$this->parse(
'FREQ=MONTHLY;INTERVAL=2;COUNT=12',
'2011-12-31 00:00:00',
array(
'2011-12-31 00:00:00',
'2012-08-31 00:00:00',
'2012-10-31 00:00:00',
'2012-12-31 00:00:00',
'2013-08-31 00:00:00',
'2013-10-31 00:00:00',
'2013-12-31 00:00:00',
'2014-08-31 00:00:00',
'2014-10-31 00:00:00',
'2014-12-31 00:00:00',
'2015-08-31 00:00:00',
'2015-10-31 00:00:00',
)
);
}
function testMonthlyByMonthDay() {
$this->parse(
'FREQ=MONTHLY;INTERVAL=5;COUNT=9;BYMONTHDAY=1,31,-7',
'2011-01-01 00:00:00',
array(
'2011-01-01 00:00:00',
'2011-01-25 00:00:00',
'2011-01-31 00:00:00',
'2011-06-01 00:00:00',
'2011-06-24 00:00:00',
'2011-11-01 00:00:00',
'2011-11-24 00:00:00',
'2012-04-01 00:00:00',
'2012-04-24 00:00:00',
)
);
}
function testMonthlyByDay() {
$this->parse(
'FREQ=MONTHLY;INTERVAL=2;COUNT=16;BYDAY=MO,-2TU,+1WE,3TH',
'2011-01-03 00:00:00',
array(
'2011-01-03 00:00:00',
'2011-01-05 00:00:00',
'2011-01-10 00:00:00',
'2011-01-17 00:00:00',
'2011-01-18 00:00:00',
'2011-01-20 00:00:00',
'2011-01-24 00:00:00',
'2011-01-31 00:00:00',
'2011-03-02 00:00:00',
'2011-03-07 00:00:00',
'2011-03-14 00:00:00',
'2011-03-17 00:00:00',
'2011-03-21 00:00:00',
'2011-03-22 00:00:00',
'2011-03-28 00:00:00',
'2011-05-02 00:00:00',
)
);
}
function testMonthlyByDayByMonthDay() {
$this->parse(
'FREQ=MONTHLY;COUNT=10;BYDAY=MO;BYMONTHDAY=1',
'2011-08-01 00:00:00',
array(
'2011-08-01 00:00:00',
'2012-10-01 00:00:00',
'2013-04-01 00:00:00',
'2013-07-01 00:00:00',
'2014-09-01 00:00:00',
'2014-12-01 00:00:00',
'2015-06-01 00:00:00',
'2016-02-01 00:00:00',
'2016-08-01 00:00:00',
'2017-05-01 00:00:00',
)
);
}
function testMonthlyByDayBySetPos() {
$this->parse(
'FREQ=MONTHLY;COUNT=10;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=1,-1',
'2011-01-03 00:00:00',
array(
'2011-01-03 00:00:00',
'2011-01-31 00:00:00',
'2011-02-01 00:00:00',
'2011-02-28 00:00:00',
'2011-03-01 00:00:00',
'2011-03-31 00:00:00',
'2011-04-01 00:00:00',
'2011-04-29 00:00:00',
'2011-05-02 00:00:00',
'2011-05-31 00:00:00',
)
);
}
function testYearly() {
$this->parse(
'FREQ=YEARLY;COUNT=10;INTERVAL=3',
'2011-01-01 00:00:00',
array(
'2011-01-01 00:00:00',
'2014-01-01 00:00:00',
'2017-01-01 00:00:00',
'2020-01-01 00:00:00',
'2023-01-01 00:00:00',
'2026-01-01 00:00:00',
'2029-01-01 00:00:00',
'2032-01-01 00:00:00',
'2035-01-01 00:00:00',
'2038-01-01 00:00:00',
)
);
}
function testYearlyLeapYear() {
$this->parse(
'FREQ=YEARLY;COUNT=3',
'2012-02-29 00:00:00',
array(
'2012-02-29 00:00:00',
'2016-02-29 00:00:00',
'2020-02-29 00:00:00',
)
);
}
function testYearlyByMonth() {
$this->parse(
'FREQ=YEARLY;COUNT=8;INTERVAL=4;BYMONTH=4,10',
'2011-04-07 00:00:00',
array(
'2011-04-07 00:00:00',
'2011-10-07 00:00:00',
'2015-04-07 00:00:00',
'2015-10-07 00:00:00',
'2019-04-07 00:00:00',
'2019-10-07 00:00:00',
'2023-04-07 00:00:00',
'2023-10-07 00:00:00',
)
);
}
function testYearlyByMonthByDay() {
$this->parse(
'FREQ=YEARLY;COUNT=8;INTERVAL=5;BYMONTH=4,10;BYDAY=1MO,-1SU',
'2011-04-04 00:00:00',
array(
'2011-04-04 00:00:00',
'2011-04-24 00:00:00',
'2011-10-03 00:00:00',
'2011-10-30 00:00:00',
'2016-04-04 00:00:00',
'2016-04-24 00:00:00',
'2016-10-03 00:00:00',
'2016-10-30 00:00:00',
)
);
}
function testFastForward() {
// The idea is that we're fast-forwarding too far in the future, so
// there will be no results left.
$this->parse(
'FREQ=YEARLY;COUNT=8;INTERVAL=5;BYMONTH=4,10;BYDAY=1MO,-1SU',
'2011-04-04 00:00:00',
array(),
'2020-05-05 00:00:00'
);
}
/**
* The bug that was in the
* system before would fail on the 5th tuesday of the month, if the 5th
* tuesday did not exist.
*
* A pretty slow test. Had to be marked as 'medium' for phpunit to not die
* after 1 second. Would be good to optimize later.
*
* @medium
*/
function testFifthTuesdayProblem() {
$this->parse(
'FREQ=MONTHLY;INTERVAL=1;UNTIL=20071030T035959Z;BYDAY=5TU',
'2007-10-04 14:46:42',
array(
"2007-10-04 14:46:42",
)
);
}
/**
* This bug came from a Fruux customer. This would result in a never-ending
* request.
*/
function testFastFowardTooFar() {
$this->parse(
'FREQ=WEEKLY;BYDAY=MO;UNTIL=20090704T205959Z;INTERVAL=1',
'2009-04-20 18:00:00',
array(
'2009-04-20 18:00:00',
'2009-04-27 18:00:00',
'2009-05-04 18:00:00',
'2009-05-11 18:00:00',
'2009-05-18 18:00:00',
'2009-05-25 18:00:00',
'2009-06-01 18:00:00',
'2009-06-08 18:00:00',
'2009-06-15 18:00:00',
'2009-06-22 18:00:00',
'2009-06-29 18:00:00',
)
);
}
/**
* This also at one point caused an infinite loop. We're keeping the test.
*/
function testYearlyByMonthLoop() {
$this->parse(
'FREQ=YEARLY;INTERVAL=1;UNTIL=20120203T225959Z;BYMONTH=2;BYSETPOS=1;BYDAY=SU,MO,TU,WE,TH,FR,SA',
'2012-01-01 15:45:00',
array(
'2012-02-01 15:45:00',
),
'2012-01-29 23:00:00'
);
}
/**
* Something, somewhere produced an ics with an interval set to 0. Because
* this means we increase the current day (or week, month) by 0, this also
* results in an infinite loop.
*
* @expectedException InvalidArgumentException
*/
function testZeroInterval() {
$this->parse(
'FREQ=YEARLY;INTERVAL=0',
'2012-08-24 14:57:00',
array(),
'2013-01-01 23:00:00'
);
}
/**
* @expectedException InvalidArgumentException
*/
function testInvalidFreq() {
$this->parse(
'FREQ=SMONTHLY;INTERVAL=3;UNTIL=20111025T000000Z',
'2011-10-07',
array()
);
}
/**
* @expectedException InvalidArgumentException
*/
function testByDayBadOffset() {
$this->parse(
'FREQ=WEEKLY;INTERVAL=1;COUNT=4;BYDAY=0MO;WKST=SA',
'2014-08-01 00:00:00',
array()
);
}
function testUntilBeginHAsTimezone() {
$this->parse(
'FREQ=WEEKLY;UNTIL=20131118T183000',
'2013-09-23 18:30:00',
array(
'2013-09-23 18:30:00',
'2013-09-30 18:30:00',
'2013-10-07 18:30:00',
'2013-10-14 18:30:00',
'2013-10-21 18:30:00',
'2013-10-28 18:30:00',
'2013-11-04 18:30:00',
'2013-11-11 18:30:00',
'2013-11-18 18:30:00',
),
null,
'America/New_York'
);
}
function testUntilBeforeDtStart() {
$this->parse(
'FREQ=DAILY;UNTIL=20140101T000000Z',
'2014-08-02 00:15:00',
array(
'2014-08-02 00:15:00',
)
);
}
function testIgnoredStuff() {
$this->parse(
'FREQ=DAILY;BYSECOND=1;BYMINUTE=1;BYYEARDAY=1;BYWEEKNO=1;COUNT=2',
'2014-08-02 00:15:00',
array(
'2014-08-02 00:15:00',
'2014-08-03 00:15:00',
)
);
}
function testMinusFifthThursday() {
$this->parse(
'FREQ=MONTHLY;BYDAY=-4TH,-5TH;COUNT=4',
'2015-01-01 00:15:00',
array(
'2015-01-01 00:15:00',
'2015-01-08 00:15:00',
'2015-02-05 00:15:00',
'2015-03-05 00:15:00'
)
);
}
/**
* @expectedException InvalidArgumentException
*/
function testUnsupportedPart() {
$this->parse(
'FREQ=DAILY;BYWODAN=1',
'2014-08-02 00:15:00',
array()
);
}
function testIteratorFunctions() {
$parser = new RRuleIterator('FREQ=DAILY', new DateTime('2014-08-02 00:00:13'));
$parser->next();
$this->assertEquals(
new DateTime('2014-08-03 00:00:13'),
$parser->current()
);
$this->assertEquals(
1,
$parser->key()
);
$parser->rewind();
$this->assertEquals(
new DateTime('2014-08-02 00:00:13'),
$parser->current()
);
$this->assertEquals(
0,
$parser->key()
);
}
function parse($rule, $start, $expected, $fastForward = null, $tz = 'UTC') {
$dt = new DateTime($start, new DateTimeZone($tz));
$parser = new RRuleIterator($rule, $dt);
if ($fastForward) {
$parser->fastForward(new DateTime($fastForward));
}
$result = array();
while($parser->valid()) {
$item = $parser->current();
$result[] = $item->format('Y-m-d H:i:s');
if ($parser->isInfinite() && count($result) >= count($expected)) {
break;
}
$parser->next();
}
$this->assertEquals(
$expected,
$result
);
}
}