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  public Test testsForEmptyList() {
128    return ListTestSuiteBuilder.using(
129            new TestStringListGenerator() {
130              @Override
131              public List<String> create(String[] elements) {
132                return emptyList();
133              }
134            })
135        .named("emptyList")
136        .withFeatures(CollectionFeature.SERIALIZABLE, CollectionSize.ZERO)
137        .suppressing(suppressForEmptyList())
138        .createTestSuite();
139  }
140
141  public Test testsForSingletonList() {
142    return ListTestSuiteBuilder.using(
143            new TestStringListGenerator() {
144              @Override
145              public List<String> create(String[] elements) {
146                return singletonList(elements[0]);
147              }
148            })
149        .named("singletonList")
150        .withFeatures(
151            CollectionFeature.SERIALIZABLE,
152            CollectionFeature.ALLOWS_NULL_VALUES,
153            CollectionSize.ONE)
154        .suppressing(suppressForSingletonList())
155        .createTestSuite();
156  }
157
158  public Test testsForArraysAsList() {
159    return ListTestSuiteBuilder.using(
160            new TestStringListGenerator() {
161              @Override
162              public List<String> create(String[] elements) {
163                return asList(elements.clone());
164              }
165            })
166        .named("Arrays.asList")
167        .withFeatures(
168            ListFeature.SUPPORTS_SET,
169            CollectionFeature.SERIALIZABLE,
170            CollectionFeature.ALLOWS_NULL_VALUES,
171            CollectionSize.ANY)
172        .suppressing(suppressForArraysAsList())
173        .createTestSuite();
174  }
175
176  public Test testsForArrayList() {
177    return ListTestSuiteBuilder.using(
178            new TestStringListGenerator() {
179              @Override
180              public List<String> create(String[] elements) {
181                return new ArrayList<>(MinimalCollection.of(elements));
182              }
183            })
184        .named("ArrayList")
185        .withFeatures(
186            ListFeature.GENERAL_PURPOSE,
187            CollectionFeature.SERIALIZABLE,
188            CollectionFeature.ALLOWS_NULL_VALUES,
189            CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
190            CollectionSize.ANY)
191        .suppressing(suppressForArrayList())
192        .createTestSuite();
193  }
194
195  public Test testsForLinkedList() {
196    return ListTestSuiteBuilder.using(
197            new TestStringListGenerator() {
198              @Override
199              public List<String> create(String[] elements) {
200                return new LinkedList<>(MinimalCollection.of(elements));
201              }
202            })
203        .named("LinkedList")
204        .withFeatures(
205            ListFeature.GENERAL_PURPOSE,
206            CollectionFeature.SERIALIZABLE,
207            CollectionFeature.ALLOWS_NULL_VALUES,
208            CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
209            CollectionSize.ANY)
210        .suppressing(suppressForLinkedList())
211        .createTestSuite();
212  }
213
214  public Test testsForCopyOnWriteArrayList() {
215    return ListTestSuiteBuilder.using(
216            new TestStringListGenerator() {
217              @Override
218              public List<String> create(String[] elements) {
219                return new CopyOnWriteArrayList<>(MinimalCollection.of(elements));
220              }
221            })
222        .named("CopyOnWriteArrayList")
223        .withFeatures(
224            ListFeature.SUPPORTS_ADD_WITH_INDEX,
225            ListFeature.SUPPORTS_REMOVE_WITH_INDEX,
226            ListFeature.SUPPORTS_SET,
227            CollectionFeature.SUPPORTS_ADD,
228            CollectionFeature.SUPPORTS_REMOVE,
229            CollectionFeature.SERIALIZABLE,
230            CollectionFeature.ALLOWS_NULL_VALUES,
231            CollectionSize.ANY)
232        .suppressing(suppressForCopyOnWriteArrayList())
233        .createTestSuite();
234  }
235
236  public Test testsForUnmodifiableList() {
237    return ListTestSuiteBuilder.using(
238            new TestStringListGenerator() {
239              @Override
240              public List<String> create(String[] elements) {
241                List<String> innerList = new ArrayList<>();
242                Collections.addAll(innerList, elements);
243                return unmodifiableList(innerList);
244              }
245            })
246        .named("unmodifiableList/ArrayList")
247        .withFeatures(
248            CollectionFeature.SERIALIZABLE,
249            CollectionFeature.ALLOWS_NULL_VALUES,
250            CollectionSize.ANY)
251        .suppressing(suppressForUnmodifiableList())
252        .createTestSuite();
253  }
254
255  public Test testsForCheckedList() {
256    return ListTestSuiteBuilder.using(
257            new TestStringListGenerator() {
258              @Override
259              public List<String> create(String[] elements) {
260                List<String> innerList = new ArrayList<>();
261                Collections.addAll(innerList, elements);
262                return Collections.checkedList(innerList, String.class);
263              }
264            })
265        .named("checkedList/ArrayList")
266        .withFeatures(
267            ListFeature.GENERAL_PURPOSE,
268            CollectionFeature.SERIALIZABLE,
269            CollectionFeature.RESTRICTS_ELEMENTS,
270            CollectionFeature.ALLOWS_NULL_VALUES,
271            CollectionSize.ANY)
272        .suppressing(suppressForCheckedList())
273        .createTestSuite();
274  }
275
276  public Test testsForAbstractList() {
277    return ListTestSuiteBuilder.using(
278            new TestStringListGenerator() {
279              @Override
280              protected List<String> create(final String[] elements) {
281                return new AbstractList<String>() {
282                  @Override
283                  public int size() {
284                    return elements.length;
285                  }
286
287                  @Override
288                  public String get(int index) {
289                    return elements[index];
290                  }
291                };
292              }
293            })
294        .named("AbstractList")
295        .withFeatures(
296            CollectionFeature.NONE, CollectionFeature.ALLOWS_NULL_VALUES, CollectionSize.ANY)
297        .suppressing(suppressForAbstractList())
298        .createTestSuite();
299  }
300
301  public Test testsForAbstractSequentialList() {
302    return ListTestSuiteBuilder.using(
303            new TestStringListGenerator() {
304              @Override
305              protected List<String> create(final String[] elements) {
306                // For this test we trust ArrayList works
307                final List<String> list = new ArrayList<>();
308                Collections.addAll(list, elements);
309                return new AbstractSequentialList<String>() {
310                  @Override
311                  public int size() {
312                    return list.size();
313                  }
314
315                  @Override
316                  public ListIterator<String> listIterator(int index) {
317                    return list.listIterator(index);
318                  }
319                };
320              }
321            })
322        .named("AbstractSequentialList")
323        .withFeatures(
324            ListFeature.GENERAL_PURPOSE, CollectionFeature.ALLOWS_NULL_VALUES, CollectionSize.ANY)
325        .suppressing(suppressForAbstractSequentialList())
326        .createTestSuite();
327  }
328
329  private Test testsForVector() {
330    return ListTestSuiteBuilder.using(
331            new TestStringListGenerator() {
332              @Override
333              protected List<String> create(String[] elements) {
334                return new Vector<>(MinimalCollection.of(elements));
335              }
336            })
337        .named("Vector")
338        .withFeatures(
339            ListFeature.GENERAL_PURPOSE,
340            CollectionFeature.ALLOWS_NULL_VALUES,
341            CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
342            CollectionFeature.SERIALIZABLE,
343            CollectionSize.ANY)
344        .createTestSuite();
345  }
346}