1 /* 2 * Copyright (C) 2007 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.collect; 18 19 import static com.google.common.collect.Iterables.getOnlyElement; 20 import static com.google.common.collect.Iterables.unmodifiableIterable; 21 import static com.google.common.collect.Sets.newHashSet; 22 import static java.lang.reflect.Proxy.newProxyInstance; 23 import static java.util.Arrays.asList; 24 25 import com.google.common.annotations.GwtCompatible; 26 import com.google.common.annotations.GwtIncompatible; 27 import com.google.common.collect.testing.Helpers; 28 import com.google.common.collect.testing.ListTestSuiteBuilder; 29 import com.google.common.collect.testing.MinimalCollection; 30 import com.google.common.collect.testing.MinimalIterable; 31 import com.google.common.collect.testing.features.CollectionFeature; 32 import com.google.common.collect.testing.features.CollectionSize; 33 import com.google.common.collect.testing.google.ListGenerators.BuilderAddAllListGenerator; 34 import com.google.common.collect.testing.google.ListGenerators.BuilderReversedListGenerator; 35 import com.google.common.collect.testing.google.ListGenerators.ImmutableListHeadSubListGenerator; 36 import com.google.common.collect.testing.google.ListGenerators.ImmutableListMiddleSubListGenerator; 37 import com.google.common.collect.testing.google.ListGenerators.ImmutableListOfGenerator; 38 import com.google.common.collect.testing.google.ListGenerators.ImmutableListTailSubListGenerator; 39 import com.google.common.collect.testing.google.ListGenerators.UnhashableElementsImmutableListGenerator; 40 import com.google.common.collect.testing.testers.ListHashCodeTester; 41 import com.google.common.testing.NullPointerTester; 42 import com.google.common.testing.SerializableTester; 43 44 import junit.framework.Test; 45 import junit.framework.TestCase; 46 import junit.framework.TestSuite; 47 48 import java.lang.reflect.InvocationHandler; 49 import java.lang.reflect.InvocationTargetException; 50 import java.lang.reflect.Method; 51 import java.util.Arrays; 52 import java.util.Collection; 53 import java.util.Collections; 54 import java.util.Iterator; 55 import java.util.List; 56 import java.util.Set; 57 import java.util.concurrent.CopyOnWriteArrayList; 58 59 /** 60 * Unit test for {@link ImmutableList}. 61 * 62 * @author Kevin Bourrillion 63 * @author George van den Driessche 64 * @author Jared Levy 65 */ 66 @GwtCompatible(emulated = true) 67 public class ImmutableListTest extends TestCase { 68 69 @GwtIncompatible("suite") suite()70 public static Test suite() { 71 TestSuite suite = new TestSuite(); 72 suite.addTest(ListTestSuiteBuilder.using(new ImmutableListOfGenerator()) 73 .named("ImmutableList") 74 .withFeatures(CollectionSize.ANY, 75 CollectionFeature.SERIALIZABLE, 76 CollectionFeature.ALLOWS_NULL_QUERIES) 77 .createTestSuite()); 78 suite.addTest(ListTestSuiteBuilder.using(new BuilderAddAllListGenerator()) 79 .named("ImmutableList, built with Builder.add") 80 .withFeatures(CollectionSize.ANY, 81 CollectionFeature.SERIALIZABLE, 82 CollectionFeature.ALLOWS_NULL_QUERIES) 83 .createTestSuite()); 84 suite.addTest(ListTestSuiteBuilder.using(new BuilderAddAllListGenerator()) 85 .named("ImmutableList, built with Builder.addAll") 86 .withFeatures(CollectionSize.ANY, 87 CollectionFeature.SERIALIZABLE, 88 CollectionFeature.ALLOWS_NULL_QUERIES) 89 .createTestSuite()); 90 suite.addTest(ListTestSuiteBuilder.using(new BuilderReversedListGenerator()) 91 .named("ImmutableList, reversed") 92 .withFeatures(CollectionSize.ANY, 93 CollectionFeature.SERIALIZABLE, 94 CollectionFeature.ALLOWS_NULL_QUERIES) 95 .createTestSuite()); 96 suite.addTest(ListTestSuiteBuilder.using( 97 new ImmutableListHeadSubListGenerator()) 98 .named("ImmutableList, head subList") 99 .withFeatures(CollectionSize.ANY, 100 CollectionFeature.SERIALIZABLE, 101 CollectionFeature.ALLOWS_NULL_QUERIES) 102 .createTestSuite()); 103 suite.addTest(ListTestSuiteBuilder.using( 104 new ImmutableListTailSubListGenerator()) 105 .named("ImmutableList, tail subList") 106 .withFeatures(CollectionSize.ANY, 107 CollectionFeature.SERIALIZABLE, 108 CollectionFeature.ALLOWS_NULL_QUERIES) 109 .createTestSuite()); 110 suite.addTest(ListTestSuiteBuilder.using( 111 new ImmutableListMiddleSubListGenerator()) 112 .named("ImmutableList, middle subList") 113 .withFeatures(CollectionSize.ANY, 114 CollectionFeature.SERIALIZABLE, 115 CollectionFeature.ALLOWS_NULL_QUERIES) 116 .createTestSuite()); 117 suite.addTest(ListTestSuiteBuilder.using( 118 new UnhashableElementsImmutableListGenerator()) 119 .suppressing(ListHashCodeTester.getHashCodeMethod()) 120 .named("ImmutableList, unhashable values") 121 .withFeatures(CollectionSize.ANY, 122 CollectionFeature.ALLOWS_NULL_QUERIES) 123 .createTestSuite()); 124 return suite; 125 } 126 127 public static class CreationTests extends TestCase { testCreation_noArgs()128 public void testCreation_noArgs() { 129 List<String> list = ImmutableList.of(); 130 assertEquals(Collections.emptyList(), list); 131 } 132 testCreation_oneElement()133 public void testCreation_oneElement() { 134 List<String> list = ImmutableList.of("a"); 135 assertEquals(Collections.singletonList("a"), list); 136 } 137 testCreation_twoElements()138 public void testCreation_twoElements() { 139 List<String> list = ImmutableList.of("a", "b"); 140 assertEquals(Lists.newArrayList("a", "b"), list); 141 } 142 testCreation_threeElements()143 public void testCreation_threeElements() { 144 List<String> list = ImmutableList.of("a", "b", "c"); 145 assertEquals(Lists.newArrayList("a", "b", "c"), list); 146 } 147 testCreation_fourElements()148 public void testCreation_fourElements() { 149 List<String> list = ImmutableList.of("a", "b", "c", "d"); 150 assertEquals(Lists.newArrayList("a", "b", "c", "d"), list); 151 } 152 testCreation_fiveElements()153 public void testCreation_fiveElements() { 154 List<String> list = ImmutableList.of("a", "b", "c", "d", "e"); 155 assertEquals(Lists.newArrayList("a", "b", "c", "d", "e"), list); 156 } 157 testCreation_sixElements()158 public void testCreation_sixElements() { 159 List<String> list = ImmutableList.of("a", "b", "c", "d", "e", "f"); 160 assertEquals(Lists.newArrayList("a", "b", "c", "d", "e", "f"), list); 161 } 162 testCreation_sevenElements()163 public void testCreation_sevenElements() { 164 List<String> list = ImmutableList.of("a", "b", "c", "d", "e", "f", "g"); 165 assertEquals(Lists.newArrayList("a", "b", "c", "d", "e", "f", "g"), list); 166 } 167 testCreation_eightElements()168 public void testCreation_eightElements() { 169 List<String> list = ImmutableList.of( 170 "a", "b", "c", "d", "e", "f", "g", "h"); 171 assertEquals(Lists.newArrayList( 172 "a", "b", "c", "d", "e", "f", "g", "h"), list); 173 } 174 testCreation_nineElements()175 public void testCreation_nineElements() { 176 List<String> list = ImmutableList.of( 177 "a", "b", "c", "d", "e", "f", "g", "h", "i"); 178 assertEquals(Lists.newArrayList( 179 "a", "b", "c", "d", "e", "f", "g", "h", "i"), list); 180 } 181 testCreation_tenElements()182 public void testCreation_tenElements() { 183 List<String> list = ImmutableList.of( 184 "a", "b", "c", "d", "e", "f", "g", "h", "i", "j"); 185 assertEquals(Lists.newArrayList( 186 "a", "b", "c", "d", "e", "f", "g", "h", "i", "j"), list); 187 } 188 testCreation_elevenElements()189 public void testCreation_elevenElements() { 190 List<String> list = ImmutableList.of( 191 "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"); 192 assertEquals(Lists.newArrayList( 193 "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"), list); 194 } 195 196 // Varargs versions 197 testCreation_twelveElements()198 public void testCreation_twelveElements() { 199 List<String> list = ImmutableList.of( 200 "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l"); 201 assertEquals(Lists.newArrayList( 202 "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l"), list); 203 } 204 testCreation_thirteenElements()205 public void testCreation_thirteenElements() { 206 List<String> list = ImmutableList.of( 207 "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m"); 208 assertEquals(Lists.newArrayList( 209 "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m"), 210 list); 211 } 212 testCreation_fourteenElements()213 public void testCreation_fourteenElements() { 214 List<String> list = ImmutableList.of( 215 "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n"); 216 assertEquals(Lists.newArrayList( 217 "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n"), 218 list); 219 } 220 testCreation_singletonNull()221 public void testCreation_singletonNull() { 222 try { 223 ImmutableList.of((String) null); 224 fail(); 225 } catch (NullPointerException expected) { 226 } 227 } 228 testCreation_withNull()229 public void testCreation_withNull() { 230 try { 231 ImmutableList.of("a", null, "b"); 232 fail(); 233 } catch (NullPointerException expected) { 234 } 235 } 236 testCreation_generic()237 public void testCreation_generic() { 238 List<String> a = ImmutableList.of("a"); 239 // only verify that there is no compile warning 240 ImmutableList.of(a, a); 241 } 242 testCreation_arrayOfArray()243 public void testCreation_arrayOfArray() { 244 String[] array = new String[] { "a" }; 245 List<String[]> list = ImmutableList.<String[]>of(array); 246 assertEquals(Collections.singletonList(array), list); 247 } 248 testCopyOf_emptyArray()249 public void testCopyOf_emptyArray() { 250 String[] array = new String[0]; 251 List<String> list = ImmutableList.copyOf(array); 252 assertEquals(Collections.emptyList(), list); 253 } 254 testCopyOf_arrayOfOneElement()255 public void testCopyOf_arrayOfOneElement() { 256 String[] array = new String[] { "a" }; 257 List<String> list = ImmutableList.copyOf(array); 258 assertEquals(Collections.singletonList("a"), list); 259 } 260 testCopyOf_nullArray()261 public void testCopyOf_nullArray() { 262 try { 263 ImmutableList.copyOf((String[]) null); 264 fail(); 265 } catch (NullPointerException expected) { 266 } 267 } 268 testCopyOf_arrayContainingOnlyNull()269 public void testCopyOf_arrayContainingOnlyNull() { 270 String[] array = new String[] { null }; 271 try { 272 ImmutableList.copyOf(array); 273 fail(); 274 } catch (NullPointerException expected) { 275 } 276 } 277 testCopyOf_collection_empty()278 public void testCopyOf_collection_empty() { 279 // "<String>" is required to work around a javac 1.5 bug. 280 Collection<String> c = MinimalCollection.<String>of(); 281 List<String> list = ImmutableList.copyOf(c); 282 assertEquals(Collections.emptyList(), list); 283 } 284 testCopyOf_collection_oneElement()285 public void testCopyOf_collection_oneElement() { 286 Collection<String> c = MinimalCollection.of("a"); 287 List<String> list = ImmutableList.copyOf(c); 288 assertEquals(Collections.singletonList("a"), list); 289 } 290 testCopyOf_collection_general()291 public void testCopyOf_collection_general() { 292 Collection<String> c = MinimalCollection.of("a", "b", "a"); 293 List<String> list = ImmutableList.copyOf(c); 294 assertEquals(asList("a", "b", "a"), list); 295 List<String> mutableList = asList("a", "b"); 296 list = ImmutableList.copyOf(mutableList); 297 mutableList.set(0, "c"); 298 assertEquals(asList("a", "b"), list); 299 } 300 testCopyOf_collectionContainingNull()301 public void testCopyOf_collectionContainingNull() { 302 Collection<String> c = MinimalCollection.of("a", null, "b"); 303 try { 304 ImmutableList.copyOf(c); 305 fail(); 306 } catch (NullPointerException expected) { 307 } 308 } 309 testCopyOf_iterator_empty()310 public void testCopyOf_iterator_empty() { 311 Iterator<String> iterator = Iterators.emptyIterator(); 312 List<String> list = ImmutableList.copyOf(iterator); 313 assertEquals(Collections.emptyList(), list); 314 } 315 testCopyOf_iterator_oneElement()316 public void testCopyOf_iterator_oneElement() { 317 Iterator<String> iterator = Iterators.singletonIterator("a"); 318 List<String> list = ImmutableList.copyOf(iterator); 319 assertEquals(Collections.singletonList("a"), list); 320 } 321 testCopyOf_iterator_general()322 public void testCopyOf_iterator_general() { 323 Iterator<String> iterator = asList("a", "b", "a").iterator(); 324 List<String> list = ImmutableList.copyOf(iterator); 325 assertEquals(asList("a", "b", "a"), list); 326 } 327 testCopyOf_iteratorContainingNull()328 public void testCopyOf_iteratorContainingNull() { 329 Iterator<String> iterator = asList("a", null, "b").iterator(); 330 try { 331 ImmutableList.copyOf(iterator); 332 fail(); 333 } catch (NullPointerException expected) { 334 } 335 } 336 testCopyOf_iteratorNull()337 public void testCopyOf_iteratorNull() { 338 try { 339 ImmutableList.copyOf((Iterator<String>) null); 340 fail(); 341 } catch (NullPointerException expected) { 342 } 343 } 344 testCopyOf_concurrentlyMutating()345 public void testCopyOf_concurrentlyMutating() { 346 List<String> sample = Lists.newArrayList("a", "b", "c"); 347 for (int delta : new int[] {-1, 0, 1}) { 348 for (int i = 0; i < sample.size(); i++) { 349 Collection<String> misleading = 350 Helpers.misleadingSizeCollection(delta); 351 List<String> expected = sample.subList(0, i); 352 misleading.addAll(expected); 353 assertEquals(expected, ImmutableList.copyOf(misleading)); 354 assertEquals(expected, 355 ImmutableList.copyOf((Iterable<String>) misleading)); 356 } 357 } 358 } 359 360 private static class CountingIterable implements Iterable<String> { 361 int count = 0; 362 @Override iterator()363 public Iterator<String> iterator() { 364 count++; 365 return asList("a", "b", "a").iterator(); 366 } 367 } 368 testCopyOf_plainIterable()369 public void testCopyOf_plainIterable() { 370 CountingIterable iterable = new CountingIterable(); 371 List<String> list = ImmutableList.copyOf(iterable); 372 assertEquals(asList("a", "b", "a"), list); 373 } 374 testCopyOf_plainIterable_iteratesOnce()375 public void testCopyOf_plainIterable_iteratesOnce() { 376 CountingIterable iterable = new CountingIterable(); 377 ImmutableList.copyOf(iterable); 378 assertEquals(1, iterable.count); 379 } 380 testCopyOf_shortcut_empty()381 public void testCopyOf_shortcut_empty() { 382 Collection<String> c = ImmutableList.of(); 383 assertSame(c, ImmutableList.copyOf(c)); 384 } 385 testCopyOf_shortcut_singleton()386 public void testCopyOf_shortcut_singleton() { 387 Collection<String> c = ImmutableList.of("a"); 388 assertSame(c, ImmutableList.copyOf(c)); 389 } 390 testCopyOf_shortcut_immutableList()391 public void testCopyOf_shortcut_immutableList() { 392 Collection<String> c = ImmutableList.of("a", "b", "c"); 393 assertSame(c, ImmutableList.copyOf(c)); 394 } 395 testBuilderAddArrayHandlesNulls()396 public void testBuilderAddArrayHandlesNulls() { 397 String[] elements = {"a", null, "b"}; 398 ImmutableList.Builder<String> builder = ImmutableList.builder(); 399 try { 400 builder.add(elements); 401 fail ("Expected NullPointerException"); 402 } catch (NullPointerException expected) { 403 } 404 ImmutableList<String> result = builder.build(); 405 406 /* 407 * Maybe it rejects all elements, or maybe it adds "a" before failing. 408 * Either way is fine with us. 409 */ 410 if (result.isEmpty()) { 411 return; 412 } 413 assertTrue(ImmutableList.of("a").equals(result)); 414 assertEquals(1, result.size()); 415 } 416 testBuilderAddCollectionHandlesNulls()417 public void testBuilderAddCollectionHandlesNulls() { 418 List<String> elements = Arrays.asList("a", null, "b"); 419 ImmutableList.Builder<String> builder = ImmutableList.builder(); 420 try { 421 builder.addAll(elements); 422 fail ("Expected NullPointerException"); 423 } catch (NullPointerException expected) { 424 } 425 ImmutableList<String> result = builder.build(); 426 assertEquals(ImmutableList.of("a"), result); 427 assertEquals(1, result.size()); 428 } 429 } 430 431 @GwtIncompatible("reflection") 432 public static class ConcurrentTests extends TestCase { 433 enum WrapWithIterable { WRAP, NO_WRAP } 434 runConcurrentlyMutatedTest( Collection<Integer> initialContents, Iterable<ListFrobber> actionsToPerformConcurrently, WrapWithIterable wrap)435 private static void runConcurrentlyMutatedTest( 436 Collection<Integer> initialContents, 437 Iterable<ListFrobber> actionsToPerformConcurrently, 438 WrapWithIterable wrap) { 439 ConcurrentlyMutatedList<Integer> concurrentlyMutatedList = 440 newConcurrentlyMutatedList( 441 initialContents, actionsToPerformConcurrently); 442 443 Iterable<Integer> iterableToCopy = wrap == WrapWithIterable.WRAP 444 ? unmodifiableIterable(concurrentlyMutatedList) 445 : concurrentlyMutatedList; 446 447 ImmutableList<Integer> copyOfIterable = 448 ImmutableList.copyOf(iterableToCopy); 449 450 assertTrue(concurrentlyMutatedList.getAllStates() 451 .contains(copyOfIterable)); 452 453 // Check that we didn't end up with a RegularImmutableList of size 1. 454 assertEquals(copyOfIterable.size() == 1, 455 copyOfIterable instanceof SingletonImmutableList); 456 } 457 runConcurrentlyMutatedTest(WrapWithIterable wrap)458 private static void runConcurrentlyMutatedTest(WrapWithIterable wrap) { 459 /* 460 * TODO: Iterate over many array sizes and all possible operation lists, 461 * performing adds and removes in different ways. 462 */ 463 runConcurrentlyMutatedTest( 464 elements(), 465 ops(add(1), add(2)), 466 wrap); 467 468 runConcurrentlyMutatedTest( 469 elements(), 470 ops(add(1), nop()), 471 wrap); 472 473 runConcurrentlyMutatedTest( 474 elements(), 475 ops(add(1), remove()), 476 wrap); 477 478 runConcurrentlyMutatedTest( 479 elements(), 480 ops(nop(), add(1)), 481 wrap); 482 483 runConcurrentlyMutatedTest( 484 elements(1), 485 ops(remove(), nop()), 486 wrap); 487 488 runConcurrentlyMutatedTest( 489 elements(1), 490 ops(remove(), add(2)), 491 wrap); 492 493 runConcurrentlyMutatedTest( 494 elements(1, 2), 495 ops(remove(), remove()), 496 wrap); 497 498 runConcurrentlyMutatedTest( 499 elements(1, 2), 500 ops(remove(), nop()), 501 wrap); 502 503 runConcurrentlyMutatedTest( 504 elements(1, 2), 505 ops(remove(), add(3)), 506 wrap); 507 508 runConcurrentlyMutatedTest( 509 elements(1, 2), 510 ops(nop(), remove()), 511 wrap); 512 513 runConcurrentlyMutatedTest( 514 elements(1, 2, 3), 515 ops(remove(), remove()), 516 wrap); 517 } 518 elements(Integer... elements)519 private static ImmutableList<Integer> elements(Integer... elements) { 520 return ImmutableList.copyOf(elements); 521 } 522 ops(ListFrobber... elements)523 private static ImmutableList<ListFrobber> ops(ListFrobber... elements) { 524 return ImmutableList.copyOf(elements); 525 } 526 testCopyOf_concurrentlyMutatedList()527 public void testCopyOf_concurrentlyMutatedList() { 528 runConcurrentlyMutatedTest(WrapWithIterable.NO_WRAP); 529 } 530 testCopyOf_concurrentlyMutatedIterable()531 public void testCopyOf_concurrentlyMutatedIterable() { 532 runConcurrentlyMutatedTest(WrapWithIterable.WRAP); 533 } 534 535 /** An operation to perform on a list. */ 536 interface ListFrobber { perform(List<Integer> list)537 void perform(List<Integer> list); 538 } 539 add(final int element)540 static ListFrobber add(final int element) { 541 return new ListFrobber() { 542 @Override 543 public void perform(List<Integer> list) { 544 list.add(0, element); 545 } 546 }; 547 } 548 remove()549 static ListFrobber remove() { 550 return new ListFrobber() { 551 @Override 552 public void perform(List<Integer> list) { 553 list.remove(0); 554 } 555 }; 556 } 557 558 static ListFrobber nop() { 559 return new ListFrobber() { 560 @Override 561 public void perform(List<Integer> list) { 562 } 563 }; 564 } 565 566 /** 567 * A list that mutates itself after every call to each of its {@link List} 568 * methods. 569 */ 570 interface ConcurrentlyMutatedList<E> extends List<E> { 571 /** 572 * The elements of a {@link ConcurrentlyMutatedList} are added and removed 573 * over time. This method returns every state that the list has passed 574 * through at some point. 575 */ 576 Set<List<E>> getAllStates(); 577 } 578 579 /** 580 * Returns a {@link ConcurrentlyMutatedList} that performs the given 581 * operations as its concurrent modifications. The mutations occur in the 582 * same thread as the triggering method call. 583 */ 584 private static ConcurrentlyMutatedList<Integer> newConcurrentlyMutatedList( 585 final Collection<Integer> initialContents, 586 final Iterable<ListFrobber> actionsToPerformConcurrently) { 587 InvocationHandler invocationHandler = new InvocationHandler() { 588 final CopyOnWriteArrayList<Integer> delegate = 589 new CopyOnWriteArrayList<Integer>(initialContents); 590 591 final Method getAllStatesMethod = getOnlyElement(asList( 592 ConcurrentlyMutatedList.class.getDeclaredMethods())); 593 594 final Iterator<ListFrobber> remainingActions = 595 actionsToPerformConcurrently.iterator(); 596 597 final Set<List<Integer>> allStates = newHashSet(); 598 599 @Override 600 public Object invoke(Object proxy, Method method, 601 Object[] args) throws Throwable { 602 return method.equals(getAllStatesMethod) 603 ? getAllStates() 604 : invokeListMethod(method, args); 605 } 606 607 private Set<List<Integer>> getAllStates() { 608 return allStates; 609 } 610 611 private Object invokeListMethod(Method method, Object[] args) 612 throws Throwable { 613 try { 614 Object returnValue = method.invoke(delegate, args); 615 mutateDelegate(); 616 return returnValue; 617 } catch (InvocationTargetException e) { 618 throw e.getCause(); 619 } catch (IllegalAccessException e) { 620 throw new AssertionError(e); 621 } 622 } 623 624 private void mutateDelegate() { 625 allStates.add(ImmutableList.copyOf(delegate)); 626 remainingActions.next().perform(delegate); 627 allStates.add(ImmutableList.copyOf(delegate)); 628 } 629 }; 630 631 @SuppressWarnings("unchecked") 632 ConcurrentlyMutatedList<Integer> list = 633 (ConcurrentlyMutatedList<Integer>) newProxyInstance( 634 ImmutableListTest.CreationTests.class.getClassLoader(), 635 new Class[] {ConcurrentlyMutatedList.class}, invocationHandler); 636 return list; 637 } 638 } 639 640 public static class BasicTests extends TestCase { 641 642 @GwtIncompatible("NullPointerTester") 643 public void testNullPointers() { 644 NullPointerTester tester = new NullPointerTester(); 645 tester.testAllPublicStaticMethods(ImmutableList.class); 646 tester.testAllPublicInstanceMethods(ImmutableList.of(1, 2, 3)); 647 } 648 649 @GwtIncompatible("SerializableTester") 650 public void testSerialization_empty() { 651 Collection<String> c = ImmutableList.of(); 652 assertSame(c, SerializableTester.reserialize(c)); 653 } 654 655 @GwtIncompatible("SerializableTester") 656 public void testSerialization_singleton() { 657 Collection<String> c = ImmutableList.of("a"); 658 SerializableTester.reserializeAndAssert(c); 659 } 660 661 @GwtIncompatible("SerializableTester") 662 public void testSerialization_multiple() { 663 Collection<String> c = ImmutableList.of("a", "b", "c"); 664 SerializableTester.reserializeAndAssert(c); 665 } 666 667 public void testEquals_immutableList() { 668 Collection<String> c = ImmutableList.of("a", "b", "c"); 669 assertTrue(c.equals(ImmutableList.of("a", "b", "c"))); 670 assertFalse(c.equals(ImmutableList.of("a", "c", "b"))); 671 assertFalse(c.equals(ImmutableList.of("a", "b"))); 672 assertFalse(c.equals(ImmutableList.of("a", "b", "c", "d"))); 673 } 674 675 public void testBuilderAdd() { 676 ImmutableList<String> list = new ImmutableList.Builder<String>() 677 .add("a") 678 .add("b") 679 .add("a") 680 .add("c") 681 .build(); 682 assertEquals(asList("a", "b", "a", "c"), list); 683 } 684 685 public void testBuilderAdd_varargs() { 686 ImmutableList<String> list = new ImmutableList.Builder<String>() 687 .add("a", "b", "a", "c") 688 .build(); 689 assertEquals(asList("a", "b", "a", "c"), list); 690 } 691 692 public void testBuilderAddAll_iterable() { 693 List<String> a = asList("a", "b"); 694 List<String> b = asList("c", "d"); 695 ImmutableList<String> list = new ImmutableList.Builder<String>() 696 .addAll(a) 697 .addAll(b) 698 .build(); 699 assertEquals(asList( "a", "b", "c", "d"), list); 700 b.set(0, "f"); 701 assertEquals(asList( "a", "b", "c", "d"), list); 702 } 703 704 public void testBuilderAddAll_iterator() { 705 List<String> a = asList("a", "b"); 706 List<String> b = asList("c", "d"); 707 ImmutableList<String> list = new ImmutableList.Builder<String>() 708 .addAll(a.iterator()) 709 .addAll(b.iterator()) 710 .build(); 711 assertEquals(asList( "a", "b", "c", "d"), list); 712 b.set(0, "f"); 713 assertEquals(asList( "a", "b", "c", "d"), list); 714 } 715 716 public void testComplexBuilder() { 717 List<Integer> colorElem = asList(0x00, 0x33, 0x66, 0x99, 0xCC, 0xFF); 718 ImmutableList.Builder<Integer> webSafeColorsBuilder 719 = ImmutableList.builder(); 720 for (Integer red : colorElem) { 721 for (Integer green : colorElem) { 722 for (Integer blue : colorElem) { 723 webSafeColorsBuilder.add((red << 16) + (green << 8) + blue); 724 } 725 } 726 } 727 ImmutableList<Integer> webSafeColors = webSafeColorsBuilder.build(); 728 assertEquals(216, webSafeColors.size()); 729 Integer[] webSafeColorArray = 730 webSafeColors.toArray(new Integer[webSafeColors.size()]); 731 assertEquals(0x000000, (int) webSafeColorArray[0]); 732 assertEquals(0x000033, (int) webSafeColorArray[1]); 733 assertEquals(0x000066, (int) webSafeColorArray[2]); 734 assertEquals(0x003300, (int) webSafeColorArray[6]); 735 assertEquals(0x330000, (int) webSafeColorArray[36]); 736 assertEquals(0x000066, (int) webSafeColors.get(2)); 737 assertEquals(0x003300, (int) webSafeColors.get(6)); 738 ImmutableList<Integer> addedColor 739 = webSafeColorsBuilder.add(0x00BFFF).build(); 740 assertEquals("Modifying the builder should not have changed any already" 741 + " built sets", 216, webSafeColors.size()); 742 assertEquals("the new array should be one bigger than webSafeColors", 743 217, addedColor.size()); 744 Integer[] appendColorArray = 745 addedColor.toArray(new Integer[addedColor.size()]); 746 assertEquals(0x00BFFF, (int) appendColorArray[216]); 747 } 748 749 public void testBuilderAddHandlesNullsCorrectly() { 750 ImmutableList.Builder<String> builder = ImmutableList.builder(); 751 try { 752 builder.add((String) null); 753 fail("expected NullPointerException"); 754 } catch (NullPointerException expected) { 755 } 756 757 try { 758 builder.add((String[]) null); 759 fail("expected NullPointerException"); 760 } catch (NullPointerException expected) { 761 } 762 763 try { 764 builder.add("a", null, "b"); 765 fail("expected NullPointerException"); 766 } catch (NullPointerException expected) { 767 } 768 } 769 770 public void testBuilderAddAllHandlesNullsCorrectly() { 771 ImmutableList.Builder<String> builder = ImmutableList.builder(); 772 try { 773 builder.addAll((Iterable<String>) null); 774 fail("expected NullPointerException"); 775 } catch (NullPointerException expected) { 776 } 777 778 try { 779 builder.addAll((Iterator<String>) null); 780 fail("expected NullPointerException"); 781 } catch (NullPointerException expected) { 782 } 783 784 builder = ImmutableList.builder(); 785 List<String> listWithNulls = asList("a", null, "b"); 786 try { 787 builder.addAll(listWithNulls); 788 fail("expected NullPointerException"); 789 } catch (NullPointerException expected) { 790 } 791 792 builder = ImmutableList.builder(); 793 Iterator<String> iteratorWithNulls = asList("a", null, "b").iterator(); 794 try { 795 builder.addAll(iteratorWithNulls); 796 fail("expected NullPointerException"); 797 } catch (NullPointerException expected) { 798 } 799 800 Iterable<String> iterableWithNulls = MinimalIterable.of("a", null, "b"); 801 try { 802 builder.addAll(iterableWithNulls); 803 fail("expected NullPointerException"); 804 } catch (NullPointerException expected) { 805 } 806 } 807 808 public void testAsList() { 809 ImmutableList<String> list = ImmutableList.of("a", "b"); 810 assertSame(list, list.asList()); 811 } 812 } 813 } 814