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