1 /* //device/content/providers/pim/RecurrenceProcessorTest.java 2 ** 3 ** Copyright 2006, The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 package com.android.calendarcommon2; 19 20 import android.os.Debug; 21 import android.test.suitebuilder.annotation.LargeTest; 22 import android.test.suitebuilder.annotation.MediumTest; 23 import android.test.suitebuilder.annotation.SmallTest; 24 import android.text.TextUtils; 25 import android.text.format.Time; 26 import android.util.Log; 27 import android.util.TimeFormatException; 28 import junit.framework.TestCase; 29 30 import java.util.TreeSet; 31 32 public class RecurrenceProcessorTest extends TestCase { 33 private static final String TAG = "RecurrenceProcessorTest"; 34 private static final boolean SPEW = true; 35 private static final boolean METHOD_TRACE = false; 36 37 private static String[] getFormattedDates(long[] dates, Time time) { 38 String[] out = new String[dates.length]; 39 int i = 0; 40 for (long date : dates) { 41 time.set(date); 42 out[i] = time.format2445(); 43 ++i; 44 } 45 return out; 46 } 47 48 private static void printLists(String[] expected, String[] out) { 49 Log.i(TAG, " expected out"); 50 int i; 51 for (i = 0; i < expected.length && i < out.length; i++) { 52 Log.i(TAG, " [" + i + "] " + expected[i] 53 + " " + out[i]); 54 } 55 for (; i < expected.length; i++) { 56 Log.i(TAG, " [" + i + "] " + expected[i]); 57 } 58 for (; i < out.length; i++) { 59 Log.i(TAG, " [" + i + "] " + out[i]); 60 } 61 } 62 63 public void verifyRecurrence(String dtstartStr, String rrule, String rdate, String exrule, 64 String exdate, String rangeStartStr, String rangeEndStr, String[] expected) 65 throws Exception { 66 verifyRecurrence(dtstartStr, rrule, rdate, exrule, exdate, rangeStartStr, 67 rangeEndStr, expected, expected[expected.length - 1]); 68 } 69 70 public void verifyRecurrence(String dtstartStr, String rrule, String rdate, String exrule, 71 String exdate, String rangeStartStr, String rangeEndStr, String[] expected, 72 String last) throws Exception { 73 74 // note that the zulu of all parameters here must be the same, expand 75 // doesn't work otherwise 76 77 if (SPEW) { 78 Log.i(TAG, "DTSTART:" + dtstartStr 79 + " RRULE:" + rrule 80 + " RDATE:" + rdate 81 + " EXRULE:" + exrule 82 + " EXDATE:" + exdate); 83 } 84 85 // we could use any timezone, incl. UTC, but we use a non-UTC 86 // timezone to make sure there are no UTC assumptions in the 87 // recurrence processing code. 88 String tz = "America/Los_Angeles"; 89 Time dtstart = new Time(tz); 90 Time rangeStart = new Time(tz); 91 Time rangeEnd = new Time(tz); 92 Time outCal = new Time(tz); 93 94 dtstart.parse(dtstartStr); 95 96 rangeStart.parse(rangeStartStr); 97 rangeEnd.parse(rangeEndStr); 98 99 if (METHOD_TRACE) { 100 String fn = "/tmp/trace/" + this.getClass().getName().replace('$', '_'); 101 String df = fn + ".data"; 102 String kf = fn + ".key"; 103 Debug.startMethodTracing(fn, 8 * 1024 * 1024); 104 } 105 106 RecurrenceProcessor rp = new RecurrenceProcessor(); 107 RecurrenceSet recur = new RecurrenceSet(rrule, rdate, exrule, exdate); 108 109 long[] out = rp.expand(dtstart, recur, rangeStart.toMillis(false /* use isDst */), 110 rangeEnd.toMillis(false /* use isDst */)); 111 112 if (METHOD_TRACE) { 113 Debug.stopMethodTracing(); 114 } 115 116 int count = out.length; 117 String[] actual = getFormattedDates(out, outCal); 118 119 if (count != expected.length) { 120 if (SPEW) { 121 Log.i(TAG, "DTSTART:" + dtstartStr + " RRULE:" + rrule); 122 printLists(expected, actual); 123 } 124 throw new RuntimeException("result lengths don't match. " 125 + " expected=" + expected.length 126 + " actual=" + count); 127 } 128 129 for (int i = 0; i < count; i++) { 130 String s = actual[i]; 131 if (!s.equals(expected[i])) { 132 if (SPEW) { 133 Log.i(TAG, "DTSTART:" + dtstartStr + " RRULE:" + rrule); 134 printLists(expected, actual); 135 Log.i(TAG, "i=" + i); 136 } 137 throw new RuntimeException("expected[" + i + "]=" 138 + expected[i] + " actual=" + actual[i]); 139 } 140 } 141 142 long lastOccur = rp.getLastOccurence(dtstart, rangeEnd, recur); 143 if (lastOccur == 0 && out.length == 0) { 144 // No occurrence found and 0 returned for lastOccur, this is ok. 145 return; 146 } 147 long lastMillis = -1; 148 long expectedMillis = -1; 149 String lastStr = ""; 150 if (lastOccur != -1) { 151 outCal.set(lastOccur); 152 lastStr = outCal.format2445(); 153 lastMillis = outCal.toMillis(true /* ignore isDst */); 154 } 155 if (last != null && last.length() > 0) { 156 Time expectedLast = new Time(tz); 157 expectedLast.parse(last); 158 expectedMillis = expectedLast.toMillis(true /* ignore isDst */); 159 } 160 if (lastMillis != expectedMillis) { 161 if (SPEW) { 162 Log.i(TAG, "DTSTART:" + dtstartStr + " RRULE:" + rrule); 163 Log.i(TAG, "Expected: " + last + "; Actual: " + lastStr); 164 printLists(expected, actual); 165 } 166 167 throw new RuntimeException("expected last occurrence date does not match." 168 + " expected=" + last 169 + " actual=" + lastStr); 170 } 171 } 172 173 @SmallTest 174 public void testMonthly0() throws Exception { 175 verifyRecurrence("20060205T100000", "FREQ=MONTHLY;COUNT=3", 176 null /* rdate */, null /* exrule */, null /* exdate */, 177 "20060101T000000", "20080101T000000", 178 new String[]{ 179 "20060205T100000", 180 "20060305T100000", 181 "20060405T100000" 182 }); 183 } 184 185 @SmallTest 186 public void testMonthly1() throws Exception { 187 verifyRecurrence("20060205T100000", "FREQ=MONTHLY;INTERVAL=2;COUNT=3", 188 null /* rdate */, null /* exrule */, null /* exdate */, 189 "20060101T000000", "20080101T000000", 190 new String[]{ 191 "20060205T100000", 192 "20060405T100000", 193 "20060605T100000" 194 }); 195 } 196 197 @SmallTest 198 public void testMonthly2() throws Exception { 199 // this tests wrapping the year when the interval isn't divisible 200 // by 12 201 verifyRecurrence("20060205T100000", "FREQ=MONTHLY;INTERVAL=5;COUNT=5", 202 null /* rdate */, null /* exrule */, null /* exdate */, 203 "20060101T000000", "20080101T000000", 204 new String[]{ 205 "20060205T100000", 206 "20060705T100000", 207 "20061205T100000", 208 "20070505T100000", 209 "20071005T100000" 210 }); 211 } 212 213 @SmallTest 214 public void testMonthly3() throws Exception { 215 // with a simple BYDAY, spanning two months 216 verifyRecurrence("20060104T123456", 217 "FREQ=MONTHLY;UNTIL=20060201T200000Z;BYDAY=TU,WE", 218 null /* rdate */, null /* exrule */, null /* exdate */, 219 "20060101T000000", "20080101T000000", 220 new String[]{ 221 "20060104T123456", 222 "20060110T123456", 223 "20060111T123456", 224 "20060117T123456", 225 "20060118T123456", 226 "20060124T123456", 227 "20060125T123456", 228 "20060131T123456" 229 }, 230 "20060201T120000"); 231 } 232 233 @SmallTest 234 public void testMonthly4() throws Exception { 235 // with a BYDAY with +1 / etc., spanning two months and 236 // one day which isn't in the result 237 verifyRecurrence("20060101T123456", 238 "FREQ=MONTHLY;UNTIL=20060301T200000Z;BYDAY=+1SU,+2MO,+3TU,+4WE,+5MO,+5TU,+5WE,+6TH", 239 null /* rdate */, null /* exrule */, null /* exdate */, 240 "20060101T000000", "20080101T000000", 241 new String[]{ 242 "20060101T123456", 243 "20060109T123456", 244 "20060117T123456", 245 "20060125T123456", 246 "20060130T123456", 247 "20060131T123456", 248 "20060205T123456", 249 "20060213T123456", 250 "20060221T123456", 251 "20060222T123456" 252 }, 253 "20060301T120000"); 254 } 255 256 @SmallTest 257 public void testMonthly5() throws Exception { 258 // with a BYDAY with -1 / etc. 259 verifyRecurrence("20060201T123456", 260 "FREQ=MONTHLY;UNTIL=20060301T200000Z;BYDAY=-1SU,-2MO,-3TU,-4TU,-4WE,-5MO,-5TU,-5WE,-6TH", 261 null /* rdate */, null /* exrule */, null /* exdate */, 262 "20060101T000000", "20080101T000000", 263 new String[]{ 264 "20060201T123456", 265 "20060207T123456", 266 "20060214T123456", 267 "20060220T123456", 268 "20060226T123456" 269 }, 270 "20060301T120000"); 271 } 272 273 @SmallTest 274 public void testMonthly6() throws Exception { 275 // With positive BYMONTHDAYs 276 verifyRecurrence("20060201T123456", 277 "FREQ=MONTHLY;UNTIL=20060301T200000Z;BYMONTHDAY=1,2,5,28,31", 278 null /* rdate */, null /* exrule */, null /* exdate */, 279 "20060101T000000", "20080101T000000", 280 new String[]{ 281 "20060201T123456", 282 "20060202T123456", 283 "20060205T123456", 284 "20060228T123456" 285 }, 286 "20060301T120000"); 287 } 288 289 @SmallTest 290 public void testMonthly7() throws Exception { 291 // With negative BYMONTHDAYs 292 verifyRecurrence("20060201T123456", 293 "FREQ=MONTHLY;UNTIL=20060301T200000Z;BYMONTHDAY=-1,-5,-27,-28,-31", 294 null /* rdate */, null /* exrule */, null /* exdate */, 295 "20060101T000000", "20080101T000000", 296 new String[]{ 297 "20060201T123456", 298 "20060202T123456", 299 "20060224T123456", 300 "20060228T123456" 301 }, 302 "20060301T120000"); 303 } 304 305 @SmallTest 306 public void testMonthly8() throws Exception { 307 verifyRecurrence("20060205T100000", "FREQ=MONTHLY;COUNT=3", 308 "America/Los_Angeles;20060207T140000,20060307T160000,20060407T180000", 309 null /* exrule */, null /* exdate */, 310 "20060101T000000", "20080101T000000", 311 new String[]{ 312 "20060205T100000", 313 "20060207T140000", 314 "20060305T100000", 315 "20060307T160000", 316 "20060405T100000", 317 "20060407T180000", 318 }); 319 } 320 321 @SmallTest 322 public void testMonthly9() throws Exception { 323 verifyRecurrence("20060205T100000", null /* rrule */, 324 "America/Los_Angeles;20060207T140000,20060307T160000,20060407T180000", 325 null /* exrule */, null /* exdate */, 326 "20060101T000000", "20080101T000000", 327 new String[]{ 328 "20060207T140000", 329 "20060307T160000", 330 "20060407T180000", 331 }); 332 } 333 334 @SmallTest 335 public void testMonthly10() throws Exception { 336 verifyRecurrence("20060205T100000", "FREQ=MONTHLY;COUNT=3\nFREQ=WEEKLY;COUNT=2", 337 "America/Los_Angeles;20060207T140000,20060307T160000,20060407T180000", 338 null /* exrule */, null /* exdate */, 339 "20060101T000000", "20080101T000000", 340 new String[]{ 341 "20060205T100000", 342 "20060207T140000", 343 "20060212T100000", 344 "20060305T100000", 345 "20060307T160000", 346 "20060405T100000", 347 "20060407T180000", 348 }); 349 } 350 351 @SmallTest 352 public void testMonthly11() throws Exception { 353 verifyRecurrence("20060205T100000", "FREQ=MONTHLY;COUNT=3\nFREQ=WEEKLY;COUNT=2", 354 null /* rdate */, 355 "FREQ=MONTHLY;COUNT=2", null /* exdate */, 356 "20060101T000000", "20080101T000000", 357 new String[]{ 358 "20060212T100000", 359 "20060405T100000", 360 }); 361 } 362 363 @SmallTest 364 public void testMonthly12() throws Exception { 365 verifyRecurrence("20060205T100000", "FREQ=MONTHLY;COUNT=3\nFREQ=WEEKLY;COUNT=2", 366 null /* rdate */, null /* exrule */, 367 "20060212T180000Z,20060405T170000Z" /* exdate */, 368 "20060101T000000", "20080101T000000", 369 new String[]{ 370 "20060205T100000", 371 "20060305T100000", 372 }); 373 } 374 375 @SmallTest 376 public void testMonthly13() throws Exception { 377 verifyRecurrence("20060101T100000", "FREQ=MONTHLY;BYDAY=FR;BYMONTHDAY=13;COUNT=10", 378 null /* rdate */, null /* exrule */, null /* exdate */, 379 "20060101T000000", "20101231T000000", 380 new String[]{ 381 "20060101T100000", 382 "20060113T100000", 383 "20061013T100000", 384 "20070413T100000", 385 "20070713T100000", 386 "20080613T100000", 387 "20090213T100000", 388 "20090313T100000", 389 "20091113T100000", 390 "20100813T100000", 391 }); 392 } 393 394 @SmallTest 395 public void testMonthly14() throws Exception { 396 verifyRecurrence("20110103T100000", "FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=1,-1", 397 null /* rdate */, null /* exrule */, null /* exdate */, 398 "20110101T000000", "20110331T235959", 399 new String[]{ 400 "20110103T100000", 401 "20110131T100000", 402 "20110201T100000", 403 "20110228T100000", 404 "20110301T100000", 405 "20110331T100000", 406 }); 407 } 408 409 @SmallTest 410 public void testMonthly15() throws Exception { 411 verifyRecurrence("20110703T100000", "FREQ=MONTHLY;BYDAY=SA,SU;BYSETPOS=2,-2", 412 null /* rdate */, null /* exrule */, null /* exdate */, 413 "20110701T000000", "20110931T235959", 414 new String[]{ 415 "20110703T100000", 416 "20110730T100000", 417 "20110807T100000", 418 "20110827T100000", 419 "20110904T100000", 420 "20110924T100000", 421 }); 422 } 423 424 @SmallTest 425 public void testWeekly0() throws Exception { 426 verifyRecurrence("20060215T100000", "FREQ=WEEKLY;COUNT=3", 427 null /* rdate */, null /* exrule */, null /* exdate */, 428 "20060101T000000", "20080101T000000", 429 new String[]{ 430 "20060215T100000", 431 "20060222T100000", 432 "20060301T100000" 433 }); 434 } 435 436 @SmallTest 437 public void testWeekly1() throws Exception { 438 verifyRecurrence("20060215T100000", "FREQ=WEEKLY;UNTIL=20060301T100000Z", 439 null /* rdate */, null /* exrule */, null /* exdate */, 440 "20060101T000000", "20080101T000000", 441 new String[]{ 442 "20060215T100000", 443 "20060222T100000" 444 }, "20060301T020000"); 445 } 446 447 @SmallTest 448 public void testWeekly2() throws Exception { 449 verifyRecurrence("20060215T100000", "FREQ=WEEKLY;UNTIL=20060301T100001Z", 450 null /* rdate */, null /* exrule */, null /* exdate */, 451 "20060101T000000", "20080101T000000", 452 new String[]{ 453 "20060215T100000", 454 "20060222T100000" 455 }, "20060301T020001"); 456 } 457 458 @SmallTest 459 public void testWeekly3() throws Exception { 460 verifyRecurrence("20060215T100000", "FREQ=WEEKLY;UNTIL=20060301T090000Z", 461 null /* rdate */, null /* exrule */, null /* exdate */, 462 "20060101T000000", "20080101T000000", 463 new String[]{ 464 "20060215T100000", 465 "20060222T100000" 466 }, "20060301T010000"); 467 } 468 469 @SmallTest 470 public void testWeekly4() throws Exception { 471 verifyRecurrence("20060215T100000", "FREQ=WEEKLY;UNTIL=20060311T100001Z;BYDAY=TU", 472 null /* rdate */, null /* exrule */, null /* exdate */, 473 "20060101T000000", "20080101T000000", 474 new String[]{ 475 "20060215T100000", 476 "20060221T100000", 477 "20060228T100000", 478 "20060307T100000" 479 }, "20060311T020001"); 480 } 481 482 // until without "Z" 483 @SmallTest 484 public void testWeekly4a() throws Exception { 485 verifyRecurrence("20060215T100000", "FREQ=WEEKLY;UNTIL=20060311T100001;BYDAY=TU", 486 null /* rdate */, null /* exrule */, null /* exdate */, 487 "20060101T000000", "20080101T000000", 488 new String[]{ 489 "20060215T100000", 490 "20060221T100000", 491 "20060228T100000", 492 "20060307T100000" 493 }, "20060311T100001"); 494 } 495 496 @SmallTest 497 public void testWeekly5() throws Exception { 498 verifyRecurrence("20060215T100000", "FREQ=WEEKLY;UNTIL=20060311T100001Z;BYDAY=TH", 499 null /* rdate */, null /* exrule */, null /* exdate */, 500 "20060101T000000", "20080101T000000", 501 new String[]{ 502 "20060215T100000", 503 "20060216T100000", 504 "20060223T100000", 505 "20060302T100000", 506 "20060309T100000" 507 }, "20060311T020001"); 508 } 509 510 @SmallTest 511 public void testWeekly6() throws Exception { 512 verifyRecurrence("20060215T100000", "FREQ=WEEKLY;UNTIL=20060309T100001Z;BYDAY=WE,TH", 513 null /* rdate */, null /* exrule */, null /* exdate */, 514 "20060101T000000", "20080101T000000", 515 new String[]{ 516 "20060215T100000", 517 "20060216T100000", 518 "20060222T100000", 519 "20060223T100000", 520 "20060301T100000", 521 "20060302T100000", 522 "20060308T100000" 523 }, "20060309T020001"); 524 } 525 526 @SmallTest 527 public void testWeekly7() throws Exception { 528 verifyRecurrence("20060215T100000", "FREQ=WEEKLY;UNTIL=20060220T100001Z;BYDAY=SU", 529 null /* rdate */, null /* exrule */, null /* exdate */, 530 "20060101T000000", "20080101T000000", 531 new String[]{ 532 "20060215T100000", 533 "20060219T100000" 534 }, "20060220T020001"); 535 } 536 537 @SmallTest 538 public void testWeekly8() throws Exception { 539 verifyRecurrence("20060215T100000", "FREQ=WEEKLY;COUNT=4;WKST=SU;BYDAY=TU,TH", 540 null /* rdate */, null /* exrule */, null /* exdate */, 541 "20060101T000000", "20080101T000000", 542 new String[]{ 543 "20060215T100000", 544 "20060216T100000", 545 "20060221T100000", 546 "20060223T100000" 547 }); 548 } 549 550 @SmallTest 551 public void testWeekly9() throws Exception { 552 verifyRecurrence("19970805T100000", 553 "FREQ=WEEKLY;INTERVAL=2;COUNT=4;BYDAY=TU,SU", // uses default WKST=MO 554 null /* rdate */, null /* exrule */, null /* exdate */, 555 "19970101T000000", "19980101T000000", 556 new String[]{ 557 "19970805T100000", 558 "19970810T100000", 559 "19970819T100000", 560 "19970824T100000", 561 }); 562 } 563 564 @SmallTest 565 public void testWeekly10() throws Exception { 566 verifyRecurrence("19970805T100000", 567 "FREQ=WEEKLY;INTERVAL=2;COUNT=4;BYDAY=TU,SU;WKST=SU", 568 null /* rdate */, null /* exrule */, null /* exdate */, 569 "19970101T000000", "19980101T000000", 570 new String[]{ 571 "19970805T100000", 572 "19970817T100000", 573 "19970819T100000", 574 "19970831T100000", 575 }); 576 } 577 578 // BUG 1658567: UNTIL=date 579 @SmallTest 580 public void testWeekly11() throws Exception { 581 verifyRecurrence("20060215T100000", "FREQ=WEEKLY;UNTIL=20060220;BYDAY=SU", 582 null /* rdate */, null /* exrule */, null /* exdate */, 583 "20060101T000000", "20080101T000000", 584 new String[]{ 585 "20060215T100000", 586 "20060219T100000" 587 }, "20060220T000000"); 588 } 589 590 @SmallTest 591 public void testWeekly12() throws Exception { 592 try { 593 verifyRecurrence("20060215T100000", "FREQ=WEEKLY;UNTIL=junk;BYDAY=SU", 594 null /* rdate */, null /* exrule */, null /* exdate */, 595 "20060101T000000", "20080101T000000", 596 new String[]{ 597 "20060215T100000", 598 "20060219T100000" 599 }, "20060220T020001"); 600 fail("Bad UNTIL string failed to throw exception"); 601 } catch (TimeFormatException e) { 602 // expected 603 } 604 } 605 606 /** 607 * Test repeating weekly event with dtstart and dtend (only one occurrence) 608 * See bug #3267616 609 * @throws Exception 610 */ 611 @SmallTest 612 public void testWeekly13() throws Exception { 613 verifyRecurrence("20101117T150000", 614 "FREQ=WEEKLY;BYDAY=WE", 615 null /* rdate */, null /* exrule */, null /* exdate */, 616 "20101117T150000", "20101117T160000", 617 new String[]{ "20101117T150000" }); 618 } 619 620 @SmallTest 621 public void testWeekly14() throws Exception { 622 verifyRecurrence("19970805T100000", 623 "FREQ=WEEKLY;INTERVAL=2;COUNT=4;BYDAY=TU,SU;WKST=TH", 624 null /* rdate */, null /* exrule */, null /* exdate */, 625 "19970101T000000", "19980101T000000", 626 new String[]{ 627 "19970805T100000", 628 "19970817T100000", 629 "19970819T100000", 630 "19970831T100000", 631 }); 632 } 633 634 @SmallTest 635 public void testDaily0() throws Exception { 636 verifyRecurrence("20060215T100000", "FREQ=DAILY;COUNT=3", 637 null /* rdate */, null /* exrule */, null /* exdate */, 638 "20060101T000000", "20080101T000000", 639 new String[]{ 640 "20060215T100000", 641 "20060216T100000", 642 "20060217T100000" 643 }); 644 } 645 646 @SmallTest 647 public void testDaily1() throws Exception { 648 verifyRecurrence("20060215T100000", "FREQ=DAILY;UNTIL=20060302T100001Z", 649 null /* rdate */, null /* exrule */, null /* exdate */, 650 "20060101T000000", "20080101T000000", 651 new String[]{ 652 "20060215T100000", 653 "20060216T100000", 654 "20060217T100000", 655 "20060218T100000", 656 "20060219T100000", 657 "20060220T100000", 658 "20060221T100000", 659 "20060222T100000", 660 "20060223T100000", 661 "20060224T100000", 662 "20060225T100000", 663 "20060226T100000", 664 "20060227T100000", 665 "20060228T100000", 666 "20060301T100000" 667 }, "20060302T100001Z"); 668 } 669 670 @SmallTest 671 public void testDaily2() throws Exception { 672 verifyRecurrence("20060215T100000", "FREQ=DAILY;UNTIL=20060220T100001Z;BYDAY=SU", 673 null /* rdate */, null /* exrule */, null /* exdate */, 674 "20060101T000000", "20080101T000000", 675 new String[]{ 676 "20060215T100000", 677 "20060219T100000" 678 }, "20060220T020001"); 679 } 680 681 @SmallTest 682 public void testDaily3() throws Exception { 683 verifyRecurrence("20060219T100000", 684 "FREQ=DAILY;UNTIL=20060225T180304Z;BYDAY=SU,MO,SA;BYHOUR=5,10,22;BYMINUTE=3,59;BYSECOND=2,5", 685 null /* rdate */, null /* exrule */, null /* exdate */, 686 "20060101T000000", "20080101T000000", 687 new String[]{ 688 "20060219T100000", 689 "20060219T100302", 690 "20060219T100305", 691 "20060219T105902", 692 "20060219T105905", 693 "20060219T220302", 694 "20060219T220305", 695 "20060219T225902", 696 "20060219T225905", 697 "20060220T050302", 698 "20060220T050305", 699 "20060220T055902", 700 "20060220T055905", 701 "20060220T100302", 702 "20060220T100305", 703 "20060220T105902", 704 "20060220T105905", 705 "20060220T220302", 706 "20060220T220305", 707 "20060220T225902", 708 "20060220T225905", 709 "20060225T050302", 710 "20060225T050305", 711 "20060225T055902", 712 "20060225T055905", 713 "20060225T100302" 714 }, "20060225T100304"); 715 } 716 717 @MediumTest 718 public void testFromGoogleCalendar0() throws Exception { 719 // Tuesday, Thursday (10/2) 720 verifyRecurrence("20061002T050000", 721 "FREQ=WEEKLY;UNTIL=20071031T200000Z;INTERVAL=1;BYDAY=TU,TH;WKST=SU", 722 null /* rdate */, null /* exrule */, null /* exdate */, 723 "20060101T000000", "20090101T000000", 724 new String[]{ 725 "20061002T050000", 726 "20061003T050000", 727 "20061005T050000", 728 "20061010T050000", 729 "20061012T050000", 730 "20061017T050000", 731 "20061019T050000", 732 "20061024T050000", 733 "20061026T050000", 734 "20061031T050000", 735 "20061102T050000", 736 "20061107T050000", 737 "20061109T050000", 738 "20061114T050000", 739 "20061116T050000", 740 "20061121T050000", 741 "20061123T050000", 742 "20061128T050000", 743 "20061130T050000", 744 "20061205T050000", 745 "20061207T050000", 746 "20061212T050000", 747 "20061214T050000", 748 "20061219T050000", 749 "20061221T050000", 750 "20061226T050000", 751 "20061228T050000", 752 "20070102T050000", 753 "20070104T050000", 754 "20070109T050000", 755 "20070111T050000", 756 "20070116T050000", 757 "20070118T050000", 758 "20070123T050000", 759 "20070125T050000", 760 "20070130T050000", 761 "20070201T050000", 762 "20070206T050000", 763 "20070208T050000", 764 "20070213T050000", 765 "20070215T050000", 766 "20070220T050000", 767 "20070222T050000", 768 "20070227T050000", 769 "20070301T050000", 770 "20070306T050000", 771 "20070308T050000", 772 "20070313T050000", 773 "20070315T050000", 774 "20070320T050000", 775 "20070322T050000", 776 "20070327T050000", 777 "20070329T050000", 778 "20070403T050000", 779 "20070405T050000", 780 "20070410T050000", 781 "20070412T050000", 782 "20070417T050000", 783 "20070419T050000", 784 "20070424T050000", 785 "20070426T050000", 786 "20070501T050000", 787 "20070503T050000", 788 "20070508T050000", 789 "20070510T050000", 790 "20070515T050000", 791 "20070517T050000", 792 "20070522T050000", 793 "20070524T050000", 794 "20070529T050000", 795 "20070531T050000", 796 "20070605T050000", 797 "20070607T050000", 798 "20070612T050000", 799 "20070614T050000", 800 "20070619T050000", 801 "20070621T050000", 802 "20070626T050000", 803 "20070628T050000", 804 "20070703T050000", 805 "20070705T050000", 806 "20070710T050000", 807 "20070712T050000", 808 "20070717T050000", 809 "20070719T050000", 810 "20070724T050000", 811 "20070726T050000", 812 "20070731T050000", 813 "20070802T050000", 814 "20070807T050000", 815 "20070809T050000", 816 "20070814T050000", 817 "20070816T050000", 818 "20070821T050000", 819 "20070823T050000", 820 "20070828T050000", 821 "20070830T050000", 822 "20070904T050000", 823 "20070906T050000", 824 "20070911T050000", 825 "20070913T050000", 826 "20070918T050000", 827 "20070920T050000", 828 "20070925T050000", 829 "20070927T050000", 830 "20071002T050000", 831 "20071004T050000", 832 "20071009T050000", 833 "20071011T050000", 834 "20071016T050000", 835 "20071018T050000", 836 "20071023T050000", 837 "20071025T050000", 838 "20071030T050000", 839 }, "20071031T130000"); 840 } 841 842 @MediumTest 843 public void testFromGoogleCalendar1() throws Exception { 844 // Mon Wed Fri 845 verifyRecurrence("20061002T030000", 846 "FREQ=WEEKLY;UNTIL=20071025T180000Z;INTERVAL=1;BYDAY=MO,WE,FR;", 847 null /* rdate */, null /* exrule */, null /* exdate */, 848 "20060101T000000", "20090101T000000", 849 new String[]{ 850 "20061002T030000", 851 "20061004T030000", 852 "20061006T030000", 853 "20061009T030000", 854 "20061011T030000", 855 "20061013T030000", 856 "20061016T030000", 857 "20061018T030000", 858 "20061020T030000", 859 "20061023T030000", 860 "20061025T030000", 861 "20061027T030000", 862 "20061030T030000", 863 "20061101T030000", 864 "20061103T030000", 865 "20061106T030000", 866 "20061108T030000", 867 "20061110T030000", 868 "20061113T030000", 869 "20061115T030000", 870 "20061117T030000", 871 "20061120T030000", 872 "20061122T030000", 873 "20061124T030000", 874 "20061127T030000", 875 "20061129T030000", 876 "20061201T030000", 877 "20061204T030000", 878 "20061206T030000", 879 "20061208T030000", 880 "20061211T030000", 881 "20061213T030000", 882 "20061215T030000", 883 "20061218T030000", 884 "20061220T030000", 885 "20061222T030000", 886 "20061225T030000", 887 "20061227T030000", 888 "20061229T030000", 889 "20070101T030000", 890 "20070103T030000", 891 "20070105T030000", 892 "20070108T030000", 893 "20070110T030000", 894 "20070112T030000", 895 "20070115T030000", 896 "20070117T030000", 897 "20070119T030000", 898 "20070122T030000", 899 "20070124T030000", 900 "20070126T030000", 901 "20070129T030000", 902 "20070131T030000", 903 "20070202T030000", 904 "20070205T030000", 905 "20070207T030000", 906 "20070209T030000", 907 "20070212T030000", 908 "20070214T030000", 909 "20070216T030000", 910 "20070219T030000", 911 "20070221T030000", 912 "20070223T030000", 913 "20070226T030000", 914 "20070228T030000", 915 "20070302T030000", 916 "20070305T030000", 917 "20070307T030000", 918 "20070309T030000", 919 "20070312T030000", 920 "20070314T030000", 921 "20070316T030000", 922 "20070319T030000", 923 "20070321T030000", 924 "20070323T030000", 925 "20070326T030000", 926 "20070328T030000", 927 "20070330T030000", 928 "20070402T030000", 929 "20070404T030000", 930 "20070406T030000", 931 "20070409T030000", 932 "20070411T030000", 933 "20070413T030000", 934 "20070416T030000", 935 "20070418T030000", 936 "20070420T030000", 937 "20070423T030000", 938 "20070425T030000", 939 "20070427T030000", 940 "20070430T030000", 941 "20070502T030000", 942 "20070504T030000", 943 "20070507T030000", 944 "20070509T030000", 945 "20070511T030000", 946 "20070514T030000", 947 "20070516T030000", 948 "20070518T030000", 949 "20070521T030000", 950 "20070523T030000", 951 "20070525T030000", 952 "20070528T030000", 953 "20070530T030000", 954 "20070601T030000", 955 "20070604T030000", 956 "20070606T030000", 957 "20070608T030000", 958 "20070611T030000", 959 "20070613T030000", 960 "20070615T030000", 961 "20070618T030000", 962 "20070620T030000", 963 "20070622T030000", 964 "20070625T030000", 965 "20070627T030000", 966 "20070629T030000", 967 "20070702T030000", 968 "20070704T030000", 969 "20070706T030000", 970 "20070709T030000", 971 "20070711T030000", 972 "20070713T030000", 973 "20070716T030000", 974 "20070718T030000", 975 "20070720T030000", 976 "20070723T030000", 977 "20070725T030000", 978 "20070727T030000", 979 "20070730T030000", 980 "20070801T030000", 981 "20070803T030000", 982 "20070806T030000", 983 "20070808T030000", 984 "20070810T030000", 985 "20070813T030000", 986 "20070815T030000", 987 "20070817T030000", 988 "20070820T030000", 989 "20070822T030000", 990 "20070824T030000", 991 "20070827T030000", 992 "20070829T030000", 993 "20070831T030000", 994 "20070903T030000", 995 "20070905T030000", 996 "20070907T030000", 997 "20070910T030000", 998 "20070912T030000", 999 "20070914T030000", 1000 "20070917T030000", 1001 "20070919T030000", 1002 "20070921T030000", 1003 "20070924T030000", 1004 "20070926T030000", 1005 "20070928T030000", 1006 "20071001T030000", 1007 "20071003T030000", 1008 "20071005T030000", 1009 "20071008T030000", 1010 "20071010T030000", 1011 "20071012T030000", 1012 "20071015T030000", 1013 "20071017T030000", 1014 "20071019T030000", 1015 "20071022T030000", 1016 "20071024T030000", 1017 }, "20071025T110000"); 1018 } 1019 1020 @SmallTest 1021 public void testFromGoogleCalendar2() throws Exception { 1022 // Monthly on day 2 1023 verifyRecurrence("20061002T070000", 1024 "FREQ=MONTHLY;INTERVAL=1;WKST=SU", 1025 null /* rdate */, null /* exrule */, null /* exdate */, 1026 "20060101T000000", "20090101T000000", 1027 new String[]{ 1028 "20061002T070000", 1029 "20061102T070000", 1030 "20061202T070000", 1031 "20070102T070000", 1032 "20070202T070000", 1033 "20070302T070000", 1034 "20070402T070000", 1035 "20070502T070000", 1036 "20070602T070000", 1037 "20070702T070000", 1038 "20070802T070000", 1039 "20070902T070000", 1040 "20071002T070000", 1041 "20071102T070000", 1042 "20071202T070000", 1043 "20080102T070000", 1044 "20080202T070000", 1045 "20080302T070000", 1046 "20080402T070000", 1047 "20080502T070000", 1048 "20080602T070000", 1049 "20080702T070000", 1050 "20080802T070000", 1051 "20080902T070000", 1052 "20081002T070000", 1053 "20081102T070000", 1054 "20081202T070000", 1055 }, "20081202T070000"); 1056 } 1057 1058 @MediumTest 1059 public void testFromGoogleCalendar3() throws Exception { 1060 // Every Weekday 1061 verifyRecurrence("20061002T100000", 1062 "FREQ=WEEKLY;UNTIL=20070215T100000Z;INTERVAL=1;BYDAY=MO,TU,WE,TH,FR;", 1063 null /* rdate */, null /* exrule */, null /* exdate */, 1064 "20060101T000000", "20090101T000000", 1065 new String[]{ 1066 "20061002T100000", 1067 "20061003T100000", 1068 "20061004T100000", 1069 "20061005T100000", 1070 "20061006T100000", 1071 "20061009T100000", 1072 "20061010T100000", 1073 "20061011T100000", 1074 "20061012T100000", 1075 "20061013T100000", 1076 "20061016T100000", 1077 "20061017T100000", 1078 "20061018T100000", 1079 "20061019T100000", 1080 "20061020T100000", 1081 "20061023T100000", 1082 "20061024T100000", 1083 "20061025T100000", 1084 "20061026T100000", 1085 "20061027T100000", 1086 "20061030T100000", 1087 "20061031T100000", 1088 "20061101T100000", 1089 "20061102T100000", 1090 "20061103T100000", 1091 "20061106T100000", 1092 "20061107T100000", 1093 "20061108T100000", 1094 "20061109T100000", 1095 "20061110T100000", 1096 "20061113T100000", 1097 "20061114T100000", 1098 "20061115T100000", 1099 "20061116T100000", 1100 "20061117T100000", 1101 "20061120T100000", 1102 "20061121T100000", 1103 "20061122T100000", 1104 "20061123T100000", 1105 "20061124T100000", 1106 "20061127T100000", 1107 "20061128T100000", 1108 "20061129T100000", 1109 "20061130T100000", 1110 "20061201T100000", 1111 "20061204T100000", 1112 "20061205T100000", 1113 "20061206T100000", 1114 "20061207T100000", 1115 "20061208T100000", 1116 "20061211T100000", 1117 "20061212T100000", 1118 "20061213T100000", 1119 "20061214T100000", 1120 "20061215T100000", 1121 "20061218T100000", 1122 "20061219T100000", 1123 "20061220T100000", 1124 "20061221T100000", 1125 "20061222T100000", 1126 "20061225T100000", 1127 "20061226T100000", 1128 "20061227T100000", 1129 "20061228T100000", 1130 "20061229T100000", 1131 "20070101T100000", 1132 "20070102T100000", 1133 "20070103T100000", 1134 "20070104T100000", 1135 "20070105T100000", 1136 "20070108T100000", 1137 "20070109T100000", 1138 "20070110T100000", 1139 "20070111T100000", 1140 "20070112T100000", 1141 "20070115T100000", 1142 "20070116T100000", 1143 "20070117T100000", 1144 "20070118T100000", 1145 "20070119T100000", 1146 "20070122T100000", 1147 "20070123T100000", 1148 "20070124T100000", 1149 "20070125T100000", 1150 "20070126T100000", 1151 "20070129T100000", 1152 "20070130T100000", 1153 "20070131T100000", 1154 "20070201T100000", 1155 "20070202T100000", 1156 "20070205T100000", 1157 "20070206T100000", 1158 "20070207T100000", 1159 "20070208T100000", 1160 "20070209T100000", 1161 "20070212T100000", 1162 "20070213T100000", 1163 "20070214T100000", 1164 }, "20070215T020000"); 1165 } 1166 1167 @SmallTest 1168 public void testFromGoogleCalendar4() throws Exception { 1169 // Every 5 months on day 2 1170 verifyRecurrence("20061003T100000", 1171 "FREQ=MONTHLY;INTERVAL=5;WKST=SU", 1172 null /* rdate */, null /* exrule */, null /* exdate */, 1173 "20060101T000000", "20090101T000000", 1174 new String[]{ 1175 "20061003T100000", 1176 "20070303T100000", 1177 "20070803T100000", 1178 "20080103T100000", 1179 "20080603T100000", 1180 "20081103T100000", 1181 }, "20081103T100000"); 1182 } 1183 1184 @MediumTest 1185 public void testFromGoogleCalendar5() throws Exception { 1186 // Tuesday, Thursday (10/3) 1187 verifyRecurrence("20061003T040000", 1188 "FREQ=WEEKLY;INTERVAL=1;BYDAY=TU,TH;WKST=SU", 1189 null /* rdate */, null /* exrule */, null /* exdate */, 1190 "20060101T000000", "20090101T000000", 1191 new String[]{ 1192 "20061003T040000", 1193 "20061005T040000", 1194 "20061010T040000", 1195 "20061012T040000", 1196 "20061017T040000", 1197 "20061019T040000", 1198 "20061024T040000", 1199 "20061026T040000", 1200 "20061031T040000", 1201 "20061102T040000", 1202 "20061107T040000", 1203 "20061109T040000", 1204 "20061114T040000", 1205 "20061116T040000", 1206 "20061121T040000", 1207 "20061123T040000", 1208 "20061128T040000", 1209 "20061130T040000", 1210 "20061205T040000", 1211 "20061207T040000", 1212 "20061212T040000", 1213 "20061214T040000", 1214 "20061219T040000", 1215 "20061221T040000", 1216 "20061226T040000", 1217 "20061228T040000", 1218 "20070102T040000", 1219 "20070104T040000", 1220 "20070109T040000", 1221 "20070111T040000", 1222 "20070116T040000", 1223 "20070118T040000", 1224 "20070123T040000", 1225 "20070125T040000", 1226 "20070130T040000", 1227 "20070201T040000", 1228 "20070206T040000", 1229 "20070208T040000", 1230 "20070213T040000", 1231 "20070215T040000", 1232 "20070220T040000", 1233 "20070222T040000", 1234 "20070227T040000", 1235 "20070301T040000", 1236 "20070306T040000", 1237 "20070308T040000", 1238 "20070313T040000", 1239 "20070315T040000", 1240 "20070320T040000", 1241 "20070322T040000", 1242 "20070327T040000", 1243 "20070329T040000", 1244 "20070403T040000", 1245 "20070405T040000", 1246 "20070410T040000", 1247 "20070412T040000", 1248 "20070417T040000", 1249 "20070419T040000", 1250 "20070424T040000", 1251 "20070426T040000", 1252 "20070501T040000", 1253 "20070503T040000", 1254 "20070508T040000", 1255 "20070510T040000", 1256 "20070515T040000", 1257 "20070517T040000", 1258 "20070522T040000", 1259 "20070524T040000", 1260 "20070529T040000", 1261 "20070531T040000", 1262 "20070605T040000", 1263 "20070607T040000", 1264 "20070612T040000", 1265 "20070614T040000", 1266 "20070619T040000", 1267 "20070621T040000", 1268 "20070626T040000", 1269 "20070628T040000", 1270 "20070703T040000", 1271 "20070705T040000", 1272 "20070710T040000", 1273 "20070712T040000", 1274 "20070717T040000", 1275 "20070719T040000", 1276 "20070724T040000", 1277 "20070726T040000", 1278 "20070731T040000", 1279 "20070802T040000", 1280 "20070807T040000", 1281 "20070809T040000", 1282 "20070814T040000", 1283 "20070816T040000", 1284 "20070821T040000", 1285 "20070823T040000", 1286 "20070828T040000", 1287 "20070830T040000", 1288 "20070904T040000", 1289 "20070906T040000", 1290 "20070911T040000", 1291 "20070913T040000", 1292 "20070918T040000", 1293 "20070920T040000", 1294 "20070925T040000", 1295 "20070927T040000", 1296 "20071002T040000", 1297 "20071004T040000", 1298 "20071009T040000", 1299 "20071011T040000", 1300 "20071016T040000", 1301 "20071018T040000", 1302 "20071023T040000", 1303 "20071025T040000", 1304 "20071030T040000", 1305 "20071101T040000", 1306 "20071106T040000", 1307 "20071108T040000", 1308 "20071113T040000", 1309 "20071115T040000", 1310 "20071120T040000", 1311 "20071122T040000", 1312 "20071127T040000", 1313 "20071129T040000", 1314 "20071204T040000", 1315 "20071206T040000", 1316 "20071211T040000", 1317 "20071213T040000", 1318 "20071218T040000", 1319 "20071220T040000", 1320 "20071225T040000", 1321 "20071227T040000", 1322 "20080101T040000", 1323 "20080103T040000", 1324 "20080108T040000", 1325 "20080110T040000", 1326 "20080115T040000", 1327 "20080117T040000", 1328 "20080122T040000", 1329 "20080124T040000", 1330 "20080129T040000", 1331 "20080131T040000", 1332 "20080205T040000", 1333 "20080207T040000", 1334 "20080212T040000", 1335 "20080214T040000", 1336 "20080219T040000", 1337 "20080221T040000", 1338 "20080226T040000", 1339 "20080228T040000", 1340 "20080304T040000", 1341 "20080306T040000", 1342 "20080311T040000", 1343 "20080313T040000", 1344 "20080318T040000", 1345 "20080320T040000", 1346 "20080325T040000", 1347 "20080327T040000", 1348 "20080401T040000", 1349 "20080403T040000", 1350 "20080408T040000", 1351 "20080410T040000", 1352 "20080415T040000", 1353 "20080417T040000", 1354 "20080422T040000", 1355 "20080424T040000", 1356 "20080429T040000", 1357 "20080501T040000", 1358 "20080506T040000", 1359 "20080508T040000", 1360 "20080513T040000", 1361 "20080515T040000", 1362 "20080520T040000", 1363 "20080522T040000", 1364 "20080527T040000", 1365 "20080529T040000", 1366 "20080603T040000", 1367 "20080605T040000", 1368 "20080610T040000", 1369 "20080612T040000", 1370 "20080617T040000", 1371 "20080619T040000", 1372 "20080624T040000", 1373 "20080626T040000", 1374 "20080701T040000", 1375 "20080703T040000", 1376 "20080708T040000", 1377 "20080710T040000", 1378 "20080715T040000", 1379 "20080717T040000", 1380 "20080722T040000", 1381 "20080724T040000", 1382 "20080729T040000", 1383 "20080731T040000", 1384 "20080805T040000", 1385 "20080807T040000", 1386 "20080812T040000", 1387 "20080814T040000", 1388 "20080819T040000", 1389 "20080821T040000", 1390 "20080826T040000", 1391 "20080828T040000", 1392 "20080902T040000", 1393 "20080904T040000", 1394 "20080909T040000", 1395 "20080911T040000", 1396 "20080916T040000", 1397 "20080918T040000", 1398 "20080923T040000", 1399 "20080925T040000", 1400 "20080930T040000", 1401 "20081002T040000", 1402 "20081007T040000", 1403 "20081009T040000", 1404 "20081014T040000", 1405 "20081016T040000", 1406 "20081021T040000", 1407 "20081023T040000", 1408 "20081028T040000", 1409 "20081030T040000", 1410 "20081104T040000", 1411 "20081106T040000", 1412 "20081111T040000", 1413 "20081113T040000", 1414 "20081118T040000", 1415 "20081120T040000", 1416 "20081125T040000", 1417 "20081127T040000", 1418 "20081202T040000", 1419 "20081204T040000", 1420 "20081209T040000", 1421 "20081211T040000", 1422 "20081216T040000", 1423 "20081218T040000", 1424 "20081223T040000", 1425 "20081225T040000", 1426 "20081230T040000", 1427 }, "20081230T040000"); 1428 } 1429 1430 @MediumTest 1431 public void testFromGoogleCalendar6() throws Exception { 1432 // Weekly on all days 1433 verifyRecurrence("20061003T060000", 1434 "FREQ=WEEKLY;INTERVAL=1;BYDAY=SU,MO,TU,WE,TH,FR,SA;WKST=SU", 1435 null /* rdate */, null /* exrule */, null /* exdate */, 1436 "20060101T000000", "20071003T060000", 1437 new String[]{ 1438 "20061003T060000", 1439 "20061004T060000", 1440 "20061005T060000", 1441 "20061006T060000", 1442 "20061007T060000", 1443 "20061008T060000", 1444 "20061009T060000", 1445 "20061010T060000", 1446 "20061011T060000", 1447 "20061012T060000", 1448 "20061013T060000", 1449 "20061014T060000", 1450 "20061015T060000", 1451 "20061016T060000", 1452 "20061017T060000", 1453 "20061018T060000", 1454 "20061019T060000", 1455 "20061020T060000", 1456 "20061021T060000", 1457 "20061022T060000", 1458 "20061023T060000", 1459 "20061024T060000", 1460 "20061025T060000", 1461 "20061026T060000", 1462 "20061027T060000", 1463 "20061028T060000", 1464 "20061029T060000", 1465 "20061030T060000", 1466 "20061031T060000", 1467 "20061101T060000", 1468 "20061102T060000", 1469 "20061103T060000", 1470 "20061104T060000", 1471 "20061105T060000", 1472 "20061106T060000", 1473 "20061107T060000", 1474 "20061108T060000", 1475 "20061109T060000", 1476 "20061110T060000", 1477 "20061111T060000", 1478 "20061112T060000", 1479 "20061113T060000", 1480 "20061114T060000", 1481 "20061115T060000", 1482 "20061116T060000", 1483 "20061117T060000", 1484 "20061118T060000", 1485 "20061119T060000", 1486 "20061120T060000", 1487 "20061121T060000", 1488 "20061122T060000", 1489 "20061123T060000", 1490 "20061124T060000", 1491 "20061125T060000", 1492 "20061126T060000", 1493 "20061127T060000", 1494 "20061128T060000", 1495 "20061129T060000", 1496 "20061130T060000", 1497 "20061201T060000", 1498 "20061202T060000", 1499 "20061203T060000", 1500 "20061204T060000", 1501 "20061205T060000", 1502 "20061206T060000", 1503 "20061207T060000", 1504 "20061208T060000", 1505 "20061209T060000", 1506 "20061210T060000", 1507 "20061211T060000", 1508 "20061212T060000", 1509 "20061213T060000", 1510 "20061214T060000", 1511 "20061215T060000", 1512 "20061216T060000", 1513 "20061217T060000", 1514 "20061218T060000", 1515 "20061219T060000", 1516 "20061220T060000", 1517 "20061221T060000", 1518 "20061222T060000", 1519 "20061223T060000", 1520 "20061224T060000", 1521 "20061225T060000", 1522 "20061226T060000", 1523 "20061227T060000", 1524 "20061228T060000", 1525 "20061229T060000", 1526 "20061230T060000", 1527 "20061231T060000", 1528 "20070101T060000", 1529 "20070102T060000", 1530 "20070103T060000", 1531 "20070104T060000", 1532 "20070105T060000", 1533 "20070106T060000", 1534 "20070107T060000", 1535 "20070108T060000", 1536 "20070109T060000", 1537 "20070110T060000", 1538 "20070111T060000", 1539 "20070112T060000", 1540 "20070113T060000", 1541 "20070114T060000", 1542 "20070115T060000", 1543 "20070116T060000", 1544 "20070117T060000", 1545 "20070118T060000", 1546 "20070119T060000", 1547 "20070120T060000", 1548 "20070121T060000", 1549 "20070122T060000", 1550 "20070123T060000", 1551 "20070124T060000", 1552 "20070125T060000", 1553 "20070126T060000", 1554 "20070127T060000", 1555 "20070128T060000", 1556 "20070129T060000", 1557 "20070130T060000", 1558 "20070131T060000", 1559 "20070201T060000", 1560 "20070202T060000", 1561 "20070203T060000", 1562 "20070204T060000", 1563 "20070205T060000", 1564 "20070206T060000", 1565 "20070207T060000", 1566 "20070208T060000", 1567 "20070209T060000", 1568 "20070210T060000", 1569 "20070211T060000", 1570 "20070212T060000", 1571 "20070213T060000", 1572 "20070214T060000", 1573 "20070215T060000", 1574 "20070216T060000", 1575 "20070217T060000", 1576 "20070218T060000", 1577 "20070219T060000", 1578 "20070220T060000", 1579 "20070221T060000", 1580 "20070222T060000", 1581 "20070223T060000", 1582 "20070224T060000", 1583 "20070225T060000", 1584 "20070226T060000", 1585 "20070227T060000", 1586 "20070228T060000", 1587 "20070301T060000", 1588 "20070302T060000", 1589 "20070303T060000", 1590 "20070304T060000", 1591 "20070305T060000", 1592 "20070306T060000", 1593 "20070307T060000", 1594 "20070308T060000", 1595 "20070309T060000", 1596 "20070310T060000", 1597 "20070311T060000", 1598 "20070312T060000", 1599 "20070313T060000", 1600 "20070314T060000", 1601 "20070315T060000", 1602 "20070316T060000", 1603 "20070317T060000", 1604 "20070318T060000", 1605 "20070319T060000", 1606 "20070320T060000", 1607 "20070321T060000", 1608 "20070322T060000", 1609 "20070323T060000", 1610 "20070324T060000", 1611 "20070325T060000", 1612 "20070326T060000", 1613 "20070327T060000", 1614 "20070328T060000", 1615 "20070329T060000", 1616 "20070330T060000", 1617 "20070331T060000", 1618 "20070401T060000", 1619 "20070402T060000", 1620 "20070403T060000", 1621 "20070404T060000", 1622 "20070405T060000", 1623 "20070406T060000", 1624 "20070407T060000", 1625 "20070408T060000", 1626 "20070409T060000", 1627 "20070410T060000", 1628 "20070411T060000", 1629 "20070412T060000", 1630 "20070413T060000", 1631 "20070414T060000", 1632 "20070415T060000", 1633 "20070416T060000", 1634 "20070417T060000", 1635 "20070418T060000", 1636 "20070419T060000", 1637 "20070420T060000", 1638 "20070421T060000", 1639 "20070422T060000", 1640 "20070423T060000", 1641 "20070424T060000", 1642 "20070425T060000", 1643 "20070426T060000", 1644 "20070427T060000", 1645 "20070428T060000", 1646 "20070429T060000", 1647 "20070430T060000", 1648 "20070501T060000", 1649 "20070502T060000", 1650 "20070503T060000", 1651 "20070504T060000", 1652 "20070505T060000", 1653 "20070506T060000", 1654 "20070507T060000", 1655 "20070508T060000", 1656 "20070509T060000", 1657 "20070510T060000", 1658 "20070511T060000", 1659 "20070512T060000", 1660 "20070513T060000", 1661 "20070514T060000", 1662 "20070515T060000", 1663 "20070516T060000", 1664 "20070517T060000", 1665 "20070518T060000", 1666 "20070519T060000", 1667 "20070520T060000", 1668 "20070521T060000", 1669 "20070522T060000", 1670 "20070523T060000", 1671 "20070524T060000", 1672 "20070525T060000", 1673 "20070526T060000", 1674 "20070527T060000", 1675 "20070528T060000", 1676 "20070529T060000", 1677 "20070530T060000", 1678 "20070531T060000", 1679 "20070601T060000", 1680 "20070602T060000", 1681 "20070603T060000", 1682 "20070604T060000", 1683 "20070605T060000", 1684 "20070606T060000", 1685 "20070607T060000", 1686 "20070608T060000", 1687 "20070609T060000", 1688 "20070610T060000", 1689 "20070611T060000", 1690 "20070612T060000", 1691 "20070613T060000", 1692 "20070614T060000", 1693 "20070615T060000", 1694 "20070616T060000", 1695 "20070617T060000", 1696 "20070618T060000", 1697 "20070619T060000", 1698 "20070620T060000", 1699 "20070621T060000", 1700 "20070622T060000", 1701 "20070623T060000", 1702 "20070624T060000", 1703 "20070625T060000", 1704 "20070626T060000", 1705 "20070627T060000", 1706 "20070628T060000", 1707 "20070629T060000", 1708 "20070630T060000", 1709 "20070701T060000", 1710 "20070702T060000", 1711 "20070703T060000", 1712 "20070704T060000", 1713 "20070705T060000", 1714 "20070706T060000", 1715 "20070707T060000", 1716 "20070708T060000", 1717 "20070709T060000", 1718 "20070710T060000", 1719 "20070711T060000", 1720 "20070712T060000", 1721 "20070713T060000", 1722 "20070714T060000", 1723 "20070715T060000", 1724 "20070716T060000", 1725 "20070717T060000", 1726 "20070718T060000", 1727 "20070719T060000", 1728 "20070720T060000", 1729 "20070721T060000", 1730 "20070722T060000", 1731 "20070723T060000", 1732 "20070724T060000", 1733 "20070725T060000", 1734 "20070726T060000", 1735 "20070727T060000", 1736 "20070728T060000", 1737 "20070729T060000", 1738 "20070730T060000", 1739 "20070731T060000", 1740 "20070801T060000", 1741 "20070802T060000", 1742 "20070803T060000", 1743 "20070804T060000", 1744 "20070805T060000", 1745 "20070806T060000", 1746 "20070807T060000", 1747 "20070808T060000", 1748 "20070809T060000", 1749 "20070810T060000", 1750 "20070811T060000", 1751 "20070812T060000", 1752 "20070813T060000", 1753 "20070814T060000", 1754 "20070815T060000", 1755 "20070816T060000", 1756 "20070817T060000", 1757 "20070818T060000", 1758 "20070819T060000", 1759 "20070820T060000", 1760 "20070821T060000", 1761 "20070822T060000", 1762 "20070823T060000", 1763 "20070824T060000", 1764 "20070825T060000", 1765 "20070826T060000", 1766 "20070827T060000", 1767 "20070828T060000", 1768 "20070829T060000", 1769 "20070830T060000", 1770 "20070831T060000", 1771 "20070901T060000", 1772 "20070902T060000", 1773 "20070903T060000", 1774 "20070904T060000", 1775 "20070905T060000", 1776 "20070906T060000", 1777 "20070907T060000", 1778 "20070908T060000", 1779 "20070909T060000", 1780 "20070910T060000", 1781 "20070911T060000", 1782 "20070912T060000", 1783 "20070913T060000", 1784 "20070914T060000", 1785 "20070915T060000", 1786 "20070916T060000", 1787 "20070917T060000", 1788 "20070918T060000", 1789 "20070919T060000", 1790 "20070920T060000", 1791 "20070921T060000", 1792 "20070922T060000", 1793 "20070923T060000", 1794 "20070924T060000", 1795 "20070925T060000", 1796 "20070926T060000", 1797 "20070927T060000", 1798 "20070928T060000", 1799 "20070929T060000", 1800 "20070930T060000", 1801 "20071001T060000", 1802 "20071002T060000", 1803 }, "20071002T060000"); 1804 } 1805 1806 @MediumTest 1807 public void testFromGoogleCalendar7() throws Exception { 1808 // Every 3 days 1809 verifyRecurrence("20061003T080000", 1810 "FREQ=DAILY;INTERVAL=3;WKST=SU", 1811 null /* rdate */, null /* exrule */, null /* exdate */, 1812 "20060101T000000", "20090101T000000", 1813 new String[]{ 1814 "20061003T080000", 1815 "20061006T080000", 1816 "20061009T080000", 1817 "20061012T080000", 1818 "20061015T080000", 1819 "20061018T080000", 1820 "20061021T080000", 1821 "20061024T080000", 1822 "20061027T080000", 1823 "20061030T080000", 1824 "20061102T080000", 1825 "20061105T080000", 1826 "20061108T080000", 1827 "20061111T080000", 1828 "20061114T080000", 1829 "20061117T080000", 1830 "20061120T080000", 1831 "20061123T080000", 1832 "20061126T080000", 1833 "20061129T080000", 1834 "20061202T080000", 1835 "20061205T080000", 1836 "20061208T080000", 1837 "20061211T080000", 1838 "20061214T080000", 1839 "20061217T080000", 1840 "20061220T080000", 1841 "20061223T080000", 1842 "20061226T080000", 1843 "20061229T080000", 1844 "20070101T080000", 1845 "20070104T080000", 1846 "20070107T080000", 1847 "20070110T080000", 1848 "20070113T080000", 1849 "20070116T080000", 1850 "20070119T080000", 1851 "20070122T080000", 1852 "20070125T080000", 1853 "20070128T080000", 1854 "20070131T080000", 1855 "20070203T080000", 1856 "20070206T080000", 1857 "20070209T080000", 1858 "20070212T080000", 1859 "20070215T080000", 1860 "20070218T080000", 1861 "20070221T080000", 1862 "20070224T080000", 1863 "20070227T080000", 1864 "20070302T080000", 1865 "20070305T080000", 1866 "20070308T080000", 1867 "20070311T080000", 1868 "20070314T080000", 1869 "20070317T080000", 1870 "20070320T080000", 1871 "20070323T080000", 1872 "20070326T080000", 1873 "20070329T080000", 1874 "20070401T080000", 1875 "20070404T080000", 1876 "20070407T080000", 1877 "20070410T080000", 1878 "20070413T080000", 1879 "20070416T080000", 1880 "20070419T080000", 1881 "20070422T080000", 1882 "20070425T080000", 1883 "20070428T080000", 1884 "20070501T080000", 1885 "20070504T080000", 1886 "20070507T080000", 1887 "20070510T080000", 1888 "20070513T080000", 1889 "20070516T080000", 1890 "20070519T080000", 1891 "20070522T080000", 1892 "20070525T080000", 1893 "20070528T080000", 1894 "20070531T080000", 1895 "20070603T080000", 1896 "20070606T080000", 1897 "20070609T080000", 1898 "20070612T080000", 1899 "20070615T080000", 1900 "20070618T080000", 1901 "20070621T080000", 1902 "20070624T080000", 1903 "20070627T080000", 1904 "20070630T080000", 1905 "20070703T080000", 1906 "20070706T080000", 1907 "20070709T080000", 1908 "20070712T080000", 1909 "20070715T080000", 1910 "20070718T080000", 1911 "20070721T080000", 1912 "20070724T080000", 1913 "20070727T080000", 1914 "20070730T080000", 1915 "20070802T080000", 1916 "20070805T080000", 1917 "20070808T080000", 1918 "20070811T080000", 1919 "20070814T080000", 1920 "20070817T080000", 1921 "20070820T080000", 1922 "20070823T080000", 1923 "20070826T080000", 1924 "20070829T080000", 1925 "20070901T080000", 1926 "20070904T080000", 1927 "20070907T080000", 1928 "20070910T080000", 1929 "20070913T080000", 1930 "20070916T080000", 1931 "20070919T080000", 1932 "20070922T080000", 1933 "20070925T080000", 1934 "20070928T080000", 1935 "20071001T080000", 1936 "20071004T080000", 1937 "20071007T080000", 1938 "20071010T080000", 1939 "20071013T080000", 1940 "20071016T080000", 1941 "20071019T080000", 1942 "20071022T080000", 1943 "20071025T080000", 1944 "20071028T080000", 1945 "20071031T080000", 1946 "20071103T080000", 1947 "20071106T080000", 1948 "20071109T080000", 1949 "20071112T080000", 1950 "20071115T080000", 1951 "20071118T080000", 1952 "20071121T080000", 1953 "20071124T080000", 1954 "20071127T080000", 1955 "20071130T080000", 1956 "20071203T080000", 1957 "20071206T080000", 1958 "20071209T080000", 1959 "20071212T080000", 1960 "20071215T080000", 1961 "20071218T080000", 1962 "20071221T080000", 1963 "20071224T080000", 1964 "20071227T080000", 1965 "20071230T080000", 1966 "20080102T080000", 1967 "20080105T080000", 1968 "20080108T080000", 1969 "20080111T080000", 1970 "20080114T080000", 1971 "20080117T080000", 1972 "20080120T080000", 1973 "20080123T080000", 1974 "20080126T080000", 1975 "20080129T080000", 1976 "20080201T080000", 1977 "20080204T080000", 1978 "20080207T080000", 1979 "20080210T080000", 1980 "20080213T080000", 1981 "20080216T080000", 1982 "20080219T080000", 1983 "20080222T080000", 1984 "20080225T080000", 1985 "20080228T080000", 1986 "20080302T080000", 1987 "20080305T080000", 1988 "20080308T080000", 1989 "20080311T080000", 1990 "20080314T080000", 1991 "20080317T080000", 1992 "20080320T080000", 1993 "20080323T080000", 1994 "20080326T080000", 1995 "20080329T080000", 1996 "20080401T080000", 1997 "20080404T080000", 1998 "20080407T080000", 1999 "20080410T080000", 2000 "20080413T080000", 2001 "20080416T080000", 2002 "20080419T080000", 2003 "20080422T080000", 2004 "20080425T080000", 2005 "20080428T080000", 2006 "20080501T080000", 2007 "20080504T080000", 2008 "20080507T080000", 2009 "20080510T080000", 2010 "20080513T080000", 2011 "20080516T080000", 2012 "20080519T080000", 2013 "20080522T080000", 2014 "20080525T080000", 2015 "20080528T080000", 2016 "20080531T080000", 2017 "20080603T080000", 2018 "20080606T080000", 2019 "20080609T080000", 2020 "20080612T080000", 2021 "20080615T080000", 2022 "20080618T080000", 2023 "20080621T080000", 2024 "20080624T080000", 2025 "20080627T080000", 2026 "20080630T080000", 2027 "20080703T080000", 2028 "20080706T080000", 2029 "20080709T080000", 2030 "20080712T080000", 2031 "20080715T080000", 2032 "20080718T080000", 2033 "20080721T080000", 2034 "20080724T080000", 2035 "20080727T080000", 2036 "20080730T080000", 2037 "20080802T080000", 2038 "20080805T080000", 2039 "20080808T080000", 2040 "20080811T080000", 2041 "20080814T080000", 2042 "20080817T080000", 2043 "20080820T080000", 2044 "20080823T080000", 2045 "20080826T080000", 2046 "20080829T080000", 2047 "20080901T080000", 2048 "20080904T080000", 2049 "20080907T080000", 2050 "20080910T080000", 2051 "20080913T080000", 2052 "20080916T080000", 2053 "20080919T080000", 2054 "20080922T080000", 2055 "20080925T080000", 2056 "20080928T080000", 2057 "20081001T080000", 2058 "20081004T080000", 2059 "20081007T080000", 2060 "20081010T080000", 2061 "20081013T080000", 2062 "20081016T080000", 2063 "20081019T080000", 2064 "20081022T080000", 2065 "20081025T080000", 2066 "20081028T080000", 2067 "20081031T080000", 2068 "20081103T080000", 2069 "20081106T080000", 2070 "20081109T080000", 2071 "20081112T080000", 2072 "20081115T080000", 2073 "20081118T080000", 2074 "20081121T080000", 2075 "20081124T080000", 2076 "20081127T080000", 2077 "20081130T080000", 2078 "20081203T080000", 2079 "20081206T080000", 2080 "20081209T080000", 2081 "20081212T080000", 2082 "20081215T080000", 2083 "20081218T080000", 2084 "20081221T080000", 2085 "20081224T080000", 2086 "20081227T080000", 2087 "20081230T080000", 2088 }, "20081230T080000"); 2089 } 2090 2091 @SmallTest 2092 public void testFromGoogleCalendar8() throws Exception { 2093 // Annually on October 4 2094 verifyRecurrence("20061004T130000", 2095 "FREQ=YEARLY;INTERVAL=1;WKST=SU", 2096 null /* rdate */, null /* exrule */, null /* exdate */, 2097 "20060101T000000", "20090101T000000", 2098 new String[]{ 2099 "20061004T130000", 2100 "20071004T130000", 2101 "20081004T130000", 2102 }, "20081004T130000"); 2103 } 2104 2105 @MediumTest 2106 public void testFromGoogleCalendar9() throws Exception { 2107 // Monthly on the last Monday 2108 verifyRecurrence("20061030T170000", 2109 "FREQ=MONTHLY;INTERVAL=1;BYDAY=-1MO;WKST=SU", 2110 null /* rdate */, null /* exrule */, null /* exdate */, 2111 "20060101T000000", "20090101T000000", 2112 new String[]{ 2113 "20061030T170000", 2114 "20061127T170000", 2115 "20061225T170000", 2116 "20070129T170000", 2117 "20070226T170000", 2118 "20070326T170000", 2119 "20070430T170000", 2120 "20070528T170000", 2121 "20070625T170000", 2122 "20070730T170000", 2123 "20070827T170000", 2124 "20070924T170000", 2125 "20071029T170000", 2126 "20071126T170000", 2127 "20071231T170000", 2128 "20080128T170000", 2129 "20080225T170000", 2130 "20080331T170000", 2131 "20080428T170000", 2132 "20080526T170000", 2133 "20080630T170000", 2134 "20080728T170000", 2135 "20080825T170000", 2136 "20080929T170000", 2137 "20081027T170000", 2138 "20081124T170000", 2139 "20081229T170000", 2140 }, "20081229T170000"); 2141 } 2142 2143 @SmallTest 2144 public void testFromGoogleCalendar10() throws Exception { 2145 // Every 7 weeks on Tuesday, Wednesday 2146 verifyRecurrence("20061004T090000", 2147 "FREQ=WEEKLY;UNTIL=20070223T010000Z;INTERVAL=7;BYDAY=TU,WE;WKST=SU", 2148 null /* rdate */, null /* exrule */, null /* exdate */, 2149 "20060101T000000", "20090101T000000", 2150 new String[]{ 2151 "20061004T090000", 2152 "20061121T090000", 2153 "20061122T090000", 2154 "20070109T090000", 2155 "20070110T090000", 2156 }, "20070222T170000"); 2157 } 2158 2159 @SmallTest 2160 public void testFromGoogleCalendar11() throws Exception { 2161 // Monthly on day 31 2162 verifyRecurrence("20061031T160000", 2163 "FREQ=MONTHLY;INTERVAL=1;WKST=SU", 2164 null /* rdate */, null /* exrule */, null /* exdate */, 2165 "20060101T000000", "20090101T000000", 2166 new String[]{ 2167 "20061031T160000", 2168 "20061231T160000", 2169 "20070131T160000", 2170 "20070331T160000", 2171 "20070531T160000", 2172 "20070731T160000", 2173 "20070831T160000", 2174 "20071031T160000", 2175 "20071231T160000", 2176 "20080131T160000", 2177 "20080331T160000", 2178 "20080531T160000", 2179 "20080731T160000", 2180 "20080831T160000", 2181 "20081031T160000", 2182 "20081231T160000", 2183 }, 2184 "20081231T160000"); 2185 } 2186 2187 @SmallTest 2188 public void testFromGoogleCalendar12() throws Exception { 2189 // Every 2 months on the first Tuesday 2190 verifyRecurrence("20061004T110000", 2191 "FREQ=MONTHLY;INTERVAL=2;BYDAY=1TU;WKST=SU", 2192 null /* rdate */, null /* exrule */, null /* exdate */, 2193 "20060101T000000", "20090101T000000", 2194 new String[]{ 2195 "20061004T110000", 2196 "20061205T110000", 2197 "20070206T110000", 2198 "20070403T110000", 2199 "20070605T110000", 2200 "20070807T110000", 2201 "20071002T110000", 2202 "20071204T110000", 2203 "20080205T110000", 2204 "20080401T110000", 2205 "20080603T110000", 2206 "20080805T110000", 2207 "20081007T110000", 2208 "20081202T110000", 2209 }, 2210 "20081202T110000"); 2211 } 2212 2213 @SmallTest 2214 public void testYearly0() throws Exception { 2215 verifyRecurrence("20080101T100000", 2216 "FREQ=YEARLY;UNTIL=20090131T090000Z;BYMONTH=1;BYDAY=SU,MO", 2217 null /* rdate */, null /* exrule */, null /* exdate */, 2218 "20080101T000000", "20090130T000000", 2219 new String[]{ 2220 "20080101T100000", 2221 "20080106T100000", 2222 "20080107T100000", 2223 "20080113T100000", 2224 "20080114T100000", 2225 "20080120T100000", 2226 "20080121T100000", 2227 "20080127T100000", 2228 "20080128T100000", 2229 "20090104T100000", 2230 "20090105T100000", 2231 "20090111T100000", 2232 "20090112T100000", 2233 "20090118T100000", 2234 "20090119T100000", 2235 "20090125T100000", 2236 "20090126T100000", 2237 }, "20090131T010000"); 2238 } 2239 2240 /** 2241 * This test fails because of a bug in RecurrenceProcessor.expand(). We 2242 * don't have time to fix the bug yet but we don't want to lose track of 2243 * this test either. The "failing" prefix on the method name prevents this 2244 * test from being run. Remove the "failing" prefix when the bug is fixed. 2245 * 2246 * @throws Exception 2247 */ 2248 @SmallTest 2249 public void failingTestYearly1() throws Exception { 2250 verifyRecurrence("20060101T100000", 2251 "FREQ=YEARLY;COUNT=10;BYYEARDAY=1,100,200", 2252 null /* rdate */, null /* exrule */, null /* exdate */, 2253 "20060101T000000", "20090131T000000", 2254 new String[]{ 2255 "20060101T100000", 2256 "20060409T100000", 2257 "20060718T100000", 2258 "20070101T100000", 2259 "20070409T100000", 2260 "20070718T100000", 2261 "20080101T100000", 2262 "20080410T100000", 2263 "20080719T100000", 2264 "20090101T100000", 2265 }); 2266 } 2267 2268 /** 2269 * This test fails because of a bug in RecurrenceProcessor.expand(). We 2270 * don't have time to fix the bug yet but we don't want to lose track of 2271 * this test either. The "failing" prefix on the method name prevents this 2272 * test from being run. Remove the "failing" prefix when the bug is fixed. 2273 * 2274 * @throws Exception 2275 */ 2276 @SmallTest 2277 public void failingTestYearly2() throws Exception { 2278 verifyRecurrence("20060101T100000", 2279 "FREQ=YEARLY;COUNT=5;BYWEEKNO=6;BYDAY=MO;WKST=MO", 2280 null /* rdate */, null /* exrule */, null /* exdate */, 2281 "20060101T000000", "20090131T000000", 2282 new String[]{ 2283 "20060101T100000", 2284 "20060206T100000", 2285 "20070205T100000", 2286 "20080204T100000", 2287 "20090209T100000", 2288 }); 2289 } 2290 2291 /** 2292 * This test fails because of a bug in RecurrenceProcessor.expand(). We 2293 * don't have time to fix the bug yet but we don't want to lose track of 2294 * this test either. The "failing" prefix on the method name prevents this 2295 * test from being run. Remove the "failing" prefix when the bug is fixed. 2296 * 2297 * @throws Exception 2298 */ 2299 @SmallTest 2300 public void failingTestYearly3() throws Exception { 2301 verifyRecurrence("20060101T100000", 2302 "FREQ=YEARLY;BYMONTH=3;BYDAY=TH", 2303 null /* rdate */, null /* exrule */, null /* exdate */, 2304 "20060101T000000", "20090131T000000", 2305 new String[]{ 2306 "20060101T100000", 2307 "20060302T100000", 2308 "20060309T100000", 2309 "20060316T100000", 2310 "20060323T100000", 2311 "20060330T100000", 2312 "20070301T100000", 2313 "20070308T100000", 2314 "20070315T100000", 2315 "20070322T100000", 2316 "20070329T100000", 2317 "20080306T100000", 2318 "20080313T100000", 2319 "20080320T100000", 2320 "20080327T100000", 2321 }); 2322 } 2323 2324 /** 2325 * This test fails because of a bug in RecurrenceProcessor.expand(). We 2326 * don't have time to fix the bug yet but we don't want to lose track of 2327 * this test either. The "failing" prefix on the method name prevents this 2328 * test from being run. Remove the "failing" prefix when the bug is fixed. 2329 * 2330 * @throws Exception 2331 */ 2332 @SmallTest 2333 public void failingTestYearly4() throws Exception { 2334 verifyRecurrence("19920101T100000", 2335 "FREQ=YEARLY;INTERVAL=4;BYMONTH=11;BYDAY=TU;BYMONTHDAY=2,3,4,5,6,7,8", 2336 null /* rdate */, null /* exrule */, null /* exdate */, 2337 "19920101T000000", "20121231T000000", 2338 new String[]{ 2339 "19920101T100000", 2340 "19921103T100000", 2341 "19961105T100000", 2342 "20001107T100000", 2343 "20041102T100000", 2344 "20081104T100000", 2345 "20121106T100000", 2346 }); 2347 } 2348 2349 /** 2350 * Test repeating event from Exchange with count field. 2351 * Time range covers the whole repetition. 2352 * 2353 * @throws Exception 2354 */ 2355 public void testCount1() throws Exception { 2356 verifyRecurrence("20100324T153000", 2357 "FREQ=WEEKLY;INTERVAL=1;COUNT=10;BYDAY=WE", 2358 null /* rdate */, null /* exrule */, null /* exdate */, 2359 "20100301T000000", "20100630T000000", 2360 new String[]{ 2361 "20100324T153000", 2362 "20100331T153000", 2363 "20100407T153000", 2364 "20100414T153000", 2365 "20100421T153000", 2366 "20100428T153000", 2367 "20100505T153000", 2368 "20100512T153000", 2369 "20100519T153000", 2370 "20100526T153000", 2371 }); 2372 } 2373 2374 /** 2375 * Test repeating event from Exchange with count field. 2376 * Time range covers the first part of the repetition. 2377 * @throws Exception 2378 */ 2379 public void testCount2() throws Exception { 2380 verifyRecurrence("20100324T153000", 2381 "FREQ=WEEKLY;INTERVAL=1;COUNT=10;BYDAY=WE", 2382 null /* rdate */, null /* exrule */, null /* exdate */, 2383 "20100501T000000", "20100630T000000", 2384 new String[]{ 2385 "20100505T153000", 2386 "20100512T153000", 2387 "20100519T153000", 2388 "20100526T153000", 2389 }); 2390 } 2391 2392 /** 2393 * Test repeating event from Exchange with count field. 2394 * Time range is beyond the repetition. 2395 * @throws Exception 2396 */ 2397 public void testCount3() throws Exception { 2398 verifyRecurrence("20100324T153000", 2399 "FREQ=WEEKLY;INTERVAL=1;COUNT=10;BYDAY=WE", 2400 null /* rdate */, null /* exrule */, null /* exdate */, 2401 "20100601T000000", "20100630T000000", 2402 new String[]{}, 2403 "20100526T153000" /* last */); 2404 } 2405 2406 /** 2407 * Test repeating event from Exchange with count field. 2408 * Time range is before the repetition 2409 * @throws Exception 2410 */ 2411 public void testCount4() throws Exception { 2412 verifyRecurrence("20100324T153000", 2413 "FREQ=WEEKLY;INTERVAL=1;COUNT=10;BYDAY=WE", 2414 null /* rdate */, null /* exrule */, null /* exdate */, 2415 "20100101T000000", "20100301T000000", 2416 new String[]{}, 2417 null /* last */); 2418 } 2419 2420 2421 // These recurrence rules are used in the loop that measures the performance 2422 // of recurrence expansion. 2423 private static final String[] performanceRrules = new String[] { 2424 "FREQ=DAILY;COUNT=100", 2425 "FREQ=DAILY;INTERVAL=2;UNTIL=20080101T000000Z", 2426 "FREQ=YEARLY;UNTIL=20090131T090000Z;BYMONTH=1;BYDAY=SU,MO,TU,WE,TH,FR,SA", 2427 "FREQ=WEEKLY;INTERVAL=2;WKST=SU", 2428 "FREQ=WEEKLY;COUNT=100;WKST=SU;BYDAY=MO,TU,WE,TH,FR", 2429 "FREQ=MONTHLY;COUNT=100;BYDAY=1FR", 2430 "FREQ=MONTHLY;INTERVAL=2;COUNT=100;BYDAY=1SU,-1SU", 2431 "FREQ=MONTHLY;BYMONTHDAY=1,15", 2432 "FREQ=MONTHLY;INTERVAL=3;COUNT=100;BYMONTHDAY=10,11,12,13,14", 2433 "FREQ=YEARLY;COUNT=100;BYMONTH=6,7,8", 2434 "FREQ=YEARLY;INTERVAL=2;BYMONTH=1,2,3,6,7,8", 2435 "FREQ=YEARLY;COUNT=100;BYYEARDAY=1,100,200", 2436 "FREQ=YEARLY;BYDAY=2MO", 2437 "FREQ=YEARLY;BYWEEKNO=2,3,4;BYDAY=MO", 2438 "FREQ=YEARLY;BYMONTH=3,4,5;BYDAY=TH", 2439 "FREQ=MONTHLY;BYDAY=FR;BYMONTHDAY=13", 2440 "FREQ=MONTHLY;BYDAY=SA;BYMONTHDAY=7,8,9,10,11,12,13", 2441 "FREQ=YEARLY;INTERVAL=2;BYMONTH=11;BYDAY=TU;BYMONTHDAY=2,3,4,5,6,7,8", 2442 "FREQ=WEEKLY;INTERVAL=2;COUNT=100;BYDAY=TU,SU;WKST=MO", 2443 "FREQ=WEEKLY;INTERVAL=2;COUNT=100;BYDAY=TU,SU;WKST=SU", 2444 }; 2445 2446 /** 2447 * This test never fails. It just runs for a while (about 10 seconds) 2448 * in order to measure the performance of recurrence expansion. 2449 * 2450 * @throws Exception 2451 */ 2452 @LargeTest 2453 public void performanceTextExpand() throws Exception { 2454 String tz = "America/Los_Angeles"; 2455 Time dtstart = new Time(tz); 2456 Time rangeStart = new Time(tz); 2457 Time rangeEnd = new Time(tz); 2458 TreeSet<Long> out = new TreeSet<Long>(); 2459 2460 dtstart.parse("20010101T000000"); 2461 rangeStart.parse("20010101T000000"); 2462 rangeEnd.parse("20090101T000000"); 2463 long rangeStartMillis = rangeStart.toMillis(false /* use isDst */); 2464 long rangeEndMillis = rangeEnd.toMillis(false /* use isDst */); 2465 2466 long startTime = System.currentTimeMillis(); 2467 for (int iterations = 0; iterations < 5; iterations++) { 2468 RecurrenceProcessor rp = new RecurrenceProcessor(); 2469 2470 int len = performanceRrules.length; 2471 for (int i = 0; i < len; i++) { 2472 String rrule = performanceRrules[i]; 2473 //Log.i(TAG, "expanding rule: " + rrule); 2474 RecurrenceSet recur = new RecurrenceSet(rrule, null, null, null); 2475 2476 long [] dates = rp.expand(dtstart, recur, rangeStartMillis, rangeEndMillis); 2477 //Log.i(TAG, "num instances: " + out.size()); 2478 2479 // Also include the time to iterate through the expanded values 2480 for (long date : dates) { 2481 // Use the date so that this loop is not optimized away. 2482 if (date == -1) { 2483 Log.e(TAG, "unexpected date"); 2484 break; 2485 } 2486 } 2487 out.clear(); 2488 } 2489 } 2490 2491 long endTime = System.currentTimeMillis(); 2492 long elapsed = endTime - startTime; 2493 Log.i(TAG, "testPerformanceExpand() expand() elapsed millis: " + elapsed); 2494 } 2495 2496 @LargeTest 2497 public void performanceTestNormalize() throws Exception { 2498 final int ITERATIONS = 50000; 2499 2500 String tz = "America/Los_Angeles"; 2501 Time date = new Time(tz); 2502 date.parse("20090404T100000"); 2503 2504 long startTime = System.currentTimeMillis(); 2505 2506 for (int i = 0; i < ITERATIONS; i++) { 2507 date.month += 1; 2508 date.monthDay += 100; 2509 date.normalize(true); 2510 date.month -= 1; 2511 date.monthDay -= 100; 2512 date.normalize(true); 2513 } 2514 2515 long endTime = System.currentTimeMillis(); 2516 long elapsed = endTime - startTime; 2517 Log.i(TAG, "date: " + date.format2445()); 2518 Log.i(TAG, "testPerformanceNormalize() normalize() elapsed millis: " + elapsed); 2519 2520 // Time the unsafe version 2521 date.parse("20090404T100000"); 2522 startTime = System.currentTimeMillis(); 2523 for (int i = 0; i < ITERATIONS; i++) { 2524 date.month += 1; 2525 date.monthDay += 100; 2526 RecurrenceProcessor.unsafeNormalize(date); 2527 date.month -= 1; 2528 date.monthDay -= 100; 2529 RecurrenceProcessor.unsafeNormalize(date); 2530 } 2531 2532 endTime = System.currentTimeMillis(); 2533 elapsed = endTime - startTime; 2534 Log.i(TAG, "date: " + date.format2445()); 2535 Log.i(TAG, "testPerformanceNormalize() unsafeNormalize() elapsed millis: " + elapsed); 2536 } 2537 } 2538