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 21 import com.google.common.annotations.GwtCompatible; 22 import com.google.common.annotations.GwtIncompatible; 23 import com.google.common.annotations.J2ktIncompatible; 24 import com.google.common.collect.testing.Helpers; 25 import com.google.common.testing.NullPointerTester; 26 import java.util.Arrays; 27 import java.util.Collection; 28 import java.util.Collections; 29 import java.util.List; 30 import junit.framework.TestCase; 31 import org.checkerframework.checker.nullness.qual.Nullable; 32 33 /** 34 * Unit test for {@link Bytes}. 35 * 36 * @author Kevin Bourrillion 37 */ 38 @ElementTypesAreNonnullByDefault 39 @GwtCompatible(emulated = true) 40 public class BytesTest extends TestCase { 41 private static final byte[] EMPTY = {}; 42 private static final byte[] ARRAY1 = {(byte) 1}; 43 private static final byte[] ARRAY234 = {(byte) 2, (byte) 3, (byte) 4}; 44 45 private static final byte[] VALUES = {Byte.MIN_VALUE, -1, 0, 1, Byte.MAX_VALUE}; 46 testHashCode()47 public void testHashCode() { 48 for (byte value : VALUES) { 49 assertThat(Bytes.hashCode(value)).isEqualTo(((Byte) value).hashCode()); 50 } 51 } 52 testContains()53 public void testContains() { 54 assertThat(Bytes.contains(EMPTY, (byte) 1)).isFalse(); 55 assertThat(Bytes.contains(ARRAY1, (byte) 2)).isFalse(); 56 assertThat(Bytes.contains(ARRAY234, (byte) 1)).isFalse(); 57 assertThat(Bytes.contains(new byte[] {(byte) -1}, (byte) -1)).isTrue(); 58 assertThat(Bytes.contains(ARRAY234, (byte) 2)).isTrue(); 59 assertThat(Bytes.contains(ARRAY234, (byte) 3)).isTrue(); 60 assertThat(Bytes.contains(ARRAY234, (byte) 4)).isTrue(); 61 } 62 testIndexOf()63 public void testIndexOf() { 64 assertThat(Bytes.indexOf(EMPTY, (byte) 1)).isEqualTo(-1); 65 assertThat(Bytes.indexOf(ARRAY1, (byte) 2)).isEqualTo(-1); 66 assertThat(Bytes.indexOf(ARRAY234, (byte) 1)).isEqualTo(-1); 67 assertThat(Bytes.indexOf(new byte[] {(byte) -1}, (byte) -1)).isEqualTo(0); 68 assertThat(Bytes.indexOf(ARRAY234, (byte) 2)).isEqualTo(0); 69 assertThat(Bytes.indexOf(ARRAY234, (byte) 3)).isEqualTo(1); 70 assertThat(Bytes.indexOf(ARRAY234, (byte) 4)).isEqualTo(2); 71 assertThat(Bytes.indexOf(new byte[] {(byte) 2, (byte) 3, (byte) 2, (byte) 3}, (byte) 3)) 72 .isEqualTo(1); 73 } 74 testIndexOf_arrayTarget()75 public void testIndexOf_arrayTarget() { 76 assertThat(Bytes.indexOf(EMPTY, EMPTY)).isEqualTo(0); 77 assertThat(Bytes.indexOf(ARRAY234, EMPTY)).isEqualTo(0); 78 assertThat(Bytes.indexOf(EMPTY, ARRAY234)).isEqualTo(-1); 79 assertThat(Bytes.indexOf(ARRAY234, ARRAY1)).isEqualTo(-1); 80 assertThat(Bytes.indexOf(ARRAY1, ARRAY234)).isEqualTo(-1); 81 assertThat(Bytes.indexOf(ARRAY1, ARRAY1)).isEqualTo(0); 82 assertThat(Bytes.indexOf(ARRAY234, ARRAY234)).isEqualTo(0); 83 assertThat(Bytes.indexOf(ARRAY234, new byte[] {(byte) 2, (byte) 3})).isEqualTo(0); 84 assertThat(Bytes.indexOf(ARRAY234, new byte[] {(byte) 3, (byte) 4})).isEqualTo(1); 85 assertThat(Bytes.indexOf(ARRAY234, new byte[] {(byte) 3})).isEqualTo(1); 86 assertThat(Bytes.indexOf(ARRAY234, new byte[] {(byte) 4})).isEqualTo(2); 87 assertThat( 88 Bytes.indexOf( 89 new byte[] {(byte) 2, (byte) 3, (byte) 3, (byte) 3, (byte) 3}, 90 new byte[] {(byte) 3})) 91 .isEqualTo(1); 92 assertThat( 93 Bytes.indexOf( 94 new byte[] {(byte) 2, (byte) 3, (byte) 2, (byte) 3, (byte) 4, (byte) 2, (byte) 3}, 95 new byte[] {(byte) 2, (byte) 3, (byte) 4})) 96 .isEqualTo(2); 97 assertThat( 98 Bytes.indexOf( 99 new byte[] {(byte) 2, (byte) 2, (byte) 3, (byte) 4, (byte) 2, (byte) 3, (byte) 4}, 100 new byte[] {(byte) 2, (byte) 3, (byte) 4})) 101 .isEqualTo(1); 102 assertThat( 103 Bytes.indexOf( 104 new byte[] {(byte) 4, (byte) 3, (byte) 2}, 105 new byte[] {(byte) 2, (byte) 3, (byte) 4})) 106 .isEqualTo(-1); 107 } 108 testLastIndexOf()109 public void testLastIndexOf() { 110 assertThat(Bytes.lastIndexOf(EMPTY, (byte) 1)).isEqualTo(-1); 111 assertThat(Bytes.lastIndexOf(ARRAY1, (byte) 2)).isEqualTo(-1); 112 assertThat(Bytes.lastIndexOf(ARRAY234, (byte) 1)).isEqualTo(-1); 113 assertThat(Bytes.lastIndexOf(new byte[] {(byte) -1}, (byte) -1)).isEqualTo(0); 114 assertThat(Bytes.lastIndexOf(ARRAY234, (byte) 2)).isEqualTo(0); 115 assertThat(Bytes.lastIndexOf(ARRAY234, (byte) 3)).isEqualTo(1); 116 assertThat(Bytes.lastIndexOf(ARRAY234, (byte) 4)).isEqualTo(2); 117 assertThat(Bytes.lastIndexOf(new byte[] {(byte) 2, (byte) 3, (byte) 2, (byte) 3}, (byte) 3)) 118 .isEqualTo(3); 119 } 120 testConcat()121 public void testConcat() { 122 assertThat(Bytes.concat()).isEqualTo(EMPTY); 123 assertThat(Bytes.concat(EMPTY)).isEqualTo(EMPTY); 124 assertThat(Bytes.concat(EMPTY, EMPTY, EMPTY)).isEqualTo(EMPTY); 125 assertThat(Bytes.concat(ARRAY1)).isEqualTo(ARRAY1); 126 assertThat(Bytes.concat(ARRAY1)).isNotSameInstanceAs(ARRAY1); 127 assertThat(Bytes.concat(EMPTY, ARRAY1, EMPTY)).isEqualTo(ARRAY1); 128 assertThat(Bytes.concat(ARRAY1, ARRAY1, ARRAY1)) 129 .isEqualTo(new byte[] {(byte) 1, (byte) 1, (byte) 1}); 130 assertThat(Bytes.concat(ARRAY1, ARRAY234)) 131 .isEqualTo(new byte[] {(byte) 1, (byte) 2, (byte) 3, (byte) 4}); 132 } 133 testEnsureCapacity()134 public void testEnsureCapacity() { 135 assertThat(Bytes.ensureCapacity(EMPTY, 0, 1)).isSameInstanceAs(EMPTY); 136 assertThat(Bytes.ensureCapacity(ARRAY1, 0, 1)).isSameInstanceAs(ARRAY1); 137 assertThat(Bytes.ensureCapacity(ARRAY1, 1, 1)).isSameInstanceAs(ARRAY1); 138 assertThat(Bytes.ensureCapacity(ARRAY1, 2, 1)) 139 .isEqualTo(new byte[] {(byte) 1, (byte) 0, (byte) 0}); 140 } 141 testEnsureCapacity_fail()142 public void testEnsureCapacity_fail() { 143 try { 144 Bytes.ensureCapacity(ARRAY1, -1, 1); 145 fail(); 146 } catch (IllegalArgumentException expected) { 147 } 148 try { 149 // notice that this should even fail when no growth was needed 150 Bytes.ensureCapacity(ARRAY1, 1, -1); 151 fail(); 152 } catch (IllegalArgumentException expected) { 153 } 154 } 155 testToArray()156 public void testToArray() { 157 // need explicit type parameter to avoid javac warning!? 158 List<Byte> none = Arrays.<Byte>asList(); 159 assertThat(Bytes.toArray(none)).isEqualTo(EMPTY); 160 161 List<Byte> one = Arrays.asList((byte) 1); 162 assertThat(Bytes.toArray(one)).isEqualTo(ARRAY1); 163 164 byte[] array = {(byte) 0, (byte) 1, (byte) 0x55}; 165 166 List<Byte> three = Arrays.asList((byte) 0, (byte) 1, (byte) 0x55); 167 assertThat(Bytes.toArray(three)).isEqualTo(array); 168 169 assertThat(Bytes.toArray(Bytes.asList(array))).isEqualTo(array); 170 } 171 testToArray_threadSafe()172 public void testToArray_threadSafe() { 173 for (int delta : new int[] {+1, 0, -1}) { 174 for (int i = 0; i < VALUES.length; i++) { 175 List<Byte> list = Bytes.asList(VALUES).subList(0, i); 176 Collection<Byte> misleadingSize = Helpers.misleadingSizeCollection(delta); 177 misleadingSize.addAll(list); 178 byte[] arr = Bytes.toArray(misleadingSize); 179 assertThat(arr).hasLength(i); 180 for (int j = 0; j < i; j++) { 181 assertThat(arr[j]).isEqualTo(VALUES[j]); 182 } 183 } 184 } 185 } 186 testToArray_withNull()187 public void testToArray_withNull() { 188 List<@Nullable Byte> list = Arrays.asList((byte) 0, (byte) 1, null); 189 try { 190 Bytes.toArray(list); 191 fail(); 192 } catch (NullPointerException expected) { 193 } 194 } 195 testToArray_withConversion()196 public void testToArray_withConversion() { 197 byte[] array = {(byte) 0, (byte) 1, (byte) 2}; 198 199 List<Byte> bytes = Arrays.asList((byte) 0, (byte) 1, (byte) 2); 200 List<Short> shorts = Arrays.asList((short) 0, (short) 1, (short) 2); 201 List<Integer> ints = Arrays.asList(0, 1, 2); 202 List<Float> floats = Arrays.asList((float) 0, (float) 1, (float) 2); 203 List<Long> longs = Arrays.asList((long) 0, (long) 1, (long) 2); 204 List<Double> doubles = Arrays.asList((double) 0, (double) 1, (double) 2); 205 206 assertThat(Bytes.toArray(bytes)).isEqualTo(array); 207 assertThat(Bytes.toArray(shorts)).isEqualTo(array); 208 assertThat(Bytes.toArray(ints)).isEqualTo(array); 209 assertThat(Bytes.toArray(floats)).isEqualTo(array); 210 assertThat(Bytes.toArray(longs)).isEqualTo(array); 211 assertThat(Bytes.toArray(doubles)).isEqualTo(array); 212 } 213 214 @J2ktIncompatible // TODO(b/278877942): Enable testAsList_isAView()215 public void testAsList_isAView() { 216 byte[] array = {(byte) 0, (byte) 1}; 217 List<Byte> list = Bytes.asList(array); 218 list.set(0, (byte) 2); 219 assertThat(array).isEqualTo(new byte[] {(byte) 2, (byte) 1}); 220 array[1] = (byte) 3; 221 assertThat(list).containsExactly((byte) 2, (byte) 3).inOrder(); 222 } 223 testAsList_toArray_roundTrip()224 public void testAsList_toArray_roundTrip() { 225 byte[] array = {(byte) 0, (byte) 1, (byte) 2}; 226 List<Byte> list = Bytes.asList(array); 227 byte[] newArray = Bytes.toArray(list); 228 229 // Make sure it returned a copy 230 list.set(0, (byte) 4); 231 assertThat(newArray).isEqualTo(new byte[] {(byte) 0, (byte) 1, (byte) 2}); 232 newArray[1] = (byte) 5; 233 assertThat((byte) list.get(1)).isEqualTo((byte) 1); 234 } 235 236 // This test stems from a real bug found by andrewk testAsList_subList_toArray_roundTrip()237 public void testAsList_subList_toArray_roundTrip() { 238 byte[] array = {(byte) 0, (byte) 1, (byte) 2, (byte) 3}; 239 List<Byte> list = Bytes.asList(array); 240 assertThat(Bytes.toArray(list.subList(1, 3))).isEqualTo(new byte[] {(byte) 1, (byte) 2}); 241 assertThat(Bytes.toArray(list.subList(2, 2))).isEqualTo(new byte[] {}); 242 } 243 testAsListEmpty()244 public void testAsListEmpty() { 245 assertThat(Bytes.asList(EMPTY)).isSameInstanceAs(Collections.emptyList()); 246 } 247 testReverse()248 public void testReverse() { 249 testReverse(new byte[] {}, new byte[] {}); 250 testReverse(new byte[] {1}, new byte[] {1}); 251 testReverse(new byte[] {1, 2}, new byte[] {2, 1}); 252 testReverse(new byte[] {3, 1, 1}, new byte[] {1, 1, 3}); 253 testReverse(new byte[] {-1, 1, -2, 2}, new byte[] {2, -2, 1, -1}); 254 } 255 testReverse(byte[] input, byte[] expectedOutput)256 private static void testReverse(byte[] input, byte[] expectedOutput) { 257 input = Arrays.copyOf(input, input.length); 258 Bytes.reverse(input); 259 assertThat(input).isEqualTo(expectedOutput); 260 } 261 testReverse(byte[] input, int fromIndex, int toIndex, byte[] expectedOutput)262 private static void testReverse(byte[] input, int fromIndex, int toIndex, byte[] expectedOutput) { 263 input = Arrays.copyOf(input, input.length); 264 Bytes.reverse(input, fromIndex, toIndex); 265 assertThat(input).isEqualTo(expectedOutput); 266 } 267 testReverseIndexed()268 public void testReverseIndexed() { 269 testReverse(new byte[] {}, 0, 0, new byte[] {}); 270 testReverse(new byte[] {1}, 0, 1, new byte[] {1}); 271 testReverse(new byte[] {1, 2}, 0, 2, new byte[] {2, 1}); 272 testReverse(new byte[] {3, 1, 1}, 0, 2, new byte[] {1, 3, 1}); 273 testReverse(new byte[] {3, 1, 1}, 0, 1, new byte[] {3, 1, 1}); 274 testReverse(new byte[] {-1, 1, -2, 2}, 1, 3, new byte[] {-1, -2, 1, 2}); 275 } 276 testRotate(byte[] input, int distance, byte[] expectedOutput)277 private static void testRotate(byte[] input, int distance, byte[] expectedOutput) { 278 input = Arrays.copyOf(input, input.length); 279 Bytes.rotate(input, distance); 280 assertThat(input).isEqualTo(expectedOutput); 281 } 282 testRotate( byte[] input, int distance, int fromIndex, int toIndex, byte[] expectedOutput)283 private static void testRotate( 284 byte[] input, int distance, int fromIndex, int toIndex, byte[] expectedOutput) { 285 input = Arrays.copyOf(input, input.length); 286 Bytes.rotate(input, distance, fromIndex, toIndex); 287 assertThat(input).isEqualTo(expectedOutput); 288 } 289 testRotate()290 public void testRotate() { 291 testRotate(new byte[] {}, -1, new byte[] {}); 292 testRotate(new byte[] {}, 0, new byte[] {}); 293 testRotate(new byte[] {}, 1, new byte[] {}); 294 295 testRotate(new byte[] {1}, -2, new byte[] {1}); 296 testRotate(new byte[] {1}, -1, new byte[] {1}); 297 testRotate(new byte[] {1}, 0, new byte[] {1}); 298 testRotate(new byte[] {1}, 1, new byte[] {1}); 299 testRotate(new byte[] {1}, 2, new byte[] {1}); 300 301 testRotate(new byte[] {1, 2}, -3, new byte[] {2, 1}); 302 testRotate(new byte[] {1, 2}, -1, new byte[] {2, 1}); 303 testRotate(new byte[] {1, 2}, -2, new byte[] {1, 2}); 304 testRotate(new byte[] {1, 2}, 0, new byte[] {1, 2}); 305 testRotate(new byte[] {1, 2}, 1, new byte[] {2, 1}); 306 testRotate(new byte[] {1, 2}, 2, new byte[] {1, 2}); 307 testRotate(new byte[] {1, 2}, 3, new byte[] {2, 1}); 308 309 testRotate(new byte[] {1, 2, 3}, -5, new byte[] {3, 1, 2}); 310 testRotate(new byte[] {1, 2, 3}, -4, new byte[] {2, 3, 1}); 311 testRotate(new byte[] {1, 2, 3}, -3, new byte[] {1, 2, 3}); 312 testRotate(new byte[] {1, 2, 3}, -2, new byte[] {3, 1, 2}); 313 testRotate(new byte[] {1, 2, 3}, -1, new byte[] {2, 3, 1}); 314 testRotate(new byte[] {1, 2, 3}, 0, new byte[] {1, 2, 3}); 315 testRotate(new byte[] {1, 2, 3}, 1, new byte[] {3, 1, 2}); 316 testRotate(new byte[] {1, 2, 3}, 2, new byte[] {2, 3, 1}); 317 testRotate(new byte[] {1, 2, 3}, 3, new byte[] {1, 2, 3}); 318 testRotate(new byte[] {1, 2, 3}, 4, new byte[] {3, 1, 2}); 319 testRotate(new byte[] {1, 2, 3}, 5, new byte[] {2, 3, 1}); 320 321 testRotate(new byte[] {1, 2, 3, 4}, -9, new byte[] {2, 3, 4, 1}); 322 testRotate(new byte[] {1, 2, 3, 4}, -5, new byte[] {2, 3, 4, 1}); 323 testRotate(new byte[] {1, 2, 3, 4}, -1, new byte[] {2, 3, 4, 1}); 324 testRotate(new byte[] {1, 2, 3, 4}, 0, new byte[] {1, 2, 3, 4}); 325 testRotate(new byte[] {1, 2, 3, 4}, 1, new byte[] {4, 1, 2, 3}); 326 testRotate(new byte[] {1, 2, 3, 4}, 5, new byte[] {4, 1, 2, 3}); 327 testRotate(new byte[] {1, 2, 3, 4}, 9, new byte[] {4, 1, 2, 3}); 328 329 testRotate(new byte[] {1, 2, 3, 4, 5}, -6, new byte[] {2, 3, 4, 5, 1}); 330 testRotate(new byte[] {1, 2, 3, 4, 5}, -4, new byte[] {5, 1, 2, 3, 4}); 331 testRotate(new byte[] {1, 2, 3, 4, 5}, -3, new byte[] {4, 5, 1, 2, 3}); 332 testRotate(new byte[] {1, 2, 3, 4, 5}, -1, new byte[] {2, 3, 4, 5, 1}); 333 testRotate(new byte[] {1, 2, 3, 4, 5}, 0, new byte[] {1, 2, 3, 4, 5}); 334 testRotate(new byte[] {1, 2, 3, 4, 5}, 1, new byte[] {5, 1, 2, 3, 4}); 335 testRotate(new byte[] {1, 2, 3, 4, 5}, 3, new byte[] {3, 4, 5, 1, 2}); 336 testRotate(new byte[] {1, 2, 3, 4, 5}, 4, new byte[] {2, 3, 4, 5, 1}); 337 testRotate(new byte[] {1, 2, 3, 4, 5}, 6, new byte[] {5, 1, 2, 3, 4}); 338 } 339 testRotateIndexed()340 public void testRotateIndexed() { 341 testRotate(new byte[] {}, 0, 0, 0, new byte[] {}); 342 343 testRotate(new byte[] {1}, 0, 0, 1, new byte[] {1}); 344 testRotate(new byte[] {1}, 1, 0, 1, new byte[] {1}); 345 testRotate(new byte[] {1}, 1, 1, 1, new byte[] {1}); 346 347 // Rotate the central 5 elements, leaving the ends as-is 348 testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, -6, 1, 6, new byte[] {0, 2, 3, 4, 5, 1, 6}); 349 testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, -1, 1, 6, new byte[] {0, 2, 3, 4, 5, 1, 6}); 350 testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, 0, 1, 6, new byte[] {0, 1, 2, 3, 4, 5, 6}); 351 testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, 5, 1, 6, new byte[] {0, 1, 2, 3, 4, 5, 6}); 352 testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, 14, 1, 6, new byte[] {0, 2, 3, 4, 5, 1, 6}); 353 354 // Rotate the first three elements 355 testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, -2, 0, 3, new byte[] {2, 0, 1, 3, 4, 5, 6}); 356 testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, -1, 0, 3, new byte[] {1, 2, 0, 3, 4, 5, 6}); 357 testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, 0, 0, 3, new byte[] {0, 1, 2, 3, 4, 5, 6}); 358 testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, 1, 0, 3, new byte[] {2, 0, 1, 3, 4, 5, 6}); 359 testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, 2, 0, 3, new byte[] {1, 2, 0, 3, 4, 5, 6}); 360 361 // Rotate the last four elements 362 testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, -6, 3, 7, new byte[] {0, 1, 2, 5, 6, 3, 4}); 363 testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, -5, 3, 7, new byte[] {0, 1, 2, 4, 5, 6, 3}); 364 testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, -4, 3, 7, new byte[] {0, 1, 2, 3, 4, 5, 6}); 365 testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, -3, 3, 7, new byte[] {0, 1, 2, 6, 3, 4, 5}); 366 testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, -2, 3, 7, new byte[] {0, 1, 2, 5, 6, 3, 4}); 367 testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, -1, 3, 7, new byte[] {0, 1, 2, 4, 5, 6, 3}); 368 testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, 0, 3, 7, new byte[] {0, 1, 2, 3, 4, 5, 6}); 369 testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, 1, 3, 7, new byte[] {0, 1, 2, 6, 3, 4, 5}); 370 testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, 2, 3, 7, new byte[] {0, 1, 2, 5, 6, 3, 4}); 371 testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, 3, 3, 7, new byte[] {0, 1, 2, 4, 5, 6, 3}); 372 } 373 374 @J2ktIncompatible 375 @GwtIncompatible // NullPointerTester testNulls()376 public void testNulls() { 377 new NullPointerTester().testAllPublicStaticMethods(Bytes.class); 378 } 379 } 380