1 /*
2  * Written by Doug Lea with assistance from members of JCP JSR-166
3  * Expert Group and released to the public domain, as explained at
4  * http://creativecommons.org/publicdomain/zero/1.0/
5  * Other contributors include Andrew Wright, Jeffrey Hayes,
6  * Pat Fisher, Mike Judd.
7  */
8 
9 package jsr166;
10 
11 import junit.framework.*;
12 import java.util.Arrays;
13 import java.util.Collection;
14 import java.util.Comparator;
15 import java.util.Iterator;
16 import java.util.NoSuchElementException;
17 import java.util.PriorityQueue;
18 import java.util.Queue;
19 
20 public class PriorityQueueTest extends JSR166TestCase {
21 
22     static class MyReverseComparator implements Comparator {
compare(Object x, Object y)23         public int compare(Object x, Object y) {
24             return ((Comparable)y).compareTo(x);
25         }
26     }
27 
28     /**
29      * Returns a new queue of given size containing consecutive
30      * Integers 0 ... n.
31      */
populatedQueue(int n)32     private PriorityQueue<Integer> populatedQueue(int n) {
33         PriorityQueue<Integer> q = new PriorityQueue<Integer>(n);
34         assertTrue(q.isEmpty());
35         for (int i = n-1; i >= 0; i-=2)
36             assertTrue(q.offer(new Integer(i)));
37         for (int i = (n & 1); i < n; i+=2)
38             assertTrue(q.offer(new Integer(i)));
39         assertFalse(q.isEmpty());
40         assertEquals(n, q.size());
41         return q;
42     }
43 
44     /**
45      * A new queue has unbounded capacity
46      */
testConstructor1()47     public void testConstructor1() {
48         assertEquals(0, new PriorityQueue(SIZE).size());
49     }
50 
51     /**
52      * Constructor throws IAE if capacity argument nonpositive
53      */
testConstructor2()54     public void testConstructor2() {
55         try {
56             PriorityQueue q = new PriorityQueue(0);
57             shouldThrow();
58         } catch (IllegalArgumentException success) {}
59     }
60 
61     /**
62      * Initializing from null Collection throws NPE
63      */
testConstructor3()64     public void testConstructor3() {
65         try {
66             PriorityQueue q = new PriorityQueue((Collection)null);
67             shouldThrow();
68         } catch (NullPointerException success) {}
69     }
70 
71     /**
72      * Initializing from Collection of null elements throws NPE
73      */
testConstructor4()74     public void testConstructor4() {
75         try {
76             Integer[] ints = new Integer[SIZE];
77             PriorityQueue q = new PriorityQueue(Arrays.asList(ints));
78             shouldThrow();
79         } catch (NullPointerException success) {}
80     }
81 
82     /**
83      * Initializing from Collection with some null elements throws NPE
84      */
testConstructor5()85     public void testConstructor5() {
86         try {
87             Integer[] ints = new Integer[SIZE];
88             for (int i = 0; i < SIZE-1; ++i)
89                 ints[i] = new Integer(i);
90             PriorityQueue q = new PriorityQueue(Arrays.asList(ints));
91             shouldThrow();
92         } catch (NullPointerException success) {}
93     }
94 
95     /**
96      * Queue contains all elements of collection used to initialize
97      */
testConstructor6()98     public void testConstructor6() {
99         Integer[] ints = new Integer[SIZE];
100         for (int i = 0; i < SIZE; ++i)
101             ints[i] = new Integer(i);
102         PriorityQueue q = new PriorityQueue(Arrays.asList(ints));
103         for (int i = 0; i < SIZE; ++i)
104             assertEquals(ints[i], q.poll());
105     }
106 
107     /**
108      * The comparator used in constructor is used
109      */
testConstructor7()110     public void testConstructor7() {
111         MyReverseComparator cmp = new MyReverseComparator();
112         PriorityQueue q = new PriorityQueue(SIZE, cmp);
113         assertEquals(cmp, q.comparator());
114         Integer[] ints = new Integer[SIZE];
115         for (int i = 0; i < SIZE; ++i)
116             ints[i] = new Integer(i);
117         q.addAll(Arrays.asList(ints));
118         for (int i = SIZE-1; i >= 0; --i)
119             assertEquals(ints[i], q.poll());
120     }
121 
122     /**
123      * isEmpty is true before add, false after
124      */
testEmpty()125     public void testEmpty() {
126         PriorityQueue q = new PriorityQueue(2);
127         assertTrue(q.isEmpty());
128         q.add(new Integer(1));
129         assertFalse(q.isEmpty());
130         q.add(new Integer(2));
131         q.remove();
132         q.remove();
133         assertTrue(q.isEmpty());
134     }
135 
136     /**
137      * size changes when elements added and removed
138      */
testSize()139     public void testSize() {
140         PriorityQueue q = populatedQueue(SIZE);
141         for (int i = 0; i < SIZE; ++i) {
142             assertEquals(SIZE-i, q.size());
143             q.remove();
144         }
145         for (int i = 0; i < SIZE; ++i) {
146             assertEquals(i, q.size());
147             q.add(new Integer(i));
148         }
149     }
150 
151     /**
152      * offer(null) throws NPE
153      */
testOfferNull()154     public void testOfferNull() {
155         try {
156             PriorityQueue q = new PriorityQueue(1);
157             q.offer(null);
158             shouldThrow();
159         } catch (NullPointerException success) {}
160     }
161 
162     /**
163      * add(null) throws NPE
164      */
testAddNull()165     public void testAddNull() {
166         try {
167             PriorityQueue q = new PriorityQueue(1);
168             q.add(null);
169             shouldThrow();
170         } catch (NullPointerException success) {}
171     }
172 
173     /**
174      * Offer of comparable element succeeds
175      */
testOffer()176     public void testOffer() {
177         PriorityQueue q = new PriorityQueue(1);
178         assertTrue(q.offer(zero));
179         assertTrue(q.offer(one));
180     }
181 
182     /**
183      * Offer of non-Comparable throws CCE
184      */
testOfferNonComparable()185     public void testOfferNonComparable() {
186         try {
187             PriorityQueue q = new PriorityQueue(1);
188             q.offer(new Object());
189             q.offer(new Object());
190             q.offer(new Object());
191             shouldThrow();
192         } catch (ClassCastException success) {}
193     }
194 
195     /**
196      * add of comparable succeeds
197      */
testAdd()198     public void testAdd() {
199         PriorityQueue q = new PriorityQueue(SIZE);
200         for (int i = 0; i < SIZE; ++i) {
201             assertEquals(i, q.size());
202             assertTrue(q.add(new Integer(i)));
203         }
204     }
205 
206     /**
207      * addAll(null) throws NPE
208      */
testAddAll1()209     public void testAddAll1() {
210         try {
211             PriorityQueue q = new PriorityQueue(1);
212             q.addAll(null);
213             shouldThrow();
214         } catch (NullPointerException success) {}
215     }
216 
217     /**
218      * addAll of a collection with null elements throws NPE
219      */
testAddAll2()220     public void testAddAll2() {
221         try {
222             PriorityQueue q = new PriorityQueue(SIZE);
223             Integer[] ints = new Integer[SIZE];
224             q.addAll(Arrays.asList(ints));
225             shouldThrow();
226         } catch (NullPointerException success) {}
227     }
228 
229     /**
230      * addAll of a collection with any null elements throws NPE after
231      * possibly adding some elements
232      */
testAddAll3()233     public void testAddAll3() {
234         try {
235             PriorityQueue q = new PriorityQueue(SIZE);
236             Integer[] ints = new Integer[SIZE];
237             for (int i = 0; i < SIZE-1; ++i)
238                 ints[i] = new Integer(i);
239             q.addAll(Arrays.asList(ints));
240             shouldThrow();
241         } catch (NullPointerException success) {}
242     }
243 
244     /**
245      * Queue contains all elements of successful addAll
246      */
testAddAll5()247     public void testAddAll5() {
248         Integer[] empty = new Integer[0];
249         Integer[] ints = new Integer[SIZE];
250         for (int i = 0; i < SIZE; ++i)
251             ints[i] = new Integer(SIZE-1-i);
252         PriorityQueue q = new PriorityQueue(SIZE);
253         assertFalse(q.addAll(Arrays.asList(empty)));
254         assertTrue(q.addAll(Arrays.asList(ints)));
255         for (int i = 0; i < SIZE; ++i)
256             assertEquals(new Integer(i), q.poll());
257     }
258 
259     /**
260      * poll succeeds unless empty
261      */
testPoll()262     public void testPoll() {
263         PriorityQueue q = populatedQueue(SIZE);
264         for (int i = 0; i < SIZE; ++i) {
265             assertEquals(i, q.poll());
266         }
267         assertNull(q.poll());
268     }
269 
270     /**
271      * peek returns next element, or null if empty
272      */
testPeek()273     public void testPeek() {
274         PriorityQueue q = populatedQueue(SIZE);
275         for (int i = 0; i < SIZE; ++i) {
276             assertEquals(i, q.peek());
277             assertEquals(i, q.poll());
278             assertTrue(q.peek() == null ||
279                        !q.peek().equals(i));
280         }
281         assertNull(q.peek());
282     }
283 
284     /**
285      * element returns next element, or throws NSEE if empty
286      */
testElement()287     public void testElement() {
288         PriorityQueue q = populatedQueue(SIZE);
289         for (int i = 0; i < SIZE; ++i) {
290             assertEquals(i, q.element());
291             assertEquals(i, q.poll());
292         }
293         try {
294             q.element();
295             shouldThrow();
296         } catch (NoSuchElementException success) {}
297     }
298 
299     /**
300      * remove removes next element, or throws NSEE if empty
301      */
testRemove()302     public void testRemove() {
303         PriorityQueue q = populatedQueue(SIZE);
304         for (int i = 0; i < SIZE; ++i) {
305             assertEquals(i, q.remove());
306         }
307         try {
308             q.remove();
309             shouldThrow();
310         } catch (NoSuchElementException success) {}
311     }
312 
313     /**
314      * remove(x) removes x and returns true if present
315      */
testRemoveElement()316     public void testRemoveElement() {
317         PriorityQueue q = populatedQueue(SIZE);
318         for (int i = 1; i < SIZE; i+=2) {
319             assertTrue(q.contains(i));
320             assertTrue(q.remove(i));
321             assertFalse(q.contains(i));
322             assertTrue(q.contains(i-1));
323         }
324         for (int i = 0; i < SIZE; i+=2) {
325             assertTrue(q.contains(i));
326             assertTrue(q.remove(i));
327             assertFalse(q.contains(i));
328             assertFalse(q.remove(i+1));
329             assertFalse(q.contains(i+1));
330         }
331         assertTrue(q.isEmpty());
332     }
333 
334     /**
335      * contains(x) reports true when elements added but not yet removed
336      */
testContains()337     public void testContains() {
338         PriorityQueue q = populatedQueue(SIZE);
339         for (int i = 0; i < SIZE; ++i) {
340             assertTrue(q.contains(new Integer(i)));
341             q.poll();
342             assertFalse(q.contains(new Integer(i)));
343         }
344     }
345 
346     /**
347      * clear removes all elements
348      */
testClear()349     public void testClear() {
350         PriorityQueue q = populatedQueue(SIZE);
351         q.clear();
352         assertTrue(q.isEmpty());
353         assertEquals(0, q.size());
354         q.add(new Integer(1));
355         assertFalse(q.isEmpty());
356         q.clear();
357         assertTrue(q.isEmpty());
358     }
359 
360     /**
361      * containsAll(c) is true when c contains a subset of elements
362      */
testContainsAll()363     public void testContainsAll() {
364         PriorityQueue q = populatedQueue(SIZE);
365         PriorityQueue p = new PriorityQueue(SIZE);
366         for (int i = 0; i < SIZE; ++i) {
367             assertTrue(q.containsAll(p));
368             assertFalse(p.containsAll(q));
369             p.add(new Integer(i));
370         }
371         assertTrue(p.containsAll(q));
372     }
373 
374     /**
375      * retainAll(c) retains only those elements of c and reports true if changed
376      */
testRetainAll()377     public void testRetainAll() {
378         PriorityQueue q = populatedQueue(SIZE);
379         PriorityQueue p = populatedQueue(SIZE);
380         for (int i = 0; i < SIZE; ++i) {
381             boolean changed = q.retainAll(p);
382             if (i == 0)
383                 assertFalse(changed);
384             else
385                 assertTrue(changed);
386 
387             assertTrue(q.containsAll(p));
388             assertEquals(SIZE-i, q.size());
389             p.remove();
390         }
391     }
392 
393     /**
394      * removeAll(c) removes only those elements of c and reports true if changed
395      */
testRemoveAll()396     public void testRemoveAll() {
397         for (int i = 1; i < SIZE; ++i) {
398             PriorityQueue q = populatedQueue(SIZE);
399             PriorityQueue p = populatedQueue(i);
400             assertTrue(q.removeAll(p));
401             assertEquals(SIZE-i, q.size());
402             for (int j = 0; j < i; ++j) {
403                 Integer I = (Integer)(p.remove());
404                 assertFalse(q.contains(I));
405             }
406         }
407     }
408 
409     /**
410      * toArray contains all elements
411      */
testToArray()412     public void testToArray() {
413         PriorityQueue q = populatedQueue(SIZE);
414         Object[] o = q.toArray();
415         Arrays.sort(o);
416         for (int i = 0; i < o.length; i++)
417             assertSame(o[i], q.poll());
418     }
419 
420     /**
421      * toArray(a) contains all elements
422      */
testToArray2()423     public void testToArray2() {
424         PriorityQueue<Integer> q = populatedQueue(SIZE);
425         Integer[] ints = new Integer[SIZE];
426         Integer[] array = q.toArray(ints);
427         assertSame(ints, array);
428         Arrays.sort(ints);
429         for (int i = 0; i < ints.length; i++)
430             assertSame(ints[i], q.poll());
431     }
432 
433     /**
434      * iterator iterates through all elements
435      */
testIterator()436     public void testIterator() {
437         PriorityQueue q = populatedQueue(SIZE);
438         int i = 0;
439         Iterator it = q.iterator();
440         while (it.hasNext()) {
441             assertTrue(q.contains(it.next()));
442             ++i;
443         }
444         assertEquals(i, SIZE);
445     }
446 
447     /**
448      * iterator.remove removes current element
449      */
testIteratorRemove()450     public void testIteratorRemove() {
451         final PriorityQueue q = new PriorityQueue(3);
452         q.add(new Integer(2));
453         q.add(new Integer(1));
454         q.add(new Integer(3));
455 
456         Iterator it = q.iterator();
457         it.next();
458         it.remove();
459 
460         it = q.iterator();
461         assertEquals(it.next(), new Integer(2));
462         assertEquals(it.next(), new Integer(3));
463         assertFalse(it.hasNext());
464     }
465 
466     /**
467      * toString contains toStrings of elements
468      */
testToString()469     public void testToString() {
470         PriorityQueue q = populatedQueue(SIZE);
471         String s = q.toString();
472         for (int i = 0; i < SIZE; ++i) {
473             assertTrue(s.contains(String.valueOf(i)));
474         }
475     }
476 
477     /**
478      * A deserialized serialized queue has same elements
479      */
testSerialization()480     public void testSerialization() throws Exception {
481         Queue x = populatedQueue(SIZE);
482         Queue y = serialClone(x);
483 
484         assertNotSame(x, y);
485         assertEquals(x.size(), y.size());
486         while (!x.isEmpty()) {
487             assertFalse(y.isEmpty());
488             assertEquals(x.remove(), y.remove());
489         }
490         assertTrue(y.isEmpty());
491     }
492 }
493