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.collect.testing.Helpers;
20import com.google.common.testing.NullPointerTester;
21import com.google.common.testing.SerializableTester;
22
23import junit.framework.TestCase;
24
25import java.util.Arrays;
26import java.util.Comparator;
27import java.util.List;
28
29/**
30 * Unit test for {@link UnsignedBytes}.
31 *
32 * @author Kevin Bourrillion
33 * @author Louis Wasserman
34 */
35public class UnsignedBytesTest extends TestCase {
36  private static final byte LEAST = 0;
37  private static final byte GREATEST = (byte) 255;
38
39  // Only in this class, VALUES must be strictly ascending
40  private static final byte[] VALUES =
41      {LEAST, 127, (byte) 128, (byte) 129, GREATEST};
42
43  public void testToInt() {
44    assertEquals(0, UnsignedBytes.toInt((byte) 0));
45    assertEquals(1, UnsignedBytes.toInt((byte) 1));
46    assertEquals(127, UnsignedBytes.toInt((byte) 127));
47    assertEquals(128, UnsignedBytes.toInt((byte) -128));
48    assertEquals(129, UnsignedBytes.toInt((byte) -127));
49    assertEquals(255, UnsignedBytes.toInt((byte) -1));
50  }
51
52  public void testCheckedCast() {
53    for (byte value : VALUES) {
54      assertEquals(value,
55          UnsignedBytes.checkedCast(UnsignedBytes.toInt(value)));
56    }
57    assertCastFails(256L);
58    assertCastFails(-1L);
59    assertCastFails(Long.MAX_VALUE);
60    assertCastFails(Long.MIN_VALUE);
61  }
62
63  public void testSaturatedCast() {
64    for (byte value : VALUES) {
65      assertEquals(value,
66          UnsignedBytes.saturatedCast(UnsignedBytes.toInt(value)));
67    }
68    assertEquals(GREATEST, UnsignedBytes.saturatedCast(256L));
69    assertEquals(LEAST, UnsignedBytes.saturatedCast(-1L));
70    assertEquals(GREATEST, UnsignedBytes.saturatedCast(Long.MAX_VALUE));
71    assertEquals(LEAST, UnsignedBytes.saturatedCast(Long.MIN_VALUE));
72  }
73
74  private static void assertCastFails(long value) {
75    try {
76      UnsignedBytes.checkedCast(value);
77      fail("Cast to byte should have failed: " + value);
78    } catch (IllegalArgumentException ex) {
79      assertTrue(value + " not found in exception text: " + ex.getMessage(),
80          ex.getMessage().contains(String.valueOf(value)));
81    }
82  }
83
84  public void testCompare() {
85    // This is the only ordering for primitives that does not have a
86    // corresponding Comparable wrapper in java.lang.
87    for (int i = 0; i < VALUES.length; i++) {
88      for (int j = 0; j < VALUES.length; j++) {
89        byte x = VALUES[i];
90        byte y = VALUES[j];
91        // note: spec requires only that the sign is the same
92        assertEquals(x + ", " + y,
93                     Math.signum(UnsignedBytes.compare(x, y)),
94                     Math.signum(Ints.compare(i, j)));
95      }
96    }
97  }
98
99  public void testMax_noArgs() {
100    try {
101      UnsignedBytes.max();
102      fail();
103    } catch (IllegalArgumentException expected) {
104    }
105  }
106
107  public void testMax() {
108    assertEquals(LEAST, UnsignedBytes.max(LEAST));
109    assertEquals(GREATEST, UnsignedBytes.max(GREATEST));
110    assertEquals((byte) 255, UnsignedBytes.max(
111        (byte) 0, (byte) -128, (byte) -1, (byte) 127, (byte) 1));
112  }
113
114  public void testMin_noArgs() {
115    try {
116      UnsignedBytes.min();
117      fail();
118    } catch (IllegalArgumentException expected) {
119    }
120  }
121
122  public void testMin() {
123    assertEquals(LEAST, UnsignedBytes.min(LEAST));
124    assertEquals(GREATEST, UnsignedBytes.min(GREATEST));
125    assertEquals((byte) 0, UnsignedBytes.min(
126        (byte) 0, (byte) -128, (byte) -1, (byte) 127, (byte) 1));
127    assertEquals((byte) 0, UnsignedBytes.min(
128        (byte) -1, (byte) 127, (byte) 1, (byte) -128, (byte) 0));
129  }
130
131  private static void assertParseFails(String value) {
132    try {
133      UnsignedBytes.parseUnsignedByte(value);
134      fail();
135    } catch (NumberFormatException expected) {
136    }
137  }
138
139  public void testParseUnsignedByte() {
140    // We can easily afford to test this exhaustively.
141    for (int i = 0; i <= 0xff; i++) {
142      assertEquals((byte) i, UnsignedBytes.parseUnsignedByte(Integer.toString(i)));
143    }
144    assertParseFails("1000");
145    assertParseFails("-1");
146    assertParseFails("-128");
147    assertParseFails("256");
148  }
149
150  public void testMaxValue() {
151    assertTrue(UnsignedBytes
152        .compare(UnsignedBytes.MAX_VALUE, (byte) (UnsignedBytes.MAX_VALUE + 1)) > 0);
153  }
154
155  private static void assertParseFails(String value, int radix) {
156    try {
157      UnsignedBytes.parseUnsignedByte(value, radix);
158      fail();
159    } catch (NumberFormatException expected) {
160    }
161  }
162
163  public void testParseUnsignedByteWithRadix() throws NumberFormatException {
164    // We can easily afford to test this exhaustively.
165    for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
166      for (int i = 0; i <= 0xff; i++) {
167        assertEquals((byte) i, UnsignedBytes.parseUnsignedByte(Integer.toString(i, radix), radix));
168      }
169      assertParseFails(Integer.toString(1000, radix), radix);
170      assertParseFails(Integer.toString(-1, radix), radix);
171      assertParseFails(Integer.toString(-128, radix), radix);
172      assertParseFails(Integer.toString(256, radix), radix);
173    }
174  }
175
176  public void testParseUnsignedByteThrowsExceptionForInvalidRadix() {
177    // Valid radix values are Character.MIN_RADIX to Character.MAX_RADIX,
178    // inclusive.
179    try {
180      UnsignedBytes.parseUnsignedByte("0", Character.MIN_RADIX - 1);
181      fail();
182    } catch (NumberFormatException nfe) {
183      // expected
184    }
185
186    try {
187      UnsignedBytes.parseUnsignedByte("0", Character.MAX_RADIX + 1);
188      fail();
189    } catch (NumberFormatException nfe) {
190      // expected
191    }
192
193    // The radix is used as an array index, so try a negative value.
194    try {
195      UnsignedBytes.parseUnsignedByte("0", -1);
196      fail();
197    } catch (NumberFormatException nfe) {
198      // expected
199    }
200  }
201
202  public void testToString() {
203    // We can easily afford to test this exhaustively.
204    for (int i = 0; i <= 0xff; i++) {
205      assertEquals(Integer.toString(i), UnsignedBytes.toString((byte) i));
206    }
207  }
208
209  public void testToStringWithRadix() {
210    // We can easily afford to test this exhaustively.
211    for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
212      for (int i = 0; i <= 0xff; i++) {
213        assertEquals(Integer.toString(i, radix), UnsignedBytes.toString((byte) i, radix));
214      }
215    }
216  }
217
218  public void testJoin() {
219    assertEquals("", UnsignedBytes.join(",", new byte[] {}));
220    assertEquals("1", UnsignedBytes.join(",", new byte[] {(byte) 1}));
221    assertEquals("1,2", UnsignedBytes.join(",", (byte) 1, (byte) 2));
222    assertEquals("123", UnsignedBytes.join("", (byte) 1, (byte) 2, (byte) 3));
223    assertEquals("128,255", UnsignedBytes.join(",", (byte) 128, (byte) -1));
224  }
225
226  public void testLexicographicalComparatorDefaultChoice() {
227    Comparator<byte[]> defaultComparator =
228        UnsignedBytes.lexicographicalComparator();
229    Comparator<byte[]> pureJavaComparator =
230        UnsignedBytes.LexicographicalComparatorHolder.PureJavaComparator.INSTANCE;
231    assertSame(defaultComparator, pureJavaComparator);
232  }
233
234  public void testLexicographicalComparator() {
235    List<byte[]> ordered = Arrays.asList(
236        new byte[] {},
237        new byte[] {LEAST},
238        new byte[] {LEAST, LEAST},
239        new byte[] {LEAST, (byte) 1},
240        new byte[] {(byte) 1},
241        new byte[] {(byte) 1, LEAST},
242        new byte[] {GREATEST, GREATEST - (byte) 1},
243        new byte[] {GREATEST, GREATEST},
244        new byte[] {GREATEST, GREATEST, GREATEST});
245
246    // The Unsafe implementation if it's available. Otherwise, the Java implementation.
247    Comparator<byte[]> comparator = UnsignedBytes.lexicographicalComparator();
248    Helpers.testComparator(comparator, ordered);
249    assertSame(comparator, SerializableTester.reserialize(comparator));
250
251    // The Java implementation.
252    Comparator<byte[]> javaImpl = UnsignedBytes.lexicographicalComparatorJavaImpl();
253    Helpers.testComparator(javaImpl, ordered);
254    assertSame(javaImpl, SerializableTester.reserialize(javaImpl));
255  }
256
257  @SuppressWarnings("unchecked")
258  public void testLexicographicalComparatorLongInputs() {
259    for (Comparator<byte[]> comparator : Arrays.asList(
260        UnsignedBytes.lexicographicalComparator(),
261        UnsignedBytes.lexicographicalComparatorJavaImpl())) {
262      for (int i = 0; i < 32; i++) {
263        byte[] left = new byte[32];
264        byte[] right = new byte[32];
265
266        assertTrue(comparator.compare(left, right) == 0);
267        left[i] = 1;
268        assertTrue(comparator.compare(left, right) > 0);
269        assertTrue(comparator.compare(right, left) < 0);
270      }
271    }
272  }
273
274  public void testNulls() {
275    new NullPointerTester().testAllPublicStaticMethods(UnsignedBytes.class);
276  }
277}
278