View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.collections4.set;
18  
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  
21  import java.util.Iterator;
22  import java.util.SortedSet;
23  import java.util.TreeSet;
24  
25  import org.apache.commons.collections4.BulkTest;
26  
27  /**
28   * Abstract test class for {@link SortedSet} methods and contracts.
29   * <p>
30   * To use, subclass and override the {@link #makeObject()}
31   * method.  You may have to override other protected methods if your
32   * set is not modifiable, or if your set restricts what kinds of
33   * elements may be added; see {@link AbstractSetTest} for more details.
34   */
35  public abstract class AbstractSortedSetTest<E> extends AbstractSetTest<E> {
36  
37      public class TestSortedSetSubSet extends AbstractSortedSetTest<E> {
38  
39          static final int TYPE_SUBSET = 0;
40          static final int TYPE_TAILSET = 1;
41          static final int TYPE_HEADSET = 2;
42          private final int type;
43          private int lowBound;
44  
45          private int highBound;
46  
47          private final E[] fullElements;
48  
49          private final E[] otherElements;
50          @SuppressWarnings("unchecked")
51          public TestSortedSetSubSet(final int bound, final boolean head) {
52              super("TestSortedSetSubSet");
53              if (head) {
54                  //System.out.println("HEADSET");
55                  this.type = TYPE_HEADSET;
56                  this.highBound = bound;
57                  this.fullElements = (E[]) new Object[bound];
58                  System.arraycopy(AbstractSortedSetTest.this.getFullElements(), 0, fullElements, 0, bound);
59                  this.otherElements = (E[]) new Object[bound - 1];
60                  System.arraycopy(//src src_pos dst dst_pos length
61                      AbstractSortedSetTest.this.getOtherElements(), 0, otherElements, 0, bound - 1);
62                  //System.out.println(new TreeSet(Arrays.asList(m_FullElements)));
63                  //System.out.println(new TreeSet(Arrays.asList(m_OtherElements)));
64              } else {
65                  //System.out.println("TAILSET");
66                  this.type = TYPE_TAILSET;
67                  this.lowBound = bound;
68                  final Object[] allElements = AbstractSortedSetTest.this.getFullElements();
69                  //System.out.println("bound = "+bound +"::length="+allElements.length);
70                  this.fullElements = (E[]) new Object[allElements.length - bound];
71                  System.arraycopy(allElements, bound, fullElements, 0, allElements.length - bound);
72                  this.otherElements = (E[]) new Object[allElements.length - bound - 1];
73                  System.arraycopy(//src src_pos dst dst_pos length
74                      AbstractSortedSetTest.this.getOtherElements(), bound, otherElements, 0, allElements.length - bound - 1);
75                  //System.out.println(new TreeSet(Arrays.asList(m_FullElements)));
76                  //System.out.println(new TreeSet(Arrays.asList(m_OtherElements)));
77                  //resetFull();
78                  //System.out.println(collection);
79                  //System.out.println(confirmed);
80  
81              }
82  
83          } //type
84          @SuppressWarnings("unchecked")
85          public TestSortedSetSubSet(final int loBound, final int hiBound) {
86              super("TestSortedSetSubSet");
87              //System.out.println("SUBSET");
88              this.type = TYPE_SUBSET;
89              this.lowBound = loBound;
90              this.highBound = hiBound;
91              final int length = hiBound - loBound;
92              //System.out.println("Low=" + loBound + "::High=" + hiBound + "::Length=" + length);
93              this.fullElements = (E[]) new Object[length];
94              System.arraycopy(AbstractSortedSetTest.this.getFullElements(), loBound, fullElements, 0, length);
95              this.otherElements = (E[]) new Object[length - 1];
96              System.arraycopy(//src src_pos dst dst_pos length
97                  AbstractSortedSetTest.this.getOtherElements(), loBound, otherElements, 0, length - 1);
98  
99              //System.out.println(new TreeSet(Arrays.asList(m_FullElements)));
100             //System.out.println(new TreeSet(Arrays.asList(m_OtherElements)));
101 
102         }
103         @Override
104         public BulkTest bulkTestSortedSetHeadSet() {
105             return null;  // prevent infinite recursion
106         }
107 
108         @Override
109         public BulkTest bulkTestSortedSetSubSet() {
110             return null;  // prevent infinite recursion
111         }
112         @Override
113         public BulkTest bulkTestSortedSetTailSet() {
114             return null;  // prevent infinite recursion
115         }
116 
117         @Override
118         public E[] getFullElements() {
119             return fullElements;
120         }
121 
122         @Override
123         public E[] getOtherElements() {
124             return otherElements;
125         }
126 
127         private SortedSet<E> getSubSet(final SortedSet<E> set) {
128             final E[] elements = AbstractSortedSetTest.this.getFullElements();
129             switch (type) {
130             case TYPE_SUBSET :
131                 return set.subSet(elements[lowBound], elements[highBound]);
132             case TYPE_HEADSET :
133                 return set.headSet(elements[highBound]);
134             case TYPE_TAILSET :
135                 return set.tailSet(elements[lowBound]);
136             default :
137                 return null;
138             }
139         }
140 
141         @Override
142         public boolean isAddSupported() {
143             return AbstractSortedSetTest.this.isAddSupported();
144         }
145 
146         @Override
147         public boolean isFailFastSupported() {
148             return AbstractSortedSetTest.this.isFailFastSupported();
149         }
150         @Override
151         public boolean isNullSupported() {
152             return AbstractSortedSetTest.this.isNullSupported();
153         }
154         @Override
155         public boolean isRemoveSupported() {
156             return AbstractSortedSetTest.this.isRemoveSupported();
157         }
158 
159         @Override
160         public boolean isTestSerialization() {
161             return false;
162         }
163         @Override
164         public SortedSet<E> makeFullCollection() {
165             return getSubSet(AbstractSortedSetTest.this.makeFullCollection());
166         }
167         @Override
168         public SortedSet<E> makeObject() {
169             return getSubSet(AbstractSortedSetTest.this.makeObject());
170         }
171 
172     }
173 
174     /**
175      * JUnit constructor.
176      *
177      * @param name  name for test
178      */
179     public AbstractSortedSetTest(final String name) {
180         super(name);
181     }
182 
183     /**
184      * Bulk test {@link SortedSet#headSet(Object)}.  This method runs through all of
185      * the tests in {@link AbstractSortedSetTest}.
186      * After modification operations, {@link #verify()} is invoked to ensure
187      * that the set and the other collection views are still valid.
188      *
189      * @return a {@link AbstractSetTest} instance for testing a headset.
190      */
191     public BulkTest bulkTestSortedSetHeadSet() {
192         final int length = getFullElements().length;
193 
194         final int loBound = length / 3;
195         final int hiBound = loBound * 2;
196         return new TestSortedSetSubSet(hiBound, true);
197     }
198 
199     /**
200      * Bulk test {@link SortedSet#subSet(Object, Object)}.  This method runs through all of
201      * the tests in {@link AbstractSortedSetTest}.
202      * After modification operations, {@link #verify()} is invoked to ensure
203      * that the set and the other collection views are still valid.
204      *
205      * @return a {@link AbstractSetTest} instance for testing a subset.
206      */
207     public BulkTest bulkTestSortedSetSubSet() {
208         final int length = getFullElements().length;
209 
210         final int loBound = length / 3;
211         final int hiBound = loBound * 2;
212         return new TestSortedSetSubSet(loBound, hiBound);
213 
214     }
215 
216     /**
217      * Bulk test {@link SortedSet#tailSet(Object)}.  This method runs through all of
218      * the tests in {@link AbstractSortedSetTest}.
219      * After modification operations, {@link #verify()} is invoked to ensure
220      * that the set and the other collection views are still valid.
221      *
222      * @return a {@link AbstractSetTest} instance for testing a tailset.
223      */
224     public BulkTest bulkTestSortedSetTailSet() {
225         final int length = getFullElements().length;
226         final int loBound = length / 3;
227         return new TestSortedSetSubSet(loBound, false);
228     }
229 
230     /**
231      * {@inheritDoc}
232      */
233     @Override
234     public SortedSet<E> getCollection() {
235         return (SortedSet<E>) super.getCollection();
236     }
237 
238     /**
239      * {@inheritDoc}
240      */
241     @Override
242     public SortedSet<E> getConfirmed() {
243         return (SortedSet<E>) super.getConfirmed();
244     }
245 
246     /**
247      * Override to return comparable objects.
248      */
249     @Override
250     @SuppressWarnings("unchecked")
251     public E[] getFullNonNullElements() {
252         final Object[] elements = new Object[30];
253 
254         for (int i = 0; i < 30; i++) {
255             elements[i] = Integer.valueOf(i + i + 1);
256         }
257         return (E[]) elements;
258     }
259 
260     /**
261      * Override to return comparable objects.
262      */
263     @Override
264     @SuppressWarnings("unchecked")
265     public E[] getOtherNonNullElements() {
266         final Object[] elements = new Object[30];
267         for (int i = 0; i < 30; i++) {
268             elements[i] = Integer.valueOf(i + i + 2);
269         }
270         return (E[]) elements;
271     }
272 
273     /**
274      * Overridden because SortedSets don't allow null elements (normally).
275      * @return false
276      */
277     @Override
278     public boolean isNullSupported() {
279         return false;
280     }
281 
282     /**
283      * Returns an empty {@link TreeSet} for use in modification testing.
284      *
285      * @return a confirmed empty collection
286      */
287     @Override
288     public SortedSet<E> makeConfirmedCollection() {
289         return new TreeSet<>();
290     }
291 
292     /**
293      * {@inheritDoc}
294      */
295     @Override
296     public SortedSet<E> makeFullCollection() {
297         return (SortedSet<E>) super.makeFullCollection();
298     }
299 
300     /**
301      * {@inheritDoc}
302      */
303     @Override
304     public abstract SortedSet<E> makeObject();
305 
306     /**
307      * Verification extension, will check the order of elements,
308      * the sets should already be verified equal.
309      */
310     @Override
311     public void verify() {
312         super.verify();
313 
314         // Check that iterator returns elements in order and first() and last()
315         // are consistent
316         final Iterator<E> collIter = getCollection().iterator();
317         final Iterator<E> confIter = getConfirmed().iterator();
318         E first = null;
319         E last = null;
320         while (collIter.hasNext()) {
321             if (first == null) {
322                 first = collIter.next();
323                 last = first;
324             } else {
325                 last = collIter.next();
326             }
327             assertEquals(last, confIter.next(), "Element appears to be out of order.");
328         }
329         if (!getCollection().isEmpty()) {
330             assertEquals(first,
331                 getCollection().first(), "Incorrect element returned by first().");
332             assertEquals(last,
333                 getCollection().last(), "Incorrect element returned by last().");
334         }
335     }
336 }