• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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;
18 
19 import com.google.common.annotations.GwtCompatible;
20 import com.google.errorprone.annotations.OverridingMethodsMustInvokeSuper;
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.List;
26 import org.junit.Ignore;
27 
28 /**
29  * Base class for testers of classes (including {@link Collection} and {@link java.util.Map Map})
30  * that contain elements.
31  *
32  * @param <C> the type of the container
33  * @param <E> the type of the container's contents
34  * @author George van den Driessche
35  */
36 @GwtCompatible
37 @Ignore // Affects only Android test runner, which respects JUnit 4 annotations on JUnit 3 tests.
38 public abstract class AbstractContainerTester<C, E>
39     extends AbstractTester<OneSizeTestContainerGenerator<C, E>> {
40   protected SampleElements<E> samples;
41   protected C container;
42 
43   @Override
44   @OverridingMethodsMustInvokeSuper
setUp()45   public void setUp() throws Exception {
46     super.setUp();
47     samples = this.getSubjectGenerator().samples();
48     resetContainer();
49   }
50 
51   /**
52    * @return the contents of the container under test, for use by {@link #expectContents(Object[])
53    *     expectContents(E...)} and its friends.
54    */
actualContents()55   protected abstract Collection<E> actualContents();
56 
57   /**
58    * Replaces the existing container under test with a new container created by the subject
59    * generator.
60    *
61    * @see #resetContainer(Object) resetContainer(C)
62    * @return the new container instance.
63    */
resetContainer()64   protected C resetContainer() {
65     return resetContainer(getSubjectGenerator().createTestSubject());
66   }
67 
68   /**
69    * Replaces the existing container under test with a new container. This is useful when a single
70    * test method needs to create multiple containers while retaining the ability to use {@link
71    * #expectContents(Object[]) expectContents(E...)} and other convenience methods. The creation of
72    * multiple containers in a single method is discouraged in most cases, but it is vital to the
73    * iterator tests.
74    *
75    * @return the new container instance
76    * @param newValue the new container instance
77    */
resetContainer(C newValue)78   protected C resetContainer(C newValue) {
79     container = newValue;
80     return container;
81   }
82 
83   /**
84    * @see #expectContents(java.util.Collection)
85    * @param elements expected contents of {@link #container}
86    */
expectContents(E... elements)87   protected final void expectContents(E... elements) {
88     expectContents(Arrays.asList(elements));
89   }
90 
91   /**
92    * Asserts that the collection under test contains exactly the given elements, respecting
93    * cardinality but not order. Subclasses may override this method to provide stronger assertions,
94    * e.g., to check ordering in lists, but realize that <strong>unless a test extends {@link
95    * com.google.common.collect.testing.testers.AbstractListTester AbstractListTester}, a call to
96    * {@code expectContents()} invokes this version</strong>.
97    *
98    * @param expected expected value of {@link #container}
99    */
100   /*
101    * TODO: improve this and other implementations and move out of this framework
102    * for wider use
103    *
104    * TODO: could we incorporate the overriding logic from AbstractListTester, by
105    * examining whether the features include KNOWN_ORDER?
106    */
expectContents(Collection<E> expected)107   protected void expectContents(Collection<E> expected) {
108     Helpers.assertEqualIgnoringOrder(expected, actualContents());
109   }
110 
expectUnchanged()111   protected void expectUnchanged() {
112     expectContents(getOrderedElements());
113   }
114 
115   /**
116    * Asserts that the collection under test contains exactly the elements it was initialized with
117    * plus the given elements, according to {@link #expectContents(java.util.Collection)}. In other
118    * words, for the default {@code expectContents()} implementation, the number of occurrences of
119    * each given element has increased by one since the test collection was created, and the number
120    * of occurrences of all other elements has not changed.
121    *
122    * <p>Note: This means that a test like the following will fail if {@code collection} is a {@code
123    * Set}:
124    *
125    * <pre>
126    * collection.add(existingElement);
127    * expectAdded(existingElement);</pre>
128    *
129    * <p>In this case, {@code collection} was not modified as a result of the {@code add()} call, and
130    * the test will fail because the number of occurrences of {@code existingElement} is unchanged.
131    *
132    * @param elements expected additional contents of {@link #container}
133    */
expectAdded(E... elements)134   protected final void expectAdded(E... elements) {
135     List<E> expected = Helpers.copyToList(getSampleElements());
136     expected.addAll(Arrays.asList(elements));
137     expectContents(expected);
138   }
139 
expectAdded(int index, E... elements)140   protected final void expectAdded(int index, E... elements) {
141     expectAdded(index, Arrays.asList(elements));
142   }
143 
expectAdded(int index, Collection<E> elements)144   protected final void expectAdded(int index, Collection<E> elements) {
145     List<E> expected = Helpers.copyToList(getSampleElements());
146     expected.addAll(index, elements);
147     expectContents(expected);
148   }
149 
150   /*
151    * TODO: if we're testing a list, we could check indexOf(). (Doing it in
152    * AbstractListTester isn't enough because many tests that run on lists don't
153    * extends AbstractListTester.) We could also iterate over all elements to
154    * verify absence
155    */
expectMissing(E... elements)156   protected void expectMissing(E... elements) {
157     for (E element : elements) {
158       assertFalse("Should not contain " + element, actualContents().contains(element));
159     }
160   }
161 
createSamplesArray()162   protected E[] createSamplesArray() {
163     E[] array = getSubjectGenerator().createArray(getNumElements());
164     getSampleElements().toArray(array);
165     return array;
166   }
167 
createOrderedArray()168   protected E[] createOrderedArray() {
169     E[] array = getSubjectGenerator().createArray(getNumElements());
170     getOrderedElements().toArray(array);
171     return array;
172   }
173 
174   public static class ArrayWithDuplicate<E> {
175     public final E[] elements;
176     public final E duplicate;
177 
ArrayWithDuplicate(E[] elements, E duplicate)178     private ArrayWithDuplicate(E[] elements, E duplicate) {
179       this.elements = elements;
180       this.duplicate = duplicate;
181     }
182   }
183 
184   /**
185    * @return an array of the proper size with a duplicate element. The size must be at least three.
186    */
createArrayWithDuplicateElement()187   protected ArrayWithDuplicate<E> createArrayWithDuplicateElement() {
188     E[] elements = createSamplesArray();
189     E duplicate = elements[(elements.length / 2) - 1];
190     elements[(elements.length / 2) + 1] = duplicate;
191     return new ArrayWithDuplicate<E>(elements, duplicate);
192   }
193 
194   // Helper methods to improve readability of derived classes
195 
getNumElements()196   protected int getNumElements() {
197     return getSubjectGenerator().getCollectionSize().getNumElements();
198   }
199 
getSampleElements(int howMany)200   protected Collection<E> getSampleElements(int howMany) {
201     return getSubjectGenerator().getSampleElements(howMany);
202   }
203 
getSampleElements()204   protected Collection<E> getSampleElements() {
205     return getSampleElements(getNumElements());
206   }
207 
208   /**
209    * Returns the {@linkplain #getSampleElements() sample elements} as ordered by {@link
210    * TestContainerGenerator#order(List)}. Tests should used this method only if they declare
211    * requirement {@link com.google.common.collect.testing.features.CollectionFeature#KNOWN_ORDER}.
212    */
getOrderedElements()213   protected List<E> getOrderedElements() {
214     List<E> list = new ArrayList<E>();
215     for (E e : getSubjectGenerator().order(new ArrayList<E>(getSampleElements()))) {
216       list.add(e);
217     }
218     return Collections.unmodifiableList(list);
219   }
220 
221   /**
222    * @return a suitable location for a null element, to use when initializing containers for tests
223    *     that involve a null element being present.
224    */
getNullLocation()225   protected int getNullLocation() {
226     return getNumElements() / 2;
227   }
228 
229   @SuppressWarnings("unchecked")
createDisjointCollection()230   protected MinimalCollection<E> createDisjointCollection() {
231     return MinimalCollection.of(e3(), e4());
232   }
233 
234   @SuppressWarnings("unchecked")
emptyCollection()235   protected MinimalCollection<E> emptyCollection() {
236     return MinimalCollection.<E>of();
237   }
238 
e0()239   protected final E e0() {
240     return samples.e0();
241   }
242 
e1()243   protected final E e1() {
244     return samples.e1();
245   }
246 
e2()247   protected final E e2() {
248     return samples.e2();
249   }
250 
e3()251   protected final E e3() {
252     return samples.e3();
253   }
254 
e4()255   protected final E e4() {
256     return samples.e4();
257   }
258 }
259