001/*
002 * Copyright (C) 2009 The Guava Authors
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package com.google.common.collect.testing;
018
019import static com.google.common.collect.testing.testers.CollectionSpliteratorTester.getSpliteratorNotImmutableCollectionAllowsAddMethod;
020import static com.google.common.collect.testing.testers.CollectionSpliteratorTester.getSpliteratorNotImmutableCollectionAllowsRemoveMethod;
021import static com.google.common.collect.testing.testers.ListListIteratorTester.getListIteratorFullyModifiableMethod;
022import static com.google.common.collect.testing.testers.ListSubListTester.getSubListOriginalListSetAffectsSubListLargeListMethod;
023import static com.google.common.collect.testing.testers.ListSubListTester.getSubListOriginalListSetAffectsSubListMethod;
024import static com.google.common.collect.testing.testers.ListSubListTester.getSubListSubListRemoveAffectsOriginalLargeListMethod;
025import static java.util.Arrays.asList;
026import static java.util.Collections.emptyList;
027import static java.util.Collections.emptySet;
028import static java.util.Collections.singletonList;
029import static java.util.Collections.unmodifiableList;
030
031import com.google.common.annotations.GwtIncompatible;
032import com.google.common.collect.testing.features.CollectionFeature;
033import com.google.common.collect.testing.features.CollectionSize;
034import com.google.common.collect.testing.features.ListFeature;
035import java.lang.reflect.Method;
036import java.util.AbstractList;
037import java.util.AbstractSequentialList;
038import java.util.ArrayList;
039import java.util.Collection;
040import java.util.Collections;
041import java.util.LinkedList;
042import java.util.List;
043import java.util.ListIterator;
044import java.util.Vector;
045import java.util.concurrent.CopyOnWriteArrayList;
046import junit.framework.Test;
047import junit.framework.TestSuite;
048
049/**
050 * Generates a test suite covering the {@link List} implementations in the {@link java.util}
051 * package. Can be subclassed to specify tests that should be suppressed.
052 *
053 * @author Kevin Bourrillion
054 */
055@GwtIncompatible
056public class TestsForListsInJavaUtil {
057  public static Test suite() {
058    return new TestsForListsInJavaUtil().allTests();
059  }
060
061  public Test allTests() {
062    TestSuite suite = new TestSuite("java.util Lists");
063    suite.addTest(testsForEmptyList());
064    suite.addTest(testsForSingletonList());
065    suite.addTest(testsForArraysAsList());
066    suite.addTest(testsForArrayList());
067    suite.addTest(testsForLinkedList());
068    suite.addTest(testsForCopyOnWriteArrayList());
069    suite.addTest(testsForUnmodifiableList());
070    suite.addTest(testsForCheckedList());
071    suite.addTest(testsForAbstractList());
072    suite.addTest(testsForAbstractSequentialList());
073    suite.addTest(testsForVector());
074    return suite;
075  }
076
077  protected Collection<Method> suppressForEmptyList() {
078    return emptySet();
079  }
080
081  protected Collection<Method> suppressForSingletonList() {
082    return emptySet();
083  }
084
085  protected Collection<Method> suppressForArraysAsList() {
086    return emptySet();
087  }
088
089  protected Collection<Method> suppressForArrayList() {
090    return emptySet();
091  }
092
093  protected Collection<Method> suppressForLinkedList() {
094    return emptySet();
095  }
096
097  protected Collection<Method> suppressForCopyOnWriteArrayList() {
098    return asList(
099        getSubListOriginalListSetAffectsSubListMethod(),
100        getSubListOriginalListSetAffectsSubListLargeListMethod(),
101        getSubListSubListRemoveAffectsOriginalLargeListMethod(),
102        getListIteratorFullyModifiableMethod(),
103        getSpliteratorNotImmutableCollectionAllowsAddMethod(),
104        getSpliteratorNotImmutableCollectionAllowsRemoveMethod());
105  }
106
107  protected Collection<Method> suppressForUnmodifiableList() {
108    return emptySet();
109  }
110
111  protected Collection<Method> suppressForCheckedList() {
112    return emptySet();
113  }
114
115  protected Collection<Method> suppressForAbstractList() {
116    return emptySet();
117  }
118
119  protected Collection<Method> suppressForAbstractSequentialList() {
120    return emptySet();
121  }
122
123  protected Collection<Method> suppressForVector() {
124    return emptySet();
125  }
126
127  @SuppressWarnings("EmptyList") // We specifically want to test emptyList()
128  public Test testsForEmptyList() {
129    return ListTestSuiteBuilder.using(
130            new TestStringListGenerator() {
131              @Override
132              protected List<String> create(String[] elements) {
133                return emptyList();
134              }
135            })
136        .named("emptyList")
137        .withFeatures(CollectionFeature.SERIALIZABLE, CollectionSize.ZERO)
138        .suppressing(suppressForEmptyList())
139        .createTestSuite();
140  }
141
142  public Test testsForSingletonList() {
143    return ListTestSuiteBuilder.using(
144            new TestStringListGenerator() {
145              @Override
146              protected List<String> create(String[] elements) {
147                return singletonList(elements[0]);
148              }
149            })
150        .named("singletonList")
151        .withFeatures(
152            CollectionFeature.SERIALIZABLE,
153            CollectionFeature.ALLOWS_NULL_VALUES,
154            CollectionSize.ONE)
155        .suppressing(suppressForSingletonList())
156        .createTestSuite();
157  }
158
159  public Test testsForArraysAsList() {
160    return ListTestSuiteBuilder.using(
161            new TestStringListGenerator() {
162              @Override
163              protected List<String> create(String[] elements) {
164                return asList(elements.clone());
165              }
166            })
167        .named("Arrays.asList")
168        .withFeatures(
169            ListFeature.SUPPORTS_SET,
170            CollectionFeature.SERIALIZABLE,
171            CollectionFeature.ALLOWS_NULL_VALUES,
172            CollectionSize.ANY)
173        .suppressing(suppressForArraysAsList())
174        .createTestSuite();
175  }
176
177  public Test testsForArrayList() {
178    return ListTestSuiteBuilder.using(
179            new TestStringListGenerator() {
180              @Override
181              protected List<String> create(String[] elements) {
182                return new ArrayList<>(MinimalCollection.of(elements));
183              }
184            })
185        .named("ArrayList")
186        .withFeatures(
187            ListFeature.GENERAL_PURPOSE,
188            CollectionFeature.SERIALIZABLE,
189            CollectionFeature.ALLOWS_NULL_VALUES,
190            CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
191            CollectionSize.ANY)
192        .suppressing(suppressForArrayList())
193        .createTestSuite();
194  }
195
196  // We are testing LinkedList / testing our tests on LinkedList.
197  @SuppressWarnings("JdkObsolete")
198  public Test testsForLinkedList() {
199    return ListTestSuiteBuilder.using(
200            new TestStringListGenerator() {
201              @Override
202              protected List<String> create(String[] elements) {
203                return new LinkedList<>(MinimalCollection.of(elements));
204              }
205            })
206        .named("LinkedList")
207        .withFeatures(
208            ListFeature.GENERAL_PURPOSE,
209            CollectionFeature.SERIALIZABLE,
210            CollectionFeature.ALLOWS_NULL_VALUES,
211            CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
212            CollectionSize.ANY)
213        .suppressing(suppressForLinkedList())
214        .createTestSuite();
215  }
216
217  public Test testsForCopyOnWriteArrayList() {
218    return ListTestSuiteBuilder.using(
219            new TestStringListGenerator() {
220              @Override
221              protected List<String> create(String[] elements) {
222                return new CopyOnWriteArrayList<>(MinimalCollection.of(elements));
223              }
224            })
225        .named("CopyOnWriteArrayList")
226        .withFeatures(
227            ListFeature.SUPPORTS_ADD_WITH_INDEX,
228            ListFeature.SUPPORTS_REMOVE_WITH_INDEX,
229            ListFeature.SUPPORTS_SET,
230            CollectionFeature.SUPPORTS_ADD,
231            CollectionFeature.SUPPORTS_REMOVE,
232            CollectionFeature.SERIALIZABLE,
233            CollectionFeature.ALLOWS_NULL_VALUES,
234            CollectionSize.ANY)
235        .suppressing(suppressForCopyOnWriteArrayList())
236        .createTestSuite();
237  }
238
239  public Test testsForUnmodifiableList() {
240    return ListTestSuiteBuilder.using(
241            new TestStringListGenerator() {
242              @Override
243              protected List<String> create(String[] elements) {
244                List<String> innerList = new ArrayList<>();
245                Collections.addAll(innerList, elements);
246                return unmodifiableList(innerList);
247              }
248            })
249        .named("unmodifiableList/ArrayList")
250        .withFeatures(
251            CollectionFeature.SERIALIZABLE,
252            CollectionFeature.ALLOWS_NULL_VALUES,
253            CollectionSize.ANY)
254        .suppressing(suppressForUnmodifiableList())
255        .createTestSuite();
256  }
257
258  public Test testsForCheckedList() {
259    return ListTestSuiteBuilder.using(
260            new TestStringListGenerator() {
261              @Override
262              protected List<String> create(String[] elements) {
263                List<String> innerList = new ArrayList<>();
264                Collections.addAll(innerList, elements);
265                return Collections.checkedList(innerList, String.class);
266              }
267            })
268        .named("checkedList/ArrayList")
269        .withFeatures(
270            ListFeature.GENERAL_PURPOSE,
271            CollectionFeature.SERIALIZABLE,
272            CollectionFeature.RESTRICTS_ELEMENTS,
273            CollectionFeature.ALLOWS_NULL_VALUES,
274            CollectionSize.ANY)
275        .suppressing(suppressForCheckedList())
276        .createTestSuite();
277  }
278
279  public Test testsForAbstractList() {
280    return ListTestSuiteBuilder.using(
281            new TestStringListGenerator() {
282              @Override
283              protected List<String> create(String[] elements) {
284                return new AbstractList<String>() {
285                  @Override
286                  public int size() {
287                    return elements.length;
288                  }
289
290                  @Override
291                  public String get(int index) {
292                    return elements[index];
293                  }
294                };
295              }
296            })
297        .named("AbstractList")
298        .withFeatures(
299            CollectionFeature.NONE, CollectionFeature.ALLOWS_NULL_VALUES, CollectionSize.ANY)
300        .suppressing(suppressForAbstractList())
301        .createTestSuite();
302  }
303
304  public Test testsForAbstractSequentialList() {
305    return ListTestSuiteBuilder.using(
306            new TestStringListGenerator() {
307              @Override
308              protected List<String> create(String[] elements) {
309                // For this test we trust ArrayList works
310                List<String> list = new ArrayList<>();
311                Collections.addAll(list, elements);
312                return new AbstractSequentialList<String>() {
313                  @Override
314                  public int size() {
315                    return list.size();
316                  }
317
318                  @Override
319                  public ListIterator<String> listIterator(int index) {
320                    return list.listIterator(index);
321                  }
322                };
323              }
324            })
325        .named("AbstractSequentialList")
326        .withFeatures(
327            ListFeature.GENERAL_PURPOSE, CollectionFeature.ALLOWS_NULL_VALUES, CollectionSize.ANY)
328        .suppressing(suppressForAbstractSequentialList())
329        .createTestSuite();
330  }
331
332  // We are testing Vector / testing our tests on Vector.
333  @SuppressWarnings("JdkObsolete")
334  private Test testsForVector() {
335    return ListTestSuiteBuilder.using(
336            new TestStringListGenerator() {
337              @Override
338              protected List<String> create(String[] elements) {
339                return new Vector<>(MinimalCollection.of(elements));
340              }
341            })
342        .named("Vector")
343        .withFeatures(
344            ListFeature.GENERAL_PURPOSE,
345            CollectionFeature.ALLOWS_NULL_VALUES,
346            CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
347            CollectionFeature.SERIALIZABLE,
348            CollectionSize.ANY)
349        .suppressing(suppressForVector())
350        .createTestSuite();
351  }
352}