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 22 import com.google.common.annotations.GwtCompatible; 23 import com.google.common.annotations.GwtIncompatible; 24 import com.google.common.annotations.J2ktIncompatible; 25 import com.google.common.collect.testing.Helpers; 26 import com.google.common.testing.NullPointerTester; 27 import com.google.common.testing.SerializableTester; 28 import java.util.Arrays; 29 import java.util.Collection; 30 import java.util.Collections; 31 import java.util.Comparator; 32 import java.util.List; 33 import java.util.Locale; 34 import junit.framework.TestCase; 35 import org.checkerframework.checker.nullness.qual.Nullable; 36 37 /** 38 * Unit test for {@link Chars}. 39 * 40 * @author Kevin Bourrillion 41 */ 42 @GwtCompatible(emulated = true) 43 @ElementTypesAreNonnullByDefault 44 @SuppressWarnings("cast") // redundant casts are intentional and harmless 45 public class CharsTest extends TestCase { 46 private static final char[] EMPTY = {}; 47 private static final char[] ARRAY1 = {(char) 1}; 48 private static final char[] ARRAY234 = {(char) 2, (char) 3, (char) 4}; 49 50 private static final char LEAST = Character.MIN_VALUE; 51 private static final char GREATEST = Character.MAX_VALUE; 52 53 private static final char[] VALUES = {LEAST, 'a', '\u00e0', '\udcaa', GREATEST}; 54 testHashCode()55 public void testHashCode() { 56 for (char value : VALUES) { 57 assertThat(Chars.hashCode(value)).isEqualTo(((Character) value).hashCode()); 58 } 59 } 60 testCheckedCast()61 public void testCheckedCast() { 62 for (char value : VALUES) { 63 assertThat(Chars.checkedCast((long) value)).isEqualTo(value); 64 } 65 assertCastFails(GREATEST + 1L); 66 assertCastFails(LEAST - 1L); 67 assertCastFails(Long.MAX_VALUE); 68 assertCastFails(Long.MIN_VALUE); 69 } 70 testSaturatedCast()71 public void testSaturatedCast() { 72 for (char value : VALUES) { 73 assertThat(Chars.saturatedCast((long) value)).isEqualTo(value); 74 } 75 assertThat(Chars.saturatedCast(GREATEST + 1L)).isEqualTo(GREATEST); 76 assertThat(Chars.saturatedCast(LEAST - 1L)).isEqualTo(LEAST); 77 assertThat(Chars.saturatedCast(Long.MAX_VALUE)).isEqualTo(GREATEST); 78 assertThat(Chars.saturatedCast(Long.MIN_VALUE)).isEqualTo(LEAST); 79 } 80 assertCastFails(long value)81 private void assertCastFails(long value) { 82 try { 83 Chars.checkedCast(value); 84 fail("Cast to char should have failed: " + value); 85 } catch (IllegalArgumentException ex) { 86 assertWithMessage(value + " not found in exception text: " + ex.getMessage()) 87 .that(ex.getMessage().contains(String.valueOf(value))) 88 .isTrue(); 89 } 90 } 91 92 @J2ktIncompatible // TODO(b/285538920): Fix and enable. testCompare()93 public void testCompare() { 94 for (char x : VALUES) { 95 for (char y : VALUES) { 96 // note: spec requires only that the sign is the same 97 assertWithMessage(x + ", " + y) 98 .that(Chars.compare(x, y)) 99 .isEqualTo(Character.valueOf(x).compareTo(y)); 100 } 101 } 102 } 103 testContains()104 public void testContains() { 105 assertThat(Chars.contains(EMPTY, (char) 1)).isFalse(); 106 assertThat(Chars.contains(ARRAY1, (char) 2)).isFalse(); 107 assertThat(Chars.contains(ARRAY234, (char) 1)).isFalse(); 108 assertThat(Chars.contains(new char[] {(char) -1}, (char) -1)).isTrue(); 109 assertThat(Chars.contains(ARRAY234, (char) 2)).isTrue(); 110 assertThat(Chars.contains(ARRAY234, (char) 3)).isTrue(); 111 assertThat(Chars.contains(ARRAY234, (char) 4)).isTrue(); 112 } 113 testIndexOf()114 public void testIndexOf() { 115 assertThat(Chars.indexOf(EMPTY, (char) 1)).isEqualTo(-1); 116 assertThat(Chars.indexOf(ARRAY1, (char) 2)).isEqualTo(-1); 117 assertThat(Chars.indexOf(ARRAY234, (char) 1)).isEqualTo(-1); 118 assertThat(Chars.indexOf(new char[] {(char) -1}, (char) -1)).isEqualTo(0); 119 assertThat(Chars.indexOf(ARRAY234, (char) 2)).isEqualTo(0); 120 assertThat(Chars.indexOf(ARRAY234, (char) 3)).isEqualTo(1); 121 assertThat(Chars.indexOf(ARRAY234, (char) 4)).isEqualTo(2); 122 assertThat(Chars.indexOf(new char[] {(char) 2, (char) 3, (char) 2, (char) 3}, (char) 3)) 123 .isEqualTo(1); 124 } 125 testIndexOf_arrayTarget()126 public void testIndexOf_arrayTarget() { 127 assertThat(Chars.indexOf(EMPTY, EMPTY)).isEqualTo(0); 128 assertThat(Chars.indexOf(ARRAY234, EMPTY)).isEqualTo(0); 129 assertThat(Chars.indexOf(EMPTY, ARRAY234)).isEqualTo(-1); 130 assertThat(Chars.indexOf(ARRAY234, ARRAY1)).isEqualTo(-1); 131 assertThat(Chars.indexOf(ARRAY1, ARRAY234)).isEqualTo(-1); 132 assertThat(Chars.indexOf(ARRAY1, ARRAY1)).isEqualTo(0); 133 assertThat(Chars.indexOf(ARRAY234, ARRAY234)).isEqualTo(0); 134 assertThat(Chars.indexOf(ARRAY234, new char[] {(char) 2, (char) 3})).isEqualTo(0); 135 assertThat(Chars.indexOf(ARRAY234, new char[] {(char) 3, (char) 4})).isEqualTo(1); 136 assertThat(Chars.indexOf(ARRAY234, new char[] {(char) 3})).isEqualTo(1); 137 assertThat(Chars.indexOf(ARRAY234, new char[] {(char) 4})).isEqualTo(2); 138 assertThat( 139 Chars.indexOf( 140 new char[] {(char) 2, (char) 3, (char) 3, (char) 3, (char) 3}, 141 new char[] {(char) 3})) 142 .isEqualTo(1); 143 assertThat( 144 Chars.indexOf( 145 new char[] {(char) 2, (char) 3, (char) 2, (char) 3, (char) 4, (char) 2, (char) 3}, 146 new char[] {(char) 2, (char) 3, (char) 4})) 147 .isEqualTo(2); 148 assertThat( 149 Chars.indexOf( 150 new char[] {(char) 2, (char) 2, (char) 3, (char) 4, (char) 2, (char) 3, (char) 4}, 151 new char[] {(char) 2, (char) 3, (char) 4})) 152 .isEqualTo(1); 153 assertThat( 154 Chars.indexOf( 155 new char[] {(char) 4, (char) 3, (char) 2}, 156 new char[] {(char) 2, (char) 3, (char) 4})) 157 .isEqualTo(-1); 158 } 159 testLastIndexOf()160 public void testLastIndexOf() { 161 assertThat(Chars.lastIndexOf(EMPTY, (char) 1)).isEqualTo(-1); 162 assertThat(Chars.lastIndexOf(ARRAY1, (char) 2)).isEqualTo(-1); 163 assertThat(Chars.lastIndexOf(ARRAY234, (char) 1)).isEqualTo(-1); 164 assertThat(Chars.lastIndexOf(new char[] {(char) -1}, (char) -1)).isEqualTo(0); 165 assertThat(Chars.lastIndexOf(ARRAY234, (char) 2)).isEqualTo(0); 166 assertThat(Chars.lastIndexOf(ARRAY234, (char) 3)).isEqualTo(1); 167 assertThat(Chars.lastIndexOf(ARRAY234, (char) 4)).isEqualTo(2); 168 assertThat(Chars.lastIndexOf(new char[] {(char) 2, (char) 3, (char) 2, (char) 3}, (char) 3)) 169 .isEqualTo(3); 170 } 171 testMax_noArgs()172 public void testMax_noArgs() { 173 try { 174 Chars.max(); 175 fail(); 176 } catch (IllegalArgumentException expected) { 177 } 178 } 179 testMax()180 public void testMax() { 181 assertThat(Chars.max(LEAST)).isEqualTo(LEAST); 182 assertThat(Chars.max(GREATEST)).isEqualTo(GREATEST); 183 assertThat(Chars.max((char) 8, (char) 6, (char) 7, (char) 5, (char) 3, (char) 0, (char) 9)) 184 .isEqualTo((char) 9); 185 } 186 testMin_noArgs()187 public void testMin_noArgs() { 188 try { 189 Chars.min(); 190 fail(); 191 } catch (IllegalArgumentException expected) { 192 } 193 } 194 testMin()195 public void testMin() { 196 assertThat(Chars.min(LEAST)).isEqualTo(LEAST); 197 assertThat(Chars.min(GREATEST)).isEqualTo(GREATEST); 198 assertThat(Chars.min((char) 8, (char) 6, (char) 7, (char) 5, (char) 3, (char) 0, (char) 9)) 199 .isEqualTo((char) 0); 200 } 201 testConstrainToRange()202 public void testConstrainToRange() { 203 assertThat(Chars.constrainToRange((char) 1, (char) 0, (char) 5)).isEqualTo((char) 1); 204 assertThat(Chars.constrainToRange((char) 1, (char) 1, (char) 5)).isEqualTo((char) 1); 205 assertThat(Chars.constrainToRange((char) 1, (char) 3, (char) 5)).isEqualTo((char) 3); 206 assertThat(Chars.constrainToRange((char) 255, (char) 250, (char) 254)).isEqualTo((char) 254); 207 assertThat(Chars.constrainToRange((char) 5, (char) 2, (char) 2)).isEqualTo((char) 2); 208 try { 209 Chars.constrainToRange((char) 1, (char) 3, (char) 2); 210 fail(); 211 } catch (IllegalArgumentException expected) { 212 } 213 } 214 testConcat()215 public void testConcat() { 216 assertThat(Chars.concat()).isEqualTo(EMPTY); 217 assertThat(Chars.concat(EMPTY)).isEqualTo(EMPTY); 218 assertThat(Chars.concat(EMPTY, EMPTY, EMPTY)).isEqualTo(EMPTY); 219 assertThat(Chars.concat(ARRAY1)).isEqualTo(ARRAY1); 220 assertThat(Chars.concat(ARRAY1)).isNotSameInstanceAs(ARRAY1); 221 assertThat(Chars.concat(EMPTY, ARRAY1, EMPTY)).isEqualTo(ARRAY1); 222 assertThat(Chars.concat(ARRAY1, ARRAY1, ARRAY1)) 223 .isEqualTo(new char[] {(char) 1, (char) 1, (char) 1}); 224 assertThat(Chars.concat(ARRAY1, ARRAY234)) 225 .isEqualTo(new char[] {(char) 1, (char) 2, (char) 3, (char) 4}); 226 } 227 228 @J2ktIncompatible 229 @GwtIncompatible // Chars.fromByteArray testFromByteArray()230 public void testFromByteArray() { 231 assertThat(Chars.fromByteArray(new byte[] {0x23, 0x45, (byte) 0xDC})).isEqualTo('\u2345'); 232 assertThat(Chars.fromByteArray(new byte[] {(byte) 0xFE, (byte) 0xDC})).isEqualTo('\uFEDC'); 233 } 234 235 @J2ktIncompatible 236 @GwtIncompatible // Chars.fromByteArray testFromByteArrayFails()237 public void testFromByteArrayFails() { 238 try { 239 Chars.fromByteArray(new byte[Chars.BYTES - 1]); 240 fail(); 241 } catch (IllegalArgumentException expected) { 242 } 243 } 244 245 @J2ktIncompatible 246 @GwtIncompatible // Chars.fromBytes testFromBytes()247 public void testFromBytes() { 248 assertThat(Chars.fromBytes((byte) 0x23, (byte) 0x45)).isEqualTo('\u2345'); 249 assertThat(Chars.fromBytes((byte) 0xFE, (byte) 0xDC)).isEqualTo('\uFEDC'); 250 } 251 252 @J2ktIncompatible 253 @GwtIncompatible // Chars.fromByteArray, Chars.toByteArray testByteArrayRoundTrips()254 public void testByteArrayRoundTrips() { 255 char c = 0; 256 for (int hi = 0; hi < 256; hi++) { 257 for (int lo = 0; lo < 256; lo++) { 258 char result = Chars.fromByteArray(new byte[] {(byte) hi, (byte) lo}); 259 assertWithMessage( 260 String.format( 261 Locale.ROOT, 262 "hi=%s, lo=%s, expected=%s, result=%s", 263 hi, 264 lo, 265 (int) c, 266 (int) result)) 267 .that(result) 268 .isEqualTo(c); 269 270 byte[] bytes = Chars.toByteArray(c); 271 assertThat(bytes[0]).isEqualTo((byte) hi); 272 assertThat(bytes[1]).isEqualTo((byte) lo); 273 274 c++; 275 } 276 } 277 assertThat(c).isEqualTo((char) 0); // sanity check 278 } 279 280 @J2ktIncompatible 281 @GwtIncompatible // Chars.fromByteArray, Chars.toByteArray testByteArrayRoundTripsFails()282 public void testByteArrayRoundTripsFails() { 283 try { 284 Chars.fromByteArray(new byte[] {0x11}); 285 fail(); 286 } catch (IllegalArgumentException expected) { 287 } 288 } 289 testEnsureCapacity()290 public void testEnsureCapacity() { 291 assertThat(Chars.ensureCapacity(EMPTY, 0, 1)).isSameInstanceAs(EMPTY); 292 assertThat(Chars.ensureCapacity(ARRAY1, 0, 1)).isSameInstanceAs(ARRAY1); 293 assertThat(Chars.ensureCapacity(ARRAY1, 1, 1)).isSameInstanceAs(ARRAY1); 294 assertThat(Chars.ensureCapacity(ARRAY1, 2, 1)) 295 .isEqualTo(new char[] {(char) 1, (char) 0, (char) 0}); 296 } 297 testEnsureCapacity_fail()298 public void testEnsureCapacity_fail() { 299 try { 300 Chars.ensureCapacity(ARRAY1, -1, 1); 301 fail(); 302 } catch (IllegalArgumentException expected) { 303 } 304 try { 305 // notice that this should even fail when no growth was needed 306 Chars.ensureCapacity(ARRAY1, 1, -1); 307 fail(); 308 } catch (IllegalArgumentException expected) { 309 } 310 } 311 testJoin()312 public void testJoin() { 313 assertThat(Chars.join(",", EMPTY)).isEmpty(); 314 assertThat(Chars.join(",", '1')).isEqualTo("1"); 315 assertThat(Chars.join(",", '1', '2')).isEqualTo("1,2"); 316 assertThat(Chars.join("", '1', '2', '3')).isEqualTo("123"); 317 } 318 testLexicographicalComparator()319 public void testLexicographicalComparator() { 320 List<char[]> ordered = 321 Arrays.asList( 322 new char[] {}, 323 new char[] {LEAST}, 324 new char[] {LEAST, LEAST}, 325 new char[] {LEAST, (char) 1}, 326 new char[] {(char) 1}, 327 new char[] {(char) 1, LEAST}, 328 new char[] {GREATEST, GREATEST - (char) 1}, 329 new char[] {GREATEST, GREATEST}, 330 new char[] {GREATEST, GREATEST, GREATEST}); 331 332 Comparator<char[]> comparator = Chars.lexicographicalComparator(); 333 Helpers.testComparator(comparator, ordered); 334 } 335 336 @J2ktIncompatible 337 @GwtIncompatible // SerializableTester testLexicographicalComparatorSerializable()338 public void testLexicographicalComparatorSerializable() { 339 Comparator<char[]> comparator = Chars.lexicographicalComparator(); 340 assertThat(SerializableTester.reserialize(comparator)).isSameInstanceAs(comparator); 341 } 342 testReverse()343 public void testReverse() { 344 testReverse(new char[] {}, new char[] {}); 345 testReverse(new char[] {'1'}, new char[] {'1'}); 346 testReverse(new char[] {'1', '2'}, new char[] {'2', '1'}); 347 testReverse(new char[] {'3', '1', '1'}, new char[] {'1', '1', '3'}); 348 testReverse(new char[] {'A', '1', 'B', '2'}, new char[] {'2', 'B', '1', 'A'}); 349 } 350 testReverse(char[] input, char[] expectedOutput)351 private static void testReverse(char[] input, char[] expectedOutput) { 352 input = Arrays.copyOf(input, input.length); 353 Chars.reverse(input); 354 assertThat(input).isEqualTo(expectedOutput); 355 } 356 testReverse(char[] input, int fromIndex, int toIndex, char[] expectedOutput)357 private static void testReverse(char[] input, int fromIndex, int toIndex, char[] expectedOutput) { 358 input = Arrays.copyOf(input, input.length); 359 Chars.reverse(input, fromIndex, toIndex); 360 assertThat(input).isEqualTo(expectedOutput); 361 } 362 testReverseIndexed()363 public void testReverseIndexed() { 364 testReverse(new char[] {}, 0, 0, new char[] {}); 365 testReverse(new char[] {'1'}, 0, 1, new char[] {'1'}); 366 testReverse(new char[] {'1', '2'}, 0, 2, new char[] {'2', '1'}); 367 testReverse(new char[] {'3', '1', '1'}, 0, 2, new char[] {'1', '3', '1'}); 368 testReverse(new char[] {'3', '1', '1'}, 0, 1, new char[] {'3', '1', '1'}); 369 testReverse(new char[] {'A', '1', 'B', '2'}, 1, 3, new char[] {'A', 'B', '1', '2'}); 370 } 371 testRotate(char[] input, int distance, char[] expectedOutput)372 private static void testRotate(char[] input, int distance, char[] expectedOutput) { 373 input = Arrays.copyOf(input, input.length); 374 Chars.rotate(input, distance); 375 assertThat(input).isEqualTo(expectedOutput); 376 } 377 testRotate( char[] input, int distance, int fromIndex, int toIndex, char[] expectedOutput)378 private static void testRotate( 379 char[] input, int distance, int fromIndex, int toIndex, char[] expectedOutput) { 380 input = Arrays.copyOf(input, input.length); 381 Chars.rotate(input, distance, fromIndex, toIndex); 382 assertThat(input).isEqualTo(expectedOutput); 383 } 384 testRotate()385 public void testRotate() { 386 testRotate(new char[] {}, -1, new char[] {}); 387 testRotate(new char[] {}, 0, new char[] {}); 388 testRotate(new char[] {}, 1, new char[] {}); 389 390 testRotate(new char[] {'1'}, -2, new char[] {'1'}); 391 testRotate(new char[] {'1'}, -1, new char[] {'1'}); 392 testRotate(new char[] {'1'}, 0, new char[] {'1'}); 393 testRotate(new char[] {'1'}, 1, new char[] {'1'}); 394 testRotate(new char[] {'1'}, 2, new char[] {'1'}); 395 396 testRotate(new char[] {'1', '2'}, -3, new char[] {'2', '1'}); 397 testRotate(new char[] {'1', '2'}, -1, new char[] {'2', '1'}); 398 testRotate(new char[] {'1', '2'}, -2, new char[] {'1', '2'}); 399 testRotate(new char[] {'1', '2'}, 0, new char[] {'1', '2'}); 400 testRotate(new char[] {'1', '2'}, 1, new char[] {'2', '1'}); 401 testRotate(new char[] {'1', '2'}, 2, new char[] {'1', '2'}); 402 testRotate(new char[] {'1', '2'}, 3, new char[] {'2', '1'}); 403 404 testRotate(new char[] {'1', '2', '3'}, -5, new char[] {'3', '1', '2'}); 405 testRotate(new char[] {'1', '2', '3'}, -4, new char[] {'2', '3', '1'}); 406 testRotate(new char[] {'1', '2', '3'}, -3, new char[] {'1', '2', '3'}); 407 testRotate(new char[] {'1', '2', '3'}, -2, new char[] {'3', '1', '2'}); 408 testRotate(new char[] {'1', '2', '3'}, -1, new char[] {'2', '3', '1'}); 409 testRotate(new char[] {'1', '2', '3'}, 0, new char[] {'1', '2', '3'}); 410 testRotate(new char[] {'1', '2', '3'}, 1, new char[] {'3', '1', '2'}); 411 testRotate(new char[] {'1', '2', '3'}, 2, new char[] {'2', '3', '1'}); 412 testRotate(new char[] {'1', '2', '3'}, 3, new char[] {'1', '2', '3'}); 413 testRotate(new char[] {'1', '2', '3'}, 4, new char[] {'3', '1', '2'}); 414 testRotate(new char[] {'1', '2', '3'}, 5, new char[] {'2', '3', '1'}); 415 416 testRotate(new char[] {'1', '2', '3', '4'}, -9, new char[] {'2', '3', '4', '1'}); 417 testRotate(new char[] {'1', '2', '3', '4'}, -5, new char[] {'2', '3', '4', '1'}); 418 testRotate(new char[] {'1', '2', '3', '4'}, -1, new char[] {'2', '3', '4', '1'}); 419 testRotate(new char[] {'1', '2', '3', '4'}, 0, new char[] {'1', '2', '3', '4'}); 420 testRotate(new char[] {'1', '2', '3', '4'}, 1, new char[] {'4', '1', '2', '3'}); 421 testRotate(new char[] {'1', '2', '3', '4'}, 5, new char[] {'4', '1', '2', '3'}); 422 testRotate(new char[] {'1', '2', '3', '4'}, 9, new char[] {'4', '1', '2', '3'}); 423 424 testRotate(new char[] {'1', '2', '3', '4', '5'}, -6, new char[] {'2', '3', '4', '5', '1'}); 425 testRotate(new char[] {'1', '2', '3', '4', '5'}, -4, new char[] {'5', '1', '2', '3', '4'}); 426 testRotate(new char[] {'1', '2', '3', '4', '5'}, -3, new char[] {'4', '5', '1', '2', '3'}); 427 testRotate(new char[] {'1', '2', '3', '4', '5'}, -1, new char[] {'2', '3', '4', '5', '1'}); 428 testRotate(new char[] {'1', '2', '3', '4', '5'}, 0, new char[] {'1', '2', '3', '4', '5'}); 429 testRotate(new char[] {'1', '2', '3', '4', '5'}, 1, new char[] {'5', '1', '2', '3', '4'}); 430 testRotate(new char[] {'1', '2', '3', '4', '5'}, 3, new char[] {'3', '4', '5', '1', '2'}); 431 testRotate(new char[] {'1', '2', '3', '4', '5'}, 4, new char[] {'2', '3', '4', '5', '1'}); 432 testRotate(new char[] {'1', '2', '3', '4', '5'}, 6, new char[] {'5', '1', '2', '3', '4'}); 433 } 434 testRotateIndexed()435 public void testRotateIndexed() { 436 testRotate(new char[] {}, 0, 0, 0, new char[] {}); 437 438 testRotate(new char[] {'1'}, 0, 0, 1, new char[] {'1'}); 439 testRotate(new char[] {'1'}, 1, 0, 1, new char[] {'1'}); 440 testRotate(new char[] {'1'}, 1, 1, 1, new char[] {'1'}); 441 442 // Rotate the central 5 elements, leaving the ends as-is 443 testRotate( 444 new char[] {'0', '1', '2', '3', '4', '5', '6'}, 445 -6, 446 1, 447 6, 448 new char[] {'0', '2', '3', '4', '5', '1', '6'}); 449 testRotate( 450 new char[] {'0', '1', '2', '3', '4', '5', '6'}, 451 -1, 452 1, 453 6, 454 new char[] {'0', '2', '3', '4', '5', '1', '6'}); 455 testRotate( 456 new char[] {'0', '1', '2', '3', '4', '5', '6'}, 457 0, 458 1, 459 6, 460 new char[] {'0', '1', '2', '3', '4', '5', '6'}); 461 testRotate( 462 new char[] {'0', '1', '2', '3', '4', '5', '6'}, 463 5, 464 1, 465 6, 466 new char[] {'0', '1', '2', '3', '4', '5', '6'}); 467 testRotate( 468 new char[] {'0', '1', '2', '3', '4', '5', '6'}, 469 14, 470 1, 471 6, 472 new char[] {'0', '2', '3', '4', '5', '1', '6'}); 473 474 // Rotate the first three elements 475 testRotate( 476 new char[] {'0', '1', '2', '3', '4', '5', '6'}, 477 -2, 478 0, 479 3, 480 new char[] {'2', '0', '1', '3', '4', '5', '6'}); 481 testRotate( 482 new char[] {'0', '1', '2', '3', '4', '5', '6'}, 483 -1, 484 0, 485 3, 486 new char[] {'1', '2', '0', '3', '4', '5', '6'}); 487 testRotate( 488 new char[] {'0', '1', '2', '3', '4', '5', '6'}, 489 0, 490 0, 491 3, 492 new char[] {'0', '1', '2', '3', '4', '5', '6'}); 493 testRotate( 494 new char[] {'0', '1', '2', '3', '4', '5', '6'}, 495 1, 496 0, 497 3, 498 new char[] {'2', '0', '1', '3', '4', '5', '6'}); 499 testRotate( 500 new char[] {'0', '1', '2', '3', '4', '5', '6'}, 501 2, 502 0, 503 3, 504 new char[] {'1', '2', '0', '3', '4', '5', '6'}); 505 506 // Rotate the last four elements 507 testRotate( 508 new char[] {'0', '1', '2', '3', '4', '5', '6'}, 509 -6, 510 3, 511 7, 512 new char[] {'0', '1', '2', '5', '6', '3', '4'}); 513 testRotate( 514 new char[] {'0', '1', '2', '3', '4', '5', '6'}, 515 -5, 516 3, 517 7, 518 new char[] {'0', '1', '2', '4', '5', '6', '3'}); 519 testRotate( 520 new char[] {'0', '1', '2', '3', '4', '5', '6'}, 521 -4, 522 3, 523 7, 524 new char[] {'0', '1', '2', '3', '4', '5', '6'}); 525 testRotate( 526 new char[] {'0', '1', '2', '3', '4', '5', '6'}, 527 -3, 528 3, 529 7, 530 new char[] {'0', '1', '2', '6', '3', '4', '5'}); 531 testRotate( 532 new char[] {'0', '1', '2', '3', '4', '5', '6'}, 533 -2, 534 3, 535 7, 536 new char[] {'0', '1', '2', '5', '6', '3', '4'}); 537 testRotate( 538 new char[] {'0', '1', '2', '3', '4', '5', '6'}, 539 -1, 540 3, 541 7, 542 new char[] {'0', '1', '2', '4', '5', '6', '3'}); 543 testRotate( 544 new char[] {'0', '1', '2', '3', '4', '5', '6'}, 545 0, 546 3, 547 7, 548 new char[] {'0', '1', '2', '3', '4', '5', '6'}); 549 testRotate( 550 new char[] {'0', '1', '2', '3', '4', '5', '6'}, 551 1, 552 3, 553 7, 554 new char[] {'0', '1', '2', '6', '3', '4', '5'}); 555 testRotate( 556 new char[] {'0', '1', '2', '3', '4', '5', '6'}, 557 2, 558 3, 559 7, 560 new char[] {'0', '1', '2', '5', '6', '3', '4'}); 561 testRotate( 562 new char[] {'0', '1', '2', '3', '4', '5', '6'}, 563 3, 564 3, 565 7, 566 new char[] {'0', '1', '2', '4', '5', '6', '3'}); 567 } 568 testSortDescending()569 public void testSortDescending() { 570 testSortDescending(new char[] {}, new char[] {}); 571 testSortDescending(new char[] {'1'}, new char[] {'1'}); 572 testSortDescending(new char[] {'1', '2'}, new char[] {'2', '1'}); 573 testSortDescending(new char[] {'1', '3', '1'}, new char[] {'3', '1', '1'}); 574 testSortDescending(new char[] {'A', '1', 'B', '2'}, new char[] {'B', 'A', '2', '1'}); 575 } 576 testSortDescending(char[] input, char[] expectedOutput)577 private static void testSortDescending(char[] input, char[] expectedOutput) { 578 input = Arrays.copyOf(input, input.length); 579 Chars.sortDescending(input); 580 assertThat(input).isEqualTo(expectedOutput); 581 } 582 testSortDescending( char[] input, int fromIndex, int toIndex, char[] expectedOutput)583 private static void testSortDescending( 584 char[] input, int fromIndex, int toIndex, char[] expectedOutput) { 585 input = Arrays.copyOf(input, input.length); 586 Chars.sortDescending(input, fromIndex, toIndex); 587 assertThat(input).isEqualTo(expectedOutput); 588 } 589 testSortDescendingIndexed()590 public void testSortDescendingIndexed() { 591 testSortDescending(new char[] {}, 0, 0, new char[] {}); 592 testSortDescending(new char[] {'1'}, 0, 1, new char[] {'1'}); 593 testSortDescending(new char[] {'1', '2'}, 0, 2, new char[] {'2', '1'}); 594 testSortDescending(new char[] {'1', '3', '1'}, 0, 2, new char[] {'3', '1', '1'}); 595 testSortDescending(new char[] {'1', '3', '1'}, 0, 1, new char[] {'1', '3', '1'}); 596 testSortDescending(new char[] {'A', '1', 'B', '2'}, 1, 3, new char[] {'A', 'B', '1', '2'}); 597 } 598 testToArray()599 public void testToArray() { 600 // need explicit type parameter to avoid javac warning!? 601 List<Character> none = Arrays.<Character>asList(); 602 assertThat(Chars.toArray(none)).isEqualTo(EMPTY); 603 604 List<Character> one = Arrays.asList((char) 1); 605 assertThat(Chars.toArray(one)).isEqualTo(ARRAY1); 606 607 char[] array = {(char) 0, (char) 1, 'A'}; 608 609 List<Character> three = Arrays.asList((char) 0, (char) 1, 'A'); 610 assertThat(Chars.toArray(three)).isEqualTo(array); 611 612 assertThat(Chars.toArray(Chars.asList(array))).isEqualTo(array); 613 } 614 testToArray_threadSafe()615 public void testToArray_threadSafe() { 616 for (int delta : new int[] {+1, 0, -1}) { 617 for (int i = 0; i < VALUES.length; i++) { 618 List<Character> list = Chars.asList(VALUES).subList(0, i); 619 Collection<Character> misleadingSize = Helpers.misleadingSizeCollection(delta); 620 misleadingSize.addAll(list); 621 char[] arr = Chars.toArray(misleadingSize); 622 assertThat(arr).hasLength(i); 623 for (int j = 0; j < i; j++) { 624 assertThat(arr[j]).isEqualTo(VALUES[j]); 625 } 626 } 627 } 628 } 629 testToArray_withNull()630 public void testToArray_withNull() { 631 List<@Nullable Character> list = Arrays.asList((char) 0, (char) 1, null); 632 try { 633 Chars.toArray(list); 634 fail(); 635 } catch (NullPointerException expected) { 636 } 637 } 638 639 @J2ktIncompatible // b/285319375 testAsList_isAView()640 public void testAsList_isAView() { 641 char[] array = {(char) 0, (char) 1}; 642 List<Character> list = Chars.asList(array); 643 list.set(0, (char) 2); 644 assertThat(array).isEqualTo(new char[] {(char) 2, (char) 1}); 645 array[1] = (char) 3; 646 assertThat(list).containsExactly((char) 2, (char) 3).inOrder(); 647 } 648 testAsList_toArray_roundTrip()649 public void testAsList_toArray_roundTrip() { 650 char[] array = {(char) 0, (char) 1, (char) 2}; 651 List<Character> list = Chars.asList(array); 652 char[] newArray = Chars.toArray(list); 653 654 // Make sure it returned a copy 655 list.set(0, (char) 4); 656 assertThat(newArray).isEqualTo(new char[] {(char) 0, (char) 1, (char) 2}); 657 newArray[1] = (char) 5; 658 assertThat((char) list.get(1)).isEqualTo((char) 1); 659 } 660 661 // This test stems from a real bug found by andrewk testAsList_subList_toArray_roundTrip()662 public void testAsList_subList_toArray_roundTrip() { 663 char[] array = {(char) 0, (char) 1, (char) 2, (char) 3}; 664 List<Character> list = Chars.asList(array); 665 assertThat(Chars.toArray(list.subList(1, 3))).isEqualTo(new char[] {(char) 1, (char) 2}); 666 assertThat(Chars.toArray(list.subList(2, 2))).isEqualTo(new char[] {}); 667 } 668 testAsListEmpty()669 public void testAsListEmpty() { 670 assertThat(Chars.asList(EMPTY)).isSameInstanceAs(Collections.emptyList()); 671 } 672 673 @J2ktIncompatible 674 @GwtIncompatible // NullPointerTester testNulls()675 public void testNulls() { 676 new NullPointerTester().testAllPublicStaticMethods(Chars.class); 677 } 678 } 679