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