1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.util; 18 19 import android.support.test.filters.SmallTest; 20 21 import junit.framework.TestCase; 22 23 import java.time.Clock; 24 import java.time.Instant; 25 import java.time.Period; 26 import java.time.ZoneId; 27 import java.time.ZonedDateTime; 28 import java.util.Iterator; 29 30 @SmallTest 31 public class RecurrenceRuleTest extends TestCase { 32 33 static Clock sOriginalClock; 34 35 @Override 36 protected void setUp() throws Exception { 37 super.setUp(); 38 sOriginalClock = RecurrenceRule.sClock; 39 } 40 41 @Override 42 protected void tearDown() throws Exception { 43 super.tearDown(); 44 RecurrenceRule.sClock = sOriginalClock; 45 } 46 47 private void setClock(Instant instant) { 48 RecurrenceRule.sClock = Clock.fixed(instant, ZoneId.systemDefault()); 49 } 50 51 public void testSimpleMonth() throws Exception { 52 setClock(Instant.parse("2015-11-20T10:15:30.00Z")); 53 final RecurrenceRule r = new RecurrenceRule( 54 ZonedDateTime.parse("2010-11-14T00:00:00.000Z"), 55 null, 56 Period.ofMonths(1)); 57 58 assertTrue(r.isMonthly()); 59 60 final Iterator<Range<ZonedDateTime>> it = r.cycleIterator(); 61 assertTrue(it.hasNext()); 62 assertEquals(new Range<>( 63 ZonedDateTime.parse("2015-11-14T00:00:00.00Z"), 64 ZonedDateTime.parse("2015-12-14T00:00:00.00Z")), it.next()); 65 assertTrue(it.hasNext()); 66 assertEquals(new Range<>( 67 ZonedDateTime.parse("2015-10-14T00:00:00.00Z"), 68 ZonedDateTime.parse("2015-11-14T00:00:00.00Z")), it.next()); 69 } 70 71 public void testSimpleDays() throws Exception { 72 setClock(Instant.parse("2015-01-01T10:15:30.00Z")); 73 final RecurrenceRule r = new RecurrenceRule( 74 ZonedDateTime.parse("2010-11-14T00:11:00.000Z"), 75 ZonedDateTime.parse("2010-11-20T00:11:00.000Z"), 76 Period.ofDays(3)); 77 78 assertFalse(r.isMonthly()); 79 80 final Iterator<Range<ZonedDateTime>> it = r.cycleIterator(); 81 assertTrue(it.hasNext()); 82 assertEquals(new Range<>( 83 ZonedDateTime.parse("2010-11-17T00:11:00.00Z"), 84 ZonedDateTime.parse("2010-11-20T00:11:00.00Z")), it.next()); 85 assertTrue(it.hasNext()); 86 assertEquals(new Range<>( 87 ZonedDateTime.parse("2010-11-14T00:11:00.00Z"), 88 ZonedDateTime.parse("2010-11-17T00:11:00.00Z")), it.next()); 89 assertFalse(it.hasNext()); 90 } 91 92 public void testNotRecurring() throws Exception { 93 setClock(Instant.parse("2015-01-01T10:15:30.00Z")); 94 final RecurrenceRule r = new RecurrenceRule( 95 ZonedDateTime.parse("2010-11-14T00:11:00.000Z"), 96 ZonedDateTime.parse("2010-11-20T00:11:00.000Z"), 97 null); 98 99 assertFalse(r.isMonthly()); 100 101 final Iterator<Range<ZonedDateTime>> it = r.cycleIterator(); 102 assertTrue(it.hasNext()); 103 assertEquals(new Range<>( 104 ZonedDateTime.parse("2010-11-14T00:11:00.000Z"), 105 ZonedDateTime.parse("2010-11-20T00:11:00.000Z")), it.next()); 106 assertFalse(it.hasNext()); 107 } 108 109 public void testNever() throws Exception { 110 setClock(Instant.parse("2015-01-01T10:15:30.00Z")); 111 final RecurrenceRule r = RecurrenceRule.buildNever(); 112 113 assertFalse(r.isMonthly()); 114 115 final Iterator<Range<ZonedDateTime>> it = r.cycleIterator(); 116 assertFalse(it.hasNext()); 117 } 118 119 public void testSane() throws Exception { 120 final RecurrenceRule r = new RecurrenceRule( 121 ZonedDateTime.parse("1980-01-31T00:00:00.000Z"), 122 ZonedDateTime.parse("2030-01-31T00:00:00.000Z"), 123 Period.ofMonths(1)); 124 125 final Iterator<Range<ZonedDateTime>> it = r.cycleIterator(); 126 ZonedDateTime lastStart = null; 127 int months = 0; 128 while (it.hasNext()) { 129 final Range<ZonedDateTime> cycle = it.next(); 130 131 // Make sure cycle has reasonable length 132 final long length = cycle.getUpper().toEpochSecond() - cycle.getLower().toEpochSecond(); 133 assertTrue(cycle + " must be more than 4 weeks", length >= 2419200); 134 assertTrue(cycle + " must be less than 5 weeks", length <= 3024000); 135 136 // Make sure we have no gaps 137 if (lastStart != null) { 138 assertEquals(lastStart, cycle.getUpper()); 139 } 140 lastStart = cycle.getLower(); 141 months++; 142 } 143 144 assertEquals(600, months); 145 } 146 } 147