View Javadoc
1   /*
2    * Copyright (C) 2008 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.testing.testers;
18  
19  import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
20  import static com.google.common.collect.testing.features.CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION;
21  import static com.google.common.collect.testing.features.CollectionSize.ONE;
22  import static com.google.common.collect.testing.features.CollectionSize.ZERO;
23  import static com.google.common.collect.testing.features.ListFeature.SUPPORTS_ADD_WITH_INDEX;
24  
25  import com.google.common.annotations.GwtCompatible;
26  import com.google.common.annotations.GwtIncompatible;
27  import com.google.common.collect.testing.Helpers;
28  import com.google.common.collect.testing.features.CollectionFeature;
29  import com.google.common.collect.testing.features.CollectionSize;
30  import com.google.common.collect.testing.features.ListFeature;
31  import java.lang.reflect.Method;
32  import java.util.ConcurrentModificationException;
33  import java.util.Iterator;
34  
35  /**
36   * A generic JUnit test which tests {@code add(int, Object)} operations on a
37   * list. Can't be invoked directly; please see
38   * {@link com.google.common.collect.testing.ListTestSuiteBuilder}.
39   *
40   * @author Chris Povirk
41   */
42  @SuppressWarnings("unchecked") // too many "unchecked generic array creations"
43  @GwtCompatible(emulated = true)
44  public class ListAddAtIndexTester<E> extends AbstractListTester<E> {
45    @ListFeature.Require(SUPPORTS_ADD_WITH_INDEX)
46    @CollectionSize.Require(absent = ZERO)
47    public void testAddAtIndex_supportedPresent() {
48      getList().add(0, e0());
49      expectAdded(0, e0());
50    }
51  
52    @ListFeature.Require(absent = SUPPORTS_ADD_WITH_INDEX)
53    @CollectionSize.Require(absent = ZERO)
54    /*
55     * absent = ZERO isn't required, since unmodList.add() must
56     * throw regardless, but it keeps the method name accurate.
57     */
58    public void testAddAtIndex_unsupportedPresent() {
59      try {
60        getList().add(0, e0());
61        fail("add(n, present) should throw");
62      } catch (UnsupportedOperationException expected) {
63      }
64      expectUnchanged();
65    }
66  
67    @ListFeature.Require(SUPPORTS_ADD_WITH_INDEX)
68    public void testAddAtIndex_supportedNotPresent() {
69      getList().add(0, e3());
70      expectAdded(0, e3());
71    }
72  
73    @CollectionFeature.Require(FAILS_FAST_ON_CONCURRENT_MODIFICATION)
74    @ListFeature.Require(SUPPORTS_ADD_WITH_INDEX)
75    public void testAddAtIndexConcurrentWithIteration() {
76      try {
77        Iterator<E> iterator = collection.iterator();
78        getList().add(0, e3());
79        iterator.next();
80        fail("Expected ConcurrentModificationException");
81      } catch (ConcurrentModificationException expected) {
82        // success
83      }
84    }
85  
86    @ListFeature.Require(absent = SUPPORTS_ADD_WITH_INDEX)
87    public void testAddAtIndex_unsupportedNotPresent() {
88      try {
89        getList().add(0, e3());
90        fail("add(n, notPresent) should throw");
91      } catch (UnsupportedOperationException expected) {
92      }
93      expectUnchanged();
94      expectMissing(e3());
95    }
96  
97    @ListFeature.Require(SUPPORTS_ADD_WITH_INDEX)
98    @CollectionSize.Require(absent = {ZERO, ONE})
99    public void testAddAtIndex_middle() {
100     getList().add(getNumElements() / 2, e3());
101     expectAdded(getNumElements() / 2, e3());
102   }
103 
104   @ListFeature.Require(SUPPORTS_ADD_WITH_INDEX)
105   @CollectionSize.Require(absent = ZERO)
106   public void testAddAtIndex_end() {
107     getList().add(getNumElements(), e3());
108     expectAdded(getNumElements(), e3());
109   }
110 
111   @ListFeature.Require(SUPPORTS_ADD_WITH_INDEX)
112   @CollectionFeature.Require(ALLOWS_NULL_VALUES)
113   public void testAddAtIndex_nullSupported() {
114     getList().add(0, null);
115     expectAdded(0, (E) null);
116   }
117 
118   @ListFeature.Require(SUPPORTS_ADD_WITH_INDEX)
119   @CollectionFeature.Require(absent = ALLOWS_NULL_VALUES)
120   public void testAddAtIndex_nullUnsupported() {
121     try {
122       getList().add(0, null);
123       fail("add(n, null) should throw");
124     } catch (NullPointerException expected) {
125     }
126     expectUnchanged();
127     expectNullMissingWhenNullUnsupported("Should not contain null after unsupported add(n, null)");
128   }
129 
130   @ListFeature.Require(SUPPORTS_ADD_WITH_INDEX)
131   public void testAddAtIndex_negative() {
132     try {
133       getList().add(-1, e3());
134       fail("add(-1, e) should throw");
135     } catch (IndexOutOfBoundsException expected) {
136     }
137     expectUnchanged();
138     expectMissing(e3());
139   }
140 
141   @ListFeature.Require(SUPPORTS_ADD_WITH_INDEX)
142   public void testAddAtIndex_tooLarge() {
143     try {
144       getList().add(getNumElements() + 1, e3());
145       fail("add(size + 1, e) should throw");
146     } catch (IndexOutOfBoundsException expected) {
147     }
148     expectUnchanged();
149     expectMissing(e3());
150   }
151 
152   /**
153    * Returns the {@link Method} instance for
154    * {@link #testAddAtIndex_nullSupported()} so that tests can suppress it. See
155    * {@link CollectionAddTester#getAddNullSupportedMethod()} for details.
156    */
157   @GwtIncompatible // reflection
158   public static Method getAddNullSupportedMethod() {
159     return Helpers.getMethod(ListAddAtIndexTester.class, "testAddAtIndex_nullSupported");
160   }
161 }