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.queue;
18  
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  import static org.junit.jupiter.api.Assertions.assertFalse;
21  import static org.junit.jupiter.api.Assertions.assertThrows;
22  import static org.junit.jupiter.api.Assertions.assertTrue;
23  
24  import java.io.ByteArrayInputStream;
25  import java.io.ByteArrayOutputStream;
26  import java.io.ObjectInputStream;
27  import java.io.ObjectOutputStream;
28  import java.util.ArrayList;
29  import java.util.Collection;
30  import java.util.Iterator;
31  import java.util.List;
32  import java.util.NoSuchElementException;
33  import java.util.Queue;
34  
35  import org.junit.jupiter.api.Test;
36  
37  /**
38   * Test cases for CircularFifoQueue.
39   */
40  public class CircularFifoQueueTest<E> extends AbstractQueueTest<E> {
41  
42      public CircularFifoQueueTest() {
43          super(CircularFifoQueueTest.class.getSimpleName());
44      }
45  
46      /**
47       * {@inheritDoc}
48       */
49      @Override
50      public CircularFifoQueue<E> getCollection() {
51          return (CircularFifoQueue<E>) super.getCollection();
52      }
53  
54      @Override
55      public String getCompatibilityVersion() {
56          return "4";
57      }
58  
59      /**
60       * Overridden because CircularFifoQueue isn't fail fast.
61       * @return false
62       */
63      @Override
64      public boolean isFailFastSupported() {
65          return false;
66      }
67  
68      /**
69       * Overridden because CircularFifoQueue doesn't allow null elements.
70       * @return false
71       */
72      @Override
73      public boolean isNullSupported() {
74          return false;
75      }
76  
77      /**
78       * Returns an empty ArrayList.
79       *
80       * @return an empty ArrayList
81       */
82      @Override
83      public Collection<E> makeConfirmedCollection() {
84          return new ArrayList<>();
85      }
86  
87      /**
88       * Returns a full ArrayList.
89       *
90       * @return a full ArrayList
91       */
92      @Override
93      public Collection<E> makeConfirmedFullCollection() {
94          final Collection<E> c = makeConfirmedCollection();
95          c.addAll(java.util.Arrays.asList(getFullElements()));
96          return c;
97      }
98  
99      /**
100      * Returns an empty CircularFifoQueue that won't overflow.
101      *
102      * @return an empty CircularFifoQueue
103      */
104     @Override
105     public Queue<E> makeObject() {
106         return new CircularFifoQueue<>(100);
107     }
108 
109     @Test
110     public void testAddNull() {
111         final CircularFifoQueue<E> b = new CircularFifoQueue<>(2);
112         assertThrows(NullPointerException.class, () -> b.add(null));
113     }
114 
115     /**
116      * Tests that the removal operation actually removes the first element.
117      */
118     @Test
119     @SuppressWarnings("unchecked")
120     public void testCircularFifoQueueCircular() {
121         final List<E> list = new ArrayList<>();
122         list.add((E) "A");
123         list.add((E) "B");
124         list.add((E) "C");
125         final Queue<E> queue = new CircularFifoQueue<>(list);
126 
127         assertTrue(queue.contains("A"));
128         assertTrue(queue.contains("B"));
129         assertTrue(queue.contains("C"));
130 
131         queue.add((E) "D");
132 
133         assertFalse(queue.contains("A"));
134         assertTrue(queue.contains("B"));
135         assertTrue(queue.contains("C"));
136         assertTrue(queue.contains("D"));
137 
138         assertEquals("B", queue.peek());
139         assertEquals("B", queue.remove());
140         assertEquals("C", queue.remove());
141         assertEquals("D", queue.remove());
142     }
143 
144     /**
145      * Tests that the removal operation actually removes the first element.
146      */
147     @Test
148     public void testCircularFifoQueueRemove() {
149         resetFull();
150         final int size = getConfirmed().size();
151         for (int i = 0; i < size; i++) {
152             final Object o1 = getCollection().remove();
153             final Object o2 = ((List<?>) getConfirmed()).remove(0);
154             assertEquals(o1, o2, "Removed objects should be equal");
155             verify();
156         }
157 
158         assertThrows(NoSuchElementException.class, () -> getCollection().remove(),
159                 "Empty queue should raise Underflow.");
160     }
161 
162     /**
163      * Tests that the constructor correctly throws an exception.
164      */
165     @Test
166     public void testConstructorException1() {
167         assertThrows(IllegalArgumentException.class, () -> new CircularFifoQueue<E>(0));
168     }
169 
170     /**
171      * Tests that the constructor correctly throws an exception.
172      */
173     @Test
174     public void testConstructorException2() {
175         assertThrows(IllegalArgumentException.class, () -> new CircularFifoQueue<E>(-20));
176     }
177 
178     /**
179      * Tests that the constructor correctly throws an exception.
180      */
181     @Test
182     public void testConstructorException3() {
183         assertThrows(NullPointerException.class, () -> new CircularFifoQueue<E>(null));
184     }
185 
186     @Test
187     public void testDefaultSizeAndGetError1() {
188         final CircularFifoQueue<E> fifo = new CircularFifoQueue<>();
189         assertEquals(32, fifo.maxSize());
190         fifo.add((E) "1");
191         fifo.add((E) "2");
192         fifo.add((E) "3");
193         fifo.add((E) "4");
194         fifo.add((E) "5");
195         assertEquals(5, fifo.size());
196         assertThrows(NoSuchElementException.class, () -> fifo.get(5));
197     }
198 
199     @Test
200     public void testDefaultSizeAndGetError2() {
201         final CircularFifoQueue<E> fifo = new CircularFifoQueue<>();
202         assertEquals(32, fifo.maxSize());
203         fifo.add((E) "1");
204         fifo.add((E) "2");
205         fifo.add((E) "3");
206         fifo.add((E) "4");
207         fifo.add((E) "5");
208         assertEquals(5, fifo.size());
209         assertThrows(NoSuchElementException.class, () -> fifo.get(-2));
210     }
211 
212     @Test
213     public void testGetIndex() {
214         resetFull();
215 
216         final CircularFifoQueue<E> queue = getCollection();
217         final List<E> confirmed = (List<E>) getConfirmed();
218         for (int i = 0; i < confirmed.size(); i++) {
219             assertEquals(confirmed.get(i), queue.get(i));
220         }
221 
222         // remove the first two elements and check again
223         queue.remove();
224         queue.remove();
225 
226         for (int i = 0; i < queue.size(); i++) {
227             assertEquals(confirmed.get(i + 2), queue.get(i));
228         }
229     }
230 
231     @Test
232     @SuppressWarnings("unchecked")
233     public void testRemoveError1() throws Exception {
234         // based on bug 33071
235         final CircularFifoQueue<E> fifo = new CircularFifoQueue<>(5);
236         fifo.add((E) "1");
237         fifo.add((E) "2");
238         fifo.add((E) "3");
239         fifo.add((E) "4");
240         fifo.add((E) "5");
241 
242         assertEquals("[1, 2, 3, 4, 5]", fifo.toString());
243 
244         fifo.remove("3");
245         assertEquals("[1, 2, 4, 5]", fifo.toString());
246 
247         fifo.remove("4");
248         assertEquals("[1, 2, 5]", fifo.toString());
249     }
250 
251     @Test
252     @SuppressWarnings("unchecked")
253     public void testRemoveError2() throws Exception {
254         // based on bug 33071
255         final CircularFifoQueue<E> fifo = new CircularFifoQueue<>(5);
256         fifo.add((E) "1");
257         fifo.add((E) "2");
258         fifo.add((E) "3");
259         fifo.add((E) "4");
260         fifo.add((E) "5");
261         fifo.add((E) "6");
262 
263         assertEquals(5, fifo.size());
264         assertEquals("[2, 3, 4, 5, 6]", fifo.toString());
265 
266         fifo.remove("3");
267         assertEquals("[2, 4, 5, 6]", fifo.toString());
268 
269         fifo.remove("4");
270         assertEquals("[2, 5, 6]", fifo.toString());
271     }
272 
273     @Test
274     @SuppressWarnings("unchecked")
275     public void testRemoveError3() throws Exception {
276         // based on bug 33071
277         final CircularFifoQueue<E> fifo = new CircularFifoQueue<>(5);
278         fifo.add((E) "1");
279         fifo.add((E) "2");
280         fifo.add((E) "3");
281         fifo.add((E) "4");
282         fifo.add((E) "5");
283 
284         assertEquals("[1, 2, 3, 4, 5]", fifo.toString());
285 
286         fifo.remove("3");
287         assertEquals("[1, 2, 4, 5]", fifo.toString());
288 
289         fifo.add((E) "6");
290         fifo.add((E) "7");
291         assertEquals("[2, 4, 5, 6, 7]", fifo.toString());
292 
293         fifo.remove("4");
294         assertEquals("[2, 5, 6, 7]", fifo.toString());
295     }
296 
297     @Test
298     @SuppressWarnings("unchecked")
299     public void testRemoveError4() throws Exception {
300         // based on bug 33071
301         final CircularFifoQueue<E> fifo = new CircularFifoQueue<>(5);
302         fifo.add((E) "1");
303         fifo.add((E) "2");
304         fifo.add((E) "3");
305         fifo.add((E) "4");
306         fifo.add((E) "5");  // end=0
307         fifo.add((E) "6");  // end=1
308         fifo.add((E) "7");  // end=2
309 
310         assertEquals("[3, 4, 5, 6, 7]", fifo.toString());
311 
312         fifo.remove("4");  // remove element in middle of array, after start
313         assertEquals("[3, 5, 6, 7]", fifo.toString());
314     }
315 
316     @Test
317     @SuppressWarnings("unchecked")
318     public void testRemoveError5() throws Exception {
319         // based on bug 33071
320         final CircularFifoQueue<E> fifo = new CircularFifoQueue<>(5);
321         fifo.add((E) "1");
322         fifo.add((E) "2");
323         fifo.add((E) "3");
324         fifo.add((E) "4");
325         fifo.add((E) "5");  // end=0
326         fifo.add((E) "6");  // end=1
327         fifo.add((E) "7");  // end=2
328 
329         assertEquals("[3, 4, 5, 6, 7]", fifo.toString());
330 
331         fifo.remove("5");  // remove element at last pos in array
332         assertEquals("[3, 4, 6, 7]", fifo.toString());
333     }
334 
335     @Test
336     @SuppressWarnings("unchecked")
337     public void testRemoveError6() throws Exception {
338         // based on bug 33071
339         final CircularFifoQueue<E> fifo = new CircularFifoQueue<>(5);
340         fifo.add((E) "1");
341         fifo.add((E) "2");
342         fifo.add((E) "3");
343         fifo.add((E) "4");
344         fifo.add((E) "5");  // end=0
345         fifo.add((E) "6");  // end=1
346         fifo.add((E) "7");  // end=2
347 
348         assertEquals("[3, 4, 5, 6, 7]", fifo.toString());
349 
350         fifo.remove("6");  // remove element at position zero in array
351         assertEquals("[3, 4, 5, 7]", fifo.toString());
352     }
353 
354     @Test
355     @SuppressWarnings("unchecked")
356     public void testRemoveError7() throws Exception {
357         // based on bug 33071
358         final CircularFifoQueue<E> fifo = new CircularFifoQueue<>(5);
359         fifo.add((E) "1");
360         fifo.add((E) "2");
361         fifo.add((E) "3");
362         fifo.add((E) "4");
363         fifo.add((E) "5");  // end=0
364         fifo.add((E) "6");  // end=1
365         fifo.add((E) "7");  // end=2
366 
367         assertEquals("[3, 4, 5, 6, 7]", fifo.toString());
368 
369         fifo.remove("7");  // remove element at position one in array
370         assertEquals("[3, 4, 5, 6]", fifo.toString());
371     }
372 
373     @Test
374     @SuppressWarnings("unchecked")
375     public void testRemoveError8() throws Exception {
376         // based on bug 33071
377         final CircularFifoQueue<E> fifo = new CircularFifoQueue<>(5);
378         fifo.add((E) "1");
379         fifo.add((E) "2");
380         fifo.add((E) "3");
381         fifo.add((E) "4");
382         fifo.add((E) "5");  // end=0
383         fifo.add((E) "6");  // end=1
384         fifo.add((E) "7");  // end=2
385         fifo.add((E) "8");  // end=3
386 
387         assertEquals("[4, 5, 6, 7, 8]", fifo.toString());
388 
389         fifo.remove("7");  // remove element at position one in array, need to shift 8
390         assertEquals("[4, 5, 6, 8]", fifo.toString());
391     }
392 
393     @Test
394     @SuppressWarnings("unchecked")
395     public void testRemoveError9() throws Exception {
396         // based on bug 33071
397         final CircularFifoQueue<E> fifo = new CircularFifoQueue<>(5);
398         fifo.add((E) "1");
399         fifo.add((E) "2");
400         fifo.add((E) "3");
401         fifo.add((E) "4");
402         fifo.add((E) "5");  // end=0
403         fifo.add((E) "6");  // end=1
404         fifo.add((E) "7");  // end=2
405         fifo.add((E) "8");  // end=3
406 
407         assertEquals("[4, 5, 6, 7, 8]", fifo.toString());
408 
409         fifo.remove("8");  // remove element at position two in array
410         assertEquals("[4, 5, 6, 7]", fifo.toString());
411     }
412 
413     @Test
414     @SuppressWarnings("unchecked")
415     public void testRepeatedSerialization() throws Exception {
416         // bug 31433
417         final CircularFifoQueue<E> b = new CircularFifoQueue<>(2);
418         b.add((E) "a");
419         assertEquals(1, b.size());
420         assertTrue(b.contains("a"));
421 
422         ByteArrayOutputStream bos = new ByteArrayOutputStream();
423         new ObjectOutputStream(bos).writeObject(b);
424 
425         final CircularFifoQueue<E> b2 = (CircularFifoQueue<E>) new ObjectInputStream(
426             new ByteArrayInputStream(bos.toByteArray())).readObject();
427 
428         assertEquals(1, b2.size());
429         assertTrue(b2.contains("a"));
430         b2.add((E) "b");
431         assertEquals(2, b2.size());
432         assertTrue(b2.contains("a"));
433         assertTrue(b2.contains("b"));
434 
435         bos = new ByteArrayOutputStream();
436         new ObjectOutputStream(bos).writeObject(b2);
437 
438         final CircularFifoQueue<E> b3 = (CircularFifoQueue<E>) new ObjectInputStream(
439             new ByteArrayInputStream(bos.toByteArray())).readObject();
440 
441         assertEquals(2, b3.size());
442         assertTrue(b3.contains("a"));
443         assertTrue(b3.contains("b"));
444         b3.add((E) "c");
445         assertEquals(2, b3.size());
446         assertTrue(b3.contains("b"));
447         assertTrue(b3.contains("c"));
448     }
449 
450 //    public void testCreate() throws Exception {
451 //        resetEmpty();
452 //        writeExternalFormToDisk((java.io.Serializable) getCollection(), "src/test/resources/data/test/CircularFifoQueue.emptyCollection.version4.obj");
453 //        resetFull();
454 //        writeExternalFormToDisk((java.io.Serializable) getCollection(), "src/test/resources/data/test/CircularFifoQueue.fullCollection.version4.obj");
455 //    }
456 
457     /**
458      *  Runs through the regular verifications, but also verifies that
459      *  the buffer contains the same elements in the same sequence as the
460      *  list.
461      */
462     @Override
463     public void verify() {
464         super.verify();
465         final Iterator<E> iterator1 = getCollection().iterator();
466         for (final E e : getConfirmed()) {
467             assertTrue(iterator1.hasNext());
468             final Object o1 = iterator1.next();
469             final Object o2 = e;
470             assertEquals(o1, o2);
471         }
472     }
473 
474 }