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.base.Preconditions.checkNotNull; 20 import static com.google.common.collect.testing.IteratorFeature.UNMODIFIABLE; 21 import static java.util.Arrays.asList; 22 import static java.util.Collections.singletonList; 23 import static org.junit.contrib.truth.Truth.ASSERT; 24 25 import com.google.common.annotations.GwtCompatible; 26 import com.google.common.annotations.GwtIncompatible; 27 import com.google.common.base.Function; 28 import com.google.common.base.Functions; 29 import com.google.common.collect.testing.IteratorTester; 30 import com.google.common.collect.testing.ListTestSuiteBuilder; 31 import com.google.common.collect.testing.SampleElements; 32 import com.google.common.collect.testing.TestListGenerator; 33 import com.google.common.collect.testing.TestStringListGenerator; 34 import com.google.common.collect.testing.features.CollectionFeature; 35 import com.google.common.collect.testing.features.CollectionSize; 36 import com.google.common.collect.testing.features.ListFeature; 37 import com.google.common.testing.NullPointerTester; 38 import com.google.common.testing.SerializableTester; 39 40 import junit.framework.Test; 41 import junit.framework.TestCase; 42 import junit.framework.TestSuite; 43 44 import org.easymock.EasyMock; 45 46 import java.io.Serializable; 47 import java.util.ArrayList; 48 import java.util.Collection; 49 import java.util.Collections; 50 import java.util.Iterator; 51 import java.util.LinkedList; 52 import java.util.List; 53 import java.util.ListIterator; 54 import java.util.NoSuchElementException; 55 import java.util.RandomAccess; 56 57 /** 58 * Unit test for {@code Lists}. 59 * 60 * @author Kevin Bourrillion 61 * @author Mike Bostock 62 * @author Jared Levy 63 */ 64 @GwtCompatible(emulated = true) 65 public class ListsTest extends TestCase { 66 67 private static final Collection<Integer> SOME_COLLECTION 68 = asList(0, 1, 1); 69 70 private static final Iterable<Integer> SOME_ITERABLE = new SomeIterable(); 71 72 private static class SomeIterable implements Iterable<Integer>, Serializable { 73 @Override iterator()74 public Iterator<Integer> iterator() { 75 return SOME_COLLECTION.iterator(); 76 } 77 private static final long serialVersionUID = 0; 78 } 79 80 private static final List<Integer> SOME_LIST 81 = Lists.newArrayList(1, 2, 3, 4); 82 83 private static final List<Integer> SOME_SEQUENTIAL_LIST 84 = Lists.newLinkedList(asList(1, 2, 3, 4)); 85 86 private static final List<String> SOME_STRING_LIST 87 = asList("1", "2", "3", "4"); 88 89 private static final Function<Number, String> SOME_FUNCTION 90 = new SomeFunction(); 91 92 private static class SomeFunction 93 implements Function<Number, String>, Serializable { 94 @Override apply(Number n)95 public String apply(Number n) { 96 return String.valueOf(n); 97 } 98 private static final long serialVersionUID = 0; 99 } 100 101 @GwtIncompatible("suite") suite()102 public static Test suite() { 103 TestSuite suite = new TestSuite(); 104 suite.addTestSuite(ListsTest.class); 105 106 suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() { 107 @Override protected List<String> create(String[] elements) { 108 String[] rest = new String[elements.length - 1]; 109 Platform.unsafeArrayCopy(elements, 1, rest, 0, elements.length - 1); 110 return Lists.asList(elements[0], rest); 111 } 112 }) 113 .named("Lists.asList, 2 parameter") 114 .withFeatures(CollectionSize.SEVERAL, CollectionSize.ONE, 115 CollectionFeature.ALLOWS_NULL_VALUES) 116 .createTestSuite()); 117 118 suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() { 119 @Override protected List<String> create(String[] elements) { 120 String[] rest = new String[elements.length - 2]; 121 Platform.unsafeArrayCopy(elements, 2, rest, 0, elements.length - 2); 122 return Lists.asList(elements[0], elements[1], rest); 123 } 124 }) 125 .named("Lists.asList, 3 parameter") 126 .withFeatures(CollectionSize.SEVERAL, 127 CollectionFeature.ALLOWS_NULL_VALUES) 128 .createTestSuite()); 129 130 final Function<String, String> removeFirst 131 = new Function<String, String>() { 132 @Override 133 public String apply(String from) { 134 return (from.length() == 0) ? from : from.substring(1); 135 } 136 }; 137 138 suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() { 139 @Override protected List<String> create(String[] elements) { 140 List<String> fromList = Lists.newArrayList(); 141 for (String element : elements) { 142 fromList.add("q" + checkNotNull(element)); 143 } 144 return Lists.transform(fromList, removeFirst); 145 } 146 }) 147 .named("Lists.transform, random access, no nulls") 148 .withFeatures(CollectionSize.ANY, 149 ListFeature.REMOVE_OPERATIONS, 150 CollectionFeature.ALLOWS_NULL_QUERIES) 151 .createTestSuite()); 152 153 suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() { 154 @Override protected List<String> create(String[] elements) { 155 List<String> fromList = Lists.newLinkedList(); 156 for (String element : elements) { 157 fromList.add("q" + checkNotNull(element)); 158 } 159 return Lists.transform(fromList, removeFirst); 160 } 161 }) 162 .named("Lists.transform, sequential access, no nulls") 163 .withFeatures(CollectionSize.ANY, 164 ListFeature.REMOVE_OPERATIONS, 165 CollectionFeature.ALLOWS_NULL_QUERIES) 166 .createTestSuite()); 167 168 suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() { 169 @Override protected List<String> create(String[] elements) { 170 List<String> fromList = Lists.newArrayList(elements); 171 return Lists.transform(fromList, Functions.<String>identity()); 172 } 173 }) 174 .named("Lists.transform, random access, nulls") 175 .withFeatures(CollectionSize.ANY, 176 ListFeature.REMOVE_OPERATIONS, 177 CollectionFeature.ALLOWS_NULL_VALUES) 178 .createTestSuite()); 179 180 suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() { 181 @Override protected List<String> create(String[] elements) { 182 List<String> fromList = 183 Lists.newLinkedList(asList(elements)); 184 return Lists.transform(fromList, Functions.<String>identity()); 185 } 186 }) 187 .named("Lists.transform, sequential access, nulls") 188 .withFeatures(CollectionSize.ANY, 189 ListFeature.REMOVE_OPERATIONS, 190 CollectionFeature.ALLOWS_NULL_VALUES) 191 .createTestSuite()); 192 193 suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() { 194 @Override protected List<String> create(String[] elements) { 195 List<String> list = Lists.newArrayList(); 196 for (int i = elements.length - 1; i >= 0; i--) 197 list.add(elements[i]); 198 return Lists.reverse(list); 199 } 200 }).named("Lists.reverse[ArrayList]").withFeatures(CollectionSize.ANY, 201 CollectionFeature.ALLOWS_NULL_VALUES, ListFeature.GENERAL_PURPOSE) 202 .createTestSuite()); 203 204 suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() { 205 @Override protected List<String> create(String[] elements) { 206 String[] reverseElements = new String[elements.length]; 207 for (int i = elements.length - 1, j = 0; i >= 0; i--, j++) 208 reverseElements[j] = elements[i]; 209 return Lists.reverse(asList(reverseElements)); 210 } 211 }).named("Lists.reverse[Arrays.asList]").withFeatures(CollectionSize.ANY, 212 CollectionFeature.ALLOWS_NULL_VALUES, ListFeature.SUPPORTS_SET) 213 .createTestSuite()); 214 215 suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() { 216 @Override protected List<String> create(String[] elements) { 217 List<String> list = Lists.newLinkedList(); 218 for (int i = elements.length - 1; i >= 0; i--) 219 list.add(elements[i]); 220 return Lists.reverse(list); 221 } 222 }).named("Lists.reverse[LinkedList]").withFeatures(CollectionSize.ANY, 223 CollectionFeature.ALLOWS_NULL_VALUES, ListFeature.GENERAL_PURPOSE) 224 .createTestSuite()); 225 226 suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() { 227 @Override protected List<String> create(String[] elements) { 228 ImmutableList.Builder<String> builder = ImmutableList.builder(); 229 for (int i = elements.length - 1; i >= 0; i--) 230 builder.add(elements[i]); 231 return Lists.reverse(builder.build()); 232 } 233 }).named("Lists.reverse[ImmutableList]").withFeatures(CollectionSize.ANY, 234 CollectionFeature.ALLOWS_NULL_QUERIES) 235 .createTestSuite()); 236 237 suite.addTest( 238 ListTestSuiteBuilder.using(new TestListGenerator<Character>() { 239 @Override public List<Character> create(Object... elements) { 240 char[] chars = new char[elements.length]; 241 for (int i = 0; i < elements.length; i++) 242 chars[i] = (Character) elements[i]; 243 return Lists.charactersOf(String.copyValueOf(chars)); 244 } 245 246 @Override public Character[] createArray(int length) { 247 return new Character[length]; 248 } 249 250 @Override public Iterable<Character> order( 251 List<Character> insertionOrder) { 252 return ImmutableList.copyOf(insertionOrder); 253 } 254 255 @Override public SampleElements<Character> samples() { 256 return new SampleElements<Character>('a', 'b', 'c', 'd', 'e'); 257 } 258 }).named("Lists.charactersOf[String]").withFeatures( 259 CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_QUERIES) 260 .createTestSuite()); 261 262 suite.addTest( 263 ListTestSuiteBuilder.using(new TestListGenerator<Character>() { 264 @Override public List<Character> create(Object... elements) { 265 char[] chars = new char[elements.length]; 266 for (int i = 0; i < elements.length; i++) 267 chars[i] = (Character) elements[i]; 268 StringBuilder str = new StringBuilder(); 269 str.append(chars); 270 return Lists.charactersOf(str); 271 } 272 273 @Override public Character[] createArray(int length) { 274 return new Character[length]; 275 } 276 277 @Override public Iterable<Character> order( 278 List<Character> insertionOrder) { 279 return ImmutableList.copyOf(insertionOrder); 280 } 281 282 @Override public SampleElements<Character> samples() { 283 return new SampleElements<Character>('a', 'b', 'c', 'd', 'e'); 284 } 285 }).named("Lists.charactersOf[CharSequence]").withFeatures( 286 CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_QUERIES) 287 .createTestSuite()); 288 289 return suite; 290 } 291 testCharactersOfIsView()292 public void testCharactersOfIsView() { 293 StringBuilder builder = new StringBuilder("abc"); 294 List<Character> chars = Lists.charactersOf(builder); 295 assertEquals(asList('a', 'b', 'c'), chars); 296 builder.append("def"); 297 assertEquals( 298 asList('a', 'b', 'c', 'd', 'e', 'f'), chars); 299 builder.deleteCharAt(5); 300 assertEquals( 301 asList('a', 'b', 'c', 'd', 'e'), chars); 302 } 303 testNewArrayListEmpty()304 public void testNewArrayListEmpty() { 305 ArrayList<Integer> list = Lists.newArrayList(); 306 assertEquals(Collections.emptyList(), list); 307 } 308 testNewArrayListWithCapacity()309 public void testNewArrayListWithCapacity() { 310 ArrayList<Integer> list = Lists.newArrayListWithCapacity(0); 311 assertEquals(Collections.emptyList(), list); 312 313 ArrayList<Integer> bigger = Lists.newArrayListWithCapacity(256); 314 assertEquals(Collections.emptyList(), bigger); 315 } 316 testNewArrayListWithCapacity_negative()317 public void testNewArrayListWithCapacity_negative() { 318 try { 319 Lists.newArrayListWithCapacity(-1); 320 fail(); 321 } catch (IllegalArgumentException expected) { 322 } 323 } 324 testNewArrayListWithExpectedSize()325 public void testNewArrayListWithExpectedSize() { 326 ArrayList<Integer> list = Lists.newArrayListWithExpectedSize(0); 327 assertEquals(Collections.emptyList(), list); 328 329 ArrayList<Integer> bigger = Lists.newArrayListWithExpectedSize(256); 330 assertEquals(Collections.emptyList(), bigger); 331 } 332 testNewArrayListWithExpectedSize_negative()333 public void testNewArrayListWithExpectedSize_negative() { 334 try { 335 Lists.newArrayListWithExpectedSize(-1); 336 fail(); 337 } catch (IllegalArgumentException expected) { 338 } 339 } 340 testNewArrayListVarArgs()341 public void testNewArrayListVarArgs() { 342 ArrayList<Integer> list = Lists.newArrayList(0, 1, 1); 343 assertEquals(SOME_COLLECTION, list); 344 } 345 testComputeArrayListCapacity()346 public void testComputeArrayListCapacity() { 347 assertEquals(5, Lists.computeArrayListCapacity(0)); 348 assertEquals(13, Lists.computeArrayListCapacity(8)); 349 assertEquals(89, Lists.computeArrayListCapacity(77)); 350 assertEquals(22000005, Lists.computeArrayListCapacity(20000000)); 351 assertEquals(Integer.MAX_VALUE, 352 Lists.computeArrayListCapacity(Integer.MAX_VALUE - 1000)); 353 } 354 testNewArrayListFromCollection()355 public void testNewArrayListFromCollection() { 356 ArrayList<Integer> list = Lists.newArrayList(SOME_COLLECTION); 357 assertEquals(SOME_COLLECTION, list); 358 } 359 testNewArrayListFromIterable()360 public void testNewArrayListFromIterable() { 361 ArrayList<Integer> list = Lists.newArrayList(SOME_ITERABLE); 362 assertEquals(SOME_COLLECTION, list); 363 } 364 testNewArrayListFromIterator()365 public void testNewArrayListFromIterator() { 366 ArrayList<Integer> list = Lists.newArrayList(SOME_COLLECTION.iterator()); 367 assertEquals(SOME_COLLECTION, list); 368 } 369 testNewLinkedListEmpty()370 public void testNewLinkedListEmpty() { 371 LinkedList<Integer> list = Lists.newLinkedList(); 372 assertEquals(Collections.emptyList(), list); 373 } 374 testNewLinkedListFromCollection()375 public void testNewLinkedListFromCollection() { 376 LinkedList<Integer> list = Lists.newLinkedList(SOME_COLLECTION); 377 assertEquals(SOME_COLLECTION, list); 378 } 379 testNewLinkedListFromIterable()380 public void testNewLinkedListFromIterable() { 381 LinkedList<Integer> list = Lists.newLinkedList(SOME_ITERABLE); 382 assertEquals(SOME_COLLECTION, list); 383 } 384 385 @GwtIncompatible("NullPointerTester") testNullPointerExceptions()386 public void testNullPointerExceptions() throws Exception { 387 NullPointerTester tester = new NullPointerTester(); 388 tester.testAllPublicStaticMethods(Lists.class); 389 } 390 391 /** 392 * This is just here to illustrate how {@code Arrays#asList} differs from 393 * {@code Lists#newArrayList}. 394 */ testArraysAsList()395 public void testArraysAsList() { 396 List<String> ourWay = Lists.newArrayList("foo", "bar", "baz"); 397 List<String> otherWay = asList("foo", "bar", "baz"); 398 399 // They're logically equal 400 assertEquals(ourWay, otherWay); 401 402 // The result of Arrays.asList() is mutable 403 otherWay.set(0, "FOO"); 404 assertEquals("FOO", otherWay.get(0)); 405 406 // But it can't grow 407 try { 408 otherWay.add("nope"); 409 fail("no exception thrown"); 410 } catch (UnsupportedOperationException expected) { 411 } 412 413 // And it can't shrink 414 try { 415 otherWay.remove(2); 416 fail("no exception thrown"); 417 } catch (UnsupportedOperationException expected) { 418 } 419 } 420 421 @GwtIncompatible("SerializableTester") testAsList1()422 public void testAsList1() { 423 List<String> list = Lists.asList("foo", new String[] { "bar", "baz" }); 424 checkFooBarBazList(list); 425 SerializableTester.reserializeAndAssert(list); 426 assertTrue(list instanceof RandomAccess); 427 428 new IteratorTester<String>(5, UNMODIFIABLE, 429 asList("foo", "bar", "baz"), 430 IteratorTester.KnownOrder.KNOWN_ORDER) { 431 @Override protected Iterator<String> newTargetIterator() { 432 return Lists.asList("foo", new String[] {"bar", "baz"}).iterator(); 433 } 434 }.test(); 435 } 436 checkFooBarBazList(List<String> list)437 private void checkFooBarBazList(List<String> list) { 438 ASSERT.that(list).hasContentsInOrder("foo", "bar", "baz"); 439 assertEquals(3, list.size()); 440 assertIndexIsOutOfBounds(list, -1); 441 assertEquals("foo", list.get(0)); 442 assertEquals("bar", list.get(1)); 443 assertEquals("baz", list.get(2)); 444 assertIndexIsOutOfBounds(list, 3); 445 } 446 testAsList1Small()447 public void testAsList1Small() { 448 List<String> list = Lists.asList("foo", new String[0]); 449 ASSERT.that(list).hasContentsInOrder("foo"); 450 assertEquals(1, list.size()); 451 assertIndexIsOutOfBounds(list, -1); 452 assertEquals("foo", list.get(0)); 453 assertIndexIsOutOfBounds(list, 1); 454 assertTrue(list instanceof RandomAccess); 455 456 new IteratorTester<String>(3, UNMODIFIABLE, singletonList("foo"), 457 IteratorTester.KnownOrder.KNOWN_ORDER) { 458 @Override protected Iterator<String> newTargetIterator() { 459 return Lists.asList("foo", new String[0]).iterator(); 460 } 461 }.test(); 462 } 463 testAsList2()464 public void testAsList2() { 465 List<String> list = Lists.asList("foo", "bar", new String[] { "baz" }); 466 checkFooBarBazList(list); 467 assertTrue(list instanceof RandomAccess); 468 469 new IteratorTester<String>(5, UNMODIFIABLE, asList("foo", "bar", 470 "baz"), IteratorTester.KnownOrder.KNOWN_ORDER) { 471 @Override protected Iterator<String> newTargetIterator() { 472 return Lists.asList("foo", "bar", new String[] {"baz"}).iterator(); 473 } 474 }.test(); 475 } 476 477 @GwtIncompatible("SerializableTester") testAsList2Small()478 public void testAsList2Small() { 479 List<String> list = Lists.asList("foo", "bar", new String[0]); 480 ASSERT.that(list).hasContentsInOrder("foo", "bar"); 481 assertEquals(2, list.size()); 482 assertIndexIsOutOfBounds(list, -1); 483 assertEquals("foo", list.get(0)); 484 assertEquals("bar", list.get(1)); 485 assertIndexIsOutOfBounds(list, 2); 486 SerializableTester.reserializeAndAssert(list); 487 assertTrue(list instanceof RandomAccess); 488 489 new IteratorTester<String>(5, UNMODIFIABLE, asList("foo", "bar"), 490 IteratorTester.KnownOrder.KNOWN_ORDER) { 491 @Override protected Iterator<String> newTargetIterator() { 492 return Lists.asList("foo", "bar", new String[0]).iterator(); 493 } 494 }.test(); 495 } 496 assertIndexIsOutOfBounds(List<String> list, int index)497 private static void assertIndexIsOutOfBounds(List<String> list, int index) { 498 try { 499 list.get(index); 500 fail(); 501 } catch (IndexOutOfBoundsException expected) { 502 } 503 } 504 testReverseViewRandomAccess()505 public void testReverseViewRandomAccess() { 506 List<Integer> fromList = Lists.newArrayList(SOME_LIST); 507 List<Integer> toList = Lists.reverse(fromList); 508 assertReverseView(fromList, toList); 509 } 510 testReverseViewSequential()511 public void testReverseViewSequential() { 512 List<Integer> fromList = Lists.newLinkedList(SOME_SEQUENTIAL_LIST); 513 List<Integer> toList = Lists.reverse(fromList); 514 assertReverseView(fromList, toList); 515 } 516 assertReverseView(List<Integer> fromList, List<Integer> toList)517 private static void assertReverseView(List<Integer> fromList, 518 List<Integer> toList) { 519 /* fromList modifications reflected in toList */ 520 fromList.set(0, 5); 521 assertEquals(asList(4, 3, 2, 5), toList); 522 fromList.add(6); 523 assertEquals(asList(6, 4, 3, 2, 5), toList); 524 fromList.add(2, 9); 525 assertEquals(asList(6, 4, 3, 9, 2, 5), toList); 526 fromList.remove(Integer.valueOf(2)); 527 assertEquals(asList(6, 4, 3, 9, 5), toList); 528 fromList.remove(3); 529 assertEquals(asList(6, 3, 9, 5), toList); 530 531 /* toList modifications reflected in fromList */ 532 toList.remove(0); 533 assertEquals(asList(5, 9, 3), fromList); 534 toList.add(7); 535 assertEquals(asList(7, 5, 9, 3), fromList); 536 toList.add(5); 537 assertEquals(asList(5, 7, 5, 9, 3), fromList); 538 toList.remove(Integer.valueOf(5)); 539 assertEquals(asList(5, 7, 9, 3), fromList); 540 toList.set(1, 8); 541 assertEquals(asList(5, 7, 8, 3), fromList); 542 toList.clear(); 543 assertEquals(Collections.emptyList(), fromList); 544 } 545 546 @GwtIncompatible("SerializableTester") testTransformEqualityRandomAccess()547 public void testTransformEqualityRandomAccess() { 548 List<String> list = Lists.transform(SOME_LIST, SOME_FUNCTION); 549 assertEquals(SOME_STRING_LIST, list); 550 SerializableTester.reserializeAndAssert(list); 551 } 552 553 @GwtIncompatible("SerializableTester") testTransformEqualitySequential()554 public void testTransformEqualitySequential() { 555 List<String> list = Lists.transform(SOME_SEQUENTIAL_LIST, SOME_FUNCTION); 556 assertEquals(SOME_STRING_LIST, list); 557 SerializableTester.reserializeAndAssert(list); 558 } 559 testTransformHashCodeRandomAccess()560 public void testTransformHashCodeRandomAccess() { 561 List<String> list = Lists.transform(SOME_LIST, SOME_FUNCTION); 562 assertEquals(SOME_STRING_LIST.hashCode(), list.hashCode()); 563 } 564 testTransformHashCodeSequential()565 public void testTransformHashCodeSequential() { 566 List<String> list = Lists.transform(SOME_SEQUENTIAL_LIST, SOME_FUNCTION); 567 assertEquals(SOME_STRING_LIST.hashCode(), list.hashCode()); 568 } 569 testTransformModifiableRandomAccess()570 public void testTransformModifiableRandomAccess() { 571 List<Integer> fromList = Lists.newArrayList(SOME_LIST); 572 List<String> list = Lists.transform(fromList, SOME_FUNCTION); 573 assertTransformModifiable(list); 574 } 575 testTransformModifiableSequential()576 public void testTransformModifiableSequential() { 577 List<Integer> fromList = Lists.newLinkedList(SOME_SEQUENTIAL_LIST); 578 List<String> list = Lists.transform(fromList, SOME_FUNCTION); 579 assertTransformModifiable(list); 580 } 581 assertTransformModifiable(List<String> list)582 private static void assertTransformModifiable(List<String> list) { 583 try { 584 list.add("5"); 585 fail("transformed list is addable"); 586 } catch (UnsupportedOperationException expected) {} 587 list.remove(0); 588 assertEquals(asList("2", "3", "4"), list); 589 list.remove("3"); 590 assertEquals(asList("2", "4"), list); 591 try { 592 list.set(0, "5"); 593 fail("transformed list is setable"); 594 } catch (UnsupportedOperationException expected) {} 595 list.clear(); 596 assertEquals(Collections.emptyList(), list); 597 } 598 testTransformViewRandomAccess()599 public void testTransformViewRandomAccess() { 600 List<Integer> fromList = Lists.newArrayList(SOME_LIST); 601 List<String> toList = Lists.transform(fromList, SOME_FUNCTION); 602 assertTransformView(fromList, toList); 603 } 604 testTransformViewSequential()605 public void testTransformViewSequential() { 606 List<Integer> fromList = Lists.newLinkedList(SOME_SEQUENTIAL_LIST); 607 List<String> toList = Lists.transform(fromList, SOME_FUNCTION); 608 assertTransformView(fromList, toList); 609 } 610 assertTransformView(List<Integer> fromList, List<String> toList)611 private static void assertTransformView(List<Integer> fromList, 612 List<String> toList) { 613 /* fromList modifications reflected in toList */ 614 fromList.set(0, 5); 615 assertEquals(asList("5", "2", "3", "4"), toList); 616 fromList.add(6); 617 assertEquals(asList("5", "2", "3", "4", "6"), toList); 618 fromList.remove(Integer.valueOf(2)); 619 assertEquals(asList("5", "3", "4", "6"), toList); 620 fromList.remove(2); 621 assertEquals(asList("5", "3", "6"), toList); 622 623 /* toList modifications reflected in fromList */ 624 toList.remove(2); 625 assertEquals(asList(5, 3), fromList); 626 toList.remove("5"); 627 assertEquals(asList(3), fromList); 628 toList.clear(); 629 assertEquals(Collections.emptyList(), fromList); 630 } 631 testTransformRandomAccess()632 public void testTransformRandomAccess() { 633 List<String> list = Lists.transform(SOME_LIST, SOME_FUNCTION); 634 assertTrue(list instanceof RandomAccess); 635 } 636 testTransformSequential()637 public void testTransformSequential() { 638 List<String> list = Lists.transform(SOME_SEQUENTIAL_LIST, SOME_FUNCTION); 639 assertFalse(list instanceof RandomAccess); 640 } 641 testTransformListIteratorRandomAccess()642 public void testTransformListIteratorRandomAccess() { 643 List<Integer> fromList = Lists.newArrayList(SOME_LIST); 644 List<String> list = Lists.transform(fromList, SOME_FUNCTION); 645 assertTransformListIterator(list); 646 } 647 testTransformListIteratorSequential()648 public void testTransformListIteratorSequential() { 649 List<Integer> fromList = Lists.newLinkedList(SOME_SEQUENTIAL_LIST); 650 List<String> list = Lists.transform(fromList, SOME_FUNCTION); 651 assertTransformListIterator(list); 652 } 653 assertTransformListIterator(List<String> list)654 private static void assertTransformListIterator(List<String> list) { 655 ListIterator<String> iterator = list.listIterator(1); 656 assertEquals(1, iterator.nextIndex()); 657 assertEquals("2", iterator.next()); 658 assertEquals("3", iterator.next()); 659 assertEquals("4", iterator.next()); 660 assertEquals(4, iterator.nextIndex()); 661 try { 662 iterator.next(); 663 fail("did not detect end of list"); 664 } catch (NoSuchElementException expected) {} 665 assertEquals(3, iterator.previousIndex()); 666 assertEquals("4", iterator.previous()); 667 assertEquals("3", iterator.previous()); 668 assertEquals("2", iterator.previous()); 669 assertTrue(iterator.hasPrevious()); 670 assertEquals("1", iterator.previous()); 671 assertFalse(iterator.hasPrevious()); 672 assertEquals(-1, iterator.previousIndex()); 673 try { 674 iterator.previous(); 675 fail("did not detect beginning of list"); 676 } catch (NoSuchElementException expected) {} 677 iterator.remove(); 678 assertEquals(asList("2", "3", "4"), list); 679 assertFalse(list.isEmpty()); 680 681 // An UnsupportedOperationException or IllegalStateException may occur. 682 try { 683 iterator.add("1"); 684 fail("transformed list iterator is addable"); 685 } catch (UnsupportedOperationException expected) { 686 } catch (IllegalStateException expected) {} 687 try { 688 iterator.set("1"); 689 fail("transformed list iterator is settable"); 690 } catch (UnsupportedOperationException expected) { 691 } catch (IllegalStateException expected) {} 692 } 693 testTransformIteratorRandomAccess()694 public void testTransformIteratorRandomAccess() { 695 List<Integer> fromList = Lists.newArrayList(SOME_LIST); 696 List<String> list = Lists.transform(fromList, SOME_FUNCTION); 697 assertTransformIterator(list); 698 } 699 testTransformIteratorSequential()700 public void testTransformIteratorSequential() { 701 List<Integer> fromList = Lists.newLinkedList(SOME_SEQUENTIAL_LIST); 702 List<String> list = Lists.transform(fromList, SOME_FUNCTION); 703 assertTransformIterator(list); 704 } 705 706 /** 707 * We use this class to avoid the need to suppress generics checks with 708 * easy mock. 709 */ 710 private interface IntegerList extends List<Integer> {} 711 712 /** 713 * This test depends on the fact that {@code AbstractSequentialList.iterator} 714 * transforms the {@code iterator()} call into a call on {@code 715 * listIterator(int)}. This is fine because the behavior is clearly 716 * documented so it's not expected to change. 717 */ 718 @GwtIncompatible("EsayMock") testTransformedSequentialIterationUsesBackingListIterationOnly()719 public void testTransformedSequentialIterationUsesBackingListIterationOnly() { 720 List<Integer> randomAccessList = Lists.newArrayList(SOME_SEQUENTIAL_LIST); 721 ListIterator<Integer> sampleListIterator = 722 SOME_SEQUENTIAL_LIST.listIterator(); 723 List<Integer> listMock = EasyMock.createMock(IntegerList.class); 724 EasyMock.expect(listMock.listIterator(0)).andReturn(sampleListIterator); 725 EasyMock.replay(listMock); 726 List<String> transform = Lists.transform(listMock, SOME_FUNCTION); 727 assertTrue(Iterables.elementsEqual( 728 transform, Lists.transform(randomAccessList, SOME_FUNCTION))); 729 EasyMock.verify(listMock); 730 } 731 assertTransformIterator(List<String> list)732 private static void assertTransformIterator(List<String> list) { 733 Iterator<String> iterator = list.iterator(); 734 assertTrue(iterator.hasNext()); 735 assertEquals("1", iterator.next()); 736 assertTrue(iterator.hasNext()); 737 assertEquals("2", iterator.next()); 738 assertTrue(iterator.hasNext()); 739 assertEquals("3", iterator.next()); 740 assertTrue(iterator.hasNext()); 741 assertEquals("4", iterator.next()); 742 assertFalse(iterator.hasNext()); 743 try { 744 iterator.next(); 745 fail("did not detect end of list"); 746 } catch (NoSuchElementException expected) {} 747 iterator.remove(); 748 assertEquals(asList("1", "2", "3"), list); 749 assertFalse(iterator.hasNext()); 750 } 751 testPartition_badSize()752 public void testPartition_badSize() { 753 List<Integer> source = Collections.singletonList(1); 754 try { 755 Lists.partition(source, 0); 756 fail(); 757 } catch (IllegalArgumentException expected) { 758 } 759 } 760 testPartition_empty()761 public void testPartition_empty() { 762 List<Integer> source = Collections.emptyList(); 763 List<List<Integer>> partitions = Lists.partition(source, 1); 764 assertTrue(partitions.isEmpty()); 765 assertEquals(0, partitions.size()); 766 } 767 testPartition_1_1()768 public void testPartition_1_1() { 769 List<Integer> source = Collections.singletonList(1); 770 List<List<Integer>> partitions = Lists.partition(source, 1); 771 assertEquals(1, partitions.size()); 772 assertEquals(Collections.singletonList(1), partitions.get(0)); 773 } 774 testPartition_1_2()775 public void testPartition_1_2() { 776 List<Integer> source = Collections.singletonList(1); 777 List<List<Integer>> partitions = Lists.partition(source, 2); 778 assertEquals(1, partitions.size()); 779 assertEquals(Collections.singletonList(1), partitions.get(0)); 780 } 781 testPartition_2_1()782 public void testPartition_2_1() { 783 List<Integer> source = asList(1, 2); 784 List<List<Integer>> partitions = Lists.partition(source, 1); 785 assertEquals(2, partitions.size()); 786 assertEquals(Collections.singletonList(1), partitions.get(0)); 787 assertEquals(Collections.singletonList(2), partitions.get(1)); 788 } 789 testPartition_3_2()790 public void testPartition_3_2() { 791 List<Integer> source = asList(1, 2, 3); 792 List<List<Integer>> partitions = Lists.partition(source, 2); 793 assertEquals(2, partitions.size()); 794 assertEquals(asList(1, 2), partitions.get(0)); 795 assertEquals(asList(3), partitions.get(1)); 796 } 797 798 @GwtIncompatible("ArrayList.subList doesn't implement RandomAccess in GWT.") testPartitionRandomAccessTrue()799 public void testPartitionRandomAccessTrue() { 800 List<Integer> source = asList(1, 2, 3); 801 List<List<Integer>> partitions = Lists.partition(source, 2); 802 803 assertTrue("partition should be RandomAccess, but not: " 804 + partitions.getClass(), 805 partitions instanceof RandomAccess); 806 807 assertTrue("partition[0] should be RandomAccess, but not: " 808 + partitions.get(0).getClass(), 809 partitions.get(0) instanceof RandomAccess); 810 811 assertTrue("partition[1] should be RandomAccess, but not: " 812 + partitions.get(1).getClass(), 813 partitions.get(1) instanceof RandomAccess); 814 } 815 testPartitionRandomAccessFalse()816 public void testPartitionRandomAccessFalse() { 817 List<Integer> source = Lists.newLinkedList(asList(1, 2, 3)); 818 List<List<Integer>> partitions = Lists.partition(source, 2); 819 assertFalse(partitions instanceof RandomAccess); 820 assertFalse(partitions.get(0) instanceof RandomAccess); 821 assertFalse(partitions.get(1) instanceof RandomAccess); 822 } 823 824 // TODO: use the ListTestSuiteBuilder 825 testPartition_view()826 public void testPartition_view() { 827 List<Integer> list = asList(1, 2, 3); 828 List<List<Integer>> partitions = Lists.partition(list, 3); 829 830 // Changes before the partition is retrieved are reflected 831 list.set(0, 3); 832 833 Iterator<List<Integer>> iterator = partitions.iterator(); 834 835 // Changes before the partition is retrieved are reflected 836 list.set(1, 4); 837 838 List<Integer> first = iterator.next(); 839 840 // Changes after are too (unlike Iterables.partition) 841 list.set(2, 5); 842 843 assertEquals(asList(3, 4, 5), first); 844 845 // Changes to a sublist also write through to the original list 846 first.set(1, 6); 847 assertEquals(asList(3, 6, 5), list); 848 } 849 testPartitionSize_1()850 public void testPartitionSize_1() { 851 List<Integer> list = asList(1, 2, 3); 852 assertEquals(1, Lists.partition(list, Integer.MAX_VALUE).size()); 853 assertEquals(1, Lists.partition(list, Integer.MAX_VALUE - 1).size()); 854 } 855 856 @GwtIncompatible("cannot do such a big explicit copy") testPartitionSize_2()857 public void testPartitionSize_2() { 858 assertEquals(2, Lists.partition(Collections.nCopies(0x40000001, 1), 0x40000000).size()); 859 } 860 861 // These tests are quick and basic and don't actually show unmodifiability... 862 } 863