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 static com.google.common.truth.Truth.assertThat; 18 19 import com.google.common.annotations.GwtCompatible; 20 import com.google.common.annotations.GwtIncompatible; 21 import com.google.common.collect.testing.Helpers; 22 import com.google.common.testing.NullPointerTester; 23 import java.util.Arrays; 24 import java.util.Comparator; 25 import java.util.List; 26 import java.util.Random; 27 import junit.framework.TestCase; 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 50 private static final int LEAST = (int) 0L; 51 private static final int GREATEST = (int) 0xffffffffL; 52 testCheckedCast()53 public void testCheckedCast() { 54 for (long value : UNSIGNED_INTS) { 55 assertEquals(value, UnsignedInts.toLong(UnsignedInts.checkedCast(value))); 56 } 57 assertCastFails(1L << 32); 58 assertCastFails(-1L); 59 assertCastFails(Long.MAX_VALUE); 60 assertCastFails(Long.MIN_VALUE); 61 } 62 assertCastFails(long value)63 private static void assertCastFails(long value) { 64 try { 65 UnsignedInts.checkedCast(value); 66 fail("Cast to int should have failed: " + value); 67 } catch (IllegalArgumentException ex) { 68 assertThat(ex.getMessage()).contains(String.valueOf(value)); 69 } 70 } 71 testSaturatedCast()72 public void testSaturatedCast() { 73 for (long value : UNSIGNED_INTS) { 74 assertEquals(value, UnsignedInts.toLong(UnsignedInts.saturatedCast(value))); 75 } 76 assertEquals(GREATEST, UnsignedInts.saturatedCast(1L << 32)); 77 assertEquals(LEAST, UnsignedInts.saturatedCast(-1L)); 78 assertEquals(GREATEST, UnsignedInts.saturatedCast(Long.MAX_VALUE)); 79 assertEquals(LEAST, UnsignedInts.saturatedCast(Long.MIN_VALUE)); 80 } 81 testToLong()82 public void testToLong() { 83 for (long a : UNSIGNED_INTS) { 84 assertEquals(a, UnsignedInts.toLong((int) a)); 85 } 86 } 87 testCompare()88 public void testCompare() { 89 for (long a : UNSIGNED_INTS) { 90 for (long b : UNSIGNED_INTS) { 91 int cmpAsLongs = Longs.compare(a, b); 92 int cmpAsUInt = UnsignedInts.compare((int) a, (int) b); 93 assertEquals(Integer.signum(cmpAsLongs), Integer.signum(cmpAsUInt)); 94 } 95 } 96 } 97 testMax_noArgs()98 public void testMax_noArgs() { 99 try { 100 UnsignedInts.max(); 101 fail(); 102 } catch (IllegalArgumentException expected) { 103 } 104 } 105 testMax()106 public void testMax() { 107 assertEquals(LEAST, UnsignedInts.max(LEAST)); 108 assertEquals(GREATEST, UnsignedInts.max(GREATEST)); 109 assertEquals( 110 (int) 0xff1a618bL, 111 UnsignedInts.max( 112 (int) 8L, 113 (int) 6L, 114 (int) 7L, 115 (int) 0x12345678L, 116 (int) 0x5a4316b8L, 117 (int) 0xff1a618bL, 118 (int) 0L)); 119 } 120 testMin_noArgs()121 public void testMin_noArgs() { 122 try { 123 UnsignedInts.min(); 124 fail(); 125 } catch (IllegalArgumentException expected) { 126 } 127 } 128 testMin()129 public void testMin() { 130 assertEquals(LEAST, UnsignedInts.min(LEAST)); 131 assertEquals(GREATEST, UnsignedInts.min(GREATEST)); 132 assertEquals( 133 (int) 0L, 134 UnsignedInts.min( 135 (int) 8L, 136 (int) 6L, 137 (int) 7L, 138 (int) 0x12345678L, 139 (int) 0x5a4316b8L, 140 (int) 0xff1a618bL, 141 (int) 0L)); 142 } 143 testLexicographicalComparator()144 public void testLexicographicalComparator() { 145 List<int[]> ordered = 146 Arrays.asList( 147 new int[] {}, 148 new int[] {LEAST}, 149 new int[] {LEAST, LEAST}, 150 new int[] {LEAST, (int) 1L}, 151 new int[] {(int) 1L}, 152 new int[] {(int) 1L, LEAST}, 153 new int[] {GREATEST, (GREATEST - (int) 1L)}, 154 new int[] {GREATEST, GREATEST}, 155 new int[] {GREATEST, GREATEST, GREATEST}); 156 157 Comparator<int[]> comparator = UnsignedInts.lexicographicalComparator(); 158 Helpers.testComparator(comparator, ordered); 159 } 160 testSort()161 public void testSort() { 162 testSort(new int[] {}, new int[] {}); 163 testSort(new int[] {2}, new int[] {2}); 164 testSort(new int[] {2, 1, 0}, new int[] {0, 1, 2}); 165 testSort(new int[] {2, GREATEST, 1, LEAST}, new int[] {LEAST, 1, 2, GREATEST}); 166 } 167 testSort(int[] input, int[] expected)168 static void testSort(int[] input, int[] expected) { 169 input = Arrays.copyOf(input, input.length); 170 UnsignedInts.sort(input); 171 assertTrue(Arrays.equals(expected, input)); 172 } 173 testSort(int[] input, int from, int to, int[] expected)174 static void testSort(int[] input, int from, int to, int[] expected) { 175 input = Arrays.copyOf(input, input.length); 176 UnsignedInts.sort(input, from, to); 177 assertTrue(Arrays.equals(expected, input)); 178 } 179 testSortIndexed()180 public void testSortIndexed() { 181 testSort(new int[] {}, 0, 0, new int[] {}); 182 testSort(new int[] {2}, 0, 1, new int[] {2}); 183 testSort(new int[] {2, 1, 0}, 0, 2, new int[] {1, 2, 0}); 184 testSort(new int[] {2, GREATEST, 1, LEAST}, 1, 4, new int[] {2, LEAST, 1, GREATEST}); 185 } 186 testSortDescending()187 public void testSortDescending() { 188 testSortDescending(new int[] {}, new int[] {}); 189 testSortDescending(new int[] {1}, new int[] {1}); 190 testSortDescending(new int[] {1, 2}, new int[] {2, 1}); 191 testSortDescending(new int[] {1, 3, 1}, new int[] {3, 1, 1}); 192 testSortDescending( 193 new int[] {GREATEST - 1, 1, GREATEST - 2, 2}, new int[] {GREATEST - 1, GREATEST - 2, 2, 1}); 194 } 195 testSortDescending(int[] input, int[] expectedOutput)196 private static void testSortDescending(int[] input, int[] expectedOutput) { 197 input = Arrays.copyOf(input, input.length); 198 UnsignedInts.sortDescending(input); 199 assertTrue(Arrays.equals(expectedOutput, input)); 200 } 201 testSortDescending( int[] input, int fromIndex, int toIndex, int[] expectedOutput)202 private static void testSortDescending( 203 int[] input, int fromIndex, int toIndex, int[] expectedOutput) { 204 input = Arrays.copyOf(input, input.length); 205 UnsignedInts.sortDescending(input, fromIndex, toIndex); 206 assertTrue(Arrays.equals(expectedOutput, input)); 207 } 208 testSortDescendingIndexed()209 public void testSortDescendingIndexed() { 210 testSortDescending(new int[] {}, 0, 0, new int[] {}); 211 testSortDescending(new int[] {1}, 0, 1, new int[] {1}); 212 testSortDescending(new int[] {1, 2}, 0, 2, new int[] {2, 1}); 213 testSortDescending(new int[] {1, 3, 1}, 0, 2, new int[] {3, 1, 1}); 214 testSortDescending(new int[] {1, 3, 1}, 0, 1, new int[] {1, 3, 1}); 215 testSortDescending( 216 new int[] {GREATEST - 1, 1, GREATEST - 2, 2}, 217 1, 218 3, 219 new int[] {GREATEST - 1, GREATEST - 2, 1, 2}); 220 } 221 testDivide()222 public void testDivide() { 223 for (long a : UNSIGNED_INTS) { 224 for (long b : UNSIGNED_INTS) { 225 try { 226 assertEquals((int) (a / b), UnsignedInts.divide((int) a, (int) b)); 227 assertFalse(b == 0); 228 } catch (ArithmeticException e) { 229 assertEquals(0, b); 230 } 231 } 232 } 233 } 234 testRemainder()235 public void testRemainder() { 236 for (long a : UNSIGNED_INTS) { 237 for (long b : UNSIGNED_INTS) { 238 try { 239 assertEquals((int) (a % b), UnsignedInts.remainder((int) a, (int) b)); 240 assertFalse(b == 0); 241 } catch (ArithmeticException e) { 242 assertEquals(0, b); 243 } 244 } 245 } 246 } 247 248 @GwtIncompatible // Too slow in GWT (~3min fully optimized) testDivideRemainderEuclideanProperty()249 public void testDivideRemainderEuclideanProperty() { 250 // Use a seed so that the test is deterministic: 251 Random r = new Random(0L); 252 for (int i = 0; i < 1000000; i++) { 253 int dividend = r.nextInt(); 254 int divisor = r.nextInt(); 255 // Test that the Euclidean property is preserved: 256 assertTrue( 257 dividend 258 - (divisor * UnsignedInts.divide(dividend, divisor) 259 + UnsignedInts.remainder(dividend, divisor)) 260 == 0); 261 } 262 } 263 testParseInt()264 public void testParseInt() { 265 for (long a : UNSIGNED_INTS) { 266 assertEquals((int) a, UnsignedInts.parseUnsignedInt(Long.toString(a))); 267 } 268 } 269 testParseIntFail()270 public void testParseIntFail() { 271 try { 272 UnsignedInts.parseUnsignedInt(Long.toString(1L << 32)); 273 fail("Expected NumberFormatException"); 274 } catch (NumberFormatException expected) { 275 } 276 } 277 testParseIntWithRadix()278 public void testParseIntWithRadix() { 279 for (long a : UNSIGNED_INTS) { 280 for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) { 281 assertEquals((int) a, UnsignedInts.parseUnsignedInt(Long.toString(a, radix), radix)); 282 } 283 } 284 } 285 testParseIntWithRadixLimits()286 public void testParseIntWithRadixLimits() { 287 // loops through all legal radix values. 288 for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) { 289 // tests can successfully parse a number string with this radix. 290 String maxAsString = Long.toString((1L << 32) - 1, radix); 291 assertEquals(-1, UnsignedInts.parseUnsignedInt(maxAsString, radix)); 292 293 try { 294 // tests that we get exception whre an overflow would occur. 295 long overflow = 1L << 32; 296 String overflowAsString = Long.toString(overflow, radix); 297 UnsignedInts.parseUnsignedInt(overflowAsString, radix); 298 fail(); 299 } catch (NumberFormatException expected) { 300 } 301 } 302 } 303 testParseIntThrowsExceptionForInvalidRadix()304 public void testParseIntThrowsExceptionForInvalidRadix() { 305 // Valid radix values are Character.MIN_RADIX to Character.MAX_RADIX, 306 // inclusive. 307 try { 308 UnsignedInts.parseUnsignedInt("0", Character.MIN_RADIX - 1); 309 fail(); 310 } catch (NumberFormatException expected) { 311 } 312 313 try { 314 UnsignedInts.parseUnsignedInt("0", Character.MAX_RADIX + 1); 315 fail(); 316 } catch (NumberFormatException expected) { 317 } 318 319 // The radix is used as an array index, so try a negative value. 320 try { 321 UnsignedInts.parseUnsignedInt("0", -1); 322 fail(); 323 } catch (NumberFormatException expected) { 324 } 325 } 326 testDecodeInt()327 public void testDecodeInt() { 328 assertEquals(0xffffffff, UnsignedInts.decode("0xffffffff")); 329 assertEquals(01234567, UnsignedInts.decode("01234567")); // octal 330 assertEquals(0x12345678, UnsignedInts.decode("#12345678")); 331 assertEquals(76543210, UnsignedInts.decode("76543210")); 332 assertEquals(0x13579135, UnsignedInts.decode("0x13579135")); 333 assertEquals(0x13579135, UnsignedInts.decode("0X13579135")); 334 assertEquals(0, UnsignedInts.decode("0")); 335 } 336 testDecodeIntFails()337 public void testDecodeIntFails() { 338 try { 339 // One more than maximum value 340 UnsignedInts.decode("0xfffffffff"); 341 fail(); 342 } catch (NumberFormatException expected) { 343 } 344 345 try { 346 UnsignedInts.decode("-5"); 347 fail(); 348 } catch (NumberFormatException expected) { 349 } 350 351 try { 352 UnsignedInts.decode("-0x5"); 353 fail(); 354 } catch (NumberFormatException expected) { 355 } 356 357 try { 358 UnsignedInts.decode("-05"); 359 fail(); 360 } catch (NumberFormatException expected) { 361 } 362 } 363 testToString()364 public void testToString() { 365 int[] bases = {2, 5, 7, 8, 10, 16}; 366 for (long a : UNSIGNED_INTS) { 367 for (int base : bases) { 368 assertEquals(UnsignedInts.toString((int) a, base), Long.toString(a, base)); 369 } 370 } 371 } 372 testJoin()373 public void testJoin() { 374 assertEquals("", join()); 375 assertEquals("1", join(1)); 376 assertEquals("1,2", join(1, 2)); 377 assertEquals("4294967295,2147483648", join(-1, Integer.MIN_VALUE)); 378 379 assertEquals("123", UnsignedInts.join("", 1, 2, 3)); 380 } 381 join(int... values)382 private static String join(int... values) { 383 return UnsignedInts.join(",", values); 384 } 385 386 @GwtIncompatible // NullPointerTester testNulls()387 public void testNulls() { 388 new NullPointerTester().testAllPublicStaticMethods(UnsignedInts.class); 389 } 390 } 391