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 
testToLong()52   public void testToLong() {
53     for (long a : UNSIGNED_INTS) {
54       assertEquals(a, UnsignedInts.toLong((int) a));
55     }
56   }
57 
testCompare()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 
testMax_noArgs()68   public void testMax_noArgs() {
69     try {
70       UnsignedInts.max();
71       fail();
72     } catch (IllegalArgumentException expected) {
73     }
74   }
75 
testMax()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 
testMin_noArgs()85   public void testMin_noArgs() {
86     try {
87       UnsignedInts.min();
88       fail();
89     } catch (IllegalArgumentException expected) {
90     }
91   }
92 
testMin()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 
testLexicographicalComparator()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 
testDivide()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 
testRemainder()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)")
testDivideRemainderEuclideanProperty()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 
testParseInt()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 
testParseIntWithRadix()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 
testParseIntThrowsExceptionForInvalidRadix()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 
testDecodeInt()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 
testDecodeIntFails()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 
testToString()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 
testJoin()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 
join(int... values)272   private static String join(int... values) {
273     return UnsignedInts.join(",", values);
274   }
275 
276   @GwtIncompatible("NullPointerTester")
testNulls()277   public void testNulls() {
278     new NullPointerTester().testAllPublicStaticMethods(UnsignedInts.class);
279   }
280 }
281