assertXMLEqualsToMimeDir( << GREGORIAN -//Example Inc.//Example Calendar//EN 2.0 2008-02-05T19:12:24Z 2008-10-06 Planning meeting 4088E990AD89CB3DBB484909 XML , 'BEGIN:VCALENDAR'."\n". // VERSION comes first because this is required by vCard 4.0. 'VERSION:2.0'."\n". 'CALSCALE:GREGORIAN'."\n". 'PRODID:-//Example Inc.//Example Calendar//EN'."\n". 'BEGIN:VEVENT'."\n". 'DTSTAMP:20080205T191224Z'."\n". 'DTSTART;VALUE=DATE:20081006'."\n". 'SUMMARY:Planning meeting'."\n". 'UID:4088E990AD89CB3DBB484909'."\n". 'END:VEVENT'."\n". 'END:VCALENDAR'."\n" ); } public function testRFC6321Example2() { $xml = << -//Example Inc.//Example Client//EN 2.0 2004-01-10T03:28:45Z US/Eastern 2000-04-04T02:00:00 YEARLY 1SU 4 EDT -05:00 -04:00 2000-10-26T02:00:00 YEARLY -1SU 10 EST -04:00 -05:00 2006-02-06T00:11:21Z US/Eastern 2006-01-02T12:00:00 PT1H DAILY 5 US/Eastern 2006-01-02T15:00:00 PT2H Event #2 We are having a meeting all this week at 12 pm for one hour, with an additional meeting on the first day 2 hours long. Please bring your own lunch for the 12 pm meetings. 00959BC664CA650E933C892C@example.com 2006-02-06T00:11:21Z US/Eastern 2006-01-04T14:00:00 PT1H US/Eastern 2006-01-04T12:00:00 Event #2 bis 00959BC664CA650E933C892C@example.com XML; $component = VObject\Reader::readXML($xml); $this->assertVObjectEqualsVObject( 'BEGIN:VCALENDAR'."\n". 'VERSION:2.0'."\n". 'PRODID:-//Example Inc.//Example Client//EN'."\n". 'BEGIN:VTIMEZONE'."\n". 'LAST-MODIFIED:20040110T032845Z'."\n". 'TZID:US/Eastern'."\n". 'BEGIN:DAYLIGHT'."\n". 'DTSTART:20000404T020000'."\n". 'RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4'."\n". 'TZNAME:EDT'."\n". 'TZOFFSETFROM:-0500'."\n". 'TZOFFSETTO:-0400'."\n". 'END:DAYLIGHT'."\n". 'BEGIN:STANDARD'."\n". 'DTSTART:20001026T020000'."\n". 'RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10'."\n". 'TZNAME:EST'."\n". 'TZOFFSETFROM:-0400'."\n". 'TZOFFSETTO:-0500'."\n". 'END:STANDARD'."\n". 'END:VTIMEZONE'."\n". 'BEGIN:VEVENT'."\n". 'DTSTAMP:20060206T001121Z'."\n". 'DTSTART;TZID=US/Eastern:20060102T120000'."\n". 'DURATION:PT1H'."\n". 'RRULE:FREQ=DAILY;COUNT=5'."\n". 'RDATE;TZID=US/Eastern;VALUE=PERIOD:20060102T150000/PT2H'."\n". 'SUMMARY:Event #2'."\n". 'DESCRIPTION:We are having a meeting all this week at 12\npm for one hour\, '."\n". ' with an additional meeting on the first day\n2 hours long.\nPlease bring y'."\n". ' our own lunch for the 12 pm\nmeetings.'."\n". 'UID:00959BC664CA650E933C892C@example.com'."\n". 'END:VEVENT'."\n". 'BEGIN:VEVENT'."\n". 'DTSTAMP:20060206T001121Z'."\n". 'DTSTART;TZID=US/Eastern:20060104T140000'."\n". 'DURATION:PT1H'."\n". 'RECURRENCE-ID;TZID=US/Eastern:20060104T120000'."\n". 'SUMMARY:Event #2 bis'."\n". 'UID:00959BC664CA650E933C892C@example.com'."\n". 'END:VEVENT'."\n". 'END:VCALENDAR'."\n", VObject\Writer::write($component) ); } /** * iCalendar Stream. */ public function testRFC6321Section3_2() { $this->assertXMLReflexivelyEqualsToMimeDir( << XML , 'BEGIN:VCALENDAR'."\n". 'END:VCALENDAR'."\n" ); } /** * All components exist. */ public function testRFC6321Section3_3() { $this->assertXMLReflexivelyEqualsToMimeDir( << XML , 'BEGIN:VCALENDAR'."\n". 'BEGIN:VTIMEZONE'."\n". 'END:VTIMEZONE'."\n". 'BEGIN:VEVENT'."\n". 'END:VEVENT'."\n". 'BEGIN:VTODO'."\n". 'END:VTODO'."\n". 'BEGIN:VJOURNAL'."\n". 'END:VJOURNAL'."\n". 'BEGIN:VFREEBUSY'."\n". 'END:VFREEBUSY'."\n". 'BEGIN:STANDARD'."\n". 'END:STANDARD'."\n". 'BEGIN:DAYLIGHT'."\n". 'END:DAYLIGHT'."\n". 'BEGIN:VALARM'."\n". 'END:VALARM'."\n". 'END:VCALENDAR'."\n" ); } /** * Properties, Special Cases, GEO. */ public function testRFC6321Section3_4_1_2() { $this->assertXMLReflexivelyEqualsToMimeDir( << 37.386013 -122.082932 XML , 'BEGIN:VCALENDAR'."\n". 'GEO:37.386013;-122.082932'."\n". 'END:VCALENDAR'."\n" ); } /** * Properties, Special Cases, REQUEST-STATUS. */ public function testRFC6321Section3_4_1_3() { // Example 1 of RFC5545, Section 3.8.8.3. $this->assertXMLReflexivelyEqualsToMimeDir( << 2.0 Success XML , 'BEGIN:VCALENDAR'."\n". 'REQUEST-STATUS:2.0;Success'."\n". 'END:VCALENDAR'."\n" ); // Example 2 of RFC5545, Section 3.8.8.3. $this->assertXMLReflexivelyEqualsToMimeDir( << 3.1 Invalid property value DTSTART:96-Apr-01 XML , 'BEGIN:VCALENDAR'."\n". 'REQUEST-STATUS:3.1;Invalid property value;DTSTART:96-Apr-01'."\n". 'END:VCALENDAR'."\n" ); // Example 3 of RFC5545, Section 3.8.8.3. $this->assertXMLReflexivelyEqualsToMimeDir( << 2.8 Success, repeating event ignored. Scheduled as a single event. RRULE:FREQ=WEEKLY;INTERVAL=2 XML , 'BEGIN:VCALENDAR'."\n". 'REQUEST-STATUS:2.8;Success\, repeating event ignored. Scheduled as a single'."\n". ' event.;RRULE:FREQ=WEEKLY\;INTERVAL=2'."\n". 'END:VCALENDAR'."\n" ); // Example 4 of RFC5545, Section 3.8.8.3. $this->assertXMLReflexivelyEqualsToMimeDir( << 4.1 Event conflict. Date-time is busy. XML , 'BEGIN:VCALENDAR'."\n". 'REQUEST-STATUS:4.1;Event conflict. Date-time is busy.'."\n". 'END:VCALENDAR'."\n" ); // Example 5 of RFC5545, Section 3.8.8.3. $this->assertXMLReflexivelyEqualsToMimeDir( << 3.7 Invalid calendar user ATTENDEE:mailto:jsmith@example.com XML , 'BEGIN:VCALENDAR'."\n". 'REQUEST-STATUS:3.7;Invalid calendar user;ATTENDEE:mailto:jsmith@example.com'."\n". 'END:VCALENDAR'."\n" ); } /** * Values, Binary. */ public function testRFC6321Section3_6_1() { $this->assertXMLEqualsToMimeDir( << SGVsbG8gV29ybGQh XML , 'BEGIN:VCALENDAR'."\n". 'ATTACH:SGVsbG8gV29ybGQh'."\n". 'END:VCALENDAR'."\n" ); // In vCard 4, BINARY no longer exists and is replaced by URI. $this->assertXMLReflexivelyEqualsToMimeDir( << SGVsbG8gV29ybGQh XML , 'BEGIN:VCALENDAR'."\n". 'ATTACH:SGVsbG8gV29ybGQh'."\n". 'END:VCALENDAR'."\n" ); } /** * Values, Boolean. */ public function testRFC6321Section3_6_2() { $this->assertXMLEqualsToMimeDir( << true mailto:cyrus@example.com XML , 'BEGIN:VCALENDAR'."\n". 'ATTENDEE;RSVP=true:mailto:cyrus@example.com'."\n". 'END:VCALENDAR'."\n" ); } /** * Values, Calendar User Address. */ public function testRFC6321Section3_6_3() { $this->assertXMLReflexivelyEqualsToMimeDir( << mailto:cyrus@example.com XML , 'BEGIN:VCALENDAR'."\n". 'ATTENDEE:mailto:cyrus@example.com'."\n". 'END:VCALENDAR'."\n" ); } /** * Values, Date. */ public function testRFC6321Section3_6_4() { $this->assertXMLReflexivelyEqualsToMimeDir( << 2011-05-17 XML , 'BEGIN:VCALENDAR'."\n". 'DTSTART;VALUE=DATE:20110517'."\n". 'END:VCALENDAR'."\n" ); } /** * Values, Date-Time. */ public function testRFC6321Section3_6_5() { $this->assertXMLReflexivelyEqualsToMimeDir( << 2011-05-17T12:00:00 XML , 'BEGIN:VCALENDAR'."\n". 'DTSTART:20110517T120000'."\n". 'END:VCALENDAR'."\n" ); } /** * Values, Duration. */ public function testRFC6321Section3_6_6() { $this->assertXMLReflexivelyEqualsToMimeDir( << P1D XML , 'BEGIN:VCALENDAR'."\n". 'DURATION:P1D'."\n". 'END:VCALENDAR'."\n" ); } /** * Values, Float. */ public function testRFC6321Section3_6_7() { // GEO uses with a positive and a non-negative numbers. $this->testRFC6321Section3_4_1_2(); } /** * Values, Integer. */ public function testRFC6321Section3_6_8() { $this->assertXMLEqualsToMimeDir( << 42 XML , 'BEGIN:VCALENDAR'."\n". 'FOO:42'."\n". 'END:VCALENDAR'."\n" ); $this->assertXMLEqualsToMimeDir( << -42 XML , 'BEGIN:VCALENDAR'."\n". 'FOO:-42'."\n". 'END:VCALENDAR'."\n" ); } /** * Values, Period of Time. */ public function testRFC6321Section3_6_9() { $this->assertXMLReflexivelyEqualsToMimeDir( << 2011-05-17T12:00:00 P1H XML , 'BEGIN:VCALENDAR'."\n". 'FREEBUSY:20110517T120000/P1H'."\n". 'END:VCALENDAR'."\n" ); $this->assertXMLReflexivelyEqualsToMimeDir( << 2011-05-17T12:00:00 2012-05-17T12:00:00 XML , 'BEGIN:VCALENDAR'."\n". 'FREEBUSY:20110517T120000/20120517T120000'."\n". 'END:VCALENDAR'."\n" ); } /** * Values, Recurrence Rule. */ public function testRFC6321Section3_6_10() { $this->assertXMLReflexivelyEqualsToMimeDir( << YEARLY 5 -1SU 10 XML , 'BEGIN:VCALENDAR'."\n". 'RRULE:FREQ=YEARLY;COUNT=5;BYDAY=-1SU;BYMONTH=10'."\n". 'END:VCALENDAR'."\n" ); } /** * Values, Text. */ public function testRFC6321Section3_6_11() { $this->assertXMLReflexivelyEqualsToMimeDir( << GREGORIAN XML , 'BEGIN:VCALENDAR'."\n". 'CALSCALE:GREGORIAN'."\n". 'END:VCALENDAR'."\n" ); } /** * Values, Time. */ public function testRFC6321Section3_6_12() { $this->assertXMLEqualsToMimeDir( << XML , 'BEGIN:VCALENDAR'."\n". 'FOO:120000'."\n". 'END:VCALENDAR'."\n" ); } /** * Values, URI. */ public function testRFC6321Section3_6_13() { $this->assertXMLReflexivelyEqualsToMimeDir( << http://calendar.example.com XML , 'BEGIN:VCALENDAR'."\n". 'ATTACH:http://calendar.example.com'."\n". 'END:VCALENDAR'."\n" ); } /** * Values, UTC Offset. */ public function testRFC6321Section3_6_14() { // Example 1 of RFC5545, Section 3.3.14. $this->assertXMLReflexivelyEqualsToMimeDir( << -05:00 XML , 'BEGIN:VCALENDAR'."\n". 'TZOFFSETFROM:-0500'."\n". 'END:VCALENDAR'."\n" ); // Example 2 of RFC5545, Section 3.3.14. $this->assertXMLReflexivelyEqualsToMimeDir( << +01:00 XML , 'BEGIN:VCALENDAR'."\n". 'TZOFFSETFROM:+0100'."\n". 'END:VCALENDAR'."\n" ); } /** * Handling Unrecognized Properties or Parameters. */ public function testRFC6321Section5() { $this->assertXMLReflexivelyEqualsToMimeDir( << 20110512T120000Z XML , 'BEGIN:VCALENDAR'."\n". 'X-PROPERTY:20110512T120000Z'."\n". 'END:VCALENDAR'."\n" ); $this->assertXMLReflexivelyEqualsToMimeDir( << PT30M 2011-05-12T13:00:00Z XML , 'BEGIN:VCALENDAR'."\n". 'DTSTART;X-PARAM=PT30M:20110512T130000Z'."\n". 'END:VCALENDAR'."\n" ); } public function testRDateWithDateTime() { $this->assertXMLReflexivelyEqualsToMimeDir( << 2008-02-05T19:12:24Z XML , 'BEGIN:VCALENDAR'."\n". 'RDATE:20080205T191224Z'."\n". 'END:VCALENDAR'."\n" ); $this->assertXMLReflexivelyEqualsToMimeDir( << 2008-02-05T19:12:24Z 2009-02-05T19:12:24Z XML , 'BEGIN:VCALENDAR'."\n". 'RDATE:20080205T191224Z,20090205T191224Z'."\n". 'END:VCALENDAR'."\n" ); } public function testRDateWithDate() { $this->assertXMLEqualsToMimeDir( << 2008-10-06 XML , 'BEGIN:VCALENDAR'."\n". 'RDATE:20081006'."\n". 'END:VCALENDAR'."\n" ); $this->assertXMLEqualsToMimeDir( << 2008-10-06 2009-10-06 2010-10-06 XML , 'BEGIN:VCALENDAR'."\n". 'RDATE:20081006,20091006,20101006'."\n". 'END:VCALENDAR'."\n" ); } public function testRDateWithPeriod() { $this->assertXMLReflexivelyEqualsToMimeDir( << US/Eastern 2006-01-02T15:00:00 PT2H XML , 'BEGIN:VCALENDAR'."\n". 'RDATE;TZID=US/Eastern;VALUE=PERIOD:20060102T150000/PT2H'."\n". 'END:VCALENDAR'."\n" ); $this->assertXMLEqualsToMimeDir( << US/Eastern 2006-01-02T15:00:00 PT2H 2008-01-02T15:00:00 PT1H XML , 'BEGIN:VCALENDAR'."\n". 'RDATE;TZID=US/Eastern;VALUE=PERIOD:20060102T150000/PT2H,20080102T150000/PT1'."\n". ' H'."\n". 'END:VCALENDAR'."\n" ); } /** * Basic example. */ public function testRFC6351Basic() { $this->assertXMLReflexivelyEqualsToMimeDir( << J. Doe Doe J. XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'FN:J. Doe'."\n". 'N:Doe;J.;;;'."\n". 'END:VCARD'."\n" ); } /** * Example 1. */ public function testRFC6351Example1() { $this->assertXMLReflexivelyEqualsToMimeDir( << J. Doe Doe J. image/jpeg alien.jpg My web page! XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'FN:J. Doe'."\n". 'N:Doe;J.;;;'."\n". 'X-FILE;MEDIATYPE=image/jpeg:alien.jpg'."\n". 'XML:M'."\n". ' y web page!'."\n". 'END:VCARD'."\n" ); } /** * Design Considerations. */ public function testRFC6351Section5() { $this->assertXMLEqualsToMimeDir( << voice video tel:+1-555-555-555 XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'TEL;TYPE="voice,video":tel:+1-555-555-555'."\n". 'END:VCARD'."\n" ); $this->assertXMLReflexivelyEqualsToMimeDir( << voice video tel:+1-555-555-555 XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'TEL;TYPE="voice,video":tel:+1-555-555-555'."\n". 'END:VCARD'."\n" ); } /** * Design Considerations. */ public function testRFC6351Section5Group() { $this->assertXMLReflexivelyEqualsToMimeDir( << tel:+1-555-555-556 tel:+1-555-555-555 Gordon Gordon XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'TEL:tel:+1-555-555-556'."\n". 'contact.TEL:tel:+1-555-555-555'."\n". 'contact.FN:Gordon'."\n". 'media.FN:Gordon'."\n". 'END:VCARD'."\n" ); } /** * Extensibility. */ public function testRFC6351Section5_1_NoNamespace() { $this->assertXMLEqualsToMimeDir( << 1 value goes here XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'X-MY-PROP;PREF=1:value goes here'."\n". 'END:VCARD'."\n" ); } /** * Section 4.3.1 of Relax NG Schema: value-date. */ public function testRFC6351ValueDateWithYearMonthDay() { $this->assertXMLReflexivelyEqualsToMimeDir( << 20150128 XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:20150128'."\n". 'END:VCARD'."\n" ); } /** * Section 4.3.1 of Relax NG Schema: value-date. */ public function testRFC6351ValueDateWithYearMonth() { $this->assertXMLReflexivelyEqualsToMimeDir( << 2015-01 XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:2015-01'."\n". 'END:VCARD'."\n" ); } /** * Section 4.3.1 of Relax NG Schema: value-date. */ public function testRFC6351ValueDateWithMonth() { $this->assertXMLReflexivelyEqualsToMimeDir( << --01 XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:--01'."\n". 'END:VCARD'."\n" ); } /** * Section 4.3.1 of Relax NG Schema: value-date. */ public function testRFC6351ValueDateWithMonthDay() { $this->assertXMLReflexivelyEqualsToMimeDir( << --0128 XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:--0128'."\n". 'END:VCARD'."\n" ); } /** * Section 4.3.1 of Relax NG Schema: value-date. */ public function testRFC6351ValueDateWithDay() { $this->assertXMLReflexivelyEqualsToMimeDir( << ---28 XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:---28'."\n". 'END:VCARD'."\n" ); } /** * Section 4.3.2 of Relax NG Schema: value-time. */ public function testRFC6351ValueTimeWithHour() { $this->assertXMLReflexivelyEqualsToMimeDir( << 13 XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:13'."\n". 'END:VCARD'."\n" ); } /** * Section 4.3.2 of Relax NG Schema: value-time. */ public function testRFC6351ValueTimeWithHourMinute() { $this->assertXMLReflexivelyEqualsToMimeDir( << 1353 XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:1353'."\n". 'END:VCARD'."\n" ); } /** * Section 4.3.2 of Relax NG Schema: value-time. */ public function testRFC6351ValueTimeWithHourMinuteSecond() { $this->assertXMLReflexivelyEqualsToMimeDir( << 135301 XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:135301'."\n". 'END:VCARD'."\n" ); } /** * Section 4.3.2 of Relax NG Schema: value-time. */ public function testRFC6351ValueTimeWithMinute() { $this->assertXMLReflexivelyEqualsToMimeDir( << -53 XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:-53'."\n". 'END:VCARD'."\n" ); } /** * Section 4.3.2 of Relax NG Schema: value-time. */ public function testRFC6351ValueTimeWithMinuteSecond() { $this->assertXMLReflexivelyEqualsToMimeDir( << -5301 XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:-5301'."\n". 'END:VCARD'."\n" ); } /** * Section 4.3.2 of Relax NG Schema: value-time. */ public function testRFC6351ValueTimeWithSecond() { $this->assertTrue(true); /* * According to the Relax NG Schema, there is a conflict between * value-date and value-time. The --01 syntax can only match a * value-date because of the higher priority set in * value-date-and-or-time. So we basically skip this test. * $this->assertXMLReflexivelyEqualsToMimeDir( << --01 XML , 'BEGIN:VCARD' . "\n" . 'VERSION:4.0' . "\n" . 'BDAY:--01' . "\n" . 'END:VCARD' . "\n" ); */ } /** * Section 4.3.2 of Relax NG Schema: value-time. */ public function testRFC6351ValueTimeWithSecondZ() { $this->assertXMLReflexivelyEqualsToMimeDir( << --01Z XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:--01Z'."\n". 'END:VCARD'."\n" ); } /** * Section 4.3.2 of Relax NG Schema: value-time. */ public function testRFC6351ValueTimeWithSecondTZ() { $this->assertXMLReflexivelyEqualsToMimeDir( << --01+1234 XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:--01+1234'."\n". 'END:VCARD'."\n" ); } /** * Section 4.3.3 of Relax NG Schema: value-date-time. */ public function testRFC6351ValueDateTimeWithYearMonthDayHour() { $this->assertXMLReflexivelyEqualsToMimeDir( << 20150128T13 XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:20150128T13'."\n". 'END:VCARD'."\n" ); } /** * Section 4.3.3 of Relax NG Schema: value-date-time. */ public function testRFC6351ValueDateTimeWithMonthDayHour() { $this->assertXMLReflexivelyEqualsToMimeDir( << --0128T13 XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:--0128T13'."\n". 'END:VCARD'."\n" ); } /** * Section 4.3.3 of Relax NG Schema: value-date-time. */ public function testRFC6351ValueDateTimeWithDayHour() { $this->assertXMLReflexivelyEqualsToMimeDir( << ---28T13 XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:---28T13'."\n". 'END:VCARD'."\n" ); } /** * Section 4.3.3 of Relax NG Schema: value-date-time. */ public function testRFC6351ValueDateTimeWithDayHourMinute() { $this->assertXMLReflexivelyEqualsToMimeDir( << ---28T1353 XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:---28T1353'."\n". 'END:VCARD'."\n" ); } /** * Section 4.3.3 of Relax NG Schema: value-date-time. */ public function testRFC6351ValueDateTimeWithDayHourMinuteSecond() { $this->assertXMLReflexivelyEqualsToMimeDir( << ---28T135301 XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:---28T135301'."\n". 'END:VCARD'."\n" ); } /** * Section 4.3.3 of Relax NG Schema: value-date-time. */ public function testRFC6351ValueDateTimeWithDayHourZ() { $this->assertXMLReflexivelyEqualsToMimeDir( << ---28T13Z XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:---28T13Z'."\n". 'END:VCARD'."\n" ); } /** * Section 4.3.3 of Relax NG Schema: value-date-time. */ public function testRFC6351ValueDateTimeWithDayHourTZ() { $this->assertXMLReflexivelyEqualsToMimeDir( << ---28T13+1234 XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:---28T13+1234'."\n". 'END:VCARD'."\n" ); } /** * Property: SOURCE. */ public function testRFC6350Section6_1_3() { $this->assertXMLReflexivelyEqualsToMimeDir( << ldap://ldap.example.com/cn=Babs%20Jensen,%20o=Babsco,%20c=US XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'SOURCE:ldap://ldap.example.com/cn=Babs%20Jensen\,%20o=Babsco\,%20c=US'."\n". 'END:VCARD'."\n" ); } /** * Property: KIND. */ public function testRFC6350Section6_1_4() { $this->assertXMLReflexivelyEqualsToMimeDir( << individual XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'KIND:individual'."\n". 'END:VCARD'."\n" ); } /** * Property: FN. */ public function testRFC6350Section6_2_1() { $this->assertXMLReflexivelyEqualsToMimeDir( << Mr. John Q. Public, Esq. XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'FN:Mr. John Q. Public\, Esq.'."\n". 'END:VCARD'."\n" ); } /** * Property: N. */ public function testRFC6350Section6_2_2() { $this->assertXMLReflexivelyEqualsToMimeDir( << Stevenson John Philip,Paul Dr. Jr.,M.D.,A.C.P. XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'N:Stevenson;John;Philip\,Paul;Dr.;Jr.\,M.D.\,A.C.P.'."\n". 'END:VCARD'."\n" ); } /** * Property: NICKNAME. */ public function testRFC6350Section6_2_3() { $this->assertXMLReflexivelyEqualsToMimeDir( << Jim Jimmie XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'NICKNAME:Jim,Jimmie'."\n". 'END:VCARD'."\n" ); } /** * Property: PHOTO. */ public function testRFC6350Section6_2_4() { $this->assertXMLReflexivelyEqualsToMimeDir( << http://www.example.com/pub/photos/jqpublic.gif XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'PHOTO:http://www.example.com/pub/photos/jqpublic.gif'."\n". 'END:VCARD'."\n" ); } public function testRFC6350Section6_2_5() { $this->assertXMLReflexivelyEqualsToMimeDir( << 19531015T231000Z XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'BDAY:19531015T231000Z'."\n". 'END:VCARD'."\n" ); } public function testRFC6350Section6_2_6() { $this->assertXMLReflexivelyEqualsToMimeDir( << 19960415 XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'ANNIVERSARY:19960415'."\n". 'END:VCARD'."\n" ); } /** * Property: GENDER. */ public function testRFC6350Section6_2_7() { $this->assertXMLReflexivelyEqualsToMimeDir( << Jim Jimmie XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'GENDER:Jim;Jimmie'."\n". 'END:VCARD'."\n" ); } /** * Property: ADR. */ public function testRFC6350Section6_3_1() { $this->assertXMLReflexivelyEqualsToMimeDir( << 123 Main Street Any Town CA 91921-1234 U.S.A. XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'ADR:;;123 Main Street;Any Town;CA;91921-1234;U.S.A.'."\n". 'END:VCARD'."\n" ); } /** * Property: TEL. */ public function testRFC6350Section6_4_1() { /* * Quoting RFC: * > Value type: By default, it is a single free-form text value (for * > backward compatibility with vCard 3), but it SHOULD be reset to a * > URI value. It is expected that the URI scheme will be "tel", as * > specified in [RFC3966], but other schemes MAY be used. * * So first, we test xCard/URI to vCard/URI. * Then, we test xCard/TEXT to vCard/TEXT to xCard/TEXT. */ $this->assertXMLEqualsToMimeDir( << home tel:+33-01-23-45-67 XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'TEL;TYPE=home:tel:+33-01-23-45-67'."\n". 'END:VCARD'."\n" ); $this->assertXMLReflexivelyEqualsToMimeDir( << home tel:+33-01-23-45-67 XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'TEL;TYPE=home:tel:+33-01-23-45-67'."\n". 'END:VCARD'."\n" ); } /** * Property: EMAIL. */ public function testRFC6350Section6_4_2() { $this->assertXMLReflexivelyEqualsToMimeDir( << work jqpublic@xyz.example.com XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'EMAIL;TYPE=work:jqpublic@xyz.example.com'."\n". 'END:VCARD'."\n" ); } /** * Property: IMPP. */ public function testRFC6350Section6_4_3() { $this->assertXMLReflexivelyEqualsToMimeDir( << 1 xmpp:alice@example.com XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'IMPP;PREF=1:xmpp:alice@example.com'."\n". 'END:VCARD'."\n" ); } /** * Property: LANG. */ public function testRFC6350Section6_4_4() { $this->assertXMLReflexivelyEqualsToMimeDir( << work 2 en XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'LANG;TYPE=work;PREF=2:en'."\n". 'END:VCARD'."\n" ); } /** * Property: TZ. */ public function testRFC6350Section6_5_1() { $this->assertXMLReflexivelyEqualsToMimeDir( << Raleigh/North America XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'TZ:Raleigh/North America'."\n". 'END:VCARD'."\n" ); } /** * Property: GEO. */ public function testRFC6350Section6_5_2() { $this->assertXMLEqualsToMimeDir( << geo:37.386013,-122.082932 XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'GEO:geo:37.386013\,-122.082932'."\n". 'END:VCARD'."\n" ); $this->assertXMLReflexivelyEqualsToMimeDir( << geo:37.386013,-122.082932 XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'GEO:geo:37.386013\,-122.082932'."\n". 'END:VCARD'."\n" ); } /** * Property: TITLE. */ public function testRFC6350Section6_6_1() { $this->assertXMLReflexivelyEqualsToMimeDir( << <text>Research Scientist</text> XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'TITLE:Research Scientist'."\n". 'END:VCARD'."\n" ); } /** * Property: ROLE. */ public function testRFC6350Section6_6_2() { $this->assertXMLReflexivelyEqualsToMimeDir( << Project Leader XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'ROLE:Project Leader'."\n". 'END:VCARD'."\n" ); } /** * Property: LOGO. */ public function testRFC6350Section6_6_3() { $this->assertXMLReflexivelyEqualsToMimeDir( << http://www.example.com/pub/logos/abccorp.jpg XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'LOGO:http://www.example.com/pub/logos/abccorp.jpg'."\n". 'END:VCARD'."\n" ); } /** * Property: ORG. */ public function testRFC6350Section6_6_4() { $this->assertXMLReflexivelyEqualsToMimeDir( << ABC, Inc. North American Division Marketing XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'ORG:ABC\, Inc.;North American Division;Marketing'."\n". 'END:VCARD'."\n" ); } /** * Property: MEMBER. */ public function testRFC6350Section6_6_5() { $this->assertXMLReflexivelyEqualsToMimeDir( << urn:uuid:03a0e51f-d1aa-4385-8a53-e29025acd8af XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'MEMBER:urn:uuid:03a0e51f-d1aa-4385-8a53-e29025acd8af'."\n". 'END:VCARD'."\n" ); $this->assertXMLReflexivelyEqualsToMimeDir( << mailto:subscriber1@example.com xmpp:subscriber2@example.com sip:subscriber3@example.com tel:+1-418-555-5555 XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'MEMBER:mailto:subscriber1@example.com'."\n". 'MEMBER:xmpp:subscriber2@example.com'."\n". 'MEMBER:sip:subscriber3@example.com'."\n". 'MEMBER:tel:+1-418-555-5555'."\n". 'END:VCARD'."\n" ); } /** * Property: RELATED. */ public function testRFC6350Section6_6_6() { $this->assertXMLReflexivelyEqualsToMimeDir( << friend urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6 XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'RELATED;TYPE=friend:urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6'."\n". 'END:VCARD'."\n" ); } /** * Property: CATEGORIES. */ public function testRFC6350Section6_7_1() { $this->assertXMLReflexivelyEqualsToMimeDir( << INTERNET IETF INDUSTRY INFORMATION TECHNOLOGY XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'CATEGORIES:INTERNET,IETF,INDUSTRY,INFORMATION TECHNOLOGY'."\n". 'END:VCARD'."\n" ); } /** * Property: NOTE. */ public function testRFC6350Section6_7_2() { $this->assertXMLReflexivelyEqualsToMimeDir( << Foo, bar XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'NOTE:Foo\, bar'."\n". 'END:VCARD'."\n" ); } /** * Property: PRODID. */ public function testRFC6350Section6_7_3() { $this->assertXMLReflexivelyEqualsToMimeDir( << -//ONLINE DIRECTORY//NONSGML Version 1//EN XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'PRODID:-//ONLINE DIRECTORY//NONSGML Version 1//EN'."\n". 'END:VCARD'."\n" ); } public function testRFC6350Section6_7_4() { $this->assertXMLReflexivelyEqualsToMimeDir( << 19951031T222710Z XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'REV:19951031T222710Z'."\n". 'END:VCARD'."\n" ); } /** * Property: SOUND. */ public function testRFC6350Section6_7_5() { $this->assertXMLEqualsToMimeDir( << CID:JOHNQPUBLIC.part8.19960229T080000.xyzMail@example.com XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'SOUND:CID:JOHNQPUBLIC.part8.19960229T080000.xyzMail@example.com'."\n". 'END:VCARD'."\n" ); $this->assertXMLReflexivelyEqualsToMimeDir( << CID:JOHNQPUBLIC.part8.19960229T080000.xyzMail@example.com XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'SOUND:CID:JOHNQPUBLIC.part8.19960229T080000.xyzMail@example.com'."\n". 'END:VCARD'."\n" ); } /** * Property: UID. */ public function testRFC6350Section6_7_6() { $this->assertXMLReflexivelyEqualsToMimeDir( << urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6 XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'UID:urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6'."\n". 'END:VCARD'."\n" ); } /** * Property: CLIENTPIDMAP. */ public function testRFC6350Section6_7_7() { $this->assertXMLReflexivelyEqualsToMimeDir( << 1 urn:uuid:3df403f4-5924-4bb7-b077-3c711d9eb34b XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'CLIENTPIDMAP:1;urn:uuid:3df403f4-5924-4bb7-b077-3c711d9eb34b'."\n". 'END:VCARD'."\n" ); } /** * Property: URL. */ public function testRFC6350Section6_7_8() { $this->assertXMLReflexivelyEqualsToMimeDir( << http://example.org/restaurant.french/~chezchic.html XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'URL:http://example.org/restaurant.french/~chezchic.html'."\n". 'END:VCARD'."\n" ); } /** * Property: VERSION. */ public function testRFC6350Section6_7_9() { $this->assertXMLReflexivelyEqualsToMimeDir( << XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'END:VCARD'."\n" ); } /** * Property: KEY. */ public function testRFC6350Section6_8_1() { $this->assertXMLReflexivelyEqualsToMimeDir( << application/pgp-keys ftp://example.com/keys/jdoe XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'KEY;MEDIATYPE=application/pgp-keys:ftp://example.com/keys/jdoe'."\n". 'END:VCARD'."\n" ); } /** * Property: FBURL. */ public function testRFC6350Section6_9_1() { $this->assertXMLReflexivelyEqualsToMimeDir( << 1 http://www.example.com/busy/janedoe XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'FBURL;PREF=1:http://www.example.com/busy/janedoe'."\n". 'END:VCARD'."\n" ); } /** * Property: CALADRURI. */ public function testRFC6350Section6_9_2() { $this->assertXMLReflexivelyEqualsToMimeDir( << http://example.com/calendar/jdoe XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'CALADRURI:http://example.com/calendar/jdoe'."\n". 'END:VCARD'."\n" ); } /** * Property: CALURI. */ public function testRFC6350Section6_9_3() { $this->assertXMLReflexivelyEqualsToMimeDir( << 1 http://cal.example.com/calA XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'CALURI;PREF=1:http://cal.example.com/calA'."\n". 'END:VCARD'."\n" ); } /** * Property: CAPURI. */ public function testRFC6350SectionA_3() { $this->assertXMLReflexivelyEqualsToMimeDir( << http://cap.example.com/capA XML , 'BEGIN:VCARD'."\n". 'VERSION:4.0'."\n". 'CAPURI:http://cap.example.com/capA'."\n". 'END:VCARD'."\n" ); } /** * Check this equality: * XML -> object model -> MIME Dir. */ protected function assertXMLEqualsToMimeDir($xml, $mimedir) { $component = VObject\Reader::readXML($xml); $this->assertVObjectEqualsVObject($mimedir, $component); } /** * Check this (reflexive) equality: * XML -> object model -> MIME Dir -> object model -> XML. */ protected function assertXMLReflexivelyEqualsToMimeDir($xml, $mimedir) { $this->assertXMLEqualsToMimeDir($xml, $mimedir); $component = VObject\Reader::read($mimedir); $this->assertXmlStringEqualsXmlString($xml, VObject\Writer::writeXML($component)); } }