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   * Tests {@link SortedSet}.
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              if (head) {
53                  //System.out.println("HEADSET");
54                  this.type = TYPE_HEADSET;
55                  this.highBound = bound;
56                  this.fullElements = (E[]) new Object[bound];
57                  System.arraycopy(AbstractSortedSetTest.this.getFullElements(), 0, fullElements, 0, bound);
58                  this.otherElements = (E[]) new Object[bound - 1];
59                  System.arraycopy(//src src_pos dst dst_pos length
60                      AbstractSortedSetTest.this.getOtherElements(), 0, otherElements, 0, bound - 1);
61                  //System.out.println(new TreeSet(Arrays.asList(m_FullElements)));
62                  //System.out.println(new TreeSet(Arrays.asList(m_OtherElements)));
63              } else {
64                  //System.out.println("TAILSET");
65                  this.type = TYPE_TAILSET;
66                  this.lowBound = bound;
67                  final Object[] allElements = AbstractSortedSetTest.this.getFullElements();
68                  //System.out.println("bound = "+bound +"::length="+allElements.length);
69                  this.fullElements = (E[]) new Object[allElements.length - bound];
70                  System.arraycopy(allElements, bound, fullElements, 0, allElements.length - bound);
71                  this.otherElements = (E[]) new Object[allElements.length - bound - 1];
72                  System.arraycopy(//src src_pos dst dst_pos length
73                      AbstractSortedSetTest.this.getOtherElements(), bound, otherElements, 0, allElements.length - bound - 1);
74                  //System.out.println(new TreeSet(Arrays.asList(m_FullElements)));
75                  //System.out.println(new TreeSet(Arrays.asList(m_OtherElements)));
76                  //resetFull();
77                  //System.out.println(collection);
78                  //System.out.println(confirmed);
79  
80              }
81  
82          } //type
83          @SuppressWarnings("unchecked")
84          public TestSortedSetSubSet(final int loBound, final int hiBound) {
85              //System.out.println("SUBSET");
86              this.type = TYPE_SUBSET;
87              this.lowBound = loBound;
88              this.highBound = hiBound;
89              final int length = hiBound - loBound;
90              //System.out.println("Low=" + loBound + "::High=" + hiBound + "::Length=" + length);
91              this.fullElements = (E[]) new Object[length];
92              System.arraycopy(AbstractSortedSetTest.this.getFullElements(), loBound, fullElements, 0, length);
93              this.otherElements = (E[]) new Object[length - 1];
94              System.arraycopy(//src src_pos dst dst_pos length
95                  AbstractSortedSetTest.this.getOtherElements(), loBound, otherElements, 0, length - 1);
96  
97              //System.out.println(new TreeSet(Arrays.asList(m_FullElements)));
98              //System.out.println(new TreeSet(Arrays.asList(m_OtherElements)));
99  
100         }
101         @Override
102         public BulkTest bulkTestSortedSetHeadSet() {
103             return null;  // prevent infinite recursion
104         }
105 
106         @Override
107         public BulkTest bulkTestSortedSetSubSet() {
108             return null;  // prevent infinite recursion
109         }
110         @Override
111         public BulkTest bulkTestSortedSetTailSet() {
112             return null;  // prevent infinite recursion
113         }
114 
115         @Override
116         public E[] getFullElements() {
117             return fullElements;
118         }
119 
120         @Override
121         public E[] getOtherElements() {
122             return otherElements;
123         }
124 
125         private SortedSet<E> getSubSet(final SortedSet<E> set) {
126             final E[] elements = AbstractSortedSetTest.this.getFullElements();
127             switch (type) {
128             case TYPE_SUBSET:
129                 return set.subSet(elements[lowBound], elements[highBound]);
130             case TYPE_HEADSET:
131                 return set.headSet(elements[highBound]);
132             case TYPE_TAILSET:
133                 return set.tailSet(elements[lowBound]);
134             default:
135                 return null;
136             }
137         }
138 
139         @Override
140         public boolean isAddSupported() {
141             return AbstractSortedSetTest.this.isAddSupported();
142         }
143 
144         @Override
145         public boolean isFailFastSupported() {
146             return AbstractSortedSetTest.this.isFailFastSupported();
147         }
148         @Override
149         public boolean isNullSupported() {
150             return AbstractSortedSetTest.this.isNullSupported();
151         }
152         @Override
153         public boolean isRemoveSupported() {
154             return AbstractSortedSetTest.this.isRemoveSupported();
155         }
156 
157         @Override
158         public boolean isTestSerialization() {
159             return false;
160         }
161         @Override
162         public SortedSet<E> makeFullCollection() {
163             return getSubSet(AbstractSortedSetTest.this.makeFullCollection());
164         }
165         @Override
166         public SortedSet<E> makeObject() {
167             return getSubSet(AbstractSortedSetTest.this.makeObject());
168         }
169 
170     }
171 
172     /**
173      * Bulk test {@link SortedSet#headSet(Object)}.  This method runs through all of
174      * the tests in {@link AbstractSortedSetTest}.
175      * After modification operations, {@link #verify()} is invoked to ensure
176      * that the set and the other collection views are still valid.
177      *
178      * @return a {@link AbstractSetTest} instance for testing a headset.
179      */
180     public BulkTest bulkTestSortedSetHeadSet() {
181         final int length = getFullElements().length;
182 
183         final int loBound = length / 3;
184         final int hiBound = loBound * 2;
185         return new TestSortedSetSubSet(hiBound, true);
186     }
187 
188     /**
189      * Bulk test {@link SortedSet#subSet(Object, Object)}.  This method runs through all of
190      * the tests in {@link AbstractSortedSetTest}.
191      * After modification operations, {@link #verify()} is invoked to ensure
192      * that the set and the other collection views are still valid.
193      *
194      * @return a {@link AbstractSetTest} instance for testing a subset.
195      */
196     public BulkTest bulkTestSortedSetSubSet() {
197         final int length = getFullElements().length;
198 
199         final int loBound = length / 3;
200         final int hiBound = loBound * 2;
201         return new TestSortedSetSubSet(loBound, hiBound);
202 
203     }
204 
205     /**
206      * Bulk test {@link SortedSet#tailSet(Object)}.  This method runs through all of
207      * the tests in {@link AbstractSortedSetTest}.
208      * After modification operations, {@link #verify()} is invoked to ensure
209      * that the set and the other collection views are still valid.
210      *
211      * @return a {@link AbstractSetTest} instance for testing a tailset.
212      */
213     public BulkTest bulkTestSortedSetTailSet() {
214         final int length = getFullElements().length;
215         final int loBound = length / 3;
216         return new TestSortedSetSubSet(loBound, false);
217     }
218 
219     /**
220      * {@inheritDoc}
221      */
222     @Override
223     public SortedSet<E> getCollection() {
224         return (SortedSet<E>) super.getCollection();
225     }
226 
227     /**
228      * {@inheritDoc}
229      */
230     @Override
231     public SortedSet<E> getConfirmed() {
232         return (SortedSet<E>) super.getConfirmed();
233     }
234 
235     /**
236      * Override to return comparable objects.
237      */
238     @Override
239     @SuppressWarnings("unchecked")
240     public E[] getFullNonNullElements() {
241         final Object[] elements = new Object[30];
242 
243         for (int i = 0; i < 30; i++) {
244             elements[i] = Integer.valueOf(i + i + 1);
245         }
246         return (E[]) elements;
247     }
248 
249     /**
250      * Override to return comparable objects.
251      */
252     @Override
253     @SuppressWarnings("unchecked")
254     public E[] getOtherNonNullElements() {
255         final Object[] elements = new Object[30];
256         for (int i = 0; i < 30; i++) {
257             elements[i] = Integer.valueOf(i + i + 2);
258         }
259         return (E[]) elements;
260     }
261 
262     /**
263      * Overridden because SortedSets don't allow null elements (normally).
264      * @return false
265      */
266     @Override
267     public boolean isNullSupported() {
268         return false;
269     }
270 
271     /**
272      * Returns an empty {@link TreeSet} for use in modification testing.
273      *
274      * @return a confirmed empty collection
275      */
276     @Override
277     public SortedSet<E> makeConfirmedCollection() {
278         return new TreeSet<>();
279     }
280 
281     /**
282      * {@inheritDoc}
283      */
284     @Override
285     public SortedSet<E> makeFullCollection() {
286         return (SortedSet<E>) super.makeFullCollection();
287     }
288 
289     /**
290      * {@inheritDoc}
291      */
292     @Override
293     public abstract SortedSet<E> makeObject();
294 
295     /**
296      * Verification extension, will check the order of elements,
297      * the sets should already be verified equal.
298      */
299     @Override
300     public void verify() {
301         super.verify();
302 
303         // Check that iterator returns elements in order and first() and last()
304         // are consistent
305         final Iterator<E> collIter = getCollection().iterator();
306         final Iterator<E> confIter = getConfirmed().iterator();
307         E first = null;
308         E last = null;
309         while (collIter.hasNext()) {
310             if (first == null) {
311                 first = collIter.next();
312                 last = first;
313             } else {
314                 last = collIter.next();
315             }
316             assertEquals(last, confIter.next(), "Element appears to be out of order.");
317         }
318         if (!getCollection().isEmpty()) {
319             assertEquals(first,
320                 getCollection().first(), "Incorrect element returned by first().");
321             assertEquals(last,
322                 getCollection().last(), "Incorrect element returned by last().");
323         }
324     }
325 }