@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
at upstream/main 1750 lines 37 kB view raw
1<?php 2 3final class PhutilCalendarRecurrenceRuleTestCase extends PhutilTestCase { 4 5 public function testSimpleRecurrenceRules() { 6 $start = PhutilCalendarAbsoluteDateTime::newFromISO8601('20160101T120000Z'); 7 8 $rrule = id(new PhutilCalendarRecurrenceRule()) 9 ->setStartDateTime($start) 10 ->setFrequency(PhutilCalendarRecurrenceRule::FREQUENCY_DAILY); 11 12 $set = id(new PhutilCalendarRecurrenceSet()) 13 ->addSource($rrule); 14 15 $result = $set->getEventsBetween(null, null, 3); 16 17 $expect = array( 18 PhutilCalendarAbsoluteDateTime::newFromISO8601('20160101T120000Z'), 19 PhutilCalendarAbsoluteDateTime::newFromISO8601('20160102T120000Z'), 20 PhutilCalendarAbsoluteDateTime::newFromISO8601('20160103T120000Z'), 21 ); 22 23 $this->assertEqual( 24 mpull($expect, 'getISO8601'), 25 mpull($result, 'getISO8601'), 26 pht('Simple daily event.')); 27 28 29 30 $rrule = id(new PhutilCalendarRecurrenceRule()) 31 ->setStartDateTime($start) 32 ->setFrequency(PhutilCalendarRecurrenceRule::FREQUENCY_HOURLY) 33 ->setByHour(array(12, 13)); 34 35 $set = id(new PhutilCalendarRecurrenceSet()) 36 ->addSource($rrule); 37 38 $result = $set->getEventsBetween(null, null, 5); 39 40 $expect = array( 41 PhutilCalendarAbsoluteDateTime::newFromISO8601('20160101T120000Z'), 42 PhutilCalendarAbsoluteDateTime::newFromISO8601('20160101T130000Z'), 43 PhutilCalendarAbsoluteDateTime::newFromISO8601('20160102T120000Z'), 44 PhutilCalendarAbsoluteDateTime::newFromISO8601('20160102T130000Z'), 45 PhutilCalendarAbsoluteDateTime::newFromISO8601('20160103T120000Z'), 46 ); 47 48 $this->assertEqual( 49 mpull($expect, 'getISO8601'), 50 mpull($result, 'getISO8601'), 51 pht('Hourly event with BYHOUR.')); 52 53 54 $rrule = id(new PhutilCalendarRecurrenceRule()) 55 ->setStartDateTime($start) 56 ->setFrequency(PhutilCalendarRecurrenceRule::FREQUENCY_YEARLY); 57 58 $set = id(new PhutilCalendarRecurrenceSet()) 59 ->addSource($rrule); 60 61 $result = $set->getEventsBetween(null, null, 2); 62 63 $expect = array( 64 PhutilCalendarAbsoluteDateTime::newFromISO8601('20160101T120000Z'), 65 PhutilCalendarAbsoluteDateTime::newFromISO8601('20170101T120000Z'), 66 ); 67 68 $this->assertEqual( 69 mpull($expect, 'getISO8601'), 70 mpull($result, 'getISO8601'), 71 pht('Yearly event.')); 72 73 74 // This is an efficiency test for bizarre rules: it defines a secondly 75 // event which only occurs one a year, and generates 3 instances of it. 76 // This implementation should be fast enough that this test doesn't take 77 // a significant amount of time. 78 79 $rrule = id(new PhutilCalendarRecurrenceRule()) 80 ->setStartDateTime($start) 81 ->setFrequency(PhutilCalendarRecurrenceRule::FREQUENCY_SECONDLY) 82 ->setByMonth(array(1)) 83 ->setByMonthDay(array(1)) 84 ->setByHour(array(12)) 85 ->setByMinute(array(0)) 86 ->setBySecond(array(0)); 87 88 $set = id(new PhutilCalendarRecurrenceSet()) 89 ->addSource($rrule); 90 91 $result = $set->getEventsBetween(null, null, 3); 92 93 $expect = array( 94 PhutilCalendarAbsoluteDateTime::newFromISO8601('20160101T120000Z'), 95 PhutilCalendarAbsoluteDateTime::newFromISO8601('20170101T120000Z'), 96 PhutilCalendarAbsoluteDateTime::newFromISO8601('20180101T120000Z'), 97 ); 98 99 $this->assertEqual( 100 mpull($expect, 'getISO8601'), 101 mpull($result, 'getISO8601'), 102 pht('Secondly event with many constraints.')); 103 } 104 105 public function testYearlyRecurrenceRules() { 106 $tests = array(); 107 $expect = array(); 108 109 $tests[] = array(); 110 $expect[] = array( 111 '19970902', 112 '19980902', 113 '19990902', 114 ); 115 116 $tests[] = array( 117 'INTERVAL' => 2, 118 ); 119 $expect[] = array( 120 '19970902', 121 '19990902', 122 '20010902', 123 ); 124 125 $tests[] = array( 126 'DTSTART' => '20000229', 127 ); 128 $expect[] = array( 129 '20000229', 130 '20040229', 131 '20080229', 132 ); 133 134 $tests[] = array( 135 'BYMONTH' => array(1, 3), 136 ); 137 $expect[] = array( 138 '19980102', 139 '19980302', 140 '19990102', 141 ); 142 143 $tests[] = array( 144 'BYMONTHDAY' => array(1, 3), 145 ); 146 $expect[] = array( 147 '19970903', 148 '19971001', 149 '19971003', 150 ); 151 152 $tests[] = array( 153 'BYMONTH' => array(1, 3), 154 'BYMONTHDAY' => array(5, 7), 155 ); 156 $expect[] = array( 157 '19980105', 158 '19980107', 159 '19980305', 160 ); 161 162 $tests[] = array( 163 'BYDAY' => array('TU', 'TH'), 164 ); 165 $expect[] = array( 166 '19970902', 167 '19970904', 168 '19970909', 169 ); 170 171 $tests[] = array( 172 'BYDAY' => array('SU'), 173 ); 174 $expect[] = array( 175 '19970907', 176 '19970914', 177 '19970921', 178 ); 179 180 $tests[] = array( 181 'BYMONTH' => array(1, 3), 182 'BYDAY' => array('TU', 'TH'), 183 ); 184 $expect[] = array( 185 '19980101', 186 '19980106', 187 '19980108', 188 ); 189 190 $tests[] = array( 191 'BYMONTHDAY' => array(1, 3), 192 'BYDAY' => array('TU', 'TH'), 193 ); 194 $expect[] = array( 195 '19980101', 196 '19980203', 197 '19980303', 198 ); 199 200 $tests[] = array( 201 'BYMONTHDAY' => array(1, 3), 202 'BYDAY' => array('TU', 'TH'), 203 'BYMONTH' => array(1, 3), 204 ); 205 $expect[] = array( 206 '19980101', 207 '19980303', 208 '20010301', 209 ); 210 211 $tests[] = array( 212 'BYDAY' => array('1TU', '-1TH'), 213 ); 214 $expect[] = array( 215 '19971225', 216 '19980106', 217 '19981231', 218 ); 219 220 // Same test as above, just making sure the optional "+" syntax works. 221 $tests[] = array( 222 'BYDAY' => array('+1TU', '-1TH'), 223 ); 224 $expect[] = array( 225 '19971225', 226 '19980106', 227 '19981231', 228 ); 229 230 $tests[] = array( 231 'BYDAY' => array('3TU', '-3TH'), 232 ); 233 $expect[] = array( 234 '19971211', 235 '19980120', 236 '19981217', 237 ); 238 239 $tests[] = array( 240 'BYMONTH' => array(1, 3), 241 'BYDAY' => array('1TU', '-1TH'), 242 ); 243 $expect[] = array( 244 '19980106', 245 '19980129', 246 '19980303', 247 ); 248 249 $tests[] = array( 250 'BYMONTH' => array(1, 3), 251 'BYDAY' => array('3TU', '-3TH'), 252 ); 253 $expect[] = array( 254 '19980115', 255 '19980120', 256 '19980312', 257 ); 258 259 $tests[] = array( 260 'BYYEARDAY' => array(1, 100, 200, 365), 261 'COUNT' => 4, 262 ); 263 $expect[] = array( 264 '19971231', 265 '19980101', 266 '19980410', 267 '19980719', 268 ); 269 270 $tests[] = array( 271 'BYYEARDAY' => array(-365, -266, -166, -1), 272 'COUNT' => 4, 273 ); 274 $expect[] = array( 275 '19971231', 276 '19980101', 277 '19980410', 278 '19980719', 279 ); 280 281 $tests[] = array( 282 'BYYEARDAY' => array(1, 100, 200, 365), 283 'BYMONTH' => array(4, 7), 284 'COUNT' => 4, 285 ); 286 $expect[] = array( 287 '19980410', 288 '19980719', 289 '19990410', 290 '19990719', 291 ); 292 293 $tests[] = array( 294 'BYYEARDAY' => array(-365, -266, -166, -1), 295 'BYMONTH' => array(4, 7), 296 'COUNT' => 4, 297 ); 298 $expect[] = array( 299 '19980410', 300 '19980719', 301 '19990410', 302 '19990719', 303 ); 304 305 $tests[] = array( 306 'BYWEEKNO' => array(20), 307 ); 308 $expect[] = array( 309 '19980511', 310 '19980512', 311 '19980513', 312 ); 313 314 $tests[] = array( 315 'BYWEEKNO' => array(1), 316 'BYDAY' => array('MO'), 317 ); 318 $expect[] = array( 319 '19971229', 320 '19990104', 321 '20000103', 322 ); 323 324 $tests[] = array( 325 'BYWEEKNO' => array(52), 326 'BYDAY' => array('SU'), 327 ); 328 $expect[] = array( 329 '19971228', 330 '19981227', 331 '20000102', 332 ); 333 334 $tests[] = array( 335 'BYWEEKNO' => array(-1), 336 'BYDAY' => array('SU'), 337 ); 338 $expect[] = array( 339 '19971228', 340 '19990103', 341 '20000102', 342 ); 343 344 $tests[] = array( 345 'BYWEEKNO' => array(53), 346 'BYDAY' => array('MO'), 347 ); 348 $expect[] = array( 349 '19981228', 350 '20041227', 351 '20091228', 352 ); 353 354 $tests[] = array( 355 'BYHOUR' => array(6, 18), 356 ); 357 $expect[] = array( 358 '19970902T060000Z', 359 '19970902T180000Z', 360 '19980902T060000Z', 361 ); 362 363 $tests[] = array( 364 'BYMINUTE' => array(15, 30), 365 ); 366 $expect[] = array( 367 '19970902T001500Z', 368 '19970902T003000Z', 369 '19980902T001500Z', 370 ); 371 372 $tests[] = array( 373 'BYSECOND' => array(10, 20), 374 ); 375 $expect[] = array( 376 '19970902T000010Z', 377 '19970902T000020Z', 378 '19980902T000010Z', 379 ); 380 381 $tests[] = array( 382 'BYHOUR' => array(6, 18), 383 'BYMINUTE' => array(15, 30), 384 ); 385 $expect[] = array( 386 '19970902T061500Z', 387 '19970902T063000Z', 388 '19970902T181500Z', 389 ); 390 391 $tests[] = array( 392 'BYHOUR' => array(6, 18), 393 'BYSECOND' => array(10, 20), 394 ); 395 $expect[] = array( 396 '19970902T060010Z', 397 '19970902T060020Z', 398 '19970902T180010Z', 399 ); 400 401 $tests[] = array( 402 'BYMINUTE' => array(15, 30), 403 'BYSECOND' => array(10, 20), 404 ); 405 $expect[] = array( 406 '19970902T001510Z', 407 '19970902T001520Z', 408 '19970902T003010Z', 409 ); 410 411 $tests[] = array( 412 'BYHOUR' => array(6, 18), 413 'BYMINUTE' => array(15, 30), 414 'BYSECOND' => array(10, 20), 415 ); 416 $expect[] = array( 417 '19970902T061510Z', 418 '19970902T061520Z', 419 '19970902T063010Z', 420 ); 421 422 $tests[] = array( 423 'BYMONTHDAY' => array(15), 424 'BYHOUR' => array(6, 18), 425 'BYSETPOS' => array(3, -3), 426 ); 427 $expect[] = array( 428 '19971115T180000Z', 429 '19980215T060000Z', 430 '19981115T180000Z', 431 ); 432 433 $this->assertRules( 434 array( 435 'FREQ' => 'YEARLY', 436 'COUNT' => 3, 437 'DTSTART' => '19970902', 438 ), 439 $tests, 440 $expect); 441 } 442 443 public function testMonthlyRecurrenceRules() { 444 $tests = array(); 445 $expect = array(); 446 447 $tests[] = array(); 448 $expect[] = array( 449 '19970902', 450 '19971002', 451 '19971102', 452 ); 453 454 $tests[] = array( 455 'INTERVAL' => 2, 456 ); 457 $expect[] = array( 458 '19970902', 459 '19971102', 460 '19980102', 461 ); 462 463 $tests[] = array( 464 'INTERVAL' => 18, 465 ); 466 $expect[] = array( 467 '19970902', 468 '19990302', 469 '20000902', 470 ); 471 472 $tests[] = array( 473 'BYMONTH' => array(1, 3), 474 ); 475 $expect[] = array( 476 '19980102', 477 '19980302', 478 '19990102', 479 ); 480 481 $tests[] = array( 482 'BYMONTHDAY' => array(1, 3), 483 ); 484 $expect[] = array( 485 '19970903', 486 '19971001', 487 '19971003', 488 ); 489 490 $tests[] = array( 491 'BYMONTHDAY' => array(5, 7), 492 'BYMONTH' => array(1, 3), 493 ); 494 $expect[] = array( 495 '19980105', 496 '19980107', 497 '19980305', 498 ); 499 500 $tests[] = array( 501 'BYDAY' => array('TU', 'TH'), 502 ); 503 $expect[] = array( 504 '19970902', 505 '19970904', 506 '19970909', 507 ); 508 509 $tests[] = array( 510 'BYDAY' => array('3MO'), 511 ); 512 $expect[] = array( 513 '19970915', 514 '19971020', 515 '19971117', 516 ); 517 518 $tests[] = array( 519 'BYDAY' => array('1TU', '-1TH'), 520 ); 521 $expect[] = array( 522 '19970902', 523 '19970925', 524 '19971007', 525 ); 526 527 $tests[] = array( 528 'BYDAY' => array('3TU', '-3TH'), 529 ); 530 $expect[] = array( 531 '19970911', 532 '19970916', 533 '19971016', 534 ); 535 536 $tests[] = array( 537 'BYDAY' => array('TU', 'TH'), 538 'BYMONTH' => array(1, 3), 539 ); 540 $expect[] = array( 541 '19980101', 542 '19980106', 543 '19980108', 544 ); 545 546 $tests[] = array( 547 'BYMONTH' => array(1, 3), 548 'BYDAY' => array('1TU', '-1TH'), 549 ); 550 $expect[] = array( 551 '19980106', 552 '19980129', 553 '19980303', 554 ); 555 556 $tests[] = array( 557 'BYMONTH' => array(1, 3), 558 'BYDAY' => array('3TU', '-3TH'), 559 ); 560 $expect[] = array( 561 '19980115', 562 '19980120', 563 '19980312', 564 ); 565 566 $tests[] = array( 567 'BYMONTHDAY' => array(1, 3), 568 'BYDAY' => array('TU', 'TH'), 569 ); 570 $expect[] = array( 571 '19980101', 572 '19980203', 573 '19980303', 574 ); 575 576 $tests[] = array( 577 'BYMONTH' => array(1, 3), 578 'BYMONTHDAY' => array(1, 3), 579 'BYDAY' => array('TU', 'TH'), 580 ); 581 $expect[] = array( 582 '19980101', 583 '19980303', 584 '20010301', 585 ); 586 587 $tests[] = array( 588 'BYDAY' => array('MO', 'TU', 'WE', 'TH', 'FR'), 589 'BYSETPOS' => array(-1), 590 ); 591 $expect[] = array( 592 '19970930', 593 '19971031', 594 '19971128', 595 ); 596 597 $tests[] = array( 598 'BYDAY' => array('1MO', '1TU', '1WE', '1TH', '1FR', '-1FR'), 599 'BYMONTHDAY' => array(1, -1, -2), 600 ); 601 $expect[] = array( 602 '19971001', 603 '19971031', 604 '19971201', 605 ); 606 607 $tests[] = array( 608 'BYDAY' => array('1MO', '1TU', '1WE', '1TH', 'FR'), 609 'BYMONTHDAY' => array(1, -1, -2), 610 ); 611 $expect[] = array( 612 '19971001', 613 '19971031', 614 '19971201', 615 ); 616 617 $tests[] = array( 618 'BYHOUR' => array(6, 18), 619 ); 620 $expect[] = array( 621 '19970902T060000Z', 622 '19970902T180000Z', 623 '19971002T060000Z', 624 ); 625 626 $tests[] = array( 627 'BYMINUTE' => array(6, 18), 628 ); 629 $expect[] = array( 630 '19970902T000600Z', 631 '19970902T001800Z', 632 '19971002T000600Z', 633 ); 634 635 $tests[] = array( 636 'BYSECOND' => array(6, 18), 637 ); 638 $expect[] = array( 639 '19970902T000006Z', 640 '19970902T000018Z', 641 '19971002T000006Z', 642 ); 643 644 $tests[] = array( 645 'BYMONTHDAY' => array(13, 17), 646 'BYHOUR' => array(6, 18), 647 'BYSETPOS' => array(3, -3), 648 ); 649 $expect[] = array( 650 '19970913T180000Z', 651 '19970917T060000Z', 652 '19971013T180000Z', 653 ); 654 655 $tests[] = array( 656 'BYMONTHDAY' => array(13, 17), 657 'BYHOUR' => array(6, 18), 658 'BYSETPOS' => array(3, 3, -3), 659 ); 660 $expect[] = array( 661 '19970913T180000Z', 662 '19970917T060000Z', 663 '19971013T180000Z', 664 ); 665 666 $tests[] = array( 667 'BYMONTHDAY' => array(13, 17), 668 'BYHOUR' => array(6, 18), 669 'BYSETPOS' => array(4, -1), 670 ); 671 $expect[] = array( 672 '19970917T180000Z', 673 '19971017T180000Z', 674 '19971117T180000Z', 675 ); 676 677 $this->assertRules( 678 array( 679 'FREQ' => 'MONTHLY', 680 'COUNT' => 3, 681 'DTSTART' => '19970902', 682 ), 683 $tests, 684 $expect); 685 } 686 687 public function testWeeklyRecurrenceRules() { 688 $tests = array(); 689 $expect = array(); 690 691 $tests[] = array(); 692 $expect[] = array( 693 '19970902', 694 '19970909', 695 '19970916', 696 ); 697 698 $tests[] = array( 699 'INTERVAL' => 2, 700 ); 701 $expect[] = array( 702 '19970902', 703 '19970916', 704 '19970930', 705 ); 706 707 $tests[] = array( 708 'INTERVAL' => 20, 709 ); 710 $expect[] = array( 711 '19970902', 712 '19980120', 713 '19980609', 714 ); 715 716 $tests[] = array( 717 'BYMONTH' => array(1, 3), 718 ); 719 $expect[] = array( 720 '19980106', 721 '19980113', 722 '19980120', 723 ); 724 725 $tests[] = array( 726 'BYDAY' => array('TU', 'TH'), 727 ); 728 $expect[] = array( 729 '19970902', 730 '19970904', 731 '19970909', 732 ); 733 734 $tests[] = array( 735 'BYMONTH' => array(1, 3), 736 'BYDAY' => array('TU', 'TH'), 737 ); 738 $expect[] = array( 739 '19980101', 740 '19980106', 741 '19980108', 742 ); 743 744 $tests[] = array( 745 'BYHOUR' => array(6, 18), 746 ); 747 $expect[] = array( 748 '19970902T060000Z', 749 '19970902T180000Z', 750 '19970909T060000Z', 751 ); 752 753 $tests[] = array( 754 'BYDAY' => array('TU', 'TH'), 755 'BYHOUR' => array(6, 18), 756 'BYSETPOS' => array(3, -3), 757 'DTSTART' => '19970902T090000Z', 758 ); 759 $expect[] = array( 760 '19970902T180000Z', 761 '19970904T060000Z', 762 '19970909T180000Z', 763 ); 764 765 $this->assertRules( 766 array( 767 'FREQ' => 'WEEKLY', 768 'COUNT' => 3, 769 'DTSTART' => '19970902', 770 ), 771 $tests, 772 $expect); 773 } 774 775 public function testDailyRecurrenceRules() { 776 $tests = array(); 777 $expect = array(); 778 779 $tests[] = array(); 780 $expect[] = array( 781 '19970902', 782 '19970903', 783 '19970904', 784 ); 785 786 $tests[] = array( 787 'INTERVAL' => 2, 788 ); 789 $expect[] = array( 790 '19970902', 791 '19970904', 792 '19970906', 793 ); 794 795 $tests[] = array( 796 'INTERVAL' => 92, 797 ); 798 $expect[] = array( 799 '19970902', 800 '19971203', 801 '19980305', 802 ); 803 804 $tests[] = array( 805 'BYMONTH' => array(1, 3), 806 ); 807 $expect[] = array( 808 '19980101', 809 '19980102', 810 '19980103', 811 ); 812 813 // This is testing that INTERVAL is respected in the presence of a BYMONTH 814 // filter which skips some months. 815 $tests[] = array( 816 'BYMONTH' => array(12), 817 'INTERVAL' => 17, 818 ); 819 $expect[] = array( 820 '19971213', 821 '19971230', 822 '19981205', 823 ); 824 825 $tests[] = array( 826 'BYMONTHDAY' => array(1, 3), 827 ); 828 $expect[] = array( 829 '19970903', 830 '19971001', 831 '19971003', 832 ); 833 834 $tests[] = array( 835 'BYMONTH' => array(1, 3), 836 'BYMONTHDAY' => array(5, 7), 837 ); 838 $expect[] = array( 839 '19980105', 840 '19980107', 841 '19980305', 842 ); 843 844 $tests[] = array( 845 'BYDAY' => array('TU', 'TH'), 846 ); 847 $expect[] = array( 848 '19970902', 849 '19970904', 850 '19970909', 851 ); 852 853 $tests[] = array( 854 'BYMONTH' => array(1, 3), 855 'BYDAY' => array('TU', 'TH'), 856 ); 857 $expect[] = array( 858 '19980101', 859 '19980106', 860 '19980108', 861 ); 862 863 $tests[] = array( 864 'BYMONTHDAY' => array(1, 3), 865 'BYDAY' => array('TU', 'TH'), 866 ); 867 $expect[] = array( 868 '19980101', 869 '19980203', 870 '19980303', 871 ); 872 873 $tests[] = array( 874 'BYMONTH' => array(1, 3), 875 'BYMONTHDAY' => array(1, 3), 876 'BYDAY' => array('TU', 'TH'), 877 ); 878 $expect[] = array( 879 '19980101', 880 '19980303', 881 '20010301', 882 ); 883 884 $tests[] = array( 885 'BYHOUR' => array(6, 18), 886 'BYMINUTE' => array(15, 45), 887 'BYSETPOS' => array(3, -3), 888 'DTSTART' => '19970902T090000Z', 889 ); 890 $expect[] = array( 891 '19970902T181500Z', 892 '19970903T064500Z', 893 '19970903T181500Z', 894 ); 895 896 $this->assertRules( 897 array( 898 'FREQ' => 'DAILY', 899 'COUNT' => 3, 900 'DTSTART' => '19970902', 901 ), 902 $tests, 903 $expect); 904 } 905 906 public function testHourlyRecurrenceRules() { 907 $tests = array(); 908 $expect = array(); 909 910 $tests[] = array(); 911 $expect[] = array( 912 '19970902T090000Z', 913 '19970902T100000Z', 914 '19970902T110000Z', 915 ); 916 917 $tests[] = array( 918 'INTERVAL' => 2, 919 ); 920 $expect[] = array( 921 '19970902T090000Z', 922 '19970902T110000Z', 923 '19970902T130000Z', 924 ); 925 926 $tests[] = array( 927 'INTERVAL' => 769, 928 ); 929 $expect[] = array( 930 '19970902T090000Z', 931 '19971004T100000Z', 932 '19971105T110000Z', 933 ); 934 935 $tests[] = array( 936 'BYMONTH' => array(1, 3), 937 ); 938 $expect[] = array( 939 '19980101T000000Z', 940 '19980101T010000Z', 941 '19980101T020000Z', 942 ); 943 944 $tests[] = array( 945 'BYMONTHDAY' => array(1, 3), 946 ); 947 $expect[] = array( 948 '19970903T000000Z', 949 '19970903T010000Z', 950 '19970903T020000Z', 951 ); 952 953 $tests[] = array( 954 'BYMONTH' => array(1, 3), 955 'BYMONTHDAY' => array(5, 7), 956 ); 957 $expect[] = array( 958 '19980105T000000Z', 959 '19980105T010000Z', 960 '19980105T020000Z', 961 ); 962 963 $tests[] = array( 964 'BYDAY' => array('TU', 'TH'), 965 ); 966 $expect[] = array( 967 '19970902T090000Z', 968 '19970902T100000Z', 969 '19970902T110000Z', 970 ); 971 972 $tests[] = array( 973 'BYMONTH' => array(1, 3), 974 'BYDAY' => array('TU', 'TH'), 975 ); 976 $expect[] = array( 977 '19980101T000000Z', 978 '19980101T010000Z', 979 '19980101T020000Z', 980 ); 981 982 $tests[] = array( 983 'BYMONTHDAY' => array(1, 3), 984 'BYDAY' => array('TU', 'TH'), 985 ); 986 $expect[] = array( 987 '19980101T000000Z', 988 '19980101T010000Z', 989 '19980101T020000Z', 990 ); 991 992 $tests[] = array( 993 'BYMONTHDAY' => array(1, 3), 994 'BYMONTH' => array(1, 3), 995 'BYDAY' => array('TU', 'TH'), 996 ); 997 $expect[] = array( 998 '19980101T000000Z', 999 '19980101T010000Z', 1000 '19980101T020000Z', 1001 ); 1002 1003 $tests[] = array( 1004 'COUNT' => 4, 1005 'BYYEARDAY' => array(1, 100, 200, 365), 1006 ); 1007 $expect[] = array( 1008 '19971231T000000Z', 1009 '19971231T010000Z', 1010 '19971231T020000Z', 1011 '19971231T030000Z', 1012 ); 1013 1014 $tests[] = array( 1015 'COUNT' => 4, 1016 'BYYEARDAY' => array(-365, -266, -166, -1), 1017 ); 1018 $expect[] = array( 1019 '19971231T000000Z', 1020 '19971231T010000Z', 1021 '19971231T020000Z', 1022 '19971231T030000Z', 1023 ); 1024 1025 $tests[] = array( 1026 'COUNT' => 4, 1027 'BYMONTH' => array(4, 7), 1028 'BYYEARDAY' => array(1, 100, 200, 365), 1029 ); 1030 $expect[] = array( 1031 '19980410T000000Z', 1032 '19980410T010000Z', 1033 '19980410T020000Z', 1034 '19980410T030000Z', 1035 ); 1036 1037 $tests[] = array( 1038 'COUNT' => 4, 1039 'BYMONTH' => array(4, 7), 1040 'BYYEARDAY' => array(-365, -266, -166, -1), 1041 ); 1042 $expect[] = array( 1043 '19980410T000000Z', 1044 '19980410T010000Z', 1045 '19980410T020000Z', 1046 '19980410T030000Z', 1047 ); 1048 1049 $tests[] = array( 1050 'BYHOUR' => array(6, 18), 1051 ); 1052 $expect[] = array( 1053 '19970902T180000Z', 1054 '19970903T060000Z', 1055 '19970903T180000Z', 1056 ); 1057 1058 $tests[] = array( 1059 'BYMINUTE' => array(15, 45), 1060 'BYSECOND' => array(15, 45), 1061 'BYSETPOS' => array(3, -3), 1062 ); 1063 $expect[] = array( 1064 '19970902T091545Z', 1065 '19970902T094515Z', 1066 '19970902T101545Z', 1067 ); 1068 1069 $this->assertRules( 1070 array( 1071 'FREQ' => 'HOURLY', 1072 'COUNT' => 3, 1073 'DTSTART' => '19970902T090000Z', 1074 ), 1075 $tests, 1076 $expect); 1077 } 1078 1079 public function testMinutelyRecurrenceRules() { 1080 $tests = array(); 1081 $expect = array(); 1082 1083 $tests[] = array( 1084 ); 1085 $expect[] = array( 1086 '19970902T090000Z', 1087 '19970902T090100Z', 1088 '19970902T090200Z', 1089 ); 1090 1091 $tests[] = array( 1092 'INTERVAL' => 2, 1093 ); 1094 $expect[] = array( 1095 '19970902T090000Z', 1096 '19970902T090200Z', 1097 '19970902T090400Z', 1098 ); 1099 1100 $tests[] = array( 1101 'BYHOUR' => array(6, 18), 1102 'BYMINUTE' => array(6, 18), 1103 'BYSECOND' => array(6, 18), 1104 ); 1105 $expect[] = array( 1106 '19970902T180606Z', 1107 '19970902T180618Z', 1108 '19970902T181806Z', 1109 ); 1110 1111 $tests[] = array( 1112 'BYSECOND' => array(15, 30, 45), 1113 'BYSETPOS' => array(3, -3), 1114 ); 1115 $expect[] = array( 1116 '19970902T090015Z', 1117 '19970902T090045Z', 1118 '19970902T090115Z', 1119 ); 1120 1121 $this->assertRules( 1122 array( 1123 'FREQ' => 'MINUTELY', 1124 'COUNT' => 3, 1125 'DTSTART' => '19970902T090000Z', 1126 ), 1127 $tests, 1128 $expect); 1129 } 1130 1131 public function testSecondlyRecurrenceRules() { 1132 $tests = array(); 1133 $expect = array(); 1134 1135 $tests[] = array(); 1136 $expect[] = array( 1137 '19970902T090000Z', 1138 '19970902T090001Z', 1139 '19970902T090002Z', 1140 ); 1141 1142 $tests[] = array( 1143 'INTERVAL' => 2, 1144 ); 1145 $expect[] = array( 1146 '19970902T090000Z', 1147 '19970902T090002Z', 1148 '19970902T090004Z', 1149 ); 1150 1151 $tests[] = array( 1152 'INTERVAL' => 90061, 1153 ); 1154 $expect[] = array( 1155 '19970902T090000Z', 1156 '19970903T100101Z', 1157 '19970904T110202Z', 1158 ); 1159 1160 $tests[] = array( 1161 'BYSECOND' => array(0), 1162 'BYMINUTE' => array(1), 1163 'DTSTART' => '20100322T120100Z', 1164 ); 1165 $expect[] = array( 1166 '20100322T120100Z', 1167 '20100322T130100Z', 1168 '20100322T140100Z', 1169 ); 1170 1171 $this->assertRules( 1172 array( 1173 'FREQ' => 'SECONDLY', 1174 'COUNT' => 3, 1175 'DTSTART' => '19970902T090000Z', 1176 ), 1177 $tests, 1178 $expect); 1179 } 1180 1181 public function testRFC5545RecurrenceRules() { 1182 // These tests are derived from the examples in RFC5545. 1183 $tests = array(); 1184 $expect = array(); 1185 1186 $tests[] = array( 1187 'FREQ' => 'DAILY', 1188 'COUNT' => 10, 1189 'DTSTART' => '19970902T090000Z', 1190 ); 1191 $expect[] = array( 1192 '19970902T090000Z', 1193 '19970903T090000Z', 1194 '19970904T090000Z', 1195 '19970905T090000Z', 1196 '19970906T090000Z', 1197 '19970907T090000Z', 1198 '19970908T090000Z', 1199 '19970909T090000Z', 1200 '19970910T090000Z', 1201 '19970911T090000Z', 1202 ); 1203 1204 $tests[] = array( 1205 'FREQ' => 'DAILY', 1206 'INTERVAL' => 2, 1207 'DTSTART' => '19970902T090000Z', 1208 'COUNT' => 5, 1209 ); 1210 $expect[] = array( 1211 '19970902T090000Z', 1212 '19970904T090000Z', 1213 '19970906T090000Z', 1214 '19970908T090000Z', 1215 '19970910T090000Z', 1216 ); 1217 1218 $tests[] = array( 1219 'FREQ' => 'YEARLY', 1220 'BYMONTH' => array(1), 1221 'BYDAY' => array('MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU'), 1222 'DTSTART' => '19970902T090000Z', 1223 'COUNT' => 3, 1224 ); 1225 $expect[] = array( 1226 '19980101T090000Z', 1227 '19980102T090000Z', 1228 '19980103T090000Z', 1229 ); 1230 1231 $tests[] = array( 1232 'FREQ' => 'MONTHLY', 1233 'COUNT' => 3, 1234 'BYDAY' => array('1FR'), 1235 'DTSTART' => '19970902T090000Z', 1236 ); 1237 $expect[] = array( 1238 '19970905T090000Z', 1239 '19971003T090000Z', 1240 '19971107T090000Z', 1241 ); 1242 1243 $tests[] = array( 1244 'FREQ' => 'MONTHLY', 1245 'INTERVAL' => 2, 1246 'COUNT' => 5, 1247 'BYDAY' => array('1SU', '-1SU'), 1248 'DTSTART' => '19970902T090000Z', 1249 ); 1250 $expect[] = array( 1251 '19970907T090000Z', 1252 '19970928T090000Z', 1253 '19971102T090000Z', 1254 '19971130T090000Z', 1255 '19980104T090000Z', 1256 ); 1257 1258 $tests[] = array( 1259 'FREQ' => 'MONTHLY', 1260 'COUNT' => 6, 1261 'BYDAY' => array('-2MO'), 1262 'DTSTART' => '19970902T090000Z', 1263 ); 1264 $expect[] = array( 1265 '19970922T090000Z', 1266 '19971020T090000Z', 1267 '19971117T090000Z', 1268 '19971222T090000Z', 1269 '19980119T090000Z', 1270 '19980216T090000Z', 1271 ); 1272 1273 $tests[] = array( 1274 'FREQ' => 'MONTHLY', 1275 'COUNT' => 6, 1276 'BYMONTHDAY' => array(-3), 1277 'DTSTART' => '19970902T090000Z', 1278 ); 1279 $expect[] = array( 1280 '19970928T090000Z', 1281 '19971029T090000Z', 1282 '19971128T090000Z', 1283 '19971229T090000Z', 1284 '19980129T090000Z', 1285 '19980226T090000Z', 1286 ); 1287 1288 $tests[] = array( 1289 'FREQ' => 'MONTHLY', 1290 'COUNT' => 5, 1291 'BYMONTHDAY' => array(2, 15), 1292 'DTSTART' => '19970902T090000Z', 1293 ); 1294 $expect[] = array( 1295 '19970902T090000Z', 1296 '19970915T090000Z', 1297 '19971002T090000Z', 1298 '19971015T090000Z', 1299 '19971102T090000Z', 1300 ); 1301 1302 $tests[] = array( 1303 'FREQ' => 'MONTHLY', 1304 'COUNT' => 5, 1305 'BYMONTHDAY' => array(-1, 1), 1306 'DTSTART' => '19970902T090000Z', 1307 ); 1308 $expect[] = array( 1309 '19970930T090000Z', 1310 '19971001T090000Z', 1311 '19971031T090000Z', 1312 '19971101T090000Z', 1313 '19971130T090000Z', 1314 ); 1315 1316 $tests[] = array( 1317 'FREQ' => 'MONTHLY', 1318 'COUNT' => 7, 1319 'INTERVAL' => 18, 1320 'BYMONTHDAY' => array(10, 11, 12, 13, 14, 15), 1321 'DTSTART' => '19970902T090000Z', 1322 ); 1323 $expect[] = array( 1324 '19970910T090000Z', 1325 '19970911T090000Z', 1326 '19970912T090000Z', 1327 '19970913T090000Z', 1328 '19970914T090000Z', 1329 '19970915T090000Z', 1330 '19990310T090000Z', 1331 ); 1332 1333 $tests[] = array( 1334 'FREQ' => 'MONTHLY', 1335 'COUNT' => 6, 1336 'INTERVAL' => 2, 1337 'BYDAY' => array('TU'), 1338 'DTSTART' => '19970902T090000Z', 1339 ); 1340 $expect[] = array( 1341 '19970902T090000Z', 1342 '19970909T090000Z', 1343 '19970916T090000Z', 1344 '19970923T090000Z', 1345 '19970930T090000Z', 1346 '19971104T090000Z', 1347 ); 1348 1349 $tests[] = array( 1350 'FREQ' => 'YEARLY', 1351 'COUNT' => 10, 1352 'BYMONTH' => array(6, 7), 1353 'DTSTART' => '19970610T090000Z', 1354 ); 1355 $expect[] = array( 1356 '19970610T090000Z', 1357 '19970710T090000Z', 1358 '19980610T090000Z', 1359 '19980710T090000Z', 1360 '19990610T090000Z', 1361 '19990710T090000Z', 1362 '20000610T090000Z', 1363 '20000710T090000Z', 1364 '20010610T090000Z', 1365 '20010710T090000Z', 1366 ); 1367 1368 $tests[] = array( 1369 'FREQ' => 'YEARLY', 1370 'COUNT' => 4, 1371 'INTERVAL' => 3, 1372 'BYYEARDAY' => array(1, 100, 200), 1373 'DTSTART' => '19970101T090000Z', 1374 ); 1375 $expect[] = array( 1376 '19970101T090000Z', 1377 '19970410T090000Z', 1378 '19970719T090000Z', 1379 '20000101T090000Z', 1380 ); 1381 1382 $tests[] = array( 1383 'FREQ' => 'YEARLY', 1384 'COUNT' => 3, 1385 'BYDAY' => array('20MO'), 1386 'DTSTART' => '19970519T090000Z', 1387 ); 1388 $expect[] = array( 1389 '19970519T090000Z', 1390 '19980518T090000Z', 1391 '19990517T090000Z', 1392 ); 1393 1394 $tests[] = array( 1395 'FREQ' => 'YEARLY', 1396 'COUNT' => 3, 1397 'BYWEEKNO' => array(20), 1398 'BYDAY' => array('MO'), 1399 'DTSTART' => '19970512T090000Z', 1400 ); 1401 $expect[] = array( 1402 '19970512T090000Z', 1403 '19980511T090000Z', 1404 '19990517T090000Z', 1405 ); 1406 1407 $tests[] = array( 1408 'FREQ' => 'YEARLY', 1409 'BYDAY' => array('TH'), 1410 'BYMONTH' => array(3), 1411 'DTSTART' => '19970313T090000Z', 1412 'COUNT' => 5, 1413 ); 1414 $expect[] = array( 1415 '19970313T090000Z', 1416 '19970320T090000Z', 1417 '19970327T090000Z', 1418 '19980305T090000Z', 1419 '19980312T090000Z', 1420 ); 1421 1422 $tests[] = array( 1423 'FREQ' => 'YEARLY', 1424 'BYDAY' => array('TH'), 1425 'BYMONTH' => array(6, 7, 8), 1426 'DTSTART' => '19970101T090000Z', 1427 'COUNT' => 15, 1428 ); 1429 $expect[] = array( 1430 '19970605T090000Z', 1431 '19970612T090000Z', 1432 '19970619T090000Z', 1433 '19970626T090000Z', 1434 '19970703T090000Z', 1435 '19970710T090000Z', 1436 '19970717T090000Z', 1437 '19970724T090000Z', 1438 '19970731T090000Z', 1439 '19970807T090000Z', 1440 '19970814T090000Z', 1441 '19970821T090000Z', 1442 '19970828T090000Z', 1443 '19980604T090000Z', 1444 '19980611T090000Z', 1445 ); 1446 1447 $tests[] = array( 1448 'FREQ' => 'YEARLY', 1449 'BYDAY' => array('FR'), 1450 'BYMONTHDAY' => array(13), 1451 'COUNT' => 4, 1452 'DTSTART' => '19970902T090000Z', 1453 ); 1454 $expect[] = array( 1455 '19980213T090000Z', 1456 '19980313T090000Z', 1457 '19981113T090000Z', 1458 '19990813T090000Z', 1459 ); 1460 1461 $tests[] = array( 1462 'FREQ' => 'MONTHLY', 1463 'BYDAY' => array('SA'), 1464 'BYMONTHDAY' => array(7, 8, 9, 10, 11, 12, 13), 1465 'COUNT' => 10, 1466 'DTSTART' => '19970902T090000Z', 1467 ); 1468 $expect[] = array( 1469 '19970913T090000Z', 1470 '19971011T090000Z', 1471 '19971108T090000Z', 1472 '19971213T090000Z', 1473 '19980110T090000Z', 1474 '19980207T090000Z', 1475 '19980307T090000Z', 1476 '19980411T090000Z', 1477 '19980509T090000Z', 1478 '19980613T090000Z', 1479 ); 1480 1481 $tests[] = array( 1482 'FREQ' => 'YEARLY', 1483 'INTERVAL' => 4, 1484 'BYMONTH' => array(11), 1485 'BYDAY' => array('TU'), 1486 'BYMONTHDAY' => array(2, 3, 4, 5, 6, 7, 8), 1487 'COUNT' => 6, 1488 'DTSTART' => '19961105T090000Z', 1489 ); 1490 $expect[] = array( 1491 '19961105T090000Z', 1492 '20001107T090000Z', 1493 '20041102T090000Z', 1494 '20081104T090000Z', 1495 '20121106T090000Z', 1496 '20161108T090000Z', 1497 ); 1498 1499 $tests[] = array( 1500 'FREQ' => 'MONTHLY', 1501 'BYDAY' => array('TU', 'WE', 'TH'), 1502 'BYSETPOS' => array(3), 1503 'COUNT' => 3, 1504 'DTSTART' => '19970904T090000Z', 1505 ); 1506 $expect[] = array( 1507 '19970904T090000Z', 1508 '19971007T090000Z', 1509 '19971106T090000Z', 1510 ); 1511 1512 $tests[] = array( 1513 'FREQ' => 'MONTHLY', 1514 'BYDAY' => array('MO', 'TU', 'WE', 'TH', 'FR'), 1515 'BYSETPOS' => array(-2), 1516 'COUNT' => 3, 1517 'DTSTART' => '19970929T090000Z', 1518 ); 1519 $expect[] = array( 1520 '19970929T090000Z', 1521 '19971030T090000Z', 1522 '19971127T090000Z', 1523 ); 1524 1525 $tests[] = array( 1526 'FREQ' => 'HOURLY', 1527 'INTERVAL' => 3, 1528 'DTSTART' => '19970929T090000Z', 1529 'COUNT' => 3, 1530 ); 1531 $expect[] = array( 1532 '19970929T090000Z', 1533 '19970929T120000Z', 1534 '19970929T150000Z', 1535 ); 1536 1537 $tests[] = array( 1538 'FREQ' => 'MINUTELY', 1539 'INTERVAL' => 15, 1540 'COUNT' => 6, 1541 'DTSTART' => '19970902T090000Z', 1542 ); 1543 $expect[] = array( 1544 '19970902T090000Z', 1545 '19970902T091500Z', 1546 '19970902T093000Z', 1547 '19970902T094500Z', 1548 '19970902T100000Z', 1549 '19970902T101500Z', 1550 ); 1551 1552 $tests[] = array( 1553 'FREQ' => 'MINUTELY', 1554 'INTERVAL' => 90, 1555 'COUNT' => 4, 1556 'DTSTART' => '19970902T090000Z', 1557 ); 1558 $expect[] = array( 1559 '19970902T090000Z', 1560 '19970902T103000Z', 1561 '19970902T120000Z', 1562 '19970902T133000Z', 1563 ); 1564 1565 $tests[] = array( 1566 'FREQ' => 'WEEKLY', 1567 'COUNT' => 10, 1568 'DTSTART' => '19970902T090000Z', 1569 ); 1570 $expect[] = array( 1571 '19970902T090000Z', 1572 '19970909T090000Z', 1573 '19970916T090000Z', 1574 '19970923T090000Z', 1575 '19970930T090000Z', 1576 '19971007T090000Z', 1577 '19971014T090000Z', 1578 '19971021T090000Z', 1579 '19971028T090000Z', 1580 '19971104T090000Z', 1581 ); 1582 1583 $tests[] = array( 1584 'FREQ' => 'WEEKLY', 1585 'INTERVAL' => 2, 1586 'COUNT' => 6, 1587 'DTSTART' => '19970902T090000Z', 1588 ); 1589 $expect[] = array( 1590 '19970902T090000Z', 1591 '19970916T090000Z', 1592 '19970930T090000Z', 1593 '19971014T090000Z', 1594 '19971028T090000Z', 1595 '19971111T090000Z', 1596 ); 1597 1598 $tests[] = array( 1599 'FREQ' => 'WEEKLY', 1600 'COUNT' => 10, 1601 'WKST' => 'SU', 1602 'BYDAY' => array('TU', 'TH'), 1603 'DTSTART' => '19970902T090000Z', 1604 ); 1605 $expect[] = array( 1606 '19970902T090000Z', 1607 '19970904T090000Z', 1608 '19970909T090000Z', 1609 '19970911T090000Z', 1610 '19970916T090000Z', 1611 '19970918T090000Z', 1612 '19970923T090000Z', 1613 '19970925T090000Z', 1614 '19970930T090000Z', 1615 '19971002T090000Z', 1616 ); 1617 1618 $tests[] = array( 1619 'FREQ' => 'WEEKLY', 1620 'INTERVAL' => 2, 1621 'COUNT' => 8, 1622 'WKST' => 'SU', 1623 'BYDAY' => array('TU', 'TH'), 1624 'DTSTART' => '19970902T090000Z', 1625 ); 1626 $expect[] = array( 1627 '19970902T090000Z', 1628 '19970904T090000Z', 1629 '19970916T090000Z', 1630 '19970918T090000Z', 1631 '19970930T090000Z', 1632 '19971002T090000Z', 1633 '19971014T090000Z', 1634 '19971016T090000Z', 1635 ); 1636 1637 $tests[] = array( 1638 'FREQ' => 'WEEKLY', 1639 'INTERVAL' => 2, 1640 'COUNT' => 4, 1641 'BYDAY' => array('TU', 'SU'), 1642 'WKST' => 'MO', 1643 'DTSTART' => '19970805T090000Z', 1644 ); 1645 $expect[] = array( 1646 '19970805T090000Z', 1647 '19970810T090000Z', 1648 '19970819T090000Z', 1649 '19970824T090000Z', 1650 ); 1651 1652 $tests[] = array( 1653 'FREQ' => 'WEEKLY', 1654 'INTERVAL' => 2, 1655 'COUNT' => 4, 1656 'BYDAY' => array('TU', 'SU'), 1657 'WKST' => 'SU', 1658 'DTSTART' => '19970805T090000Z', 1659 ); 1660 $expect[] = array( 1661 '19970805T090000Z', 1662 '19970817T090000Z', 1663 '19970819T090000Z', 1664 '19970831T090000Z', 1665 ); 1666 1667 1668 $this->assertRules(array(), $tests, $expect); 1669 } 1670 1671 1672 private function assertRules(array $defaults, array $tests, array $expect) { 1673 foreach ($tests as $key => $test) { 1674 $options = $test + $defaults; 1675 1676 $start = PhutilCalendarAbsoluteDateTime::newFromISO8601( 1677 $options['DTSTART']); 1678 1679 $rrule = id(new PhutilCalendarRecurrenceRule()) 1680 ->setStartDateTime($start) 1681 ->setFrequency($options['FREQ']); 1682 1683 $interval = idx($options, 'INTERVAL'); 1684 if ($interval) { 1685 $rrule->setInterval($interval); 1686 } 1687 1688 $by_day = idx($options, 'BYDAY'); 1689 if ($by_day) { 1690 $rrule->setByDay($by_day); 1691 } 1692 1693 $by_month = idx($options, 'BYMONTH'); 1694 if ($by_month) { 1695 $rrule->setByMonth($by_month); 1696 } 1697 1698 $by_monthday = idx($options, 'BYMONTHDAY'); 1699 if ($by_monthday) { 1700 $rrule->setByMonthDay($by_monthday); 1701 } 1702 1703 $by_yearday = idx($options, 'BYYEARDAY'); 1704 if ($by_yearday) { 1705 $rrule->setByYearDay($by_yearday); 1706 } 1707 1708 $by_weekno = idx($options, 'BYWEEKNO'); 1709 if ($by_weekno) { 1710 $rrule->setByWeekNumber($by_weekno); 1711 } 1712 1713 $by_hour = idx($options, 'BYHOUR'); 1714 if ($by_hour) { 1715 $rrule->setByHour($by_hour); 1716 } 1717 1718 $by_minute = idx($options, 'BYMINUTE'); 1719 if ($by_minute) { 1720 $rrule->setByMinute($by_minute); 1721 } 1722 1723 $by_second = idx($options, 'BYSECOND'); 1724 if ($by_second) { 1725 $rrule->setBySecond($by_second); 1726 } 1727 1728 $by_setpos = idx($options, 'BYSETPOS'); 1729 if ($by_setpos) { 1730 $rrule->setBySetPosition($by_setpos); 1731 } 1732 1733 $week_start = idx($options, 'WKST'); 1734 if ($week_start) { 1735 $rrule->setWeekStart($week_start); 1736 } 1737 1738 $set = id(new PhutilCalendarRecurrenceSet()) 1739 ->addSource($rrule); 1740 1741 $result = $set->getEventsBetween(null, null, $options['COUNT']); 1742 1743 $this->assertEqual( 1744 $expect[$key], 1745 mpull($result, 'getISO8601')); 1746 } 1747 } 1748 1749 1750}