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