1   /*
2    * Copyright (C) 2006  Tom Gibara
3    *
4    * This library is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU Lesser General Public
6    * License as published by the Free Software Foundation; either
7    * version 2.1 of the License, or (at your option) any later version.
8    *
9    * This library is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12   * Lesser General Public License for more details.
13   *
14   * You should have received a copy of the GNU Lesser General Public
15   * License along with this library; if not, write to the Free Software
16   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17   */
18  package com.tomgibara.pronto.util;
19  
20  import junit.framework.TestCase;
21  
22  public class DurationTest extends TestCase {
23  
24      public void testUnitParsing() {
25          testUnitParsing("1ms", 1L);
26          testUnitParsing("1milli", 1L);
27          testUnitParsing("1millis", 1L);
28          testUnitParsing("1millisecond", 1L);
29          testUnitParsing("1milliseconds", 1L);
30          testUnitParsing("1s", 1000L);
31          testUnitParsing("1sec", 1000L);
32          testUnitParsing("1secs", 1000L);
33          testUnitParsing("1second", 1000L);
34          testUnitParsing("1seconds", 1000L);
35          testUnitParsing("1m", 60 * 1000L);
36          testUnitParsing("1min", 60 * 1000L);
37          testUnitParsing("1mins", 60 * 1000L);
38          testUnitParsing("1minute", 60 * 1000L);
39          testUnitParsing("1minutes", 60 * 1000L);
40          testUnitParsing("1h", 60 * 60 * 1000L);
41          testUnitParsing("1hr", 60 * 60 * 1000L);
42          testUnitParsing("1hrs", 60 * 60 * 1000L);
43          testUnitParsing("1hour", 60 * 60 * 1000L);
44          testUnitParsing("1hours", 60 * 60 * 1000L);
45          testUnitParsing("1d", 24 * 60 * 60 * 1000L);
46          testUnitParsing("1day", 24 * 60 * 60 * 1000L);
47          testUnitParsing("1days", 24 * 60 * 60 * 1000L);
48      }
49  
50      public void testEmptyString() {
51          testUnitParsing("", 0L);
52      }
53  
54      public void testEquality() {
55          assertEquals(new Duration("1hr"), new Duration("1hr"));
56          assertEquals(new Duration("1minute"), new Duration("60seconds"));
57          assertEquals(new Duration("1s"), new Duration(1000L));
58      }
59  
60      public void testNegativeString() {
61          testBadString("-1ms", "Allowed negative millis");
62      }
63  
64      public void testNegativeTime() {
65          try {
66              new Duration(-1L);
67              fail("Allowed negative time");
68          } catch (IllegalArgumentException e) {
69              /* expected behaviour */
70          }
71      }
72  
73      public void testSpaces() {
74          testSpaces("1day 1min");
75          testSpaces("1day 1hr       1min");
76          testSpaces("    1s    ");
77      }
78  
79      public void testNoSpaces() {
80          testBadString("1 min", "Allowed space between number and unit");
81      }
82  
83      public void testOutOfOrder() {
84          String message = "Allowed out of order units";
85          testBadString("1h1d", message);
86          testBadString("1m1h", message);
87          testBadString("1s1m", message);
88          testBadString("1ms1s", message);
89      }
90  
91      public void testPlurals() {
92          assertFalse(isPlural(1 * 1L));
93          assertTrue(isPlural(2 * 1L));
94          assertFalse(isPlural(1 * 1000L));
95          assertTrue(isPlural(2 * 1000L));
96          assertFalse(isPlural(1 * 60 * 1000L));
97          assertTrue(isPlural(2 * 60 * 1000L));
98          assertFalse(isPlural(1 * 60 * 60 * 1000L));
99          assertTrue(isPlural(2 * 60 * 60 * 1000L));
100         assertFalse(isPlural(1 * 24 * 60 * 60 * 1000L));
101         assertTrue(isPlural(2 * 24 * 60 * 60 * 1000L));
102     }
103 
104     public void testEquivalence() {
105         for (int i = 1; i < 80; i++) {
106             long f = fib(i);
107             String str = new Duration(f).toString();
108             long g = new Duration(str).getTime();
109             assertEquals(f, g);
110         }
111     }
112 
113     private void testBadString(String str, String message) {
114         try {
115             new Duration(str);
116             fail(message);
117         } catch (IllegalArgumentException e) {
118             /* expected behaviour */
119         }
120     }
121 
122     private void testUnitParsing(String str, long ms) {
123         assertEquals(ms, new Duration(str).getTime());
124     }
125 
126     private void testSpaces(String str) {
127         Duration d1 = new Duration(str);
128         Duration d2 = new Duration(str.replaceAll("\\s", ""));
129         assertEquals(d1, d2);
130     }
131 
132     private boolean isPlural(long ms) {
133         String str = new Duration(ms).toString();
134         return 's' == str.charAt(str.length() - 1);
135     }
136 
137     private long fib(int i) {
138         return fib(1, 1, i - 1);
139     }
140 
141     private long fib(final long fa, final long fb, final int i) {
142         if (i == 0) return fa;
143         if (i == 1) return fb;
144         return fib(fb, fa + fb, i - 1);
145     }
146 }