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  // We are testing LinkedList / testing our tests on LinkedList.
196  @SuppressWarnings("JdkObsolete")
197  public Test testsForLinkedList() {
198    return ListTestSuiteBuilder.using(
199            new TestStringListGenerator() {
200              @Override
201              public List<String> create(String[] elements) {
202                return new LinkedList<>(MinimalCollection.of(elements));
203              }
204            })
205        .named("LinkedList")
206        .withFeatures(
207            ListFeature.GENERAL_PURPOSE,
208            CollectionFeature.SERIALIZABLE,
209            CollectionFeature.ALLOWS_NULL_VALUES,
210            CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
211            CollectionSize.ANY)
212        .suppressing(suppressForLinkedList())
213        .createTestSuite();
214  }
215
216  public Test testsForCopyOnWriteArrayList() {
217    return ListTestSuiteBuilder.using(
218            new TestStringListGenerator() {
219              @Override
220              public List<String> create(String[] elements) {
221                return new CopyOnWriteArrayList<>(MinimalCollection.of(elements));
222              }
223            })
224        .named("CopyOnWriteArrayList")
225        .withFeatures(
226            ListFeature.SUPPORTS_ADD_WITH_INDEX,
227            ListFeature.SUPPORTS_REMOVE_WITH_INDEX,
228            ListFeature.SUPPORTS_SET,
229            CollectionFeature.SUPPORTS_ADD,
230            CollectionFeature.SUPPORTS_REMOVE,
231            CollectionFeature.SERIALIZABLE,
232            CollectionFeature.ALLOWS_NULL_VALUES,
233            CollectionSize.ANY)
234        .suppressing(suppressForCopyOnWriteArrayList())
235        .createTestSuite();
236  }
237
238  public Test testsForUnmodifiableList() {
239    return ListTestSuiteBuilder.using(
240            new TestStringListGenerator() {
241              @Override
242              public List<String> create(String[] elements) {
243                List<String> innerList = new ArrayList<>();
244                Collections.addAll(innerList, elements);
245                return unmodifiableList(innerList);
246              }
247            })
248        .named("unmodifiableList/ArrayList")
249        .withFeatures(
250            CollectionFeature.SERIALIZABLE,
251            CollectionFeature.ALLOWS_NULL_VALUES,
252            CollectionSize.ANY)
253        .suppressing(suppressForUnmodifiableList())
254        .createTestSuite();
255  }
256
257  public Test testsForCheckedList() {
258    return ListTestSuiteBuilder.using(
259            new TestStringListGenerator() {
260              @Override
261              public List<String> create(String[] elements) {
262                List<String> innerList = new ArrayList<>();
263                Collections.addAll(innerList, elements);
264                return Collections.checkedList(innerList, String.class);
265              }
266            })
267        .named("checkedList/ArrayList")
268        .withFeatures(
269            ListFeature.GENERAL_PURPOSE,
270            CollectionFeature.SERIALIZABLE,
271            CollectionFeature.RESTRICTS_ELEMENTS,
272            CollectionFeature.ALLOWS_NULL_VALUES,
273            CollectionSize.ANY)
274        .suppressing(suppressForCheckedList())
275        .createTestSuite();
276  }
277
278  public Test testsForAbstractList() {
279    return ListTestSuiteBuilder.using(
280            new TestStringListGenerator() {
281              @Override
282              protected List<String> create(String[] elements) {
283                return new AbstractList<String>() {
284                  @Override
285                  public int size() {
286                    return elements.length;
287                  }
288
289                  @Override
290                  public String get(int index) {
291                    return elements[index];
292                  }
293                };
294              }
295            })
296        .named("AbstractList")
297        .withFeatures(
298            CollectionFeature.NONE, CollectionFeature.ALLOWS_NULL_VALUES, CollectionSize.ANY)
299        .suppressing(suppressForAbstractList())
300        .createTestSuite();
301  }
302
303  public Test testsForAbstractSequentialList() {
304    return ListTestSuiteBuilder.using(
305            new TestStringListGenerator() {
306              @Override
307              protected List<String> create(String[] elements) {
308                // For this test we trust ArrayList works
309                List<String> list = new ArrayList<>();
310                Collections.addAll(list, elements);
311                return new AbstractSequentialList<String>() {
312                  @Override
313                  public int size() {
314                    return list.size();
315                  }
316
317                  @Override
318                  public ListIterator<String> listIterator(int index) {
319                    return list.listIterator(index);
320                  }
321                };
322              }
323            })
324        .named("AbstractSequentialList")
325        .withFeatures(
326            ListFeature.GENERAL_PURPOSE, CollectionFeature.ALLOWS_NULL_VALUES, CollectionSize.ANY)
327        .suppressing(suppressForAbstractSequentialList())
328        .createTestSuite();
329  }
330
331  // We are testing Vector / testing our tests on Vector.
332  @SuppressWarnings("JdkObsolete")
333  private Test testsForVector() {
334    return ListTestSuiteBuilder.using(
335            new TestStringListGenerator() {
336              @Override
337              protected List<String> create(String[] elements) {
338                return new Vector<>(MinimalCollection.of(elements));
339              }
340            })
341        .named("Vector")
342        .withFeatures(
343            ListFeature.GENERAL_PURPOSE,
344            CollectionFeature.ALLOWS_NULL_VALUES,
345            CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
346            CollectionFeature.SERIALIZABLE,
347            CollectionSize.ANY)
348        .createTestSuite();
349  }
350}