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
17package com.google.common.primitives;
18
19import com.google.common.annotations.GwtCompatible;
20import com.google.common.annotations.GwtIncompatible;
21import com.google.common.collect.testing.Helpers;
22import com.google.common.testing.NullPointerTester;
23import com.google.common.testing.SerializableTester;
24
25import junit.framework.TestCase;
26
27import java.util.Arrays;
28import java.util.Collection;
29import java.util.Collections;
30import java.util.Comparator;
31import java.util.List;
32import java.util.Random;
33
34/**
35 * Unit test for {@link Shorts}.
36 *
37 * @author Kevin Bourrillion
38 */
39@GwtCompatible(emulated = true)
40@SuppressWarnings("cast") // redundant casts are intentional and harmless
41public class ShortsTest extends TestCase {
42  private static final short[] EMPTY = {};
43  private static final short[] ARRAY1 = {(short) 1};
44  private static final short[] ARRAY234
45      = {(short) 2, (short) 3, (short) 4};
46
47  private static final short LEAST = Short.MIN_VALUE;
48  private static final short GREATEST = Short.MAX_VALUE;
49
50  private static final short[] VALUES =
51      { LEAST, (short) -1, (short) 0, (short) 1, GREATEST };
52
53  public void testHashCode() {
54    for (short value : VALUES) {
55      assertEquals(((Short) value).hashCode(), Shorts.hashCode(value));
56    }
57  }
58
59  public void testCheckedCast() {
60    for (short value : VALUES) {
61      assertEquals(value, Shorts.checkedCast((long) value));
62    }
63    assertCastFails(GREATEST + 1L);
64    assertCastFails(LEAST - 1L);
65    assertCastFails(Long.MAX_VALUE);
66    assertCastFails(Long.MIN_VALUE);
67  }
68
69  public void testSaturatedCast() {
70    for (short value : VALUES) {
71      assertEquals(value, Shorts.saturatedCast((long) value));
72    }
73    assertEquals(GREATEST, Shorts.saturatedCast(GREATEST + 1L));
74    assertEquals(LEAST, Shorts.saturatedCast(LEAST - 1L));
75    assertEquals(GREATEST, Shorts.saturatedCast(Long.MAX_VALUE));
76    assertEquals(LEAST, Shorts.saturatedCast(Long.MIN_VALUE));
77  }
78
79  private void assertCastFails(long value) {
80    try {
81      Shorts.checkedCast(value);
82      fail("Cast to short should have failed: " + value);
83    } catch (IllegalArgumentException ex) {
84      assertTrue(value + " not found in exception text: " + ex.getMessage(),
85          ex.getMessage().contains(String.valueOf(value)));
86    }
87  }
88
89  public void testCompare() {
90    for (short x : VALUES) {
91      for (short y : VALUES) {
92        // Only compare the sign of the result of compareTo().
93        int expected = Short.valueOf(x).compareTo(y);
94        int actual = Shorts.compare(x, y);
95        if (expected == 0) {
96          assertEquals(x + ", " + y, expected, actual);
97        } else if (expected < 0) {
98          assertTrue(x + ", " + y + " (expected: " + expected + ", actual" + actual + ")",
99              actual < 0);
100        } else {
101          assertTrue(x + ", " + y + " (expected: " + expected + ", actual" + actual + ")",
102              actual > 0);
103        }
104      }
105    }
106  }
107
108  public void testContains() {
109    assertFalse(Shorts.contains(EMPTY, (short) 1));
110    assertFalse(Shorts.contains(ARRAY1, (short) 2));
111    assertFalse(Shorts.contains(ARRAY234, (short) 1));
112    assertTrue(Shorts.contains(new short[] {(short) -1}, (short) -1));
113    assertTrue(Shorts.contains(ARRAY234, (short) 2));
114    assertTrue(Shorts.contains(ARRAY234, (short) 3));
115    assertTrue(Shorts.contains(ARRAY234, (short) 4));
116  }
117
118  public void testIndexOf() {
119    assertEquals(-1, Shorts.indexOf(EMPTY, (short) 1));
120    assertEquals(-1, Shorts.indexOf(ARRAY1, (short) 2));
121    assertEquals(-1, Shorts.indexOf(ARRAY234, (short) 1));
122    assertEquals(0, Shorts.indexOf(
123        new short[] {(short) -1}, (short) -1));
124    assertEquals(0, Shorts.indexOf(ARRAY234, (short) 2));
125    assertEquals(1, Shorts.indexOf(ARRAY234, (short) 3));
126    assertEquals(2, Shorts.indexOf(ARRAY234, (short) 4));
127    assertEquals(1, Shorts.indexOf(
128        new short[] { (short) 2, (short) 3, (short) 2, (short) 3 },
129        (short) 3));
130  }
131
132  public void testIndexOf_arrayTarget() {
133    assertEquals(0, Shorts.indexOf(EMPTY, EMPTY));
134    assertEquals(0, Shorts.indexOf(ARRAY234, EMPTY));
135    assertEquals(-1, Shorts.indexOf(EMPTY, ARRAY234));
136    assertEquals(-1, Shorts.indexOf(ARRAY234, ARRAY1));
137    assertEquals(-1, Shorts.indexOf(ARRAY1, ARRAY234));
138    assertEquals(0, Shorts.indexOf(ARRAY1, ARRAY1));
139    assertEquals(0, Shorts.indexOf(ARRAY234, ARRAY234));
140    assertEquals(0, Shorts.indexOf(
141        ARRAY234, new short[] { (short) 2, (short) 3 }));
142    assertEquals(1, Shorts.indexOf(
143        ARRAY234, new short[] { (short) 3, (short) 4 }));
144    assertEquals(1, Shorts.indexOf(ARRAY234, new short[] { (short) 3 }));
145    assertEquals(2, Shorts.indexOf(ARRAY234, new short[] { (short) 4 }));
146    assertEquals(1, Shorts.indexOf(new short[] { (short) 2, (short) 3,
147        (short) 3, (short) 3, (short) 3 },
148        new short[] { (short) 3 }
149    ));
150    assertEquals(2, Shorts.indexOf(
151        new short[] { (short) 2, (short) 3, (short) 2,
152            (short) 3, (short) 4, (short) 2, (short) 3},
153        new short[] { (short) 2, (short) 3, (short) 4}
154    ));
155    assertEquals(1, Shorts.indexOf(
156        new short[] { (short) 2, (short) 2, (short) 3,
157            (short) 4, (short) 2, (short) 3, (short) 4},
158        new short[] { (short) 2, (short) 3, (short) 4}
159    ));
160    assertEquals(-1, Shorts.indexOf(
161        new short[] { (short) 4, (short) 3, (short) 2},
162        new short[] { (short) 2, (short) 3, (short) 4}
163    ));
164  }
165
166  public void testLastIndexOf() {
167    assertEquals(-1, Shorts.lastIndexOf(EMPTY, (short) 1));
168    assertEquals(-1, Shorts.lastIndexOf(ARRAY1, (short) 2));
169    assertEquals(-1, Shorts.lastIndexOf(ARRAY234, (short) 1));
170    assertEquals(0, Shorts.lastIndexOf(
171        new short[] {(short) -1}, (short) -1));
172    assertEquals(0, Shorts.lastIndexOf(ARRAY234, (short) 2));
173    assertEquals(1, Shorts.lastIndexOf(ARRAY234, (short) 3));
174    assertEquals(2, Shorts.lastIndexOf(ARRAY234, (short) 4));
175    assertEquals(3, Shorts.lastIndexOf(
176        new short[] { (short) 2, (short) 3, (short) 2, (short) 3 },
177        (short) 3));
178  }
179
180  public void testMax_noArgs() {
181    try {
182      Shorts.max();
183      fail();
184    } catch (IllegalArgumentException expected) {
185    }
186  }
187
188  public void testMax() {
189    assertEquals(LEAST, Shorts.max(LEAST));
190    assertEquals(GREATEST, Shorts.max(GREATEST));
191    assertEquals((short) 9, Shorts.max(
192        (short) 8, (short) 6, (short) 7,
193        (short) 5, (short) 3, (short) 0, (short) 9));
194  }
195
196  public void testMin_noArgs() {
197    try {
198      Shorts.min();
199      fail();
200    } catch (IllegalArgumentException expected) {
201    }
202  }
203
204  public void testMin() {
205    assertEquals(LEAST, Shorts.min(LEAST));
206    assertEquals(GREATEST, Shorts.min(GREATEST));
207    assertEquals((short) 0, Shorts.min(
208        (short) 8, (short) 6, (short) 7,
209        (short) 5, (short) 3, (short) 0, (short) 9));
210  }
211
212  public void testConcat() {
213    assertTrue(Arrays.equals(EMPTY, Shorts.concat()));
214    assertTrue(Arrays.equals(EMPTY, Shorts.concat(EMPTY)));
215    assertTrue(Arrays.equals(EMPTY, Shorts.concat(EMPTY, EMPTY, EMPTY)));
216    assertTrue(Arrays.equals(ARRAY1, Shorts.concat(ARRAY1)));
217    assertNotSame(ARRAY1, Shorts.concat(ARRAY1));
218    assertTrue(Arrays.equals(ARRAY1, Shorts.concat(EMPTY, ARRAY1, EMPTY)));
219    assertTrue(Arrays.equals(
220        new short[] {(short) 1, (short) 1, (short) 1},
221        Shorts.concat(ARRAY1, ARRAY1, ARRAY1)));
222    assertTrue(Arrays.equals(
223        new short[] {(short) 1, (short) 2, (short) 3, (short) 4},
224        Shorts.concat(ARRAY1, ARRAY234)));
225  }
226
227  @GwtIncompatible("Shorts.toByteArray")
228  public void testToByteArray() {
229    assertTrue(Arrays.equals(
230        new byte[] {0x23, 0x45}, Shorts.toByteArray((short) 0x2345)));
231    assertTrue(Arrays.equals(
232        new byte[] {(byte) 0xFE, (byte) 0xDC},
233        Shorts.toByteArray((short) 0xFEDC)));
234  }
235
236  @GwtIncompatible("Shorts.fromByteArray")
237  public void testFromByteArray() {
238    assertEquals((short) 0x2345,
239        Shorts.fromByteArray(new byte[] {0x23, 0x45}));
240    assertEquals((short) 0xFEDC, Shorts.fromByteArray(
241        new byte[] {(byte) 0xFE, (byte) 0xDC}));
242
243    try {
244      Shorts.fromByteArray(new byte[] {0x01});
245      fail();
246    } catch (IllegalArgumentException expected) {
247    }
248  }
249
250  @GwtIncompatible("Shorts.fromBytes")
251  public void testFromBytes() {
252    assertEquals((short) 0x2345, Shorts.fromBytes((byte) 0x23, (byte) 0x45));
253    assertEquals((short) 0xFEDC, Shorts.fromBytes((byte) 0xFE, (byte) 0xDC));
254  }
255
256  @GwtIncompatible("Shorts.fromByteArray, Shorts.toByteArray")
257  public void testByteArrayRoundTrips() {
258    Random r = new Random(5);
259    byte[] b = new byte[Shorts.BYTES];
260
261    // total overkill, but, it takes 0.1 sec so why not...
262    for (int i = 0; i < 10000; i++) {
263      short num = (short) r.nextInt();
264      assertEquals(num, Shorts.fromByteArray(Shorts.toByteArray(num)));
265
266      r.nextBytes(b);
267      assertTrue(Arrays.equals(b,
268          Shorts.toByteArray(Shorts.fromByteArray(b))));
269    }
270  }
271
272  public void testEnsureCapacity() {
273    assertSame(EMPTY, Shorts.ensureCapacity(EMPTY, 0, 1));
274    assertSame(ARRAY1, Shorts.ensureCapacity(ARRAY1, 0, 1));
275    assertSame(ARRAY1, Shorts.ensureCapacity(ARRAY1, 1, 1));
276    assertTrue(Arrays.equals(
277        new short[] {(short) 1, (short) 0, (short) 0},
278        Shorts.ensureCapacity(ARRAY1, 2, 1)));
279  }
280
281  public void testEnsureCapacity_fail() {
282    try {
283      Shorts.ensureCapacity(ARRAY1, -1, 1);
284      fail();
285    } catch (IllegalArgumentException expected) {
286    }
287    try {
288      // notice that this should even fail when no growth was needed
289      Shorts.ensureCapacity(ARRAY1, 1, -1);
290      fail();
291    } catch (IllegalArgumentException expected) {
292    }
293  }
294
295  public void testJoin() {
296    assertEquals("", Shorts.join(",", EMPTY));
297    assertEquals("1", Shorts.join(",", ARRAY1));
298    assertEquals("1,2", Shorts.join(",", (short) 1, (short) 2));
299    assertEquals("123",
300        Shorts.join("", (short) 1, (short) 2, (short) 3));
301  }
302
303  public void testLexicographicalComparator() {
304    List<short[]> ordered = Arrays.asList(
305        new short[] {},
306        new short[] {LEAST},
307        new short[] {LEAST, LEAST},
308        new short[] {LEAST, (short) 1},
309        new short[] {(short) 1},
310        new short[] {(short) 1, LEAST},
311        new short[] {GREATEST, GREATEST - (short) 1},
312        new short[] {GREATEST, GREATEST},
313        new short[] {GREATEST, GREATEST, GREATEST});
314
315    Comparator<short[]> comparator = Shorts.lexicographicalComparator();
316    Helpers.testComparator(comparator, ordered);
317  }
318
319  @GwtIncompatible("SerializableTester")
320  public void testLexicographicalComparatorSerializable() {
321    Comparator<short[]> comparator = Shorts.lexicographicalComparator();
322    assertSame(comparator, SerializableTester.reserialize(comparator));
323  }
324
325  public void testToArray() {
326    // need explicit type parameter to avoid javac warning!?
327    List<Short> none = Arrays.<Short>asList();
328    assertTrue(Arrays.equals(EMPTY, Shorts.toArray(none)));
329
330    List<Short> one = Arrays.asList((short) 1);
331    assertTrue(Arrays.equals(ARRAY1, Shorts.toArray(one)));
332
333    short[] array = {(short) 0, (short) 1, (short) 3};
334
335    List<Short> three = Arrays.asList((short) 0, (short) 1, (short) 3);
336    assertTrue(Arrays.equals(array, Shorts.toArray(three)));
337
338    assertTrue(Arrays.equals(array, Shorts.toArray(Shorts.asList(array))));
339  }
340
341  public void testToArray_threadSafe() {
342    for (int delta : new int[] { +1, 0, -1 }) {
343      for (int i = 0; i < VALUES.length; i++) {
344        List<Short> list = Shorts.asList(VALUES).subList(0, i);
345        Collection<Short> misleadingSize =
346            Helpers.misleadingSizeCollection(delta);
347        misleadingSize.addAll(list);
348        short[] arr = Shorts.toArray(misleadingSize);
349        assertEquals(i, arr.length);
350        for (int j = 0; j < i; j++) {
351          assertEquals(VALUES[j], arr[j]);
352        }
353      }
354    }
355  }
356
357  public void testToArray_withNull() {
358    List<Short> list = Arrays.asList((short) 0, (short) 1, null);
359    try {
360      Shorts.toArray(list);
361      fail();
362    } catch (NullPointerException expected) {
363    }
364  }
365
366  public void testAsList_isAView() {
367    short[] array = {(short) 0, (short) 1};
368    List<Short> list = Shorts.asList(array);
369    list.set(0, (short) 2);
370    assertTrue(Arrays.equals(new short[] {(short) 2, (short) 1}, array));
371    array[1] = (short) 3;
372    assertEquals(Arrays.asList((short) 2, (short) 3), list);
373  }
374
375  public void testAsList_toArray_roundTrip() {
376    short[] array = { (short) 0, (short) 1, (short) 2 };
377    List<Short> list = Shorts.asList(array);
378    short[] newArray = Shorts.toArray(list);
379
380    // Make sure it returned a copy
381    list.set(0, (short) 4);
382    assertTrue(Arrays.equals(
383        new short[] { (short) 0, (short) 1, (short) 2 }, newArray));
384    newArray[1] = (short) 5;
385    assertEquals((short) 1, (short) list.get(1));
386  }
387
388  // This test stems from a real bug found by andrewk
389  public void testAsList_subList_toArray_roundTrip() {
390    short[] array = { (short) 0, (short) 1, (short) 2, (short) 3 };
391    List<Short> list = Shorts.asList(array);
392    assertTrue(Arrays.equals(new short[] { (short) 1, (short) 2 },
393        Shorts.toArray(list.subList(1, 3))));
394    assertTrue(Arrays.equals(new short[] {},
395        Shorts.toArray(list.subList(2, 2))));
396  }
397
398  public void testAsListEmpty() {
399    assertSame(Collections.emptyList(), Shorts.asList(EMPTY));
400  }
401
402  @GwtIncompatible("NullPointerTester")
403  public void testNulls() throws Exception {
404    NullPointerTester tester = new NullPointerTester();
405    tester.setDefault(short[].class, new short[0]);
406    tester.testAllPublicStaticMethods(Shorts.class);
407  }
408}
409