• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.common.primitives;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 import static com.google.common.truth.Truth.assertWithMessage;
21 import static java.lang.Long.MAX_VALUE;
22 import static java.lang.Long.MIN_VALUE;
23 
24 import com.google.common.annotations.GwtCompatible;
25 import com.google.common.annotations.GwtIncompatible;
26 import com.google.common.annotations.J2ktIncompatible;
27 import com.google.common.base.Converter;
28 import com.google.common.collect.testing.Helpers;
29 import com.google.common.testing.NullPointerTester;
30 import com.google.common.testing.SerializableTester;
31 import java.math.BigInteger;
32 import java.util.Arrays;
33 import java.util.Collection;
34 import java.util.Collections;
35 import java.util.Comparator;
36 import java.util.List;
37 import java.util.Random;
38 import junit.framework.TestCase;
39 import org.checkerframework.checker.nullness.qual.Nullable;
40 
41 /**
42  * Unit test for {@link Longs}.
43  *
44  * @author Kevin Bourrillion
45  */
46 @ElementTypesAreNonnullByDefault
47 @GwtCompatible(emulated = true)
48 @SuppressWarnings("cast") // redundant casts are intentional and harmless
49 public class LongsTest extends TestCase {
50   private static final long[] EMPTY = {};
51   private static final long[] ARRAY1 = {(long) 1};
52   private static final long[] ARRAY234 = {(long) 2, (long) 3, (long) 4};
53 
54   private static final long[] VALUES = {MIN_VALUE, (long) -1, (long) 0, (long) 1, MAX_VALUE};
55 
56   @J2ktIncompatible
57   @GwtIncompatible // Long.hashCode returns different values in GWT.
testHashCode()58   public void testHashCode() {
59     for (long value : VALUES) {
60       assertWithMessage("hashCode for " + value)
61           .that(Longs.hashCode(value))
62           .isEqualTo(((Long) value).hashCode());
63     }
64   }
65 
testCompare()66   public void testCompare() {
67     for (long x : VALUES) {
68       for (long y : VALUES) {
69         // note: spec requires only that the sign is the same
70         assertWithMessage(x + ", " + y)
71             .that(Longs.compare(x, y))
72             .isEqualTo(Long.valueOf(x).compareTo(y));
73       }
74     }
75   }
76 
testContains()77   public void testContains() {
78     assertThat(Longs.contains(EMPTY, (long) 1)).isFalse();
79     assertThat(Longs.contains(ARRAY1, (long) 2)).isFalse();
80     assertThat(Longs.contains(ARRAY234, (long) 1)).isFalse();
81     assertThat(Longs.contains(new long[] {(long) -1}, (long) -1)).isTrue();
82     assertThat(Longs.contains(ARRAY234, (long) 2)).isTrue();
83     assertThat(Longs.contains(ARRAY234, (long) 3)).isTrue();
84     assertThat(Longs.contains(ARRAY234, (long) 4)).isTrue();
85   }
86 
testIndexOf()87   public void testIndexOf() {
88     assertThat(Longs.indexOf(EMPTY, (long) 1)).isEqualTo(-1);
89     assertThat(Longs.indexOf(ARRAY1, (long) 2)).isEqualTo(-1);
90     assertThat(Longs.indexOf(ARRAY234, (long) 1)).isEqualTo(-1);
91     assertThat(Longs.indexOf(new long[] {(long) -1}, (long) -1)).isEqualTo(0);
92     assertThat(Longs.indexOf(ARRAY234, (long) 2)).isEqualTo(0);
93     assertThat(Longs.indexOf(ARRAY234, (long) 3)).isEqualTo(1);
94     assertThat(Longs.indexOf(ARRAY234, (long) 4)).isEqualTo(2);
95     assertThat(Longs.indexOf(new long[] {(long) 2, (long) 3, (long) 2, (long) 3}, (long) 3))
96         .isEqualTo(1);
97   }
98 
testIndexOf_arrayTarget()99   public void testIndexOf_arrayTarget() {
100     assertThat(Longs.indexOf(EMPTY, EMPTY)).isEqualTo(0);
101     assertThat(Longs.indexOf(ARRAY234, EMPTY)).isEqualTo(0);
102     assertThat(Longs.indexOf(EMPTY, ARRAY234)).isEqualTo(-1);
103     assertThat(Longs.indexOf(ARRAY234, ARRAY1)).isEqualTo(-1);
104     assertThat(Longs.indexOf(ARRAY1, ARRAY234)).isEqualTo(-1);
105     assertThat(Longs.indexOf(ARRAY1, ARRAY1)).isEqualTo(0);
106     assertThat(Longs.indexOf(ARRAY234, ARRAY234)).isEqualTo(0);
107     assertThat(Longs.indexOf(ARRAY234, new long[] {(long) 2, (long) 3})).isEqualTo(0);
108     assertThat(Longs.indexOf(ARRAY234, new long[] {(long) 3, (long) 4})).isEqualTo(1);
109     assertThat(Longs.indexOf(ARRAY234, new long[] {(long) 3})).isEqualTo(1);
110     assertThat(Longs.indexOf(ARRAY234, new long[] {(long) 4})).isEqualTo(2);
111     assertThat(
112             Longs.indexOf(
113                 new long[] {(long) 2, (long) 3, (long) 3, (long) 3, (long) 3},
114                 new long[] {(long) 3}))
115         .isEqualTo(1);
116     assertThat(
117             Longs.indexOf(
118                 new long[] {(long) 2, (long) 3, (long) 2, (long) 3, (long) 4, (long) 2, (long) 3},
119                 new long[] {(long) 2, (long) 3, (long) 4}))
120         .isEqualTo(2);
121     assertThat(
122             Longs.indexOf(
123                 new long[] {(long) 2, (long) 2, (long) 3, (long) 4, (long) 2, (long) 3, (long) 4},
124                 new long[] {(long) 2, (long) 3, (long) 4}))
125         .isEqualTo(1);
126     assertThat(
127             Longs.indexOf(
128                 new long[] {(long) 4, (long) 3, (long) 2},
129                 new long[] {(long) 2, (long) 3, (long) 4}))
130         .isEqualTo(-1);
131   }
132 
testLastIndexOf()133   public void testLastIndexOf() {
134     assertThat(Longs.lastIndexOf(EMPTY, (long) 1)).isEqualTo(-1);
135     assertThat(Longs.lastIndexOf(ARRAY1, (long) 2)).isEqualTo(-1);
136     assertThat(Longs.lastIndexOf(ARRAY234, (long) 1)).isEqualTo(-1);
137     assertThat(Longs.lastIndexOf(new long[] {(long) -1}, (long) -1)).isEqualTo(0);
138     assertThat(Longs.lastIndexOf(ARRAY234, (long) 2)).isEqualTo(0);
139     assertThat(Longs.lastIndexOf(ARRAY234, (long) 3)).isEqualTo(1);
140     assertThat(Longs.lastIndexOf(ARRAY234, (long) 4)).isEqualTo(2);
141     assertThat(Longs.lastIndexOf(new long[] {(long) 2, (long) 3, (long) 2, (long) 3}, (long) 3))
142         .isEqualTo(3);
143   }
144 
testMax_noArgs()145   public void testMax_noArgs() {
146     try {
147       Longs.max();
148       fail();
149     } catch (IllegalArgumentException expected) {
150     }
151   }
152 
testMax()153   public void testMax() {
154     assertThat(Longs.max(MIN_VALUE)).isEqualTo(MIN_VALUE);
155     assertThat(Longs.max(MAX_VALUE)).isEqualTo(MAX_VALUE);
156     assertThat(Longs.max((long) 8, (long) 6, (long) 7, (long) 5, (long) 3, (long) 0, (long) 9))
157         .isEqualTo((long) 9);
158   }
159 
testMin_noArgs()160   public void testMin_noArgs() {
161     try {
162       Longs.min();
163       fail();
164     } catch (IllegalArgumentException expected) {
165     }
166   }
167 
testMin()168   public void testMin() {
169     assertThat(Longs.min(MIN_VALUE)).isEqualTo(MIN_VALUE);
170     assertThat(Longs.min(MAX_VALUE)).isEqualTo(MAX_VALUE);
171     assertThat(Longs.min((long) 8, (long) 6, (long) 7, (long) 5, (long) 3, (long) 0, (long) 9))
172         .isEqualTo((long) 0);
173   }
174 
testConstrainToRange()175   public void testConstrainToRange() {
176     assertThat(Longs.constrainToRange((long) 1, (long) 0, (long) 5)).isEqualTo((long) 1);
177     assertThat(Longs.constrainToRange((long) 1, (long) 1, (long) 5)).isEqualTo((long) 1);
178     assertThat(Longs.constrainToRange((long) 1, (long) 3, (long) 5)).isEqualTo((long) 3);
179     assertThat(Longs.constrainToRange((long) 0, (long) -5, (long) -1)).isEqualTo((long) -1);
180     assertThat(Longs.constrainToRange((long) 5, (long) 2, (long) 2)).isEqualTo((long) 2);
181     try {
182       Longs.constrainToRange((long) 1, (long) 3, (long) 2);
183       fail();
184     } catch (IllegalArgumentException expected) {
185     }
186   }
187 
testConcat()188   public void testConcat() {
189     assertThat(Longs.concat()).isEqualTo(EMPTY);
190     assertThat(Longs.concat(EMPTY)).isEqualTo(EMPTY);
191     assertThat(Longs.concat(EMPTY, EMPTY, EMPTY)).isEqualTo(EMPTY);
192     assertThat(Longs.concat(ARRAY1)).isEqualTo(ARRAY1);
193     assertThat(Longs.concat(ARRAY1)).isNotSameInstanceAs(ARRAY1);
194     assertThat(Longs.concat(EMPTY, ARRAY1, EMPTY)).isEqualTo(ARRAY1);
195     assertThat(Longs.concat(ARRAY1, ARRAY1, ARRAY1))
196         .isEqualTo(new long[] {(long) 1, (long) 1, (long) 1});
197     assertThat(Longs.concat(ARRAY1, ARRAY234))
198         .isEqualTo(new long[] {(long) 1, (long) 2, (long) 3, (long) 4});
199   }
200 
201   @GwtIncompatible // different overflow behavior; could probably be made to work by using ~~
testConcat_overflow_negative()202   public void testConcat_overflow_negative() {
203     int dim1 = 1 << 16;
204     int dim2 = 1 << 15;
205     assertThat(dim1 * dim2).isLessThan(0);
206     testConcat_overflow(dim1, dim2);
207   }
208 
209   @GwtIncompatible // different overflow behavior; could probably be made to work by using ~~
testConcat_overflow_nonNegative()210   public void testConcat_overflow_nonNegative() {
211     int dim1 = 1 << 16;
212     int dim2 = 1 << 16;
213     assertThat(dim1 * dim2).isAtLeast(0);
214     testConcat_overflow(dim1, dim2);
215   }
216 
testConcat_overflow(int arraysDim1, int arraysDim2)217   private static void testConcat_overflow(int arraysDim1, int arraysDim2) {
218     assertThat((long) arraysDim1 * arraysDim2).isNotEqualTo((long) (arraysDim1 * arraysDim2));
219 
220     long[][] arrays = new long[arraysDim1][];
221     // it's shared to avoid using too much memory in tests
222     long[] sharedArray = new long[arraysDim2];
223     Arrays.fill(arrays, sharedArray);
224 
225     try {
226       Longs.concat(arrays);
227       fail();
228     } catch (IllegalArgumentException expected) {
229     }
230   }
231 
assertByteArrayEquals(byte[] expected, byte[] actual)232   private static void assertByteArrayEquals(byte[] expected, byte[] actual) {
233     assertWithMessage(
234             "Expected: " + Arrays.toString(expected) + ", but got: " + Arrays.toString(actual))
235         .that(Arrays.equals(expected, actual))
236         .isTrue();
237   }
238 
testToByteArray()239   public void testToByteArray() {
240     assertByteArrayEquals(
241         new byte[] {0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19},
242         Longs.toByteArray(0x1213141516171819L));
243     assertByteArrayEquals(
244         new byte[] {
245           (byte) 0xFF, (byte) 0xEE, (byte) 0xDD, (byte) 0xCC,
246           (byte) 0xBB, (byte) 0xAA, (byte) 0x99, (byte) 0x88
247         },
248         Longs.toByteArray(0xFFEEDDCCBBAA9988L));
249   }
250 
testFromByteArray()251   public void testFromByteArray() {
252     assertThat(
253             Longs.fromByteArray(new byte[] {0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x33}))
254         .isEqualTo(0x1213141516171819L);
255     assertThat(
256             Longs.fromByteArray(
257                 new byte[] {
258                   (byte) 0xFF, (byte) 0xEE, (byte) 0xDD, (byte) 0xCC,
259                   (byte) 0xBB, (byte) 0xAA, (byte) 0x99, (byte) 0x88
260                 }))
261         .isEqualTo(0xFFEEDDCCBBAA9988L);
262   }
263 
testFromByteArrayFails()264   public void testFromByteArrayFails() {
265     try {
266       Longs.fromByteArray(new byte[Longs.BYTES - 1]);
267       fail();
268     } catch (IllegalArgumentException expected) {
269     }
270   }
271 
testFromBytes()272   public void testFromBytes() {
273     assertThat(
274             Longs.fromBytes(
275                 (byte) 0x12,
276                 (byte) 0x13,
277                 (byte) 0x14,
278                 (byte) 0x15,
279                 (byte) 0x16,
280                 (byte) 0x17,
281                 (byte) 0x18,
282                 (byte) 0x19))
283         .isEqualTo(0x1213141516171819L);
284     assertThat(
285             Longs.fromBytes(
286                 (byte) 0xFF,
287                 (byte) 0xEE,
288                 (byte) 0xDD,
289                 (byte) 0xCC,
290                 (byte) 0xBB,
291                 (byte) 0xAA,
292                 (byte) 0x99,
293                 (byte) 0x88))
294         .isEqualTo(0xFFEEDDCCBBAA9988L);
295   }
296 
testByteArrayRoundTrips()297   public void testByteArrayRoundTrips() {
298     Random r = new Random(5);
299     byte[] b = new byte[Longs.BYTES];
300 
301     for (int i = 0; i < 1000; i++) {
302       long num = r.nextLong();
303       assertThat(Longs.fromByteArray(Longs.toByteArray(num))).isEqualTo(num);
304 
305       r.nextBytes(b);
306       long value = Longs.fromByteArray(b);
307       assertWithMessage("" + value).that(Arrays.equals(b, Longs.toByteArray(value))).isTrue();
308     }
309   }
310 
testEnsureCapacity()311   public void testEnsureCapacity() {
312     assertThat(Longs.ensureCapacity(EMPTY, 0, 1)).isSameInstanceAs(EMPTY);
313     assertThat(Longs.ensureCapacity(ARRAY1, 0, 1)).isSameInstanceAs(ARRAY1);
314     assertThat(Longs.ensureCapacity(ARRAY1, 1, 1)).isSameInstanceAs(ARRAY1);
315     assertThat(Longs.ensureCapacity(ARRAY1, 2, 1))
316         .isEqualTo(new long[] {(long) 1, (long) 0, (long) 0});
317   }
318 
testEnsureCapacity_fail()319   public void testEnsureCapacity_fail() {
320     try {
321       Longs.ensureCapacity(ARRAY1, -1, 1);
322       fail();
323     } catch (IllegalArgumentException expected) {
324     }
325     try {
326       // notice that this should even fail when no growth was needed
327       Longs.ensureCapacity(ARRAY1, 1, -1);
328       fail();
329     } catch (IllegalArgumentException expected) {
330     }
331   }
332 
testJoin()333   public void testJoin() {
334     assertThat(Longs.join(",", EMPTY)).isEmpty();
335     assertThat(Longs.join(",", ARRAY1)).isEqualTo("1");
336     assertThat(Longs.join(",", (long) 1, (long) 2)).isEqualTo("1,2");
337     assertThat(Longs.join("", (long) 1, (long) 2, (long) 3)).isEqualTo("123");
338   }
339 
testLexicographicalComparator()340   public void testLexicographicalComparator() {
341     List<long[]> ordered =
342         Arrays.asList(
343             new long[] {},
344             new long[] {MIN_VALUE},
345             new long[] {MIN_VALUE, MIN_VALUE},
346             new long[] {MIN_VALUE, (long) 1},
347             new long[] {(long) 1},
348             new long[] {(long) 1, MIN_VALUE},
349             new long[] {MAX_VALUE, MAX_VALUE - (long) 1},
350             new long[] {MAX_VALUE, MAX_VALUE},
351             new long[] {MAX_VALUE, MAX_VALUE, MAX_VALUE});
352 
353     Comparator<long[]> comparator = Longs.lexicographicalComparator();
354     Helpers.testComparator(comparator, ordered);
355   }
356 
357   @J2ktIncompatible
358   @GwtIncompatible // SerializableTester
testLexicographicalComparatorSerializable()359   public void testLexicographicalComparatorSerializable() {
360     Comparator<long[]> comparator = Longs.lexicographicalComparator();
361     assertThat(SerializableTester.reserialize(comparator)).isSameInstanceAs(comparator);
362   }
363 
testReverse()364   public void testReverse() {
365     testReverse(new long[] {}, new long[] {});
366     testReverse(new long[] {1}, new long[] {1});
367     testReverse(new long[] {1, 2}, new long[] {2, 1});
368     testReverse(new long[] {3, 1, 1}, new long[] {1, 1, 3});
369     testReverse(new long[] {-1, 1, -2, 2}, new long[] {2, -2, 1, -1});
370   }
371 
testReverse(long[] input, long[] expectedOutput)372   private static void testReverse(long[] input, long[] expectedOutput) {
373     input = Arrays.copyOf(input, input.length);
374     Longs.reverse(input);
375     assertThat(input).isEqualTo(expectedOutput);
376   }
377 
testReverse(long[] input, int fromIndex, int toIndex, long[] expectedOutput)378   private static void testReverse(long[] input, int fromIndex, int toIndex, long[] expectedOutput) {
379     input = Arrays.copyOf(input, input.length);
380     Longs.reverse(input, fromIndex, toIndex);
381     assertThat(input).isEqualTo(expectedOutput);
382   }
383 
testReverseIndexed()384   public void testReverseIndexed() {
385     testReverse(new long[] {}, 0, 0, new long[] {});
386     testReverse(new long[] {1}, 0, 1, new long[] {1});
387     testReverse(new long[] {1, 2}, 0, 2, new long[] {2, 1});
388     testReverse(new long[] {3, 1, 1}, 0, 2, new long[] {1, 3, 1});
389     testReverse(new long[] {3, 1, 1}, 0, 1, new long[] {3, 1, 1});
390     testReverse(new long[] {-1, 1, -2, 2}, 1, 3, new long[] {-1, -2, 1, 2});
391   }
392 
testRotate(long[] input, int distance, long[] expectedOutput)393   private static void testRotate(long[] input, int distance, long[] expectedOutput) {
394     input = Arrays.copyOf(input, input.length);
395     Longs.rotate(input, distance);
396     assertThat(input).isEqualTo(expectedOutput);
397   }
398 
testRotate( long[] input, int distance, int fromIndex, int toIndex, long[] expectedOutput)399   private static void testRotate(
400       long[] input, int distance, int fromIndex, int toIndex, long[] expectedOutput) {
401     input = Arrays.copyOf(input, input.length);
402     Longs.rotate(input, distance, fromIndex, toIndex);
403     assertThat(input).isEqualTo(expectedOutput);
404   }
405 
testRotate()406   public void testRotate() {
407     testRotate(new long[] {}, -1, new long[] {});
408     testRotate(new long[] {}, 0, new long[] {});
409     testRotate(new long[] {}, 1, new long[] {});
410 
411     testRotate(new long[] {1}, -2, new long[] {1});
412     testRotate(new long[] {1}, -1, new long[] {1});
413     testRotate(new long[] {1}, 0, new long[] {1});
414     testRotate(new long[] {1}, 1, new long[] {1});
415     testRotate(new long[] {1}, 2, new long[] {1});
416 
417     testRotate(new long[] {1, 2}, -3, new long[] {2, 1});
418     testRotate(new long[] {1, 2}, -1, new long[] {2, 1});
419     testRotate(new long[] {1, 2}, -2, new long[] {1, 2});
420     testRotate(new long[] {1, 2}, 0, new long[] {1, 2});
421     testRotate(new long[] {1, 2}, 1, new long[] {2, 1});
422     testRotate(new long[] {1, 2}, 2, new long[] {1, 2});
423     testRotate(new long[] {1, 2}, 3, new long[] {2, 1});
424 
425     testRotate(new long[] {1, 2, 3}, -5, new long[] {3, 1, 2});
426     testRotate(new long[] {1, 2, 3}, -4, new long[] {2, 3, 1});
427     testRotate(new long[] {1, 2, 3}, -3, new long[] {1, 2, 3});
428     testRotate(new long[] {1, 2, 3}, -2, new long[] {3, 1, 2});
429     testRotate(new long[] {1, 2, 3}, -1, new long[] {2, 3, 1});
430     testRotate(new long[] {1, 2, 3}, 0, new long[] {1, 2, 3});
431     testRotate(new long[] {1, 2, 3}, 1, new long[] {3, 1, 2});
432     testRotate(new long[] {1, 2, 3}, 2, new long[] {2, 3, 1});
433     testRotate(new long[] {1, 2, 3}, 3, new long[] {1, 2, 3});
434     testRotate(new long[] {1, 2, 3}, 4, new long[] {3, 1, 2});
435     testRotate(new long[] {1, 2, 3}, 5, new long[] {2, 3, 1});
436 
437     testRotate(new long[] {1, 2, 3, 4}, -9, new long[] {2, 3, 4, 1});
438     testRotate(new long[] {1, 2, 3, 4}, -5, new long[] {2, 3, 4, 1});
439     testRotate(new long[] {1, 2, 3, 4}, -1, new long[] {2, 3, 4, 1});
440     testRotate(new long[] {1, 2, 3, 4}, 0, new long[] {1, 2, 3, 4});
441     testRotate(new long[] {1, 2, 3, 4}, 1, new long[] {4, 1, 2, 3});
442     testRotate(new long[] {1, 2, 3, 4}, 5, new long[] {4, 1, 2, 3});
443     testRotate(new long[] {1, 2, 3, 4}, 9, new long[] {4, 1, 2, 3});
444 
445     testRotate(new long[] {1, 2, 3, 4, 5}, -6, new long[] {2, 3, 4, 5, 1});
446     testRotate(new long[] {1, 2, 3, 4, 5}, -4, new long[] {5, 1, 2, 3, 4});
447     testRotate(new long[] {1, 2, 3, 4, 5}, -3, new long[] {4, 5, 1, 2, 3});
448     testRotate(new long[] {1, 2, 3, 4, 5}, -1, new long[] {2, 3, 4, 5, 1});
449     testRotate(new long[] {1, 2, 3, 4, 5}, 0, new long[] {1, 2, 3, 4, 5});
450     testRotate(new long[] {1, 2, 3, 4, 5}, 1, new long[] {5, 1, 2, 3, 4});
451     testRotate(new long[] {1, 2, 3, 4, 5}, 3, new long[] {3, 4, 5, 1, 2});
452     testRotate(new long[] {1, 2, 3, 4, 5}, 4, new long[] {2, 3, 4, 5, 1});
453     testRotate(new long[] {1, 2, 3, 4, 5}, 6, new long[] {5, 1, 2, 3, 4});
454   }
455 
testRotateIndexed()456   public void testRotateIndexed() {
457     testRotate(new long[] {}, 0, 0, 0, new long[] {});
458 
459     testRotate(new long[] {1}, 0, 0, 1, new long[] {1});
460     testRotate(new long[] {1}, 1, 0, 1, new long[] {1});
461     testRotate(new long[] {1}, 1, 1, 1, new long[] {1});
462 
463     // Rotate the central 5 elements, leaving the ends as-is
464     testRotate(new long[] {0, 1, 2, 3, 4, 5, 6}, -6, 1, 6, new long[] {0, 2, 3, 4, 5, 1, 6});
465     testRotate(new long[] {0, 1, 2, 3, 4, 5, 6}, -1, 1, 6, new long[] {0, 2, 3, 4, 5, 1, 6});
466     testRotate(new long[] {0, 1, 2, 3, 4, 5, 6}, 0, 1, 6, new long[] {0, 1, 2, 3, 4, 5, 6});
467     testRotate(new long[] {0, 1, 2, 3, 4, 5, 6}, 5, 1, 6, new long[] {0, 1, 2, 3, 4, 5, 6});
468     testRotate(new long[] {0, 1, 2, 3, 4, 5, 6}, 14, 1, 6, new long[] {0, 2, 3, 4, 5, 1, 6});
469 
470     // Rotate the first three elements
471     testRotate(new long[] {0, 1, 2, 3, 4, 5, 6}, -2, 0, 3, new long[] {2, 0, 1, 3, 4, 5, 6});
472     testRotate(new long[] {0, 1, 2, 3, 4, 5, 6}, -1, 0, 3, new long[] {1, 2, 0, 3, 4, 5, 6});
473     testRotate(new long[] {0, 1, 2, 3, 4, 5, 6}, 0, 0, 3, new long[] {0, 1, 2, 3, 4, 5, 6});
474     testRotate(new long[] {0, 1, 2, 3, 4, 5, 6}, 1, 0, 3, new long[] {2, 0, 1, 3, 4, 5, 6});
475     testRotate(new long[] {0, 1, 2, 3, 4, 5, 6}, 2, 0, 3, new long[] {1, 2, 0, 3, 4, 5, 6});
476 
477     // Rotate the last four elements
478     testRotate(new long[] {0, 1, 2, 3, 4, 5, 6}, -6, 3, 7, new long[] {0, 1, 2, 5, 6, 3, 4});
479     testRotate(new long[] {0, 1, 2, 3, 4, 5, 6}, -5, 3, 7, new long[] {0, 1, 2, 4, 5, 6, 3});
480     testRotate(new long[] {0, 1, 2, 3, 4, 5, 6}, -4, 3, 7, new long[] {0, 1, 2, 3, 4, 5, 6});
481     testRotate(new long[] {0, 1, 2, 3, 4, 5, 6}, -3, 3, 7, new long[] {0, 1, 2, 6, 3, 4, 5});
482     testRotate(new long[] {0, 1, 2, 3, 4, 5, 6}, -2, 3, 7, new long[] {0, 1, 2, 5, 6, 3, 4});
483     testRotate(new long[] {0, 1, 2, 3, 4, 5, 6}, -1, 3, 7, new long[] {0, 1, 2, 4, 5, 6, 3});
484     testRotate(new long[] {0, 1, 2, 3, 4, 5, 6}, 0, 3, 7, new long[] {0, 1, 2, 3, 4, 5, 6});
485     testRotate(new long[] {0, 1, 2, 3, 4, 5, 6}, 1, 3, 7, new long[] {0, 1, 2, 6, 3, 4, 5});
486     testRotate(new long[] {0, 1, 2, 3, 4, 5, 6}, 2, 3, 7, new long[] {0, 1, 2, 5, 6, 3, 4});
487     testRotate(new long[] {0, 1, 2, 3, 4, 5, 6}, 3, 3, 7, new long[] {0, 1, 2, 4, 5, 6, 3});
488   }
489 
testSortDescending()490   public void testSortDescending() {
491     testSortDescending(new long[] {}, new long[] {});
492     testSortDescending(new long[] {1}, new long[] {1});
493     testSortDescending(new long[] {1, 2}, new long[] {2, 1});
494     testSortDescending(new long[] {1, 3, 1}, new long[] {3, 1, 1});
495     testSortDescending(new long[] {-1, 1, -2, 2}, new long[] {2, 1, -1, -2});
496   }
497 
testSortDescending(long[] input, long[] expectedOutput)498   private static void testSortDescending(long[] input, long[] expectedOutput) {
499     input = Arrays.copyOf(input, input.length);
500     Longs.sortDescending(input);
501     assertThat(input).isEqualTo(expectedOutput);
502   }
503 
testSortDescending( long[] input, int fromIndex, int toIndex, long[] expectedOutput)504   private static void testSortDescending(
505       long[] input, int fromIndex, int toIndex, long[] expectedOutput) {
506     input = Arrays.copyOf(input, input.length);
507     Longs.sortDescending(input, fromIndex, toIndex);
508     assertThat(input).isEqualTo(expectedOutput);
509   }
510 
testSortDescendingIndexed()511   public void testSortDescendingIndexed() {
512     testSortDescending(new long[] {}, 0, 0, new long[] {});
513     testSortDescending(new long[] {1}, 0, 1, new long[] {1});
514     testSortDescending(new long[] {1, 2}, 0, 2, new long[] {2, 1});
515     testSortDescending(new long[] {1, 3, 1}, 0, 2, new long[] {3, 1, 1});
516     testSortDescending(new long[] {1, 3, 1}, 0, 1, new long[] {1, 3, 1});
517     testSortDescending(new long[] {-1, -2, 1, 2}, 1, 3, new long[] {-1, 1, -2, 2});
518   }
519 
520   @J2ktIncompatible
521   @GwtIncompatible // SerializableTester
testStringConverterSerialization()522   public void testStringConverterSerialization() {
523     SerializableTester.reserializeAndAssert(Longs.stringConverter());
524   }
525 
testToArray()526   public void testToArray() {
527     // need explicit type parameter to avoid javac warning!?
528     List<Long> none = Arrays.<Long>asList();
529     assertThat(Longs.toArray(none)).isEqualTo(EMPTY);
530 
531     List<Long> one = Arrays.asList((long) 1);
532     assertThat(Longs.toArray(one)).isEqualTo(ARRAY1);
533 
534     long[] array = {(long) 0, (long) 1, 0x0FF1C1AL};
535 
536     List<Long> three = Arrays.asList((long) 0, (long) 1, 0x0FF1C1AL);
537     assertThat(Longs.toArray(three)).isEqualTo(array);
538 
539     assertThat(Longs.toArray(Longs.asList(array))).isEqualTo(array);
540   }
541 
testToArray_threadSafe()542   public void testToArray_threadSafe() {
543     for (int delta : new int[] {+1, 0, -1}) {
544       for (int i = 0; i < VALUES.length; i++) {
545         List<Long> list = Longs.asList(VALUES).subList(0, i);
546         Collection<Long> misleadingSize = Helpers.misleadingSizeCollection(delta);
547         misleadingSize.addAll(list);
548         long[] arr = Longs.toArray(misleadingSize);
549         assertThat(arr).hasLength(i);
550         for (int j = 0; j < i; j++) {
551           assertThat(arr[j]).isEqualTo(VALUES[j]);
552         }
553       }
554     }
555   }
556 
testToArray_withNull()557   public void testToArray_withNull() {
558     List<@Nullable Long> list = Arrays.asList((long) 0, (long) 1, null);
559     try {
560       Longs.toArray(list);
561       fail();
562     } catch (NullPointerException expected) {
563     }
564   }
565 
testToArray_withConversion()566   public void testToArray_withConversion() {
567     long[] array = {(long) 0, (long) 1, (long) 2};
568 
569     List<Byte> bytes = Arrays.asList((byte) 0, (byte) 1, (byte) 2);
570     List<Short> shorts = Arrays.asList((short) 0, (short) 1, (short) 2);
571     List<Integer> ints = Arrays.asList(0, 1, 2);
572     List<Float> floats = Arrays.asList((float) 0, (float) 1, (float) 2);
573     List<Long> longs = Arrays.asList((long) 0, (long) 1, (long) 2);
574     List<Double> doubles = Arrays.asList((double) 0, (double) 1, (double) 2);
575 
576     assertThat(Longs.toArray(bytes)).isEqualTo(array);
577     assertThat(Longs.toArray(shorts)).isEqualTo(array);
578     assertThat(Longs.toArray(ints)).isEqualTo(array);
579     assertThat(Longs.toArray(floats)).isEqualTo(array);
580     assertThat(Longs.toArray(longs)).isEqualTo(array);
581     assertThat(Longs.toArray(doubles)).isEqualTo(array);
582   }
583 
584   @J2ktIncompatible // b/285319375
testAsList_isAView()585   public void testAsList_isAView() {
586     long[] array = {(long) 0, (long) 1};
587     List<Long> list = Longs.asList(array);
588     list.set(0, (long) 2);
589     assertThat(array).isEqualTo(new long[] {(long) 2, (long) 1});
590     array[1] = (long) 3;
591     assertThat(list).containsExactly((long) 2, (long) 3).inOrder();
592   }
593 
testAsList_toArray_roundTrip()594   public void testAsList_toArray_roundTrip() {
595     long[] array = {(long) 0, (long) 1, (long) 2};
596     List<Long> list = Longs.asList(array);
597     long[] newArray = Longs.toArray(list);
598 
599     // Make sure it returned a copy
600     list.set(0, (long) 4);
601     assertThat(newArray).isEqualTo(new long[] {(long) 0, (long) 1, (long) 2});
602     newArray[1] = (long) 5;
603     assertThat((long) list.get(1)).isEqualTo((long) 1);
604   }
605 
606   // This test stems from a real bug found by andrewk
testAsList_subList_toArray_roundTrip()607   public void testAsList_subList_toArray_roundTrip() {
608     long[] array = {(long) 0, (long) 1, (long) 2, (long) 3};
609     List<Long> list = Longs.asList(array);
610     assertThat(Longs.toArray(list.subList(1, 3))).isEqualTo(new long[] {(long) 1, (long) 2});
611     assertThat(Longs.toArray(list.subList(2, 2))).isEqualTo(new long[] {});
612   }
613 
testAsListEmpty()614   public void testAsListEmpty() {
615     assertThat(Longs.asList(EMPTY)).isSameInstanceAs(Collections.emptyList());
616   }
617 
618   @J2ktIncompatible
619   @GwtIncompatible // NullPointerTester
testNulls()620   public void testNulls() {
621     new NullPointerTester().testAllPublicStaticMethods(Longs.class);
622   }
623 
testStringConverter_convert()624   public void testStringConverter_convert() {
625     Converter<String, Long> converter = Longs.stringConverter();
626     assertThat(converter.convert("1")).isEqualTo((Long) 1L);
627     assertThat(converter.convert("0")).isEqualTo((Long) 0L);
628     assertThat(converter.convert("-1")).isEqualTo((Long) (-1L));
629     assertThat(converter.convert("0xff")).isEqualTo((Long) 255L);
630     assertThat(converter.convert("0xFF")).isEqualTo((Long) 255L);
631     assertThat(converter.convert("-0xFF")).isEqualTo((Long) (-255L));
632     assertThat(converter.convert("#0000FF")).isEqualTo((Long) 255L);
633     assertThat(converter.convert("0666")).isEqualTo((Long) 438L);
634   }
635 
testStringConverter_convertError()636   public void testStringConverter_convertError() {
637     try {
638       Longs.stringConverter().convert("notanumber");
639       fail();
640     } catch (NumberFormatException expected) {
641     }
642   }
643 
testStringConverter_nullConversions()644   public void testStringConverter_nullConversions() {
645     assertThat(Longs.stringConverter().convert(null)).isNull();
646     assertThat(Longs.stringConverter().reverse().convert(null)).isNull();
647   }
648 
testStringConverter_reverse()649   public void testStringConverter_reverse() {
650     Converter<String, Long> converter = Longs.stringConverter();
651     assertThat(converter.reverse().convert(1L)).isEqualTo("1");
652     assertThat(converter.reverse().convert(0L)).isEqualTo("0");
653     assertThat(converter.reverse().convert(-1L)).isEqualTo("-1");
654     assertThat(converter.reverse().convert(0xffL)).isEqualTo("255");
655     assertThat(converter.reverse().convert(0xFFL)).isEqualTo("255");
656     assertThat(converter.reverse().convert(-0xFFL)).isEqualTo("-255");
657     assertThat(converter.reverse().convert(0666L)).isEqualTo("438");
658   }
659 
660   @J2ktIncompatible
661   @GwtIncompatible // NullPointerTester
testStringConverter_nullPointerTester()662   public void testStringConverter_nullPointerTester() throws Exception {
663     NullPointerTester tester = new NullPointerTester();
664     tester.testAllPublicInstanceMethods(Longs.stringConverter());
665   }
666 
testTryParse()667   public void testTryParse() {
668     tryParseAndAssertEquals(0L, "0");
669     tryParseAndAssertEquals(0L, "-0");
670     tryParseAndAssertEquals(1L, "1");
671     tryParseAndAssertEquals(-1L, "-1");
672     tryParseAndAssertEquals(8900L, "8900");
673     tryParseAndAssertEquals(-8900L, "-8900");
674     tryParseAndAssertEquals(MAX_VALUE, Long.toString(MAX_VALUE));
675     tryParseAndAssertEquals(MIN_VALUE, Long.toString(MIN_VALUE));
676     assertThat(Longs.tryParse("")).isNull();
677     assertThat(Longs.tryParse("-")).isNull();
678     assertThat(Longs.tryParse("+1")).isNull();
679     assertThat(Longs.tryParse("999999999999999999999999")).isNull();
680     assertWithMessage("Max long + 1")
681         .that(Longs.tryParse(BigInteger.valueOf(MAX_VALUE).add(BigInteger.ONE).toString()))
682         .isNull();
683     assertWithMessage("Max long * 10")
684         .that(Longs.tryParse(BigInteger.valueOf(MAX_VALUE).multiply(BigInteger.TEN).toString()))
685         .isNull();
686     assertWithMessage("Min long - 1")
687         .that(Longs.tryParse(BigInteger.valueOf(MIN_VALUE).subtract(BigInteger.ONE).toString()))
688         .isNull();
689     assertWithMessage("Min long * 10")
690         .that(Longs.tryParse(BigInteger.valueOf(MIN_VALUE).multiply(BigInteger.TEN).toString()))
691         .isNull();
692     assertThat(Longs.tryParse("\u0662\u06f3")).isNull();
693   }
694 
695   /**
696    * Applies {@link Longs#tryParse(String)} to the given string and asserts that the result is as
697    * expected.
698    */
tryParseAndAssertEquals(Long expected, String value)699   private static void tryParseAndAssertEquals(Long expected, String value) {
700     assertThat(Longs.tryParse(value)).isEqualTo(expected);
701   }
702 
testTryParse_radix()703   public void testTryParse_radix() {
704     for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
705       radixEncodeParseAndAssertEquals((long) 0, radix);
706       radixEncodeParseAndAssertEquals((long) 8000, radix);
707       radixEncodeParseAndAssertEquals((long) -8000, radix);
708       radixEncodeParseAndAssertEquals(MAX_VALUE, radix);
709       radixEncodeParseAndAssertEquals(MIN_VALUE, radix);
710       assertWithMessage("Radix: " + radix)
711           .that(Longs.tryParse("999999999999999999999999", radix))
712           .isNull();
713       assertWithMessage("Radix: " + radix)
714           .that(Longs.tryParse(BigInteger.valueOf(MAX_VALUE).add(BigInteger.ONE).toString(), radix))
715           .isNull();
716       assertWithMessage("Radix: " + radix)
717           .that(
718               Longs.tryParse(
719                   BigInteger.valueOf(MIN_VALUE).subtract(BigInteger.ONE).toString(), radix))
720           .isNull();
721     }
722     assertWithMessage("Hex string and dec parm").that(Longs.tryParse("FFFF", 10)).isNull();
723     assertWithMessage("Mixed hex case")
724         .that(Longs.tryParse("ffFF", 16).longValue())
725         .isEqualTo(65535);
726   }
727 
728   /**
729    * Encodes the long as a string with given radix, then uses {@link Longs#tryParse(String, int)} to
730    * parse the result. Asserts the result is the same as what we started with.
731    */
radixEncodeParseAndAssertEquals(Long value, int radix)732   private static void radixEncodeParseAndAssertEquals(Long value, int radix) {
733     assertWithMessage("Radix: " + radix)
734         .that(Longs.tryParse(Long.toString(value, radix), radix))
735         .isEqualTo(value);
736   }
737 
testTryParse_radixTooBig()738   public void testTryParse_radixTooBig() {
739     try {
740       Longs.tryParse("0", Character.MAX_RADIX + 1);
741       fail();
742     } catch (IllegalArgumentException expected) {
743     }
744   }
745 
testTryParse_radixTooSmall()746   public void testTryParse_radixTooSmall() {
747     try {
748       Longs.tryParse("0", Character.MIN_RADIX - 1);
749       fail();
750     } catch (IllegalArgumentException expected) {
751     }
752   }
753 
testTryParse_withNullGwt()754   public void testTryParse_withNullGwt() {
755     assertThat(Longs.tryParse("null")).isNull();
756     try {
757       Longs.tryParse(null);
758       fail("Expected NPE");
759     } catch (NullPointerException expected) {
760     }
761   }
762 }
763