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 this
4    * work for additional information regarding copyright ownership. The ASF
5    * licenses this file to You under the Apache License, Version 2.0 (the
6    * "License"); you may not use this file except in compliance with the License.
7    * You may obtain a copy of the License at
8    * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
9    * or agreed to in writing, software distributed under the License is
10   * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11   * KIND, either express or implied. See the License for the specific language
12   * governing permissions and limitations under the License.
13   */
14  package org.apache.commons.collections4.iterators;
15  
16  import java.util.ArrayList;
17  import java.util.Arrays;
18  import java.util.Collections;
19  import java.util.Iterator;
20  import java.util.List;
21  import java.util.NoSuchElementException;
22  
23  import org.junit.Test;
24  
25  /**
26   * A unit test to test the basic functions of {@link BoundedIterator}.
27   *
28   */
29  public class BoundedIteratorTest<E> extends AbstractIteratorTest<E> {
30  
31      /** Test array of size 7 */
32      private final String[] testArray = {
33          "a", "b", "c", "d", "e", "f", "g"
34      };
35  
36      private List<E> testList;
37  
38      public BoundedIteratorTest(final String testName) {
39          super(testName);
40      }
41  
42      @SuppressWarnings("unchecked")
43      @Override
44      public void setUp()
45          throws Exception {
46          super.setUp();
47          testList = Arrays.asList((E[]) testArray);
48      }
49  
50      @Override
51      public Iterator<E> makeEmptyIterator() {
52          return new BoundedIterator<>(Collections.<E>emptyList().iterator(), 0, 10);
53      }
54  
55      @Override
56      public Iterator<E> makeObject() {
57          return new BoundedIterator<>(new ArrayList<>(testList).iterator(), 1, testList.size() - 1);
58      }
59  
60      // ---------------- Tests ---------------------
61  
62      /**
63       * Test a decorated iterator bounded such that the first element returned is
64       * at an index greater its first element, and the last element returned is
65       * at an index less than its last element.
66       */
67      @Test
68      public void testBounded() {
69          final Iterator<E> iter = new BoundedIterator<>(testList.iterator(), 2, 4);
70  
71          assertTrue(iter.hasNext());
72          assertEquals("c", iter.next());
73          assertTrue(iter.hasNext());
74          assertEquals("d", iter.next());
75          assertTrue(iter.hasNext());
76          assertEquals("e", iter.next());
77          assertTrue(iter.hasNext());
78          assertEquals("f", iter.next());
79  
80          assertFalse(iter.hasNext());
81          try {
82              iter.next();
83              fail("Expected NoSuchElementException.");
84          } catch (final NoSuchElementException nsee) { /* Success case */
85          }
86      }
87  
88      /**
89       * Test a decorated iterator bounded such that the <code>offset</code> is
90       * zero and the <code>max</code> is its size, in that the BoundedIterator
91       * should return all the same elements as its decorated iterator.
92       */
93      @Test
94      public void testSameAsDecorated() {
95          final Iterator<E> iter = new BoundedIterator<>(testList.iterator(), 0,
96                                                    testList.size());
97  
98          assertTrue(iter.hasNext());
99          assertEquals("a", iter.next());
100         assertTrue(iter.hasNext());
101         assertEquals("b", iter.next());
102         assertTrue(iter.hasNext());
103         assertEquals("c", iter.next());
104         assertTrue(iter.hasNext());
105         assertEquals("d", iter.next());
106         assertTrue(iter.hasNext());
107         assertEquals("e", iter.next());
108         assertTrue(iter.hasNext());
109         assertEquals("f", iter.next());
110         assertTrue(iter.hasNext());
111         assertEquals("g", iter.next());
112 
113         assertFalse(iter.hasNext());
114         try {
115             iter.next();
116             fail("Expected NoSuchElementException.");
117         } catch (final NoSuchElementException nsee) { /* Success case */
118         }
119     }
120 
121     /**
122      * Test a decorated iterator bounded to a <code>max</code> of 0. The
123      * BoundedIterator should behave as if there are no more elements to return,
124      * since it is technically an empty iterator.
125      */
126     @Test
127     public void testEmptyBounded() {
128         final Iterator<E> iter = new BoundedIterator<>(testList.iterator(), 3, 0);
129         assertFalse(iter.hasNext());
130         try {
131             iter.next();
132             fail("Expected NoSuchElementException.");
133         } catch (final NoSuchElementException nsee) { /* Success case */
134         }
135     }
136 
137     /**
138      * Test the case if a negative <code>offset</code> is passed to the
139      * constructor. {@link IllegalArgumentException} is expected.
140      */
141     @Test
142     public void testNegativeOffset() {
143         try {
144             new BoundedIterator<>(testList.iterator(), -1, 4);
145             fail("Expected IllegalArgumentException.");
146         } catch (final IllegalArgumentException iae) { /* Success case */
147         }
148     }
149 
150     /**
151      * Test the case if a negative <code>max</code> is passed to the
152      * constructor. {@link IllegalArgumentException} is expected.
153      */
154     @Test
155     public void testNegativeMax() {
156         try {
157             new BoundedIterator<>(testList.iterator(), 3, -1);
158             fail("Expected IllegalArgumentException.");
159         } catch (final IllegalArgumentException iae) { /* Success case */
160         }
161     }
162 
163     /**
164      * Test the case if the <code>offset</code> passed to the constructor is
165      * greater than the decorated iterator's size. The BoundedIterator should
166      * behave as if there are no more elements to return.
167      */
168     @Test
169     public void testOffsetGreaterThanSize() {
170         final Iterator<E> iter = new BoundedIterator<>(testList.iterator(), 10, 4);
171         assertFalse(iter.hasNext());
172         try {
173             iter.next();
174             fail("Expected NoSuchElementException.");
175         } catch (final NoSuchElementException nsee) { /* Success case */
176         }
177     }
178 
179     /**
180      * Test the case if the <code>max</code> passed to the constructor is
181      * greater than the size of the decorated iterator. The last element
182      * returned should be the same as the last element of the decorated
183      * iterator.
184      */
185     @Test
186     public void testMaxGreaterThanSize() {
187         final Iterator<E> iter = new BoundedIterator<>(testList.iterator(), 1, 10);
188 
189         assertTrue(iter.hasNext());
190         assertEquals("b", iter.next());
191         assertTrue(iter.hasNext());
192         assertEquals("c", iter.next());
193         assertTrue(iter.hasNext());
194         assertEquals("d", iter.next());
195         assertTrue(iter.hasNext());
196         assertEquals("e", iter.next());
197         assertTrue(iter.hasNext());
198         assertEquals("f", iter.next());
199         assertTrue(iter.hasNext());
200         assertEquals("g", iter.next());
201 
202         assertFalse(iter.hasNext());
203         try {
204             iter.next();
205             fail("Expected NoSuchElementException.");
206         } catch (final NoSuchElementException nsee) { /* Success case */
207         }
208     }
209 
210     /**
211      * Test the <code>remove()</code> method being called without
212      * <code>next()</code> being called first.
213      */
214     @Test
215     public void testRemoveWithoutCallingNext() {
216         final List<E> testListCopy = new ArrayList<>(testList);
217         final Iterator<E> iter = new BoundedIterator<>(testListCopy.iterator(), 1, 5);
218 
219         try {
220             iter.remove();
221             fail("Expected IllegalStateException.");
222         } catch (final IllegalStateException ise) { /* Success case */
223         }
224     }
225 
226     /**
227      * Test the <code>remove()</code> method being called twice without calling
228      * <code>next()</code> in between.
229      */
230     @Test
231     public void testRemoveCalledTwice() {
232         final List<E> testListCopy = new ArrayList<>(testList);
233         final Iterator<E> iter = new BoundedIterator<>(testListCopy.iterator(), 1, 5);
234 
235         assertTrue(iter.hasNext());
236         assertEquals("b", iter.next());
237         iter.remove();
238 
239         try {
240             iter.remove();
241             fail("Expected IllegalStateException.");
242         } catch (final IllegalStateException ise) { /* Success case */
243         }
244     }
245 
246     /**
247      * Test removing the first element. Verify that the element is removed from
248      * the underlying collection.
249      */
250     @Test
251     public void testRemoveFirst() {
252         final List<E> testListCopy = new ArrayList<>(testList);
253         final Iterator<E> iter = new BoundedIterator<>(testListCopy.iterator(), 1, 5);
254 
255         assertTrue(iter.hasNext());
256         assertEquals("b", iter.next());
257 
258         iter.remove();
259         assertFalse(testListCopy.contains("b"));
260 
261         assertTrue(iter.hasNext());
262         assertEquals("c", iter.next());
263         assertTrue(iter.hasNext());
264         assertEquals("d", iter.next());
265         assertTrue(iter.hasNext());
266         assertEquals("e", iter.next());
267         assertTrue(iter.hasNext());
268         assertEquals("f", iter.next());
269 
270         assertFalse(iter.hasNext());
271         try {
272             iter.next();
273             fail("Expected NoSuchElementException.");
274         } catch (final NoSuchElementException nsee) { /* Success case */
275         }
276     }
277 
278     /**
279      * Test removing an element in the middle of the iterator. Verify that the
280      * element is removed from the underlying collection.
281      */
282     @Test
283     public void testRemoveMiddle() {
284         final List<E> testListCopy = new ArrayList<>(testList);
285         final Iterator<E> iter = new BoundedIterator<>(testListCopy.iterator(), 1, 5);
286 
287         assertTrue(iter.hasNext());
288         assertEquals("b", iter.next());
289         assertTrue(iter.hasNext());
290         assertEquals("c", iter.next());
291         assertTrue(iter.hasNext());
292         assertEquals("d", iter.next());
293 
294         iter.remove();
295         assertFalse(testListCopy.contains("d"));
296 
297         assertTrue(iter.hasNext());
298         assertEquals("e", iter.next());
299         assertTrue(iter.hasNext());
300         assertEquals("f", iter.next());
301 
302         assertFalse(iter.hasNext());
303         try {
304             iter.next();
305             fail("Expected NoSuchElementException.");
306         } catch (final NoSuchElementException nsee) { /* Success case */
307         }
308     }
309 
310     /**
311      * Test removing the last element. Verify that the element is removed from
312      * the underlying collection.
313      */
314     @Test
315     public void testRemoveLast() {
316         final List<E> testListCopy = new ArrayList<>(testList);
317         final Iterator<E> iter = new BoundedIterator<>(testListCopy.iterator(), 1, 5);
318 
319         assertTrue(iter.hasNext());
320         assertEquals("b", iter.next());
321         assertTrue(iter.hasNext());
322         assertEquals("c", iter.next());
323         assertTrue(iter.hasNext());
324         assertEquals("d", iter.next());
325         assertTrue(iter.hasNext());
326         assertEquals("e", iter.next());
327         assertTrue(iter.hasNext());
328         assertEquals("f", iter.next());
329 
330         assertFalse(iter.hasNext());
331         try {
332             iter.next();
333             fail("Expected NoSuchElementException.");
334         } catch (final NoSuchElementException nsee) { /* Success case */
335         }
336 
337         iter.remove();
338         assertFalse(testListCopy.contains("f"));
339 
340         assertFalse(iter.hasNext());
341         try {
342             iter.next();
343             fail("Expected NoSuchElementException.");
344         } catch (final NoSuchElementException nsee) { /* Success case */
345         }
346     }
347 
348     /**
349      * Test the case if the decorated iterator does not support the
350      * <code>remove()</code> method and throws an {@link UnsupportedOperationException}.
351      */
352     @Test
353     public void testRemoveUnsupported() {
354         final Iterator<E> mockIterator = new AbstractIteratorDecorator<E>(testList.iterator()) {
355             @Override
356             public void remove() {
357                 throw new UnsupportedOperationException();
358             }
359         };
360 
361         final Iterator<E> iter = new BoundedIterator<>(mockIterator, 1, 5);
362         assertTrue(iter.hasNext());
363         assertEquals("b", iter.next());
364         try {
365             iter.remove();
366             fail("Expected UnsupportedOperationException.");
367         } catch (final UnsupportedOperationException usoe) { /* Success case */
368         }
369     }
370 }