View Javadoc
1   /*
2    * Copyright (C) 2011 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5    * in compliance with the License. You may obtain a copy of the License at
6    *
7    * http://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software distributed under the
10   * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11   * express or implied. See the License for the specific language governing permissions and
12   * limitations under the License.
13   */
14  
15  package com.google.common.primitives;
16  
17  import com.google.common.annotations.GwtCompatible;
18  import com.google.common.annotations.GwtIncompatible;
19  import com.google.common.collect.testing.Helpers;
20  import com.google.common.testing.NullPointerTester;
21  
22  import junit.framework.TestCase;
23  
24  import java.util.Arrays;
25  import java.util.Comparator;
26  import java.util.List;
27  import java.util.Random;
28  
29  /**
30   * Tests for UnsignedInts
31   *
32   * @author Louis Wasserman
33   */
34  @GwtCompatible(emulated = true)
35  public class UnsignedIntsTest extends TestCase {
36    private static final long[] UNSIGNED_INTS = {
37        0L,
38        1L,
39        2L,
40        3L,
41        0x12345678L,
42        0x5a4316b8L,
43        0x6cf78a4bL,
44        0xff1a618bL,
45        0xfffffffdL,
46        0xfffffffeL,
47        0xffffffffL};
48    
49    private static final int LEAST = (int) 0L;
50    private static final int GREATEST = (int) 0xffffffffL;
51  
52    public void testToLong() {
53      for (long a : UNSIGNED_INTS) {
54        assertEquals(a, UnsignedInts.toLong((int) a));
55      }
56    }
57  
58    public void testCompare() {
59      for (long a : UNSIGNED_INTS) {
60        for (long b : UNSIGNED_INTS) {
61          int cmpAsLongs = Longs.compare(a, b);
62          int cmpAsUInt = UnsignedInts.compare((int) a, (int) b);
63          assertEquals(Integer.signum(cmpAsLongs), Integer.signum(cmpAsUInt));
64        }
65      }
66    }
67    
68    public void testMax_noArgs() {
69      try {
70        UnsignedInts.max();
71        fail();
72      } catch (IllegalArgumentException expected) {
73      }
74    }
75    
76    public void testMax() {
77      assertEquals(LEAST, UnsignedInts.max(LEAST));
78      assertEquals(GREATEST, UnsignedInts.max(GREATEST));
79      assertEquals((int) 0xff1a618bL, UnsignedInts.max(
80          (int) 8L, (int) 6L, (int) 7L,
81          (int) 0x12345678L, (int) 0x5a4316b8L,
82          (int) 0xff1a618bL, (int) 0L));
83    }
84    
85    public void testMin_noArgs() {
86      try {
87        UnsignedInts.min();
88        fail();
89      } catch (IllegalArgumentException expected) {
90      }
91    }
92    
93    public void testMin() {
94      assertEquals(LEAST, UnsignedInts.min(LEAST));
95      assertEquals(GREATEST, UnsignedInts.min(GREATEST));
96      assertEquals((int) 0L, UnsignedInts.min(
97          (int) 8L, (int) 6L, (int) 7L,
98          (int) 0x12345678L, (int) 0x5a4316b8L,
99          (int) 0xff1a618bL, (int) 0L));
100   }
101   
102   public void testLexicographicalComparator() {
103     List<int[]> ordered = Arrays.asList(
104         new int[] {},
105         new int[] {LEAST},
106         new int[] {LEAST, LEAST},
107         new int[] {LEAST, (int) 1L},
108         new int[] {(int) 1L},
109         new int[] {(int) 1L, LEAST},
110         new int[] {GREATEST, (GREATEST - (int) 1L)},
111         new int[] {GREATEST, GREATEST},
112         new int[] {GREATEST, GREATEST, GREATEST}
113         );
114 
115     Comparator<int[]> comparator = UnsignedInts.lexicographicalComparator();
116     Helpers.testComparator(comparator, ordered);
117   }
118 
119   public void testDivide() {
120     for (long a : UNSIGNED_INTS) {
121       for (long b : UNSIGNED_INTS) {
122         try {
123           assertEquals((int) (a / b), UnsignedInts.divide((int) a, (int) b));
124           assertFalse(b == 0);
125         } catch (ArithmeticException e) {
126           assertEquals(0, b);
127         }
128       }
129     }
130   }
131 
132   public void testRemainder() {
133     for (long a : UNSIGNED_INTS) {
134       for (long b : UNSIGNED_INTS) {
135         try {
136           assertEquals((int) (a % b), UnsignedInts.remainder((int) a, (int) b));
137           assertFalse(b == 0);
138         } catch (ArithmeticException e) {
139           assertEquals(0, b);
140         }
141       }
142     }
143   }
144 
145   @GwtIncompatible("Too slow in GWT (~3min fully optimized)")
146   public void testDivideRemainderEuclideanProperty() {
147     // Use a seed so that the test is deterministic:
148     Random r = new Random(0L);
149     for (int i = 0; i < 1000000; i++) {
150       int dividend = r.nextInt();
151       int divisor = r.nextInt();
152       // Test that the Euclidean property is preserved:
153       assertTrue(dividend
154           - (divisor * UnsignedInts.divide(dividend, divisor) + UnsignedInts.remainder(dividend,
155               divisor)) == 0);
156     }
157   }
158 
159   public void testParseInt() {
160     try {
161       for (long a : UNSIGNED_INTS) {
162         assertEquals((int) a, UnsignedInts.parseUnsignedInt(Long.toString(a)));
163       }
164     } catch (NumberFormatException e) {
165       fail(e.getMessage());
166     }
167 
168     try {
169       UnsignedInts.parseUnsignedInt(Long.toString(1L << 32));
170       fail("Expected NumberFormatException");
171     } catch (NumberFormatException expected) {}
172   }
173 
174   public void testParseIntWithRadix() throws NumberFormatException {
175     for (long a : UNSIGNED_INTS) {
176       for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
177         assertEquals((int) a, UnsignedInts.parseUnsignedInt(Long.toString(a, radix), radix));
178       }
179     }
180 
181     // loops through all legal radix values.
182     for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
183       // tests can successfully parse a number string with this radix.
184       String maxAsString = Long.toString((1L << 32) - 1, radix);
185       assertEquals(-1, UnsignedInts.parseUnsignedInt(maxAsString, radix));
186 
187       try {
188         // tests that we get exception whre an overflow would occur.
189         long overflow = 1L << 32;
190         String overflowAsString = Long.toString(overflow, radix);
191         UnsignedInts.parseUnsignedInt(overflowAsString, radix);
192         fail();
193       } catch (NumberFormatException expected) {}
194     }
195   }
196 
197   public void testParseIntThrowsExceptionForInvalidRadix() {
198     // Valid radix values are Character.MIN_RADIX to Character.MAX_RADIX,
199     // inclusive.
200     try {
201       UnsignedInts.parseUnsignedInt("0", Character.MIN_RADIX - 1);
202       fail();
203     } catch (NumberFormatException expected) {}
204 
205     try {
206       UnsignedInts.parseUnsignedInt("0", Character.MAX_RADIX + 1);
207       fail();
208     } catch (NumberFormatException expected) {}
209 
210     // The radix is used as an array index, so try a negative value.
211     try {
212       UnsignedInts.parseUnsignedInt("0", -1);
213       fail();
214     } catch (NumberFormatException expected) {}
215   }
216 
217   public void testDecodeInt() {
218     assertEquals(0xffffffff, UnsignedInts.decode("0xffffffff"));
219     assertEquals(01234567, UnsignedInts.decode("01234567")); // octal
220     assertEquals(0x12345678, UnsignedInts.decode("#12345678"));
221     assertEquals(76543210, UnsignedInts.decode("76543210"));
222     assertEquals(0x13579135, UnsignedInts.decode("0x13579135"));
223     assertEquals(0x13579135, UnsignedInts.decode("0X13579135"));
224     assertEquals(0, UnsignedInts.decode("0"));
225   }
226 
227   public void testDecodeIntFails() {
228     try {
229       // One more than maximum value
230       UnsignedInts.decode("0xfffffffff");
231       fail();
232     } catch (NumberFormatException expected) {
233     }
234 
235     try {
236       UnsignedInts.decode("-5");
237       fail();
238     } catch (NumberFormatException expected) {
239     }
240 
241     try {
242       UnsignedInts.decode("-0x5");
243       fail();
244     } catch (NumberFormatException expected) {
245     }
246 
247     try {
248       UnsignedInts.decode("-05");
249       fail();
250     } catch (NumberFormatException expected) {
251     }
252   }
253 
254   public void testToString() {
255     int[] bases = {2, 5, 7, 8, 10, 16};
256     for (long a : UNSIGNED_INTS) {
257       for (int base : bases) {
258         assertEquals(UnsignedInts.toString((int) a, base), Long.toString(a, base));
259       }
260     }
261   }
262 
263   public void testJoin() {
264     assertEquals("", join());
265     assertEquals("1", join(1));
266     assertEquals("1,2", join(1, 2));
267     assertEquals("4294967295,2147483648", join(-1, Integer.MIN_VALUE));
268 
269     assertEquals("123", UnsignedInts.join("", 1, 2, 3));
270   }
271 
272   private static String join(int... values) {
273     return UnsignedInts.join(",", values);
274   }
275 
276   @GwtIncompatible("NullPointerTester")
277   public void testNulls() {
278     new NullPointerTester().testAllPublicStaticMethods(UnsignedInts.class);
279   }
280 }