[Pkg-owncloud-commits] [php-sabre-vobject] 03/05: Imported Upstream version 2.1.3

David Prévot taffit at alioth.debian.org
Sat Oct 12 22:22:53 UTC 2013


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch master
in repository php-sabre-vobject.

commit 480923b7898ffba5307911fd35c0d3c7697563c3
Author: David Prévot <taffit at debian.org>
Date:   Sat Oct 12 18:08:04 2013 -0400

    Imported Upstream version 2.1.3
---
 ChangeLog                                          |   14 ++
 doc/DesignFor3_0.md                                |  202 --------------------
 lib/Sabre/VObject/Parameter.php                    |    6 +-
 lib/Sabre/VObject/Property.php                     |    2 +
 lib/Sabre/VObject/RecurrenceIterator.php           |  158 +++++++++------
 lib/Sabre/VObject/Version.php                      |    2 +-
 tests/Sabre/VObject/Issue48Test.php                |   47 +++++
 tests/Sabre/VObject/Issue50Test.php                |  128 +++++++++++++
 tests/Sabre/VObject/ParameterTest.php              |    7 +
 .../RecurrenceIteratorIncorrectExpandTest.php      |   62 ++++++
 .../RecurrenceIteratorMissingOverriddenTest.php    |   63 ++++++
 tests/Sabre/VObject/SlashRTest.php                 |   19 ++
 tests/bootstrap.php                                |    2 +
 13 files changed, 445 insertions(+), 267 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index c330fa2..616c7ce 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2.1.3-stable (2013-10-02)
+	* Fixed: Issue #55. \r must be stripped from property values.
+	* Fixed: Issue #65. Putting quotes around parameter values that contain a
+	  colon.
+
+2.1.2-stable (2013-08-02)
+	* Fixed: Issue #53. A regression in RecurrenceIterator.
+
+2.1.1-stable (2013-07-27)
+	* Fixed: Issue #50. RecurrenceIterator gives incorrect result when
+	  exception events are out of order in the iCalendar file.
+	* Fixed: Issue #48. Overridden events in the recurrence iterator that were
+	  past the UNTIL date were ignored.
+
 2.1.0-stable (2013-06-17)
 	* This version is fully backwards compatible with 2.0.*. However, it
 	  contains a few new API's that mimic the VObject 3 API. This allows it to
diff --git a/doc/DesignFor3_0.md b/doc/DesignFor3_0.md
deleted file mode 100644
index 88f9190..0000000
--- a/doc/DesignFor3_0.md
+++ /dev/null
@@ -1,202 +0,0 @@
-Design for VObject 3.0
-======================
-
-There are some fundamental issues with the current VObject library. The
-purpose of this document is to describe them, and gather all the data
-needed to make sure that this will not be an issue in VObject 3.0.
-
-Most of the issues revolve around escaping, and mapping of properties to
-classes.
-
-Relevant documents
-------------------
-
-* http://tools.ietf.org/html/rfc5545 - iCalendar 2.0
-* http://tools.ietf.org/html/rfc2445 - The old iCalendar 2.0 spec.
-* http://tools.ietf.org/html/rfc6350 - vCard 4.0
-* http://tools.ietf.org/html/rfc2425 - Mime-dir (syntax for vCard 3.0)
-* http://tools.ietf.org/html/rfc2426 - vCard 3.0
-* http://www.imc.org/pdi/pdiproddev.html - Old school vCalendar 1.0 and vCard 2.1
-
-We care about pretty much all of them, with the exception of vCalendar 1.0.
-This particular format is at this point so outdated, it's pretty much irrelevant.
-
-We may add support for that one later though.
-
-We also don't really care about the old iCalendar 2.0 spec. There are some
-differences, but they are not relevant to us at the moment.
-
-### Some specs we care about later down the road
-
-* http://tools.ietf.org/html/rfc6321 - xCal
-* http://tools.ietf.org/html/rfc6351 - xCard
-* http://tools.ietf.org/html/draft-kewisch-et-al-icalendar-in-json-00 - jCal
-* And.. jCard.. it will happen, no RFC drafts yet though :)
-
-Escaping
---------
-
-In a vCard and iCalendar object, escaping of values must be done on the
-following characters:
-
-* semicolon - `\;`
-* newline - `\n` or `\N`
-* comma - `\,`
-* slash - `\\`
-
-The only spec that's totally unclear about this is vCard 2.1. It only really
-mentions escaping of property parameters. And for those, it only mentions
-escaping of the semi-colon.
-
-So even for 2.1 vcards we're going to assume that list. In practice it seems
-that vCard 2.1 producers follow those rules for the most part.
-
-Bonus
------
-
-The brand new (February 2013) RFC6868 also uses `^` as an escape character.
-This is a BC break for both vCard and iCalendar, but we will implement it too
-in VObject 3.0.
-
-http://tools.ietf.org/html/rfc6868
-
-Delimiters
-----------
-
-The reason `;` and `,` are escaped, is because properties may have multiple values,
-and when they do.. they are separated by either `;` or `,`.
-
-Un-escaping in VObject 2.1
---------------------------
-
-Unescaping in vobject 2.1 is done rather naively. It really only escapes
-newlines and slashes when reading property values, and it does so in the
-Reader class.
-
-The original assumption was that values with multiple values (N, EXDATE,
-etc) would do so internally, but this is highly problematic.
-
-We don't know anymore in those property classes if something was meant as a
-real delimiter, or as an escaped delimiter, if `\;` was encoded, because it
-could have meant `\\;` before, or it could have meant `\;`.
-
-Furthermore, when serializing again, we only serialize newlines and slashes
-again. The problem there, is if a genuine `\;` showed up in the property
-value, we will all of a sudden encode it as `\\;`.
-
-**In conclusion**: there is absolutely no way right now to decode a
-multi-valued property, and encode it again.. if one of the values contained
-a literal `;`.
-
-Property constructors
----------------------
-
-The other issue in this whole ordeal, is that property constructors receive
-a half-assed, partially unescaped string. This may in practice work OK for the
-vCard and iCalendar specs, but will become problematic when we're implementing
-xCal, xCard, jCal and jCard.
-
-### VObject 3.0 approach
-
-Every property-class will get a static deserialize() method, responsible for
-doing all deserializing.
-
-The constructor for every property-class will receive a value that's logical
-for PHP, and allow for total serialization and deserialization.
-
-This means that for single-value properties, it will be a string, and for
-multiple-value properties it will be an array.
-
-Since every property class knows to fully serialize and deserialize itself,
-they should have full flexibility and no data-loss.
-
-Then, when we want to add (x|j card|calendar) support, each format will get
-its own serializer and static deserializer method.
-
-The `VALUE=` argument
----------------------
-
-Another flaw in the system, is that currently specific property classes are
-mapped based on their property name. For instance, a `DTSTART` property is
-mapped to a `DateTime` class, and the `N` is mapped to a `Compound` class.
-
-The way this was actually designed, is that every property has a value-type.
-
-The value-type is specified by a `VALUE` parameter. For instance, if a
-`DTSTART` property has `VALUE=DATE`, it means that the value-type is a DATE.
-
-Many properties can specify how they are encoded with `VALUE`. An `ATTACH`
-property may have `VALUE=BINARY`m or `VALUE=URI`.
-
-Every property class should really be mapped based on this value-type.
-Also, every property has a default value-type. That means that if no `VALUE`
-parameter is supplied, it defaults to some value.
-
-For example, the default value-type for `DTSTART` is not `DATE`, but it's
-`DATE-TIME`.
-
-### In VObject 3.0
-
-Every property is mapped based on the content of the `VALUE` parameter.
-If no `VALUE` parameter is supplied, there will be a default list of
-parameters that are used instead.
-
-### Multiple values
-
-The problem with that approach, is that many properties have a single value,
-but some have multiple values.
-
-`DTSTART`, `DUE`, `BDAY` and many others contain a single `DATE-TIME` or
-`DATE`, but `EXDATE` can contain multiple `DATE-TIME` or `DATE` values.
-
-Some of these are split based on `;`, others with `,`. I keep getting stuck
-with this issue. At the moment there's a `MultipleDateTime` class, and a `Date`
-class. For standard text there's `Property` and `Compound` for multiple
-properties.
-
-I don't want to have to duplicate every property class for the ones that may
-support multiple. So instead, I made the decision that the best course of
-action is to allow every property to have 1 or more values.
-
-### Two Issues
-
-This should cover almost any situation, but then there's the issue of vCard
-and iCalendar producers that don't escape `;` and `,` in single-value
-properties.
-
-So we need to create exceptions for that.
-
-One other exception is `DTEND`. By default `DTEND` is encoded a `DATE-TIME`
-value, but if `DTSTART` has `VALUE=DATE`, `DTEND` must also be a date, and it's
-not required to actually specify this.
-
-So even with this basic model, that's in itself a robust way to parse this
-format, we will need a whole bunch of exceptions to the rules.
-
-### iCalendar and vCard differences
-
-In iCalendar multiple values are always separated with `;`, but in vCards they
-are sometimes `;` and sometimes `,`. So we must also somehow special-case
-and deal with these differences.
-
-### Conclusion
-
-When these modifications are implemented, I believe we should be able to handle
-any future oddity in the realm of vCard and iCalendar.
-
-I really want to push this library to the point where it's the one and only
-choice for PHP to deal with these formats, and really these two major issues
-(value-based encoding and escaping) are the things that stand it's way.
-
-After those have been tackled, I believe there will be no other option for
-PHP developers to parse and generate these formats.
-
-Generally I believe that these formats could have been great and re-usable for
-other applications. The concepts of grouping, the way components are nested
-are actually not bad.
-
-But a lack of properly defining how things should be done, the fact that not
-every single value can be encoded (see the `bonus` chapter), and the fact that
-almost every single design concept (`VALUE=`) has it's exceptions, makes me
-believe that this format is a dead end, and there should never be another
-`vAnything` or `iAnything`.
diff --git a/lib/Sabre/VObject/Parameter.php b/lib/Sabre/VObject/Parameter.php
index 37c9fd0..72bf03b 100644
--- a/lib/Sabre/VObject/Parameter.php
+++ b/lib/Sabre/VObject/Parameter.php
@@ -82,7 +82,11 @@ class Parameter extends Node {
             '\,',
         );
 
-        return $this->name . '=' . str_replace($src, $out, $this->value);
+        $value = str_replace($src, $out, $this->value);
+        if (strpos($value,":")!==false) {
+            $value = '"' . $value . '"';
+        }
+        return $this->name . '=' . $value;
 
     }
 
diff --git a/lib/Sabre/VObject/Property.php b/lib/Sabre/VObject/Property.php
index ad54146..63ae645 100644
--- a/lib/Sabre/VObject/Property.php
+++ b/lib/Sabre/VObject/Property.php
@@ -188,10 +188,12 @@ class Property extends Node {
         $src = array(
             '\\',
             "\n",
+            "\r",
         );
         $out = array(
             '\\\\',
             '\n',
+            '',
         );
         $str.=':' . str_replace($src, $out, $this->value);
 
diff --git a/lib/Sabre/VObject/RecurrenceIterator.php b/lib/Sabre/VObject/RecurrenceIterator.php
index 0d5997e..8bd4ed2 100644
--- a/lib/Sabre/VObject/RecurrenceIterator.php
+++ b/lib/Sabre/VObject/RecurrenceIterator.php
@@ -105,7 +105,6 @@ class RecurrenceIterator implements \Iterator {
      */
     public $overriddenEvents = array();
 
-
     /**
      * Frequency is one of: secondly, minutely, hourly, daily, weekly, monthly,
      * yearly.
@@ -297,6 +296,13 @@ class RecurrenceIterator implements \Iterator {
     private $nextDate;
 
     /**
+     * This counts the number of overridden events we've handled so far
+     *
+     * @var int
+     */
+    private $handledOverridden = 0;
+
+    /**
      * Creates the iterator
      *
      * You should pass a VCALENDAR component, as well as the UID of the event
@@ -326,6 +332,9 @@ class RecurrenceIterator implements \Iterator {
                 }
             }
         }
+
+        ksort($this->overriddenEvents);
+
         if (!$this->baseEvent) {
             throw new \InvalidArgumentException('Could not find a base event with uid: ' . $uid);
         }
@@ -552,8 +561,18 @@ class RecurrenceIterator implements \Iterator {
         if (!is_null($this->count)) {
             return $this->counter < $this->count;
         }
-        if (!is_null($this->until)) {
-            return $this->currentDate <= $this->until;
+        if (!is_null($this->until) && $this->currentDate > $this->until) {
+
+            // Need to make sure there's no overridden events past the
+            // until date.
+            foreach($this->overriddenEvents as $overriddenEvent) {
+
+                if ($overriddenEvent->DTSTART->getDateTime() >= $this->currentDate) {
+
+                    return true;
+                }
+            }
+            return false;
         }
         return true;
 
@@ -608,93 +627,106 @@ class RecurrenceIterator implements \Iterator {
      */
     public function next() {
 
-        /*
-        if (!is_null($this->count) && $this->counter >= $this->count) {
-            $this->currentDate = null;
-        }*/
-
-
         $previousStamp = $this->currentDate->getTimeStamp();
 
-        while(true) {
-
-            $this->currentOverriddenEvent = null;
+        // Finding the next overridden event in line, and storing that for
+        // later use.
+        $overriddenEvent = null;
+        $overriddenDate = null;
+        $this->currentOverriddenEvent = null;
+
+        foreach($this->overriddenEvents as $index=>$event) {
+            if ($index > $previousStamp) {
+                $overriddenEvent = $event;
+                $overriddenDate = clone $event->DTSTART->getDateTime();
+                break;
+            }
+        }
 
-            // If we have a next date 'stored', we use that
-            if ($this->nextDate) {
+        // If we have a stored 'next date', we will use that.
+        if ($this->nextDate) {
+            if (!$overriddenDate || $this->nextDate < $overriddenDate) {
                 $this->currentDate = $this->nextDate;
                 $currentStamp = $this->currentDate->getTimeStamp();
                 $this->nextDate = null;
             } else {
+                $this->currentDate = clone $overriddenDate;
+                $this->currentOverriddenEvent = $overriddenEvent;
+            }
+            $this->counter++;
+            return;
+        }
 
-                // Otherwise, we calculate it
-                switch($this->frequency) {
-
-                    case 'hourly' :
-                        $this->nextHourly();
-                        break;
+        while(true) {
 
-                    case 'daily' :
-                        $this->nextDaily();
-                        break;
+            // Otherwise, we find the next event in the normal RRULE
+            // sequence.
+            switch($this->frequency) {
 
-                    case 'weekly' :
-                        $this->nextWeekly();
-                        break;
+                case 'hourly' :
+                    $this->nextHourly();
+                    break;
 
-                    case 'monthly' :
-                        $this->nextMonthly();
-                        break;
+                case 'daily' :
+                    $this->nextDaily();
+                    break;
 
-                    case 'yearly' :
-                        $this->nextYearly();
-                        break;
+                case 'weekly' :
+                    $this->nextWeekly();
+                    break;
 
-                }
-                $currentStamp = $this->currentDate->getTimeStamp();
+                case 'monthly' :
+                    $this->nextMonthly();
+                    break;
 
-                // Checking exception dates
-                foreach($this->exceptionDates as $exceptionDate) {
-                    if ($this->currentDate == $exceptionDate) {
-                        $this->counter++;
-                        continue 2;
-                    }
-                }
-                foreach($this->overriddenDates as $overriddenDate) {
-                    if ($this->currentDate == $overriddenDate) {
-                        continue 2;
-                    }
-                }
+                case 'yearly' :
+                    $this->nextYearly();
+                    break;
 
             }
+            $currentStamp = $this->currentDate->getTimeStamp();
 
-            // Checking overridden events
-            foreach($this->overriddenEvents as $index=>$event) {
-                if ($index > $previousStamp && $index <= $currentStamp) {
 
-                    // We're moving the 'next date' aside, for later use.
-                    $this->nextDate = clone $this->currentDate;
-
-                    $this->currentDate = $event->DTSTART->getDateTime();
-                    $this->currentOverriddenEvent = $event;
-
-                    break;
+            // Checking exception dates
+            foreach($this->exceptionDates as $exceptionDate) {
+                if ($this->currentDate == $exceptionDate) {
+                    $this->counter++;
+                    continue 2;
+                }
+            }
+            foreach($this->overriddenDates as $check) {
+                if ($this->currentDate == $check) {
+                    continue 2;
                 }
             }
-
             break;
 
         }
 
-        /*
-        if (!is_null($this->until)) {
-            if($this->currentDate > $this->until) {
-                $this->currentDate = null;
-            }
-        }*/
 
+
+        // Is the date we have actually higher than the next overiddenEvent?
+        if ($overriddenDate && $this->currentDate > $overriddenDate) {
+            $this->nextDate = clone $this->currentDate;
+            $this->currentDate = clone $overriddenDate;
+            $this->currentOverriddenEvent = $overriddenEvent;
+            $this->handledOverridden++;
+        }
         $this->counter++;
 
+
+        /*
+         * If we have overridden events left in the queue, but our counter is
+         * running out, we should grab one of those.
+         */
+        if (!is_null($overriddenEvent) && !is_null($this->count) && count($this->overriddenEvents) - $this->handledOverridden >= ($this->count - $this->counter)) {
+
+            $this->currentOverriddenEvent = $overriddenEvent;
+            $this->currentDate = clone $overriddenDate;
+            $this->handledOverridden++;
+
+        }
+
     }
 
     /**
diff --git a/lib/Sabre/VObject/Version.php b/lib/Sabre/VObject/Version.php
index 373980e..2a64140 100644
--- a/lib/Sabre/VObject/Version.php
+++ b/lib/Sabre/VObject/Version.php
@@ -14,7 +14,7 @@ class Version {
     /**
      * Full version number
      */
-    const VERSION = '2.1.0';
+    const VERSION = '2.1.3';
 
     /**
      * Stability : alpha, beta, stable
diff --git a/tests/Sabre/VObject/Issue48Test.php b/tests/Sabre/VObject/Issue48Test.php
new file mode 100644
index 0000000..980d432
--- /dev/null
+++ b/tests/Sabre/VObject/Issue48Test.php
@@ -0,0 +1,47 @@
+<?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 RecurrenceIterator($vcal, 'foo');
+
+        $result = iterator_to_array($it);
+
+        $tz = new DateTimeZone('Europe/Moscow');
+
+        $this->assertEquals(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),
+        ), $result);
+
+    }
+
+}
diff --git a/tests/Sabre/VObject/Issue50Test.php b/tests/Sabre/VObject/Issue50Test.php
new file mode 100644
index 0000000..fdb012b
--- /dev/null
+++ b/tests/Sabre/VObject/Issue50Test.php
@@ -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 RecurrenceIterator($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);
+
+    }
+
+}
diff --git a/tests/Sabre/VObject/ParameterTest.php b/tests/Sabre/VObject/ParameterTest.php
index a96d53f..90eb5d2 100644
--- a/tests/Sabre/VObject/ParameterTest.php
+++ b/tests/Sabre/VObject/ParameterTest.php
@@ -34,4 +34,11 @@ class ParameterTest extends \PHPUnit_Framework_TestCase {
         $this->assertEquals('NAME',$param->serialize());
 
     }
+
+    function testSerializeColon() {
+
+        $param = new Parameter('name','va:lue');
+        $this->assertEquals('NAME="va:lue"',$param->serialize());
+
+    }
 }
diff --git a/tests/Sabre/VObject/RecurrenceIteratorIncorrectExpandTest.php b/tests/Sabre/VObject/RecurrenceIteratorIncorrectExpandTest.php
new file mode 100644
index 0000000..9adc853
--- /dev/null
+++ b/tests/Sabre/VObject/RecurrenceIteratorIncorrectExpandTest.php
@@ -0,0 +1,62 @@
+<?php
+
+namespace Sabre\VObject;
+
+use
+    DateTime,
+    DateTimeZone;
+
+/**
+ * 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;VALUE=DATE-TIME:20130711T050000Z
+DTEND;VALUE=DATE-TIME:20130711T053000Z
+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));
+    
+    }
+
+}
diff --git a/tests/Sabre/VObject/RecurrenceIteratorMissingOverriddenTest.php b/tests/Sabre/VObject/RecurrenceIteratorMissingOverriddenTest.php
new file mode 100644
index 0000000..f311329
--- /dev/null
+++ b/tests/Sabre/VObject/RecurrenceIteratorMissingOverriddenTest.php
@@ -0,0 +1,63 @@
+<?php
+
+namespace Sabre\VObject;
+
+use
+    DateTime,
+    DateTimeZone;
+
+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;VALUE=DATE-TIME:20130727T120000Z
+DURATION:PT1H
+SUMMARY:A
+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));
+    
+    }
+
+}
diff --git a/tests/Sabre/VObject/SlashRTest.php b/tests/Sabre/VObject/SlashRTest.php
new file mode 100644
index 0000000..ebbfb04
--- /dev/null
+++ b/tests/Sabre/VObject/SlashRTest.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace Sabre\VObject;
+
+/**
+ * This issue was pointed out in Issue 55. \r should be stripped completely 
+ * when encoding property values.
+ */
+class SlashRTest extends \PHPUnit_Framework_TestCase {
+
+    function testEncode() {
+
+        $prop = new \Sabre\VObject\Property('test', "abc\r\ndef");
+        $this->assertEquals("TEST:abc\\ndef\r\n", $prop->serialize());
+
+    }
+
+
+}
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
index d1145d2..3608abe 100644
--- a/tests/bootstrap.php
+++ b/tests/bootstrap.php
@@ -1,5 +1,7 @@
 <?php
 
+date_default_timezone_set('UTC');
+
 $try = array(
     __DIR__ . '/../vendor/autoload.php',
     __DIR__ . '/../../../autoload.php',

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-owncloud/php-sabre-vobject.git



More information about the Pkg-owncloud-commits mailing list