• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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