117bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey/* 217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * Copyright (C) 2017 The Android Open Source Project 317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * 417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License"); 517bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * you may not use this file except in compliance with the License. 617bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * You may obtain a copy of the License at 717bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * 817bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * http://www.apache.org/licenses/LICENSE-2.0 917bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * 1017bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * Unless required by applicable law or agreed to in writing, software 1117bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS, 1217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * See the License for the specific language governing permissions and 1417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey * limitations under the License. 1517bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey */ 1617bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey 1717bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkeypackage android.util; 1817bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey 1917bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkeyimport android.support.test.filters.SmallTest; 2017bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey 2117bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkeyimport junit.framework.TestCase; 2217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey 2317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkeyimport java.time.Clock; 2417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkeyimport java.time.Instant; 2517bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkeyimport java.time.Period; 2617bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkeyimport java.time.ZoneId; 2717bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkeyimport java.time.ZonedDateTime; 2817bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkeyimport java.util.Iterator; 2917bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey 3017bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey@SmallTest 3117bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkeypublic class RecurrenceRuleTest extends TestCase { 3217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey 3317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey static Clock sOriginalClock; 3417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey 3517bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey @Override 3617bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey protected void setUp() throws Exception { 3717bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey super.setUp(); 3817bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey sOriginalClock = RecurrenceRule.sClock; 3917bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey } 4017bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey 4117bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey @Override 4217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey protected void tearDown() throws Exception { 4317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey super.tearDown(); 4417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey RecurrenceRule.sClock = sOriginalClock; 4517bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey } 4617bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey 4717bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey private void setClock(Instant instant) { 4817bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey RecurrenceRule.sClock = Clock.fixed(instant, ZoneId.systemDefault()); 4917bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey } 5017bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey 5117bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey public void testSimpleMonth() throws Exception { 5217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey setClock(Instant.parse("2015-11-20T10:15:30.00Z")); 5317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey final RecurrenceRule r = new RecurrenceRule( 5417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey ZonedDateTime.parse("2010-11-14T00:00:00.000Z"), 5517bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey null, 5617bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey Period.ofMonths(1)); 5717bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey 5817bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey assertTrue(r.isMonthly()); 5917bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey 600fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey final Iterator<Range<ZonedDateTime>> it = r.cycleIterator(); 6117bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey assertTrue(it.hasNext()); 620fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey assertEquals(new Range<>( 6317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey ZonedDateTime.parse("2015-11-14T00:00:00.00Z"), 6417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey ZonedDateTime.parse("2015-12-14T00:00:00.00Z")), it.next()); 6517bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey assertTrue(it.hasNext()); 660fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey assertEquals(new Range<>( 6717bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey ZonedDateTime.parse("2015-10-14T00:00:00.00Z"), 6817bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey ZonedDateTime.parse("2015-11-14T00:00:00.00Z")), it.next()); 6917bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey } 7017bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey 7117bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey public void testSimpleDays() throws Exception { 7217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey setClock(Instant.parse("2015-01-01T10:15:30.00Z")); 7317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey final RecurrenceRule r = new RecurrenceRule( 7417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey ZonedDateTime.parse("2010-11-14T00:11:00.000Z"), 7517bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey ZonedDateTime.parse("2010-11-20T00:11:00.000Z"), 7617bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey Period.ofDays(3)); 7717bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey 7817bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey assertFalse(r.isMonthly()); 7917bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey 800fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey final Iterator<Range<ZonedDateTime>> it = r.cycleIterator(); 8117bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey assertTrue(it.hasNext()); 820fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey assertEquals(new Range<>( 8317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey ZonedDateTime.parse("2010-11-17T00:11:00.00Z"), 8417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey ZonedDateTime.parse("2010-11-20T00:11:00.00Z")), it.next()); 8517bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey assertTrue(it.hasNext()); 860fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey assertEquals(new Range<>( 8717bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey ZonedDateTime.parse("2010-11-14T00:11:00.00Z"), 8817bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey ZonedDateTime.parse("2010-11-17T00:11:00.00Z")), it.next()); 8917bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey assertFalse(it.hasNext()); 9017bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey } 9117bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey 9217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey public void testNotRecurring() throws Exception { 9317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey setClock(Instant.parse("2015-01-01T10:15:30.00Z")); 9417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey final RecurrenceRule r = new RecurrenceRule( 9517bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey ZonedDateTime.parse("2010-11-14T00:11:00.000Z"), 9617bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey ZonedDateTime.parse("2010-11-20T00:11:00.000Z"), 9717bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey null); 9817bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey 9917bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey assertFalse(r.isMonthly()); 10017bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey 1010fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey final Iterator<Range<ZonedDateTime>> it = r.cycleIterator(); 10217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey assertTrue(it.hasNext()); 1030fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey assertEquals(new Range<>( 10417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey ZonedDateTime.parse("2010-11-14T00:11:00.000Z"), 10517bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey ZonedDateTime.parse("2010-11-20T00:11:00.000Z")), it.next()); 10617bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey assertFalse(it.hasNext()); 10717bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey } 10817bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey 10917bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey public void testNever() throws Exception { 11017bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey setClock(Instant.parse("2015-01-01T10:15:30.00Z")); 11117bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey final RecurrenceRule r = RecurrenceRule.buildNever(); 11217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey 11317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey assertFalse(r.isMonthly()); 11417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey 1150fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey final Iterator<Range<ZonedDateTime>> it = r.cycleIterator(); 11617bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey assertFalse(it.hasNext()); 11717bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey } 11817bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey 11917bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey public void testSane() throws Exception { 12017bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey final RecurrenceRule r = new RecurrenceRule( 12117bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey ZonedDateTime.parse("1980-01-31T00:00:00.000Z"), 12217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey ZonedDateTime.parse("2030-01-31T00:00:00.000Z"), 12317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey Period.ofMonths(1)); 12417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey 1250fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey final Iterator<Range<ZonedDateTime>> it = r.cycleIterator(); 12617bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey ZonedDateTime lastStart = null; 12717bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey int months = 0; 12817bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey while (it.hasNext()) { 1290fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey final Range<ZonedDateTime> cycle = it.next(); 13017bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey 13117bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey // Make sure cycle has reasonable length 1320fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey final long length = cycle.getUpper().toEpochSecond() - cycle.getLower().toEpochSecond(); 13317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey assertTrue(cycle + " must be more than 4 weeks", length >= 2419200); 13417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey assertTrue(cycle + " must be less than 5 weeks", length <= 3024000); 13517bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey 13617bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey // Make sure we have no gaps 13717bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey if (lastStart != null) { 1380fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey assertEquals(lastStart, cycle.getUpper()); 13917bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey } 1400fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey lastStart = cycle.getLower(); 14117bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey months++; 14217bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey } 14317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey 14417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey assertEquals(600, months); 14517bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey } 14617bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey} 147