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