1<?php 2 3namespace Sabre\VObject\Parser; 4 5use Sabre\VObject; 6 7class XmlTest extends \PHPUnit_Framework_TestCase { 8 9 use VObject\PHPUnitAssertions; 10 11 function testRFC6321Example1() { 12 13 $this->assertXMLEqualsToMimeDir( 14<<<XML 15<?xml version="1.0" encoding="UTF-8"?> 16<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 17 <vcalendar> 18 <properties> 19 <calscale> 20 <text>GREGORIAN</text> 21 </calscale> 22 <prodid> 23 <text>-//Example Inc.//Example Calendar//EN</text> 24 </prodid> 25 <version> 26 <text>2.0</text> 27 </version> 28 </properties> 29 <components> 30 <vevent> 31 <properties> 32 <dtstamp> 33 <date-time>2008-02-05T19:12:24Z</date-time> 34 </dtstamp> 35 <dtstart> 36 <date>2008-10-06</date> 37 </dtstart> 38 <summary> 39 <text>Planning meeting</text> 40 </summary> 41 <uid> 42 <text>4088E990AD89CB3DBB484909</text> 43 </uid> 44 </properties> 45 </vevent> 46 </components> 47 </vcalendar> 48</icalendar> 49XML 50, 51 'BEGIN:VCALENDAR' . "\n" . 52 // VERSION comes first because this is required by vCard 4.0. 53 'VERSION:2.0' . "\n" . 54 'CALSCALE:GREGORIAN' . "\n" . 55 'PRODID:-//Example Inc.//Example Calendar//EN' . "\n" . 56 'BEGIN:VEVENT' . "\n" . 57 'DTSTAMP:20080205T191224Z' . "\n" . 58 'DTSTART;VALUE=DATE:20081006' . "\n" . 59 'SUMMARY:Planning meeting' . "\n" . 60 'UID:4088E990AD89CB3DBB484909' . "\n" . 61 'END:VEVENT' . "\n" . 62 'END:VCALENDAR' . "\n" 63 ); 64 65 } 66 67 function testRFC6321Example2() { 68 69 $xml = <<<XML 70<?xml version="1.0" encoding="UTF-8" ?> 71<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 72 <vcalendar> 73 <properties> 74 <prodid> 75 <text>-//Example Inc.//Example Client//EN</text> 76 </prodid> 77 <version> 78 <text>2.0</text> 79 </version> 80 </properties> 81 <components> 82 <vtimezone> 83 <properties> 84 <last-modified> 85 <date-time>2004-01-10T03:28:45Z</date-time> 86 </last-modified> 87 <tzid><text>US/Eastern</text></tzid> 88 </properties> 89 <components> 90 <daylight> 91 <properties> 92 <dtstart> 93 <date-time>2000-04-04T02:00:00</date-time> 94 </dtstart> 95 <rrule> 96 <recur> 97 <freq>YEARLY</freq> 98 <byday>1SU</byday> 99 <bymonth>4</bymonth> 100 </recur> 101 </rrule> 102 <tzname> 103 <text>EDT</text> 104 </tzname> 105 <tzoffsetfrom> 106 <utc-offset>-05:00</utc-offset> 107 </tzoffsetfrom> 108 <tzoffsetto> 109 <utc-offset>-04:00</utc-offset> 110 </tzoffsetto> 111 </properties> 112 </daylight> 113 <standard> 114 <properties> 115 <dtstart> 116 <date-time>2000-10-26T02:00:00</date-time> 117 </dtstart> 118 <rrule> 119 <recur> 120 <freq>YEARLY</freq> 121 <byday>-1SU</byday> 122 <bymonth>10</bymonth> 123 </recur> 124 </rrule> 125 <tzname> 126 <text>EST</text> 127 </tzname> 128 <tzoffsetfrom> 129 <utc-offset>-04:00</utc-offset> 130 </tzoffsetfrom> 131 <tzoffsetto> 132 <utc-offset>-05:00</utc-offset> 133 </tzoffsetto> 134 </properties> 135 </standard> 136 </components> 137 </vtimezone> 138 <vevent> 139 <properties> 140 <dtstamp> 141 <date-time>2006-02-06T00:11:21Z</date-time> 142 </dtstamp> 143 <dtstart> 144 <parameters> 145 <tzid><text>US/Eastern</text></tzid> 146 </parameters> 147 <date-time>2006-01-02T12:00:00</date-time> 148 </dtstart> 149 <duration> 150 <duration>PT1H</duration> 151 </duration> 152 <rrule> 153 <recur> 154 <freq>DAILY</freq> 155 <count>5</count> 156 </recur> 157 </rrule> 158 <rdate> 159 <parameters> 160 <tzid><text>US/Eastern</text></tzid> 161 </parameters> 162 <period> 163 <start>2006-01-02T15:00:00</start> 164 <duration>PT2H</duration> 165 </period> 166 </rdate> 167 <summary> 168 <text>Event #2</text> 169 </summary> 170 <description> 171 <text>We are having a meeting all this week at 12 172pm for one hour, with an additional meeting on the first day 1732 hours long.
Please bring your own lunch for the 12 pm 174meetings.</text> 175 </description> 176 <uid> 177 <text>00959BC664CA650E933C892C@example.com</text> 178 </uid> 179 </properties> 180 </vevent> 181 <vevent> 182 <properties> 183 <dtstamp> 184 <date-time>2006-02-06T00:11:21Z</date-time> 185 </dtstamp> 186 <dtstart> 187 <parameters> 188 <tzid><text>US/Eastern</text></tzid> 189 </parameters> 190 <date-time>2006-01-04T14:00:00</date-time> 191 </dtstart> 192 <duration> 193 <duration>PT1H</duration> 194 </duration> 195 <recurrence-id> 196 <parameters> 197 <tzid><text>US/Eastern</text></tzid> 198 </parameters> 199 <date-time>2006-01-04T12:00:00</date-time> 200 </recurrence-id> 201 <summary> 202 <text>Event #2 bis</text> 203 </summary> 204 <uid> 205 <text>00959BC664CA650E933C892C@example.com</text> 206 </uid> 207 </properties> 208 </vevent> 209 </components> 210 </vcalendar> 211</icalendar> 212XML; 213 214 $component = VObject\Reader::readXML($xml); 215 $this->assertVObjectEqualsVObject( 216 'BEGIN:VCALENDAR' . "\n" . 217 'VERSION:2.0' . "\n" . 218 'PRODID:-//Example Inc.//Example Client//EN' . "\n" . 219 'BEGIN:VTIMEZONE' . "\n" . 220 'LAST-MODIFIED:20040110T032845Z' . "\n" . 221 'TZID:US/Eastern' . "\n" . 222 'BEGIN:DAYLIGHT' . "\n" . 223 'DTSTART:20000404T020000' . "\n" . 224 'RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4' . "\n" . 225 'TZNAME:EDT' . "\n" . 226 'TZOFFSETFROM:-0500' . "\n" . 227 'TZOFFSETTO:-0400' . "\n" . 228 'END:DAYLIGHT' . "\n" . 229 'BEGIN:STANDARD' . "\n" . 230 'DTSTART:20001026T020000' . "\n" . 231 'RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10' . "\n" . 232 'TZNAME:EST' . "\n" . 233 'TZOFFSETFROM:-0400' . "\n" . 234 'TZOFFSETTO:-0500' . "\n" . 235 'END:STANDARD' . "\n" . 236 'END:VTIMEZONE' . "\n" . 237 'BEGIN:VEVENT' . "\n" . 238 'DTSTAMP:20060206T001121Z' . "\n" . 239 'DTSTART;TZID=US/Eastern:20060102T120000' . "\n" . 240 'DURATION:PT1H' . "\n" . 241 'RRULE:FREQ=DAILY;COUNT=5' . "\n" . 242 'RDATE;TZID=US/Eastern;VALUE=PERIOD:20060102T150000/PT2H' . "\n" . 243 'SUMMARY:Event #2' . "\n" . 244 'DESCRIPTION:We are having a meeting all this week at 12\npm for one hour\, ' . "\n" . 245 ' with an additional meeting on the first day\n2 hours long.\nPlease bring y' . "\n" . 246 ' our own lunch for the 12 pm\nmeetings.' . "\n" . 247 'UID:00959BC664CA650E933C892C@example.com' . "\n" . 248 'END:VEVENT' . "\n" . 249 'BEGIN:VEVENT' . "\n" . 250 'DTSTAMP:20060206T001121Z' . "\n" . 251 'DTSTART;TZID=US/Eastern:20060104T140000' . "\n" . 252 'DURATION:PT1H' . "\n" . 253 'RECURRENCE-ID;TZID=US/Eastern:20060104T120000' . "\n" . 254 'SUMMARY:Event #2 bis' . "\n" . 255 'UID:00959BC664CA650E933C892C@example.com' . "\n" . 256 'END:VEVENT' . "\n" . 257 'END:VCALENDAR' . "\n", 258 VObject\Writer::write($component) 259 ); 260 261 } 262 263 /** 264 * iCalendar Stream. 265 */ 266 function testRFC6321Section3_2() { 267 268 $this->assertXMLReflexivelyEqualsToMimeDir( 269<<<XML 270<?xml version="1.0" encoding="UTF-8"?> 271<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 272 <vcalendar/> 273</icalendar> 274XML 275, 276 'BEGIN:VCALENDAR' . "\n" . 277 'END:VCALENDAR' . "\n" 278 ); 279 } 280 281 /** 282 * All components exist. 283 */ 284 function testRFC6321Section3_3() { 285 286 $this->assertXMLReflexivelyEqualsToMimeDir( 287<<<XML 288<?xml version="1.0" encoding="UTF-8"?> 289<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 290 <vcalendar> 291 <components> 292 <vtimezone/> 293 <vevent/> 294 <vtodo/> 295 <vjournal/> 296 <vfreebusy/> 297 <standard/> 298 <daylight/> 299 <valarm/> 300 </components> 301 </vcalendar> 302</icalendar> 303XML 304, 305 'BEGIN:VCALENDAR' . "\n" . 306 'BEGIN:VTIMEZONE' . "\n" . 307 'END:VTIMEZONE' . "\n" . 308 'BEGIN:VEVENT' . "\n" . 309 'END:VEVENT' . "\n" . 310 'BEGIN:VTODO' . "\n" . 311 'END:VTODO' . "\n" . 312 'BEGIN:VJOURNAL' . "\n" . 313 'END:VJOURNAL' . "\n" . 314 'BEGIN:VFREEBUSY' . "\n" . 315 'END:VFREEBUSY' . "\n" . 316 'BEGIN:STANDARD' . "\n" . 317 'END:STANDARD' . "\n" . 318 'BEGIN:DAYLIGHT' . "\n" . 319 'END:DAYLIGHT' . "\n" . 320 'BEGIN:VALARM' . "\n" . 321 'END:VALARM' . "\n" . 322 'END:VCALENDAR' . "\n" 323 ); 324 325 } 326 327 /** 328 * Properties, Special Cases, GEO. 329 */ 330 function testRFC6321Section3_4_1_2() { 331 332 $this->assertXMLReflexivelyEqualsToMimeDir( 333<<<XML 334<?xml version="1.0" encoding="UTF-8"?> 335<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 336 <vcalendar> 337 <properties> 338 <geo> 339 <latitude>37.386013</latitude> 340 <longitude>-122.082932</longitude> 341 </geo> 342 </properties> 343 </vcalendar> 344</icalendar> 345XML 346, 347 'BEGIN:VCALENDAR' . "\n" . 348 'GEO:37.386013;-122.082932' . "\n" . 349 'END:VCALENDAR' . "\n" 350 ); 351 352 } 353 354 /** 355 * Properties, Special Cases, REQUEST-STATUS. 356 */ 357 function testRFC6321Section3_4_1_3() { 358 359 // Example 1 of RFC5545, Section 3.8.8.3. 360 $this->assertXMLReflexivelyEqualsToMimeDir( 361<<<XML 362<?xml version="1.0" encoding="UTF-8"?> 363<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 364 <vcalendar> 365 <properties> 366 <request-status> 367 <code>2.0</code> 368 <description>Success</description> 369 </request-status> 370 </properties> 371 </vcalendar> 372</icalendar> 373XML 374, 375 'BEGIN:VCALENDAR' . "\n" . 376 'REQUEST-STATUS:2.0;Success' . "\n" . 377 'END:VCALENDAR' . "\n" 378 ); 379 380 // Example 2 of RFC5545, Section 3.8.8.3. 381 $this->assertXMLReflexivelyEqualsToMimeDir( 382<<<XML 383<?xml version="1.0" encoding="UTF-8"?> 384<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 385 <vcalendar> 386 <properties> 387 <request-status> 388 <code>3.1</code> 389 <description>Invalid property value</description> 390 <data>DTSTART:96-Apr-01</data> 391 </request-status> 392 </properties> 393 </vcalendar> 394</icalendar> 395XML 396, 397 'BEGIN:VCALENDAR' . "\n" . 398 'REQUEST-STATUS:3.1;Invalid property value;DTSTART:96-Apr-01' . "\n" . 399 'END:VCALENDAR' . "\n" 400 ); 401 402 // Example 3 of RFC5545, Section 3.8.8.3. 403 $this->assertXMLReflexivelyEqualsToMimeDir( 404<<<XML 405<?xml version="1.0" encoding="UTF-8"?> 406<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 407 <vcalendar> 408 <properties> 409 <request-status> 410 <code>2.8</code> 411 <description>Success, repeating event ignored. Scheduled as a single event.</description> 412 <data>RRULE:FREQ=WEEKLY;INTERVAL=2</data> 413 </request-status> 414 </properties> 415 </vcalendar> 416</icalendar> 417XML 418, 419 'BEGIN:VCALENDAR' . "\n" . 420 'REQUEST-STATUS:2.8;Success\, repeating event ignored. Scheduled as a single' . "\n" . 421 ' event.;RRULE:FREQ=WEEKLY\;INTERVAL=2' . "\n" . 422 'END:VCALENDAR' . "\n" 423 ); 424 425 // Example 4 of RFC5545, Section 3.8.8.3. 426 $this->assertXMLReflexivelyEqualsToMimeDir( 427<<<XML 428<?xml version="1.0" encoding="UTF-8"?> 429<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 430 <vcalendar> 431 <properties> 432 <request-status> 433 <code>4.1</code> 434 <description>Event conflict. Date-time is busy.</description> 435 </request-status> 436 </properties> 437 </vcalendar> 438</icalendar> 439XML 440, 441 'BEGIN:VCALENDAR' . "\n" . 442 'REQUEST-STATUS:4.1;Event conflict. Date-time is busy.' . "\n" . 443 'END:VCALENDAR' . "\n" 444 ); 445 446 // Example 5 of RFC5545, Section 3.8.8.3. 447 $this->assertXMLReflexivelyEqualsToMimeDir( 448<<<XML 449<?xml version="1.0" encoding="UTF-8"?> 450<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 451 <vcalendar> 452 <properties> 453 <request-status> 454 <code>3.7</code> 455 <description>Invalid calendar user</description> 456 <data>ATTENDEE:mailto:jsmith@example.com</data> 457 </request-status> 458 </properties> 459 </vcalendar> 460</icalendar> 461XML 462, 463 'BEGIN:VCALENDAR' . "\n" . 464 'REQUEST-STATUS:3.7;Invalid calendar user;ATTENDEE:mailto:jsmith@example.com' . "\n" . 465 'END:VCALENDAR' . "\n" 466 ); 467 468 } 469 470 /** 471 * Values, Binary. 472 */ 473 function testRFC6321Section3_6_1() { 474 475 $this->assertXMLEqualsToMimeDir( 476<<<XML 477<?xml version="1.0" encoding="UTF-8"?> 478<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 479 <vcalendar> 480 <properties> 481 <attach> 482 <binary>SGVsbG8gV29ybGQh</binary> 483 </attach> 484 </properties> 485 </vcalendar> 486</icalendar> 487XML 488, 489 'BEGIN:VCALENDAR' . "\n" . 490 'ATTACH:SGVsbG8gV29ybGQh' . "\n" . 491 'END:VCALENDAR' . "\n" 492 ); 493 494 // In vCard 4, BINARY no longer exists and is replaced by URI. 495 $this->assertXMLReflexivelyEqualsToMimeDir( 496<<<XML 497<?xml version="1.0" encoding="UTF-8"?> 498<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 499 <vcalendar> 500 <properties> 501 <attach> 502 <uri>SGVsbG8gV29ybGQh</uri> 503 </attach> 504 </properties> 505 </vcalendar> 506</icalendar> 507XML 508, 509 'BEGIN:VCALENDAR' . "\n" . 510 'ATTACH:SGVsbG8gV29ybGQh' . "\n" . 511 'END:VCALENDAR' . "\n" 512 ); 513 514 } 515 516 /** 517 * Values, Boolean. 518 */ 519 function testRFC6321Section3_6_2() { 520 521 $this->assertXMLEqualsToMimeDir( 522<<<XML 523<?xml version="1.0" encoding="UTF-8"?> 524<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 525 <vcalendar> 526 <properties> 527 <attendee> 528 <parameters> 529 <rsvp><boolean>true</boolean></rsvp> 530 </parameters> 531 <cal-address>mailto:cyrus@example.com</cal-address> 532 </attendee> 533 </properties> 534 </vcalendar> 535</icalendar> 536XML 537, 538 'BEGIN:VCALENDAR' . "\n" . 539 'ATTENDEE;RSVP=true:mailto:cyrus@example.com' . "\n" . 540 'END:VCALENDAR' . "\n" 541 ); 542 543 } 544 545 /** 546 * Values, Calendar User Address. 547 */ 548 function testRFC6321Section3_6_3() { 549 550 $this->assertXMLReflexivelyEqualsToMimeDir( 551<<<XML 552<?xml version="1.0" encoding="UTF-8"?> 553<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 554 <vcalendar> 555 <properties> 556 <attendee> 557 <cal-address>mailto:cyrus@example.com</cal-address> 558 </attendee> 559 </properties> 560 </vcalendar> 561</icalendar> 562XML 563, 564 'BEGIN:VCALENDAR' . "\n" . 565 'ATTENDEE:mailto:cyrus@example.com' . "\n" . 566 'END:VCALENDAR' . "\n" 567 ); 568 569 } 570 571 /** 572 * Values, Date. 573 */ 574 function testRFC6321Section3_6_4() { 575 576 $this->assertXMLReflexivelyEqualsToMimeDir( 577<<<XML 578<?xml version="1.0" encoding="UTF-8"?> 579<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 580 <vcalendar> 581 <properties> 582 <dtstart> 583 <date>2011-05-17</date> 584 </dtstart> 585 </properties> 586 </vcalendar> 587</icalendar> 588XML 589, 590 'BEGIN:VCALENDAR' . "\n" . 591 'DTSTART;VALUE=DATE:20110517' . "\n" . 592 'END:VCALENDAR' . "\n" 593 ); 594 595 } 596 597 /** 598 * Values, Date-Time. 599 */ 600 function testRFC6321Section3_6_5() { 601 602 $this->assertXMLReflexivelyEqualsToMimeDir( 603<<<XML 604<?xml version="1.0" encoding="UTF-8"?> 605<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 606 <vcalendar> 607 <properties> 608 <dtstart> 609 <date-time>2011-05-17T12:00:00</date-time> 610 </dtstart> 611 </properties> 612 </vcalendar> 613</icalendar> 614XML 615, 616 'BEGIN:VCALENDAR' . "\n" . 617 'DTSTART:20110517T120000' . "\n" . 618 'END:VCALENDAR' . "\n" 619 ); 620 621 } 622 623 /** 624 * Values, Duration. 625 */ 626 function testRFC6321Section3_6_6() { 627 628 $this->assertXMLReflexivelyEqualsToMimeDir( 629<<<XML 630<?xml version="1.0" encoding="UTF-8"?> 631<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 632 <vcalendar> 633 <properties> 634 <duration> 635 <duration>P1D</duration> 636 </duration> 637 </properties> 638 </vcalendar> 639</icalendar> 640XML 641, 642 'BEGIN:VCALENDAR' . "\n" . 643 'DURATION:P1D' . "\n" . 644 'END:VCALENDAR' . "\n" 645 ); 646 647 } 648 649 /** 650 * Values, Float. 651 */ 652 function testRFC6321Section3_6_7() { 653 654 // GEO uses <float /> with a positive and a non-negative numbers. 655 $this->testRFC6321Section3_4_1_2(); 656 657 } 658 659 /** 660 * Values, Integer. 661 */ 662 function testRFC6321Section3_6_8() { 663 664 $this->assertXMLEqualsToMimeDir( 665<<<XML 666<?xml version="1.0" encoding="UTF-8"?> 667<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 668 <vcalendar> 669 <properties> 670 <foo> 671 <integer>42</integer> 672 </foo> 673 </properties> 674 </vcalendar> 675</icalendar> 676XML 677, 678 'BEGIN:VCALENDAR' . "\n" . 679 'FOO:42' . "\n" . 680 'END:VCALENDAR' . "\n" 681 ); 682 683 $this->assertXMLEqualsToMimeDir( 684<<<XML 685<?xml version="1.0" encoding="UTF-8"?> 686<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 687 <vcalendar> 688 <properties> 689 <foo> 690 <integer>-42</integer> 691 </foo> 692 </properties> 693 </vcalendar> 694</icalendar> 695XML 696, 697 'BEGIN:VCALENDAR' . "\n" . 698 'FOO:-42' . "\n" . 699 'END:VCALENDAR' . "\n" 700 ); 701 702 } 703 704 /** 705 * Values, Period of Time. 706 */ 707 function testRFC6321Section3_6_9() { 708 709 $this->assertXMLReflexivelyEqualsToMimeDir( 710<<<XML 711<?xml version="1.0" encoding="UTF-8"?> 712<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 713 <vcalendar> 714 <properties> 715 <freebusy> 716 <period> 717 <start>2011-05-17T12:00:00</start> 718 <duration>P1H</duration> 719 </period> 720 </freebusy> 721 </properties> 722 </vcalendar> 723</icalendar> 724XML 725, 726 'BEGIN:VCALENDAR' . "\n" . 727 'FREEBUSY:20110517T120000/P1H' . "\n" . 728 'END:VCALENDAR' . "\n" 729 ); 730 731 $this->assertXMLReflexivelyEqualsToMimeDir( 732<<<XML 733<?xml version="1.0" encoding="UTF-8"?> 734<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 735 <vcalendar> 736 <properties> 737 <freebusy> 738 <period> 739 <start>2011-05-17T12:00:00</start> 740 <end>2012-05-17T12:00:00</end> 741 </period> 742 </freebusy> 743 </properties> 744 </vcalendar> 745</icalendar> 746XML 747, 748 'BEGIN:VCALENDAR' . "\n" . 749 'FREEBUSY:20110517T120000/20120517T120000' . "\n" . 750 'END:VCALENDAR' . "\n" 751 ); 752 753 } 754 755 /** 756 * Values, Recurrence Rule. 757 */ 758 function testRFC6321Section3_6_10() { 759 760 $this->assertXMLReflexivelyEqualsToMimeDir( 761<<<XML 762<?xml version="1.0" encoding="UTF-8"?> 763<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 764 <vcalendar> 765 <properties> 766 <rrule> 767 <recur> 768 <freq>YEARLY</freq> 769 <count>5</count> 770 <byday>-1SU</byday> 771 <bymonth>10</bymonth> 772 </recur> 773 </rrule> 774 </properties> 775 </vcalendar> 776</icalendar> 777XML 778, 779 'BEGIN:VCALENDAR' . "\n" . 780 'RRULE:FREQ=YEARLY;COUNT=5;BYDAY=-1SU;BYMONTH=10' . "\n" . 781 'END:VCALENDAR' . "\n" 782 ); 783 784 } 785 786 /** 787 * Values, Text. 788 */ 789 function testRFC6321Section3_6_11() { 790 791 $this->assertXMLReflexivelyEqualsToMimeDir( 792<<<XML 793<?xml version="1.0" encoding="UTF-8"?> 794<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 795 <vcalendar> 796 <properties> 797 <calscale> 798 <text>GREGORIAN</text> 799 </calscale> 800 </properties> 801 </vcalendar> 802</icalendar> 803XML 804, 805 'BEGIN:VCALENDAR' . "\n" . 806 'CALSCALE:GREGORIAN' . "\n" . 807 'END:VCALENDAR' . "\n" 808 ); 809 810 } 811 812 /** 813 * Values, Time. 814 */ 815 function testRFC6321Section3_6_12() { 816 817 $this->assertXMLEqualsToMimeDir( 818<<<XML 819<?xml version="1.0" encoding="UTF-8"?> 820<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 821 <vcalendar> 822 <properties> 823 <foo> 824 <time>12:00:00</time> 825 </foo> 826 </properties> 827 </vcalendar> 828</icalendar> 829XML 830, 831 'BEGIN:VCALENDAR' . "\n" . 832 'FOO:120000' . "\n" . 833 'END:VCALENDAR' . "\n" 834 ); 835 836 } 837 838 /** 839 * Values, URI. 840 */ 841 function testRFC6321Section3_6_13() { 842 843 $this->assertXMLReflexivelyEqualsToMimeDir( 844<<<XML 845<?xml version="1.0" encoding="UTF-8"?> 846<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 847 <vcalendar> 848 <properties> 849 <attach> 850 <uri>http://calendar.example.com</uri> 851 </attach> 852 </properties> 853 </vcalendar> 854</icalendar> 855XML 856, 857 'BEGIN:VCALENDAR' . "\n" . 858 'ATTACH:http://calendar.example.com' . "\n" . 859 'END:VCALENDAR' . "\n" 860 ); 861 862 } 863 864 /** 865 * Values, UTC Offset. 866 */ 867 function testRFC6321Section3_6_14() { 868 869 // Example 1 of RFC5545, Section 3.3.14. 870 $this->assertXMLReflexivelyEqualsToMimeDir( 871<<<XML 872<?xml version="1.0" encoding="UTF-8"?> 873<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 874 <vcalendar> 875 <properties> 876 <tzoffsetfrom> 877 <utc-offset>-05:00</utc-offset> 878 </tzoffsetfrom> 879 </properties> 880 </vcalendar> 881</icalendar> 882XML 883, 884 'BEGIN:VCALENDAR' . "\n" . 885 'TZOFFSETFROM:-0500' . "\n" . 886 'END:VCALENDAR' . "\n" 887 ); 888 889 // Example 2 of RFC5545, Section 3.3.14. 890 $this->assertXMLReflexivelyEqualsToMimeDir( 891<<<XML 892<?xml version="1.0" encoding="UTF-8"?> 893<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 894 <vcalendar> 895 <properties> 896 <tzoffsetfrom> 897 <utc-offset>+01:00</utc-offset> 898 </tzoffsetfrom> 899 </properties> 900 </vcalendar> 901</icalendar> 902XML 903, 904 'BEGIN:VCALENDAR' . "\n" . 905 'TZOFFSETFROM:+0100' . "\n" . 906 'END:VCALENDAR' . "\n" 907 ); 908 909 } 910 911 /** 912 * Handling Unrecognized Properties or Parameters. 913 */ 914 function testRFC6321Section5() { 915 916 $this->assertXMLReflexivelyEqualsToMimeDir( 917<<<XML 918<?xml version="1.0" encoding="UTF-8"?> 919<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 920 <vcalendar> 921 <properties> 922 <x-property> 923 <unknown>20110512T120000Z</unknown> 924 </x-property> 925 </properties> 926 </vcalendar> 927</icalendar> 928XML 929, 930 'BEGIN:VCALENDAR' . "\n" . 931 'X-PROPERTY:20110512T120000Z' . "\n" . 932 'END:VCALENDAR' . "\n" 933 ); 934 935 $this->assertXMLReflexivelyEqualsToMimeDir( 936<<<XML 937<?xml version="1.0" encoding="UTF-8"?> 938<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 939 <vcalendar> 940 <properties> 941 <dtstart> 942 <parameters> 943 <x-param> 944 <text>PT30M</text> 945 </x-param> 946 </parameters> 947 <date-time>2011-05-12T13:00:00Z</date-time> 948 </dtstart> 949 </properties> 950 </vcalendar> 951</icalendar> 952XML 953, 954 'BEGIN:VCALENDAR' . "\n" . 955 'DTSTART;X-PARAM=PT30M:20110512T130000Z' . "\n" . 956 'END:VCALENDAR' . "\n" 957 ); 958 959 } 960 961 function testRDateWithDateTime() { 962 963 $this->assertXMLReflexivelyEqualsToMimeDir( 964<<<XML 965<?xml version="1.0" encoding="UTF-8"?> 966<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 967 <vcalendar> 968 <properties> 969 <rdate> 970 <date-time>2008-02-05T19:12:24Z</date-time> 971 </rdate> 972 </properties> 973 </vcalendar> 974</icalendar> 975XML 976, 977 'BEGIN:VCALENDAR' . "\n" . 978 'RDATE:20080205T191224Z' . "\n" . 979 'END:VCALENDAR' . "\n" 980 ); 981 982 $this->assertXMLReflexivelyEqualsToMimeDir( 983<<<XML 984<?xml version="1.0" encoding="UTF-8"?> 985<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 986 <vcalendar> 987 <properties> 988 <rdate> 989 <date-time>2008-02-05T19:12:24Z</date-time> 990 <date-time>2009-02-05T19:12:24Z</date-time> 991 </rdate> 992 </properties> 993 </vcalendar> 994</icalendar> 995XML 996, 997 'BEGIN:VCALENDAR' . "\n" . 998 'RDATE:20080205T191224Z,20090205T191224Z' . "\n" . 999 'END:VCALENDAR' . "\n" 1000 ); 1001 1002 } 1003 1004 function testRDateWithDate() { 1005 1006 $this->assertXMLEqualsToMimeDir( 1007<<<XML 1008<?xml version="1.0" encoding="UTF-8"?> 1009<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 1010 <vcalendar> 1011 <properties> 1012 <rdate> 1013 <date>2008-10-06</date> 1014 </rdate> 1015 </properties> 1016 </vcalendar> 1017</icalendar> 1018XML 1019, 1020 'BEGIN:VCALENDAR' . "\n" . 1021 'RDATE:20081006' . "\n" . 1022 'END:VCALENDAR' . "\n" 1023 ); 1024 1025 $this->assertXMLEqualsToMimeDir( 1026<<<XML 1027<?xml version="1.0" encoding="UTF-8"?> 1028<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 1029 <vcalendar> 1030 <properties> 1031 <rdate> 1032 <date>2008-10-06</date> 1033 <date>2009-10-06</date> 1034 <date>2010-10-06</date> 1035 </rdate> 1036 </properties> 1037 </vcalendar> 1038</icalendar> 1039XML 1040, 1041 'BEGIN:VCALENDAR' . "\n" . 1042 'RDATE:20081006,20091006,20101006' . "\n" . 1043 'END:VCALENDAR' . "\n" 1044 ); 1045 1046 } 1047 1048 function testRDateWithPeriod() { 1049 1050 $this->assertXMLReflexivelyEqualsToMimeDir( 1051<<<XML 1052<?xml version="1.0" encoding="UTF-8"?> 1053<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 1054 <vcalendar> 1055 <properties> 1056 <rdate> 1057 <parameters> 1058 <tzid> 1059 <text>US/Eastern</text> 1060 </tzid> 1061 </parameters> 1062 <period> 1063 <start>2006-01-02T15:00:00</start> 1064 <duration>PT2H</duration> 1065 </period> 1066 </rdate> 1067 </properties> 1068 </vcalendar> 1069</icalendar> 1070XML 1071, 1072 'BEGIN:VCALENDAR' . "\n" . 1073 'RDATE;TZID=US/Eastern;VALUE=PERIOD:20060102T150000/PT2H' . "\n" . 1074 'END:VCALENDAR' . "\n" 1075 ); 1076 1077 $this->assertXMLEqualsToMimeDir( 1078<<<XML 1079<?xml version="1.0" encoding="UTF-8"?> 1080<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"> 1081 <vcalendar> 1082 <properties> 1083 <rdate> 1084 <parameters> 1085 <tzid> 1086 <text>US/Eastern</text> 1087 </tzid> 1088 </parameters> 1089 <period> 1090 <start>2006-01-02T15:00:00</start> 1091 <duration>PT2H</duration> 1092 </period> 1093 <period> 1094 <start>2008-01-02T15:00:00</start> 1095 <duration>PT1H</duration> 1096 </period> 1097 </rdate> 1098 </properties> 1099 </vcalendar> 1100</icalendar> 1101XML 1102, 1103 'BEGIN:VCALENDAR' . "\n" . 1104 'RDATE;TZID=US/Eastern;VALUE=PERIOD:20060102T150000/PT2H,20080102T150000/PT1' . "\n" . 1105 ' H' . "\n" . 1106 'END:VCALENDAR' . "\n" 1107 ); 1108 1109 } 1110 1111 /** 1112 * Basic example. 1113 */ 1114 function testRFC6351Basic() { 1115 1116 $this->assertXMLReflexivelyEqualsToMimeDir( 1117<<<XML 1118<?xml version="1.0" encoding="UTF-8"?> 1119<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 1120 <vcard> 1121 <fn> 1122 <text>J. Doe</text> 1123 </fn> 1124 <n> 1125 <surname>Doe</surname> 1126 <given>J.</given> 1127 <additional/> 1128 <prefix/> 1129 <suffix/> 1130 </n> 1131 </vcard> 1132</vcards> 1133XML 1134, 1135 'BEGIN:VCARD' . "\n" . 1136 'VERSION:4.0' . "\n" . 1137 'FN:J. Doe' . "\n" . 1138 'N:Doe;J.;;;' . "\n" . 1139 'END:VCARD' . "\n" 1140 ); 1141 1142 } 1143 1144 /** 1145 * Example 1. 1146 */ 1147 function testRFC6351Example1() { 1148 1149 $this->assertXMLReflexivelyEqualsToMimeDir( 1150<<<XML 1151<?xml version="1.0" encoding="UTF-8"?> 1152<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 1153 <vcard> 1154 <fn> 1155 <text>J. Doe</text> 1156 </fn> 1157 <n> 1158 <surname>Doe</surname> 1159 <given>J.</given> 1160 <additional/> 1161 <prefix/> 1162 <suffix/> 1163 </n> 1164 <x-file> 1165 <parameters> 1166 <mediatype> 1167 <text>image/jpeg</text> 1168 </mediatype> 1169 </parameters> 1170 <unknown>alien.jpg</unknown> 1171 </x-file> 1172 <x1:a href="http://www.example.com" xmlns:x1="http://www.w3.org/1999/xhtml">My web page!</x1:a> 1173 </vcard> 1174</vcards> 1175XML 1176, 1177 'BEGIN:VCARD' . "\n" . 1178 'VERSION:4.0' . "\n" . 1179 'FN:J. Doe' . "\n" . 1180 'N:Doe;J.;;;' . "\n" . 1181 'X-FILE;MEDIATYPE=image/jpeg:alien.jpg' . "\n" . 1182 'XML:<a xmlns="http://www.w3.org/1999/xhtml" href="http://www.example.com">M' . "\n" . 1183 ' y web page!</a>' . "\n" . 1184 'END:VCARD' . "\n" 1185 ); 1186 1187 } 1188 1189 /** 1190 * Design Considerations. 1191 */ 1192 function testRFC6351Section5() { 1193 1194 $this->assertXMLEqualsToMimeDir( 1195<<<XML 1196<?xml version="1.0" encoding="UTF-8"?> 1197<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 1198 <vcard> 1199 <tel> 1200 <parameters> 1201 <type> 1202 <text>voice</text> 1203 <text>video</text> 1204 </type> 1205 </parameters> 1206 <uri>tel:+1-555-555-555</uri> 1207 </tel> 1208 </vcard> 1209</vcards> 1210XML 1211, 1212 'BEGIN:VCARD' . "\n" . 1213 'VERSION:4.0' . "\n" . 1214 'TEL;TYPE="voice,video":tel:+1-555-555-555' . "\n" . 1215 'END:VCARD' . "\n" 1216 ); 1217 1218 $this->assertXMLReflexivelyEqualsToMimeDir( 1219<<<XML 1220<?xml version="1.0" encoding="UTF-8"?> 1221<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 1222 <vcard> 1223 <tel> 1224 <parameters> 1225 <type> 1226 <text>voice</text> 1227 <text>video</text> 1228 </type> 1229 </parameters> 1230 <text>tel:+1-555-555-555</text> 1231 </tel> 1232 </vcard> 1233</vcards> 1234XML 1235, 1236 'BEGIN:VCARD' . "\n" . 1237 'VERSION:4.0' . "\n" . 1238 'TEL;TYPE="voice,video":tel:+1-555-555-555' . "\n" . 1239 'END:VCARD' . "\n" 1240 ); 1241 1242 } 1243 1244 /** 1245 * Design Considerations. 1246 */ 1247 function testRFC6351Section5Group() { 1248 1249 $this->assertXMLReflexivelyEqualsToMimeDir( 1250<<<XML 1251<?xml version="1.0" encoding="UTF-8"?> 1252<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 1253 <vcard> 1254 <tel> 1255 <text>tel:+1-555-555-556</text> 1256 </tel> 1257 <group name="contact"> 1258 <tel> 1259 <text>tel:+1-555-555-555</text> 1260 </tel> 1261 <fn> 1262 <text>Gordon</text> 1263 </fn> 1264 </group> 1265 <group name="media"> 1266 <fn> 1267 <text>Gordon</text> 1268 </fn> 1269 </group> 1270 </vcard> 1271</vcards> 1272XML 1273, 1274 'BEGIN:VCARD' . "\n" . 1275 'VERSION:4.0' . "\n" . 1276 'TEL:tel:+1-555-555-556' . "\n" . 1277 'contact.TEL:tel:+1-555-555-555' . "\n" . 1278 'contact.FN:Gordon' . "\n" . 1279 'media.FN:Gordon' . "\n" . 1280 'END:VCARD' . "\n" 1281 ); 1282 1283 } 1284 1285 /** 1286 * Extensibility. 1287 */ 1288 function testRFC6351Section5_1_NoNamespace() { 1289 1290 $this->assertXMLEqualsToMimeDir( 1291<<<XML 1292<?xml version="1.0" encoding="UTF-8"?> 1293<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 1294 <vcard> 1295 <x-my-prop> 1296 <parameters> 1297 <pref> 1298 <integer>1</integer> 1299 </pref> 1300 </parameters> 1301 <text>value goes here</text> 1302 </x-my-prop> 1303 </vcard> 1304</vcards> 1305XML 1306, 1307 'BEGIN:VCARD' . "\n" . 1308 'VERSION:4.0' . "\n" . 1309 'X-MY-PROP;PREF=1:value goes here' . "\n" . 1310 'END:VCARD' . "\n" 1311 ); 1312 1313 } 1314 1315 /** 1316 * Section 4.3.1 of Relax NG Schema: value-date. 1317 */ 1318 function testRFC6351ValueDateWithYearMonthDay() { 1319 1320 $this->assertXMLReflexivelyEqualsToMimeDir( 1321<<<XML 1322<?xml version="1.0" encoding="UTF-8"?> 1323<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 1324 <vcard> 1325 <bday> 1326 <date-and-or-time>20150128</date-and-or-time> 1327 </bday> 1328 </vcard> 1329</vcards> 1330XML 1331, 1332 'BEGIN:VCARD' . "\n" . 1333 'VERSION:4.0' . "\n" . 1334 'BDAY:20150128' . "\n" . 1335 'END:VCARD' . "\n" 1336 ); 1337 1338 } 1339 1340 /** 1341 * Section 4.3.1 of Relax NG Schema: value-date. 1342 */ 1343 function testRFC6351ValueDateWithYearMonth() { 1344 1345 $this->assertXMLReflexivelyEqualsToMimeDir( 1346<<<XML 1347<?xml version="1.0" encoding="UTF-8"?> 1348<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 1349 <vcard> 1350 <bday> 1351 <date-and-or-time>2015-01</date-and-or-time> 1352 </bday> 1353 </vcard> 1354</vcards> 1355XML 1356, 1357 'BEGIN:VCARD' . "\n" . 1358 'VERSION:4.0' . "\n" . 1359 'BDAY:2015-01' . "\n" . 1360 'END:VCARD' . "\n" 1361 ); 1362 1363 } 1364 1365 /** 1366 * Section 4.3.1 of Relax NG Schema: value-date. 1367 */ 1368 function testRFC6351ValueDateWithMonth() { 1369 1370 $this->assertXMLReflexivelyEqualsToMimeDir( 1371<<<XML 1372<?xml version="1.0" encoding="UTF-8"?> 1373<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 1374 <vcard> 1375 <bday> 1376 <date-and-or-time>--01</date-and-or-time> 1377 </bday> 1378 </vcard> 1379</vcards> 1380XML 1381, 1382 'BEGIN:VCARD' . "\n" . 1383 'VERSION:4.0' . "\n" . 1384 'BDAY:--01' . "\n" . 1385 'END:VCARD' . "\n" 1386 ); 1387 1388 } 1389 1390 /** 1391 * Section 4.3.1 of Relax NG Schema: value-date. 1392 */ 1393 function testRFC6351ValueDateWithMonthDay() { 1394 1395 $this->assertXMLReflexivelyEqualsToMimeDir( 1396<<<XML 1397<?xml version="1.0" encoding="UTF-8"?> 1398<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 1399 <vcard> 1400 <bday> 1401 <date-and-or-time>--0128</date-and-or-time> 1402 </bday> 1403 </vcard> 1404</vcards> 1405XML 1406, 1407 'BEGIN:VCARD' . "\n" . 1408 'VERSION:4.0' . "\n" . 1409 'BDAY:--0128' . "\n" . 1410 'END:VCARD' . "\n" 1411 ); 1412 1413 } 1414 1415 /** 1416 * Section 4.3.1 of Relax NG Schema: value-date. 1417 */ 1418 function testRFC6351ValueDateWithDay() { 1419 1420 $this->assertXMLReflexivelyEqualsToMimeDir( 1421<<<XML 1422<?xml version="1.0" encoding="UTF-8"?> 1423<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 1424 <vcard> 1425 <bday> 1426 <date-and-or-time>---28</date-and-or-time> 1427 </bday> 1428 </vcard> 1429</vcards> 1430XML 1431, 1432 'BEGIN:VCARD' . "\n" . 1433 'VERSION:4.0' . "\n" . 1434 'BDAY:---28' . "\n" . 1435 'END:VCARD' . "\n" 1436 ); 1437 1438 } 1439 1440 /** 1441 * Section 4.3.2 of Relax NG Schema: value-time. 1442 */ 1443 function testRFC6351ValueTimeWithHour() { 1444 1445 $this->assertXMLReflexivelyEqualsToMimeDir( 1446<<<XML 1447<?xml version="1.0" encoding="UTF-8"?> 1448<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 1449 <vcard> 1450 <bday> 1451 <date-and-or-time>13</date-and-or-time> 1452 </bday> 1453 </vcard> 1454</vcards> 1455XML 1456, 1457 'BEGIN:VCARD' . "\n" . 1458 'VERSION:4.0' . "\n" . 1459 'BDAY:13' . "\n" . 1460 'END:VCARD' . "\n" 1461 ); 1462 1463 } 1464 1465 /** 1466 * Section 4.3.2 of Relax NG Schema: value-time. 1467 */ 1468 function testRFC6351ValueTimeWithHourMinute() { 1469 1470 $this->assertXMLReflexivelyEqualsToMimeDir( 1471<<<XML 1472<?xml version="1.0" encoding="UTF-8"?> 1473<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 1474 <vcard> 1475 <bday> 1476 <date-and-or-time>1353</date-and-or-time> 1477 </bday> 1478 </vcard> 1479</vcards> 1480XML 1481, 1482 'BEGIN:VCARD' . "\n" . 1483 'VERSION:4.0' . "\n" . 1484 'BDAY:1353' . "\n" . 1485 'END:VCARD' . "\n" 1486 ); 1487 1488 } 1489 1490 /** 1491 * Section 4.3.2 of Relax NG Schema: value-time. 1492 */ 1493 function testRFC6351ValueTimeWithHourMinuteSecond() { 1494 1495 $this->assertXMLReflexivelyEqualsToMimeDir( 1496<<<XML 1497<?xml version="1.0" encoding="UTF-8"?> 1498<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 1499 <vcard> 1500 <bday> 1501 <date-and-or-time>135301</date-and-or-time> 1502 </bday> 1503 </vcard> 1504</vcards> 1505XML 1506, 1507 'BEGIN:VCARD' . "\n" . 1508 'VERSION:4.0' . "\n" . 1509 'BDAY:135301' . "\n" . 1510 'END:VCARD' . "\n" 1511 ); 1512 1513 } 1514 1515 /** 1516 * Section 4.3.2 of Relax NG Schema: value-time. 1517 */ 1518 function testRFC6351ValueTimeWithMinute() { 1519 1520 $this->assertXMLReflexivelyEqualsToMimeDir( 1521<<<XML 1522<?xml version="1.0" encoding="UTF-8"?> 1523<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 1524 <vcard> 1525 <bday> 1526 <date-and-or-time>-53</date-and-or-time> 1527 </bday> 1528 </vcard> 1529</vcards> 1530XML 1531, 1532 'BEGIN:VCARD' . "\n" . 1533 'VERSION:4.0' . "\n" . 1534 'BDAY:-53' . "\n" . 1535 'END:VCARD' . "\n" 1536 ); 1537 1538 } 1539 1540 /** 1541 * Section 4.3.2 of Relax NG Schema: value-time. 1542 */ 1543 function testRFC6351ValueTimeWithMinuteSecond() { 1544 1545 $this->assertXMLReflexivelyEqualsToMimeDir( 1546<<<XML 1547<?xml version="1.0" encoding="UTF-8"?> 1548<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 1549 <vcard> 1550 <bday> 1551 <date-and-or-time>-5301</date-and-or-time> 1552 </bday> 1553 </vcard> 1554</vcards> 1555XML 1556, 1557 'BEGIN:VCARD' . "\n" . 1558 'VERSION:4.0' . "\n" . 1559 'BDAY:-5301' . "\n" . 1560 'END:VCARD' . "\n" 1561 ); 1562 1563 } 1564 1565 /** 1566 * Section 4.3.2 of Relax NG Schema: value-time. 1567 */ 1568 function testRFC6351ValueTimeWithSecond() { 1569 1570 $this->assertTrue(true); 1571 1572 /* 1573 * According to the Relax NG Schema, there is a conflict between 1574 * value-date and value-time. The --01 syntax can only match a 1575 * value-date because of the higher priority set in 1576 * value-date-and-or-time. So we basically skip this test. 1577 * 1578 $this->assertXMLReflexivelyEqualsToMimeDir( 1579<<<XML 1580<?xml version="1.0" encoding="UTF-8"?> 1581<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 1582 <vcard> 1583 <bday> 1584 <date-and-or-time>--01</date-and-or-time> 1585 </bday> 1586 </vcard> 1587</vcards> 1588XML 1589, 1590 'BEGIN:VCARD' . "\n" . 1591 'VERSION:4.0' . "\n" . 1592 'BDAY:--01' . "\n" . 1593 'END:VCARD' . "\n" 1594 ); 1595 */ 1596 1597 } 1598 1599 /** 1600 * Section 4.3.2 of Relax NG Schema: value-time. 1601 */ 1602 function testRFC6351ValueTimeWithSecondZ() { 1603 1604 $this->assertXMLReflexivelyEqualsToMimeDir( 1605<<<XML 1606<?xml version="1.0" encoding="UTF-8"?> 1607<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 1608 <vcard> 1609 <bday> 1610 <date-and-or-time>--01Z</date-and-or-time> 1611 </bday> 1612 </vcard> 1613</vcards> 1614XML 1615, 1616 'BEGIN:VCARD' . "\n" . 1617 'VERSION:4.0' . "\n" . 1618 'BDAY:--01Z' . "\n" . 1619 'END:VCARD' . "\n" 1620 ); 1621 1622 } 1623 1624 /** 1625 * Section 4.3.2 of Relax NG Schema: value-time. 1626 */ 1627 function testRFC6351ValueTimeWithSecondTZ() { 1628 1629 $this->assertXMLReflexivelyEqualsToMimeDir( 1630<<<XML 1631<?xml version="1.0" encoding="UTF-8"?> 1632<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 1633 <vcard> 1634 <bday> 1635 <date-and-or-time>--01+1234</date-and-or-time> 1636 </bday> 1637 </vcard> 1638</vcards> 1639XML 1640, 1641 'BEGIN:VCARD' . "\n" . 1642 'VERSION:4.0' . "\n" . 1643 'BDAY:--01+1234' . "\n" . 1644 'END:VCARD' . "\n" 1645 ); 1646 1647 } 1648 1649 /** 1650 * Section 4.3.3 of Relax NG Schema: value-date-time. 1651 */ 1652 function testRFC6351ValueDateTimeWithYearMonthDayHour() { 1653 1654 $this->assertXMLReflexivelyEqualsToMimeDir( 1655<<<XML 1656<?xml version="1.0" encoding="UTF-8"?> 1657<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 1658 <vcard> 1659 <bday> 1660 <date-and-or-time>20150128T13</date-and-or-time> 1661 </bday> 1662 </vcard> 1663</vcards> 1664XML 1665, 1666 'BEGIN:VCARD' . "\n" . 1667 'VERSION:4.0' . "\n" . 1668 'BDAY:20150128T13' . "\n" . 1669 'END:VCARD' . "\n" 1670 ); 1671 1672 } 1673 1674 /** 1675 * Section 4.3.3 of Relax NG Schema: value-date-time. 1676 */ 1677 function testRFC6351ValueDateTimeWithMonthDayHour() { 1678 1679 $this->assertXMLReflexivelyEqualsToMimeDir( 1680<<<XML 1681<?xml version="1.0" encoding="UTF-8"?> 1682<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 1683 <vcard> 1684 <bday> 1685 <date-and-or-time>--0128T13</date-and-or-time> 1686 </bday> 1687 </vcard> 1688</vcards> 1689XML 1690, 1691 'BEGIN:VCARD' . "\n" . 1692 'VERSION:4.0' . "\n" . 1693 'BDAY:--0128T13' . "\n" . 1694 'END:VCARD' . "\n" 1695 ); 1696 1697 } 1698 1699 /** 1700 * Section 4.3.3 of Relax NG Schema: value-date-time. 1701 */ 1702 function testRFC6351ValueDateTimeWithDayHour() { 1703 1704 $this->assertXMLReflexivelyEqualsToMimeDir( 1705<<<XML 1706<?xml version="1.0" encoding="UTF-8"?> 1707<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 1708 <vcard> 1709 <bday> 1710 <date-and-or-time>---28T13</date-and-or-time> 1711 </bday> 1712 </vcard> 1713</vcards> 1714XML 1715, 1716 'BEGIN:VCARD' . "\n" . 1717 'VERSION:4.0' . "\n" . 1718 'BDAY:---28T13' . "\n" . 1719 'END:VCARD' . "\n" 1720 ); 1721 1722 } 1723 1724 /** 1725 * Section 4.3.3 of Relax NG Schema: value-date-time. 1726 */ 1727 function testRFC6351ValueDateTimeWithDayHourMinute() { 1728 1729 $this->assertXMLReflexivelyEqualsToMimeDir( 1730<<<XML 1731<?xml version="1.0" encoding="UTF-8"?> 1732<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 1733 <vcard> 1734 <bday> 1735 <date-and-or-time>---28T1353</date-and-or-time> 1736 </bday> 1737 </vcard> 1738</vcards> 1739XML 1740, 1741 'BEGIN:VCARD' . "\n" . 1742 'VERSION:4.0' . "\n" . 1743 'BDAY:---28T1353' . "\n" . 1744 'END:VCARD' . "\n" 1745 ); 1746 1747 } 1748 1749 /** 1750 * Section 4.3.3 of Relax NG Schema: value-date-time. 1751 */ 1752 function testRFC6351ValueDateTimeWithDayHourMinuteSecond() { 1753 1754 $this->assertXMLReflexivelyEqualsToMimeDir( 1755<<<XML 1756<?xml version="1.0" encoding="UTF-8"?> 1757<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 1758 <vcard> 1759 <bday> 1760 <date-and-or-time>---28T135301</date-and-or-time> 1761 </bday> 1762 </vcard> 1763</vcards> 1764XML 1765, 1766 'BEGIN:VCARD' . "\n" . 1767 'VERSION:4.0' . "\n" . 1768 'BDAY:---28T135301' . "\n" . 1769 'END:VCARD' . "\n" 1770 ); 1771 1772 } 1773 1774 /** 1775 * Section 4.3.3 of Relax NG Schema: value-date-time. 1776 */ 1777 function testRFC6351ValueDateTimeWithDayHourZ() { 1778 1779 $this->assertXMLReflexivelyEqualsToMimeDir( 1780<<<XML 1781<?xml version="1.0" encoding="UTF-8"?> 1782<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 1783 <vcard> 1784 <bday> 1785 <date-and-or-time>---28T13Z</date-and-or-time> 1786 </bday> 1787 </vcard> 1788</vcards> 1789XML 1790, 1791 'BEGIN:VCARD' . "\n" . 1792 'VERSION:4.0' . "\n" . 1793 'BDAY:---28T13Z' . "\n" . 1794 'END:VCARD' . "\n" 1795 ); 1796 1797 } 1798 1799 /** 1800 * Section 4.3.3 of Relax NG Schema: value-date-time. 1801 */ 1802 function testRFC6351ValueDateTimeWithDayHourTZ() { 1803 1804 $this->assertXMLReflexivelyEqualsToMimeDir( 1805<<<XML 1806<?xml version="1.0" encoding="UTF-8"?> 1807<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 1808 <vcard> 1809 <bday> 1810 <date-and-or-time>---28T13+1234</date-and-or-time> 1811 </bday> 1812 </vcard> 1813</vcards> 1814XML 1815, 1816 'BEGIN:VCARD' . "\n" . 1817 'VERSION:4.0' . "\n" . 1818 'BDAY:---28T13+1234' . "\n" . 1819 'END:VCARD' . "\n" 1820 ); 1821 1822 } 1823 1824 /** 1825 * Property: SOURCE. 1826 */ 1827 function testRFC6350Section6_1_3() { 1828 1829 $this->assertXMLReflexivelyEqualsToMimeDir( 1830<<<XML 1831<?xml version="1.0" encoding="UTF-8"?> 1832<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 1833 <vcard> 1834 <source> 1835 <uri>ldap://ldap.example.com/cn=Babs%20Jensen,%20o=Babsco,%20c=US</uri> 1836 </source> 1837 </vcard> 1838</vcards> 1839XML 1840, 1841 'BEGIN:VCARD' . "\n" . 1842 'VERSION:4.0' . "\n" . 1843 'SOURCE:ldap://ldap.example.com/cn=Babs%20Jensen\,%20o=Babsco\,%20c=US' . "\n" . 1844 'END:VCARD' . "\n" 1845 ); 1846 1847 } 1848 1849 /** 1850 * Property: KIND. 1851 */ 1852 function testRFC6350Section6_1_4() { 1853 1854 $this->assertXMLReflexivelyEqualsToMimeDir( 1855<<<XML 1856<?xml version="1.0" encoding="UTF-8"?> 1857<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 1858 <vcard> 1859 <kind> 1860 <text>individual</text> 1861 </kind> 1862 </vcard> 1863</vcards> 1864XML 1865, 1866 'BEGIN:VCARD' . "\n" . 1867 'VERSION:4.0' . "\n" . 1868 'KIND:individual' . "\n" . 1869 'END:VCARD' . "\n" 1870 ); 1871 1872 } 1873 1874 /** 1875 * Property: FN. 1876 */ 1877 function testRFC6350Section6_2_1() { 1878 1879 $this->assertXMLReflexivelyEqualsToMimeDir( 1880<<<XML 1881<?xml version="1.0" encoding="UTF-8"?> 1882<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 1883 <vcard> 1884 <fn> 1885 <text>Mr. John Q. Public, Esq.</text> 1886 </fn> 1887 </vcard> 1888</vcards> 1889XML 1890, 1891 'BEGIN:VCARD' . "\n" . 1892 'VERSION:4.0' . "\n" . 1893 'FN:Mr. John Q. Public\, Esq.' . "\n" . 1894 'END:VCARD' . "\n" 1895 ); 1896 1897 } 1898 1899 /** 1900 * Property: N. 1901 */ 1902 function testRFC6350Section6_2_2() { 1903 1904 $this->assertXMLReflexivelyEqualsToMimeDir( 1905<<<XML 1906<?xml version="1.0" encoding="UTF-8"?> 1907<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 1908 <vcard> 1909 <n> 1910 <surname>Stevenson</surname> 1911 <given>John</given> 1912 <additional>Philip,Paul</additional> 1913 <prefix>Dr.</prefix> 1914 <suffix>Jr.,M.D.,A.C.P.</suffix> 1915 </n> 1916 </vcard> 1917</vcards> 1918XML 1919, 1920 'BEGIN:VCARD' . "\n" . 1921 'VERSION:4.0' . "\n" . 1922 'N:Stevenson;John;Philip\,Paul;Dr.;Jr.\,M.D.\,A.C.P.' . "\n" . 1923 'END:VCARD' . "\n" 1924 ); 1925 1926 } 1927 1928 /** 1929 * Property: NICKNAME. 1930 */ 1931 function testRFC6350Section6_2_3() { 1932 1933 $this->assertXMLReflexivelyEqualsToMimeDir( 1934<<<XML 1935<?xml version="1.0" encoding="UTF-8"?> 1936<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 1937 <vcard> 1938 <nickname> 1939 <text>Jim</text> 1940 <text>Jimmie</text> 1941 </nickname> 1942 </vcard> 1943</vcards> 1944XML 1945, 1946 'BEGIN:VCARD' . "\n" . 1947 'VERSION:4.0' . "\n" . 1948 'NICKNAME:Jim,Jimmie' . "\n" . 1949 'END:VCARD' . "\n" 1950 ); 1951 1952 } 1953 1954 /** 1955 * Property: PHOTO. 1956 */ 1957 function testRFC6350Section6_2_4() { 1958 1959 $this->assertXMLReflexivelyEqualsToMimeDir( 1960<<<XML 1961<?xml version="1.0" encoding="UTF-8"?> 1962<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 1963 <vcard> 1964 <photo> 1965 <uri>http://www.example.com/pub/photos/jqpublic.gif</uri> 1966 </photo> 1967 </vcard> 1968</vcards> 1969XML 1970, 1971 'BEGIN:VCARD' . "\n" . 1972 'VERSION:4.0' . "\n" . 1973 'PHOTO:http://www.example.com/pub/photos/jqpublic.gif' . "\n" . 1974 'END:VCARD' . "\n" 1975 ); 1976 1977 } 1978 1979 function testRFC6350Section6_2_5() { 1980 1981 $this->assertXMLReflexivelyEqualsToMimeDir( 1982<<<XML 1983<?xml version="1.0" encoding="UTF-8"?> 1984<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 1985 <vcard> 1986 <bday> 1987 <date-and-or-time>19531015T231000Z</date-and-or-time> 1988 </bday> 1989 </vcard> 1990</vcards> 1991XML 1992, 1993 'BEGIN:VCARD' . "\n" . 1994 'VERSION:4.0' . "\n" . 1995 'BDAY:19531015T231000Z' . "\n" . 1996 'END:VCARD' . "\n" 1997 ); 1998 1999 } 2000 2001 function testRFC6350Section6_2_6() { 2002 2003 $this->assertXMLReflexivelyEqualsToMimeDir( 2004<<<XML 2005<?xml version="1.0" encoding="UTF-8"?> 2006<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 2007 <vcard> 2008 <anniversary> 2009 <date-and-or-time>19960415</date-and-or-time> 2010 </anniversary> 2011 </vcard> 2012</vcards> 2013XML 2014, 2015 'BEGIN:VCARD' . "\n" . 2016 'VERSION:4.0' . "\n" . 2017 'ANNIVERSARY:19960415' . "\n" . 2018 'END:VCARD' . "\n" 2019 ); 2020 2021 } 2022 2023 /** 2024 * Property: GENDER. 2025 */ 2026 function testRFC6350Section6_2_7() { 2027 2028 $this->assertXMLReflexivelyEqualsToMimeDir( 2029<<<XML 2030<?xml version="1.0" encoding="UTF-8"?> 2031<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 2032 <vcard> 2033 <gender> 2034 <sex>Jim</sex> 2035 <text>Jimmie</text> 2036 </gender> 2037 </vcard> 2038</vcards> 2039XML 2040, 2041 'BEGIN:VCARD' . "\n" . 2042 'VERSION:4.0' . "\n" . 2043 'GENDER:Jim;Jimmie' . "\n" . 2044 'END:VCARD' . "\n" 2045 ); 2046 2047 } 2048 2049 /** 2050 * Property: ADR. 2051 */ 2052 function testRFC6350Section6_3_1() { 2053 2054 $this->assertXMLReflexivelyEqualsToMimeDir( 2055<<<XML 2056<?xml version="1.0" encoding="UTF-8"?> 2057<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 2058 <vcard> 2059 <adr> 2060 <pobox/> 2061 <ext/> 2062 <street>123 Main Street</street> 2063 <locality>Any Town</locality> 2064 <region>CA</region> 2065 <code>91921-1234</code> 2066 <country>U.S.A.</country> 2067 </adr> 2068 </vcard> 2069</vcards> 2070XML 2071, 2072 'BEGIN:VCARD' . "\n" . 2073 'VERSION:4.0' . "\n" . 2074 'ADR:;;123 Main Street;Any Town;CA;91921-1234;U.S.A.' . "\n" . 2075 'END:VCARD' . "\n" 2076 ); 2077 2078 } 2079 2080 /** 2081 * Property: TEL. 2082 */ 2083 function testRFC6350Section6_4_1() { 2084 2085 /** 2086 * Quoting RFC: 2087 * > Value type: By default, it is a single free-form text value (for 2088 * > backward compatibility with vCard 3), but it SHOULD be reset to a 2089 * > URI value. It is expected that the URI scheme will be "tel", as 2090 * > specified in [RFC3966], but other schemes MAY be used. 2091 * 2092 * So first, we test xCard/URI to vCard/URI. 2093 * Then, we test xCard/TEXT to vCard/TEXT to xCard/TEXT. 2094 */ 2095 $this->assertXMLEqualsToMimeDir( 2096<<<XML 2097<?xml version="1.0" encoding="UTF-8"?> 2098<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 2099 <vcard> 2100 <tel> 2101 <parameters> 2102 <type> 2103 <text>home</text> 2104 </type> 2105 </parameters> 2106 <uri>tel:+33-01-23-45-67</uri> 2107 </tel> 2108 </vcard> 2109</vcards> 2110XML 2111, 2112 'BEGIN:VCARD' . "\n" . 2113 'VERSION:4.0' . "\n" . 2114 'TEL;TYPE=home:tel:+33-01-23-45-67' . "\n" . 2115 'END:VCARD' . "\n" 2116 ); 2117 2118 $this->assertXMLReflexivelyEqualsToMimeDir( 2119<<<XML 2120<?xml version="1.0" encoding="UTF-8"?> 2121<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 2122 <vcard> 2123 <tel> 2124 <parameters> 2125 <type> 2126 <text>home</text> 2127 </type> 2128 </parameters> 2129 <text>tel:+33-01-23-45-67</text> 2130 </tel> 2131 </vcard> 2132</vcards> 2133XML 2134, 2135 'BEGIN:VCARD' . "\n" . 2136 'VERSION:4.0' . "\n" . 2137 'TEL;TYPE=home:tel:+33-01-23-45-67' . "\n" . 2138 'END:VCARD' . "\n" 2139 ); 2140 2141 } 2142 2143 /** 2144 * Property: EMAIL. 2145 */ 2146 function testRFC6350Section6_4_2() { 2147 2148 $this->assertXMLReflexivelyEqualsToMimeDir( 2149<<<XML 2150<?xml version="1.0" encoding="UTF-8"?> 2151<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 2152 <vcard> 2153 <email> 2154 <parameters> 2155 <type> 2156 <text>work</text> 2157 </type> 2158 </parameters> 2159 <text>jqpublic@xyz.example.com</text> 2160 </email> 2161 </vcard> 2162</vcards> 2163XML 2164, 2165 'BEGIN:VCARD' . "\n" . 2166 'VERSION:4.0' . "\n" . 2167 'EMAIL;TYPE=work:jqpublic@xyz.example.com' . "\n" . 2168 'END:VCARD' . "\n" 2169 ); 2170 2171 } 2172 2173 /** 2174 * Property: IMPP. 2175 */ 2176 function testRFC6350Section6_4_3() { 2177 2178 $this->assertXMLReflexivelyEqualsToMimeDir( 2179<<<XML 2180<?xml version="1.0" encoding="UTF-8"?> 2181<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 2182 <vcard> 2183 <impp> 2184 <parameters> 2185 <pref> 2186 <text>1</text> 2187 </pref> 2188 </parameters> 2189 <uri>xmpp:alice@example.com</uri> 2190 </impp> 2191 </vcard> 2192</vcards> 2193XML 2194, 2195 'BEGIN:VCARD' . "\n" . 2196 'VERSION:4.0' . "\n" . 2197 'IMPP;PREF=1:xmpp:alice@example.com' . "\n" . 2198 'END:VCARD' . "\n" 2199 ); 2200 2201 } 2202 2203 /** 2204 * Property: LANG. 2205 */ 2206 function testRFC6350Section6_4_4() { 2207 2208 $this->assertXMLReflexivelyEqualsToMimeDir( 2209<<<XML 2210<?xml version="1.0" encoding="UTF-8"?> 2211<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 2212 <vcard> 2213 <lang> 2214 <parameters> 2215 <type> 2216 <text>work</text> 2217 </type> 2218 <pref> 2219 <text>2</text> 2220 </pref> 2221 </parameters> 2222 <language-tag>en</language-tag> 2223 </lang> 2224 </vcard> 2225</vcards> 2226XML 2227, 2228 'BEGIN:VCARD' . "\n" . 2229 'VERSION:4.0' . "\n" . 2230 'LANG;TYPE=work;PREF=2:en' . "\n" . 2231 'END:VCARD' . "\n" 2232 ); 2233 2234 } 2235 2236 /** 2237 * Property: TZ. 2238 */ 2239 function testRFC6350Section6_5_1() { 2240 2241 $this->assertXMLReflexivelyEqualsToMimeDir( 2242<<<XML 2243<?xml version="1.0" encoding="UTF-8"?> 2244<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 2245 <vcard> 2246 <tz> 2247 <text>Raleigh/North America</text> 2248 </tz> 2249 </vcard> 2250</vcards> 2251XML 2252, 2253 'BEGIN:VCARD' . "\n" . 2254 'VERSION:4.0' . "\n" . 2255 'TZ:Raleigh/North America' . "\n" . 2256 'END:VCARD' . "\n" 2257 ); 2258 2259 } 2260 2261 /** 2262 * Property: GEO. 2263 */ 2264 function testRFC6350Section6_5_2() { 2265 2266 $this->assertXMLEqualsToMimeDir( 2267<<<XML 2268<?xml version="1.0" encoding="UTF-8"?> 2269<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 2270 <vcard> 2271 <geo> 2272 <uri>geo:37.386013,-122.082932</uri> 2273 </geo> 2274 </vcard> 2275</vcards> 2276XML 2277, 2278 'BEGIN:VCARD' . "\n" . 2279 'VERSION:4.0' . "\n" . 2280 'GEO:geo:37.386013\,-122.082932' . "\n" . 2281 'END:VCARD' . "\n" 2282 ); 2283 2284 $this->assertXMLReflexivelyEqualsToMimeDir( 2285<<<XML 2286<?xml version="1.0" encoding="UTF-8"?> 2287<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 2288 <vcard> 2289 <geo> 2290 <text>geo:37.386013,-122.082932</text> 2291 </geo> 2292 </vcard> 2293</vcards> 2294XML 2295, 2296 'BEGIN:VCARD' . "\n" . 2297 'VERSION:4.0' . "\n" . 2298 'GEO:geo:37.386013\,-122.082932' . "\n" . 2299 'END:VCARD' . "\n" 2300 ); 2301 2302 } 2303 2304 /** 2305 * Property: TITLE. 2306 */ 2307 function testRFC6350Section6_6_1() { 2308 2309 $this->assertXMLReflexivelyEqualsToMimeDir( 2310<<<XML 2311<?xml version="1.0" encoding="UTF-8"?> 2312<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 2313 <vcard> 2314 <title> 2315 <text>Research Scientist</text> 2316 </title> 2317 </vcard> 2318</vcards> 2319XML 2320, 2321 'BEGIN:VCARD' . "\n" . 2322 'VERSION:4.0' . "\n" . 2323 'TITLE:Research Scientist' . "\n" . 2324 'END:VCARD' . "\n" 2325 ); 2326 2327 } 2328 2329 /** 2330 * Property: ROLE. 2331 */ 2332 function testRFC6350Section6_6_2() { 2333 2334 $this->assertXMLReflexivelyEqualsToMimeDir( 2335<<<XML 2336<?xml version="1.0" encoding="UTF-8"?> 2337<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 2338 <vcard> 2339 <role> 2340 <text>Project Leader</text> 2341 </role> 2342 </vcard> 2343</vcards> 2344XML 2345, 2346 'BEGIN:VCARD' . "\n" . 2347 'VERSION:4.0' . "\n" . 2348 'ROLE:Project Leader' . "\n" . 2349 'END:VCARD' . "\n" 2350 ); 2351 2352 } 2353 2354 /** 2355 * Property: LOGO. 2356 */ 2357 function testRFC6350Section6_6_3() { 2358 2359 $this->assertXMLReflexivelyEqualsToMimeDir( 2360<<<XML 2361<?xml version="1.0" encoding="UTF-8"?> 2362<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 2363 <vcard> 2364 <logo> 2365 <uri>http://www.example.com/pub/logos/abccorp.jpg</uri> 2366 </logo> 2367 </vcard> 2368</vcards> 2369XML 2370, 2371 'BEGIN:VCARD' . "\n" . 2372 'VERSION:4.0' . "\n" . 2373 'LOGO:http://www.example.com/pub/logos/abccorp.jpg' . "\n" . 2374 'END:VCARD' . "\n" 2375 ); 2376 2377 } 2378 2379 /** 2380 * Property: ORG. 2381 */ 2382 function testRFC6350Section6_6_4() { 2383 2384 $this->assertXMLReflexivelyEqualsToMimeDir( 2385<<<XML 2386<?xml version="1.0" encoding="UTF-8"?> 2387<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 2388 <vcard> 2389 <org> 2390 <text>ABC, Inc.</text> 2391 <text>North American Division</text> 2392 <text>Marketing</text> 2393 </org> 2394 </vcard> 2395</vcards> 2396XML 2397, 2398 'BEGIN:VCARD' . "\n" . 2399 'VERSION:4.0' . "\n" . 2400 'ORG:ABC\, Inc.;North American Division;Marketing' . "\n" . 2401 'END:VCARD' . "\n" 2402 ); 2403 2404 } 2405 2406 /** 2407 * Property: MEMBER. 2408 */ 2409 function testRFC6350Section6_6_5() { 2410 2411 $this->assertXMLReflexivelyEqualsToMimeDir( 2412<<<XML 2413<?xml version="1.0" encoding="UTF-8"?> 2414<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 2415 <vcard> 2416 <member> 2417 <uri>urn:uuid:03a0e51f-d1aa-4385-8a53-e29025acd8af</uri> 2418 </member> 2419 </vcard> 2420</vcards> 2421XML 2422, 2423 'BEGIN:VCARD' . "\n" . 2424 'VERSION:4.0' . "\n" . 2425 'MEMBER:urn:uuid:03a0e51f-d1aa-4385-8a53-e29025acd8af' . "\n" . 2426 'END:VCARD' . "\n" 2427 ); 2428 2429 $this->assertXMLReflexivelyEqualsToMimeDir( 2430<<<XML 2431<?xml version="1.0" encoding="UTF-8"?> 2432<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 2433 <vcard> 2434 <member> 2435 <uri>mailto:subscriber1@example.com</uri> 2436 </member> 2437 <member> 2438 <uri>xmpp:subscriber2@example.com</uri> 2439 </member> 2440 <member> 2441 <uri>sip:subscriber3@example.com</uri> 2442 </member> 2443 <member> 2444 <uri>tel:+1-418-555-5555</uri> 2445 </member> 2446 </vcard> 2447</vcards> 2448XML 2449, 2450 'BEGIN:VCARD' . "\n" . 2451 'VERSION:4.0' . "\n" . 2452 'MEMBER:mailto:subscriber1@example.com' . "\n" . 2453 'MEMBER:xmpp:subscriber2@example.com' . "\n" . 2454 'MEMBER:sip:subscriber3@example.com' . "\n" . 2455 'MEMBER:tel:+1-418-555-5555' . "\n" . 2456 'END:VCARD' . "\n" 2457 ); 2458 2459 } 2460 2461 /** 2462 * Property: RELATED. 2463 */ 2464 function testRFC6350Section6_6_6() { 2465 2466 $this->assertXMLReflexivelyEqualsToMimeDir( 2467<<<XML 2468<?xml version="1.0" encoding="UTF-8"?> 2469<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 2470 <vcard> 2471 <related> 2472 <parameters> 2473 <type> 2474 <text>friend</text> 2475 </type> 2476 </parameters> 2477 <uri>urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6</uri> 2478 </related> 2479 </vcard> 2480</vcards> 2481XML 2482, 2483 'BEGIN:VCARD' . "\n" . 2484 'VERSION:4.0' . "\n" . 2485 'RELATED;TYPE=friend:urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6' . "\n" . 2486 'END:VCARD' . "\n" 2487 ); 2488 2489 } 2490 2491 /** 2492 * Property: CATEGORIES. 2493 */ 2494 function testRFC6350Section6_7_1() { 2495 2496 $this->assertXMLReflexivelyEqualsToMimeDir( 2497<<<XML 2498<?xml version="1.0" encoding="UTF-8"?> 2499<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 2500 <vcard> 2501 <categories> 2502 <text>INTERNET</text> 2503 <text>IETF</text> 2504 <text>INDUSTRY</text> 2505 <text>INFORMATION TECHNOLOGY</text> 2506 </categories> 2507 </vcard> 2508</vcards> 2509XML 2510, 2511 'BEGIN:VCARD' . "\n" . 2512 'VERSION:4.0' . "\n" . 2513 'CATEGORIES:INTERNET,IETF,INDUSTRY,INFORMATION TECHNOLOGY' . "\n" . 2514 'END:VCARD' . "\n" 2515 ); 2516 2517 } 2518 2519 /** 2520 * Property: NOTE. 2521 */ 2522 function testRFC6350Section6_7_2() { 2523 2524 $this->assertXMLReflexivelyEqualsToMimeDir( 2525<<<XML 2526<?xml version="1.0" encoding="UTF-8"?> 2527<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 2528 <vcard> 2529 <note> 2530 <text>Foo, bar</text> 2531 </note> 2532 </vcard> 2533</vcards> 2534XML 2535, 2536 'BEGIN:VCARD' . "\n" . 2537 'VERSION:4.0' . "\n" . 2538 'NOTE:Foo\, bar' . "\n" . 2539 'END:VCARD' . "\n" 2540 ); 2541 2542 } 2543 2544 /** 2545 * Property: PRODID. 2546 */ 2547 function testRFC6350Section6_7_3() { 2548 2549 $this->assertXMLReflexivelyEqualsToMimeDir( 2550<<<XML 2551<?xml version="1.0" encoding="UTF-8"?> 2552<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 2553 <vcard> 2554 <prodid> 2555 <text>-//ONLINE DIRECTORY//NONSGML Version 1//EN</text> 2556 </prodid> 2557 </vcard> 2558</vcards> 2559XML 2560, 2561 'BEGIN:VCARD' . "\n" . 2562 'VERSION:4.0' . "\n" . 2563 'PRODID:-//ONLINE DIRECTORY//NONSGML Version 1//EN' . "\n" . 2564 'END:VCARD' . "\n" 2565 ); 2566 2567 } 2568 2569 function testRFC6350Section6_7_4() { 2570 2571 $this->assertXMLReflexivelyEqualsToMimeDir( 2572<<<XML 2573<?xml version="1.0" encoding="UTF-8"?> 2574<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 2575 <vcard> 2576 <rev> 2577 <timestamp>19951031T222710Z</timestamp> 2578 </rev> 2579 </vcard> 2580</vcards> 2581XML 2582, 2583 'BEGIN:VCARD' . "\n" . 2584 'VERSION:4.0' . "\n" . 2585 'REV:19951031T222710Z' . "\n" . 2586 'END:VCARD' . "\n" 2587 ); 2588 2589 } 2590 2591 /** 2592 * Property: SOUND. 2593 */ 2594 function testRFC6350Section6_7_5() { 2595 2596 $this->assertXMLEqualsToMimeDir( 2597<<<XML 2598<?xml version="1.0" encoding="UTF-8"?> 2599<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 2600 <vcard> 2601 <sound> 2602 <uri>CID:JOHNQPUBLIC.part8.19960229T080000.xyzMail@example.com</uri> 2603 </sound> 2604 </vcard> 2605</vcards> 2606XML 2607, 2608 'BEGIN:VCARD' . "\n" . 2609 'VERSION:4.0' . "\n" . 2610 'SOUND:CID:JOHNQPUBLIC.part8.19960229T080000.xyzMail@example.com' . "\n" . 2611 'END:VCARD' . "\n" 2612 ); 2613 2614 $this->assertXMLReflexivelyEqualsToMimeDir( 2615<<<XML 2616<?xml version="1.0" encoding="UTF-8"?> 2617<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 2618 <vcard> 2619 <sound> 2620 <text>CID:JOHNQPUBLIC.part8.19960229T080000.xyzMail@example.com</text> 2621 </sound> 2622 </vcard> 2623</vcards> 2624XML 2625, 2626 'BEGIN:VCARD' . "\n" . 2627 'VERSION:4.0' . "\n" . 2628 'SOUND:CID:JOHNQPUBLIC.part8.19960229T080000.xyzMail@example.com' . "\n" . 2629 'END:VCARD' . "\n" 2630 ); 2631 2632 } 2633 2634 /** 2635 * Property: UID. 2636 */ 2637 function testRFC6350Section6_7_6() { 2638 2639 $this->assertXMLReflexivelyEqualsToMimeDir( 2640<<<XML 2641<?xml version="1.0" encoding="UTF-8"?> 2642<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 2643 <vcard> 2644 <uid> 2645 <text>urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6</text> 2646 </uid> 2647 </vcard> 2648</vcards> 2649XML 2650, 2651 'BEGIN:VCARD' . "\n" . 2652 'VERSION:4.0' . "\n" . 2653 'UID:urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6' . "\n" . 2654 'END:VCARD' . "\n" 2655 ); 2656 2657 } 2658 2659 /** 2660 * Property: CLIENTPIDMAP. 2661 */ 2662 function testRFC6350Section6_7_7() { 2663 2664 $this->assertXMLReflexivelyEqualsToMimeDir( 2665<<<XML 2666<?xml version="1.0" encoding="UTF-8"?> 2667<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 2668 <vcard> 2669 <clientpidmap> 2670 <sourceid>1</sourceid> 2671 <uri>urn:uuid:3df403f4-5924-4bb7-b077-3c711d9eb34b</uri> 2672 </clientpidmap> 2673 </vcard> 2674</vcards> 2675XML 2676, 2677 'BEGIN:VCARD' . "\n" . 2678 'VERSION:4.0' . "\n" . 2679 'CLIENTPIDMAP:1;urn:uuid:3df403f4-5924-4bb7-b077-3c711d9eb34b' . "\n" . 2680 'END:VCARD' . "\n" 2681 ); 2682 2683 } 2684 2685 /** 2686 * Property: URL. 2687 */ 2688 function testRFC6350Section6_7_8() { 2689 2690 $this->assertXMLReflexivelyEqualsToMimeDir( 2691<<<XML 2692<?xml version="1.0" encoding="UTF-8"?> 2693<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 2694 <vcard> 2695 <url> 2696 <uri>http://example.org/restaurant.french/~chezchic.html</uri> 2697 </url> 2698 </vcard> 2699</vcards> 2700XML 2701, 2702 'BEGIN:VCARD' . "\n" . 2703 'VERSION:4.0' . "\n" . 2704 'URL:http://example.org/restaurant.french/~chezchic.html' . "\n" . 2705 'END:VCARD' . "\n" 2706 ); 2707 2708 } 2709 2710 /** 2711 * Property: VERSION. 2712 */ 2713 function testRFC6350Section6_7_9() { 2714 2715 $this->assertXMLReflexivelyEqualsToMimeDir( 2716<<<XML 2717<?xml version="1.0" encoding="UTF-8"?> 2718<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 2719 <vcard/> 2720</vcards> 2721XML 2722, 2723 'BEGIN:VCARD' . "\n" . 2724 'VERSION:4.0' . "\n" . 2725 'END:VCARD' . "\n" 2726 ); 2727 2728 } 2729 2730 /** 2731 * Property: KEY. 2732 */ 2733 function testRFC6350Section6_8_1() { 2734 2735 $this->assertXMLReflexivelyEqualsToMimeDir( 2736<<<XML 2737<?xml version="1.0" encoding="UTF-8"?> 2738<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 2739 <vcard> 2740 <key> 2741 <parameters> 2742 <mediatype> 2743 <text>application/pgp-keys</text> 2744 </mediatype> 2745 </parameters> 2746 <text>ftp://example.com/keys/jdoe</text> 2747 </key> 2748 </vcard> 2749</vcards> 2750XML 2751, 2752 'BEGIN:VCARD' . "\n" . 2753 'VERSION:4.0' . "\n" . 2754 'KEY;MEDIATYPE=application/pgp-keys:ftp://example.com/keys/jdoe' . "\n" . 2755 'END:VCARD' . "\n" 2756 ); 2757 2758 } 2759 2760 /** 2761 * Property: FBURL. 2762 */ 2763 function testRFC6350Section6_9_1() { 2764 2765 $this->assertXMLReflexivelyEqualsToMimeDir( 2766<<<XML 2767<?xml version="1.0" encoding="UTF-8"?> 2768<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 2769 <vcard> 2770 <fburl> 2771 <parameters> 2772 <pref> 2773 <text>1</text> 2774 </pref> 2775 </parameters> 2776 <uri>http://www.example.com/busy/janedoe</uri> 2777 </fburl> 2778 </vcard> 2779</vcards> 2780XML 2781, 2782 'BEGIN:VCARD' . "\n" . 2783 'VERSION:4.0' . "\n" . 2784 'FBURL;PREF=1:http://www.example.com/busy/janedoe' . "\n" . 2785 'END:VCARD' . "\n" 2786 ); 2787 2788 } 2789 2790 /** 2791 * Property: CALADRURI. 2792 */ 2793 function testRFC6350Section6_9_2() { 2794 2795 $this->assertXMLReflexivelyEqualsToMimeDir( 2796<<<XML 2797<?xml version="1.0" encoding="UTF-8"?> 2798<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 2799 <vcard> 2800 <caladruri> 2801 <uri>http://example.com/calendar/jdoe</uri> 2802 </caladruri> 2803 </vcard> 2804</vcards> 2805XML 2806, 2807 'BEGIN:VCARD' . "\n" . 2808 'VERSION:4.0' . "\n" . 2809 'CALADRURI:http://example.com/calendar/jdoe' . "\n" . 2810 'END:VCARD' . "\n" 2811 ); 2812 2813 } 2814 2815 /** 2816 * Property: CALURI. 2817 */ 2818 function testRFC6350Section6_9_3() { 2819 2820 $this->assertXMLReflexivelyEqualsToMimeDir( 2821<<<XML 2822<?xml version="1.0" encoding="UTF-8"?> 2823<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 2824 <vcard> 2825 <caluri> 2826 <parameters> 2827 <pref> 2828 <text>1</text> 2829 </pref> 2830 </parameters> 2831 <uri>http://cal.example.com/calA</uri> 2832 </caluri> 2833 </vcard> 2834</vcards> 2835XML 2836, 2837 'BEGIN:VCARD' . "\n" . 2838 'VERSION:4.0' . "\n" . 2839 'CALURI;PREF=1:http://cal.example.com/calA' . "\n" . 2840 'END:VCARD' . "\n" 2841 ); 2842 2843 } 2844 2845 /** 2846 * Property: CAPURI. 2847 */ 2848 function testRFC6350SectionA_3() { 2849 2850 $this->assertXMLReflexivelyEqualsToMimeDir( 2851<<<XML 2852<?xml version="1.0" encoding="UTF-8"?> 2853<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0"> 2854 <vcard> 2855 <capuri> 2856 <uri>http://cap.example.com/capA</uri> 2857 </capuri> 2858 </vcard> 2859</vcards> 2860XML 2861, 2862 'BEGIN:VCARD' . "\n" . 2863 'VERSION:4.0' . "\n" . 2864 'CAPURI:http://cap.example.com/capA' . "\n" . 2865 'END:VCARD' . "\n" 2866 ); 2867 2868 } 2869 2870 /** 2871 * Check this equality: 2872 * XML -> object model -> MIME Dir. 2873 */ 2874 protected function assertXMLEqualsToMimeDir($xml, $mimedir) { 2875 2876 $component = VObject\Reader::readXML($xml); 2877 $this->assertVObjectEqualsVObject($mimedir, $component); 2878 2879 } 2880 2881 /** 2882 * Check this (reflexive) equality: 2883 * XML -> object model -> MIME Dir -> object model -> XML. 2884 */ 2885 protected function assertXMLReflexivelyEqualsToMimeDir($xml, $mimedir) { 2886 2887 $this->assertXMLEqualsToMimeDir($xml, $mimedir); 2888 2889 $component = VObject\Reader::read($mimedir); 2890 $this->assertXmlStringEqualsXmlString($xml, VObject\Writer::writeXML($component)); 2891 2892 } 2893} 2894