ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/TreeSetTest.java
(Generate patch)

Comparing jsr166/src/test/tck/TreeSetTest.java (file contents):
Revision 1.1 by dl, Tue Dec 28 16:15:59 2004 UTC vs.
Revision 1.49 by dl, Tue Jan 26 13:33:06 2021 UTC

# Line 1 | Line 1
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/licenses/publicdomain
4 > * http://creativecommons.org/publicdomain/zero/1.0/
5   */
6  
7 < import junit.framework.*;
8 < import java.util.*;
9 < import java.util.concurrent.*;
10 < import java.io.*;
7 > import java.util.Arrays;
8 > import java.util.BitSet;
9 > import java.util.Collection;
10 > import java.util.Comparator;
11 > import java.util.Iterator;
12 > import java.util.NavigableSet;
13 > import java.util.NoSuchElementException;
14 > import java.util.Random;
15 > import java.util.Set;
16 > import java.util.SortedSet;
17 > import java.util.TreeSet;
18 >
19 > import junit.framework.Test;
20 > import junit.framework.TestSuite;
21  
22   public class TreeSetTest extends JSR166TestCase {
23      public static void main(String[] args) {
24 <        junit.textui.TestRunner.run (suite());  
24 >        main(suite(), args);
25      }
26      public static Test suite() {
27 <        return new TestSuite(TreeSetTest.class);
27 >        return new TestSuite(TreeSetTest.class);
28      }
29  
30 <    static class MyReverseComparator implements Comparator {
30 >    static class MyReverseComparator implements Comparator {
31 >        @SuppressWarnings("unchecked")
32          public int compare(Object x, Object y) {
33 <            int i = ((Integer)x).intValue();
23 <            int j = ((Integer)y).intValue();
24 <            if (i < j) return 1;
25 <            if (i > j) return -1;
26 <            return 0;
33 >            return ((Comparable)y).compareTo(x);
34          }
35      }
36  
37      /**
38 <     * The number of elements to place in collections, arrays, etc.
39 <     */
33 <    static final int SIZE = 20;
34 <
35 <    /**
36 <     * Create a set of given size containing consecutive
37 <     * Integers 0 ... n.
38 >     * Returns a new set of given size containing consecutive
39 >     * Items 0 ... n - 1.
40       */
41 <    private TreeSet populatedSet(int n) {
42 <        TreeSet q = new TreeSet();
41 >    private static TreeSet<Item> populatedSet(int n) {
42 >        TreeSet<Item> q = new TreeSet<>();
43          assertTrue(q.isEmpty());
44 <        for(int i = n-1; i >= 0; i-=2)
45 <            assertTrue(q.add(new Integer(i)));
46 <        for(int i = (n & 1); i < n; i+=2)
47 <            assertTrue(q.add(new Integer(i)));
44 >        for (int i = n - 1; i >= 0; i -= 2)
45 >            mustAdd(q, i);
46 >        for (int i = (n & 1); i < n; i += 2)
47 >            mustAdd(q, i);
48          assertFalse(q.isEmpty());
49 <        assertEquals(n, q.size());
49 >        mustEqual(n, q.size());
50          return q;
51      }
52  
53      /**
54 <     * Create set of first 5 ints
54 >     * Returns a new set of first 5 ints.
55       */
56 <    private TreeSet set5() {
57 <        TreeSet q = new TreeSet();
56 >    private static TreeSet<Item> set5() {
57 >        TreeSet<Item> q = new TreeSet<Item>();
58          assertTrue(q.isEmpty());
59          q.add(one);
60          q.add(two);
61          q.add(three);
62          q.add(four);
63          q.add(five);
64 <        assertEquals(5, q.size());
64 >        mustEqual(5, q.size());
65          return q;
66      }
67 <
67 >
68      /**
69       * A new set has unbounded capacity
70       */
71      public void testConstructor1() {
72 <        assertEquals(0, new TreeSet().size());
72 >        mustEqual(0, new TreeSet<Item>().size());
73      }
74  
75      /**
# Line 75 | Line 77 | public class TreeSetTest extends JSR166T
77       */
78      public void testConstructor3() {
79          try {
80 <            TreeSet q = new TreeSet((Collection)null);
80 >            new TreeSet<Item>((Collection<Item>)null);
81              shouldThrow();
82 <        }
81 <        catch (NullPointerException success) {}
82 >        } catch (NullPointerException success) {}
83      }
84  
85      /**
# Line 86 | Line 87 | public class TreeSetTest extends JSR166T
87       */
88      public void testConstructor4() {
89          try {
90 <            Integer[] ints = new Integer[SIZE];
90 <            TreeSet q = new TreeSet(Arrays.asList(ints));
90 >            new TreeSet<Item>(Arrays.asList(new Item[SIZE]));
91              shouldThrow();
92 <        }
93 <        catch (NullPointerException success) {}
92 >        } catch (NullPointerException success) {}
93      }
94  
95      /**
96       * Initializing from Collection with some null elements throws NPE
97       */
98      public void testConstructor5() {
99 +        Item[] items = new Item[2];
100 +        items[1] = zero;
101          try {
102 <            Integer[] ints = new Integer[SIZE];
102 <            for (int i = 0; i < SIZE-1; ++i)
103 <                ints[i] = new Integer(i);
104 <            TreeSet q = new TreeSet(Arrays.asList(ints));
102 >            new TreeSet<Item>(Arrays.asList(items));
103              shouldThrow();
104 <        }
107 <        catch (NullPointerException success) {}
104 >        } catch (NullPointerException success) {}
105      }
106  
107      /**
108       * Set contains all elements of collection used to initialize
109       */
110      public void testConstructor6() {
111 <        try {
112 <            Integer[] ints = new Integer[SIZE];
113 <            for (int i = 0; i < SIZE; ++i)
114 <                ints[i] = new Integer(i);
118 <            TreeSet q = new TreeSet(Arrays.asList(ints));
119 <            for (int i = 0; i < SIZE; ++i)
120 <                assertEquals(ints[i], q.pollFirst());
121 <        }
122 <        finally {}
111 >        Item[] items = defaultItems;
112 >        TreeSet<Item> q = new TreeSet<Item>(Arrays.asList(items));
113 >        for (int i = 0; i < SIZE; ++i)
114 >            mustEqual(items[i], q.pollFirst());
115      }
116  
117      /**
118       * The comparator used in constructor is used
119       */
120      public void testConstructor7() {
121 <        try {
122 <            MyReverseComparator cmp = new MyReverseComparator();
123 <            TreeSet q = new TreeSet(cmp);
124 <            assertEquals(cmp, q.comparator());
125 <            Integer[] ints = new Integer[SIZE];
126 <            for (int i = 0; i < SIZE; ++i)
127 <                ints[i] = new Integer(i);
128 <            q.addAll(Arrays.asList(ints));
137 <            for (int i = SIZE-1; i >= 0; --i)
138 <                assertEquals(ints[i], q.pollFirst());
139 <        }
140 <        finally {}
121 >        MyReverseComparator cmp = new MyReverseComparator();
122 >        @SuppressWarnings("unchecked")
123 >        TreeSet<Item> q = new TreeSet<Item>(cmp);
124 >        mustEqual(cmp, q.comparator());
125 >        Item[] items = defaultItems;
126 >        q.addAll(Arrays.asList(items));
127 >        for (int i = SIZE - 1; i >= 0; --i)
128 >            mustEqual(items[i], q.pollFirst());
129      }
130  
131      /**
132       * isEmpty is true before add, false after
133       */
134      public void testEmpty() {
135 <        TreeSet q = new TreeSet();
135 >        TreeSet<Item> q = new TreeSet<Item>();
136          assertTrue(q.isEmpty());
137 <        q.add(new Integer(1));
137 >        q.add(one);
138          assertFalse(q.isEmpty());
139 <        q.add(new Integer(2));
139 >        q.add(two);
140          q.pollFirst();
141          q.pollFirst();
142          assertTrue(q.isEmpty());
# Line 158 | Line 146 | public class TreeSetTest extends JSR166T
146       * size changes when elements added and removed
147       */
148      public void testSize() {
149 <        TreeSet q = populatedSet(SIZE);
149 >        TreeSet<Item> q = populatedSet(SIZE);
150          for (int i = 0; i < SIZE; ++i) {
151 <            assertEquals(SIZE-i, q.size());
151 >            mustEqual(SIZE - i, q.size());
152              q.pollFirst();
153          }
154          for (int i = 0; i < SIZE; ++i) {
155 <            assertEquals(i, q.size());
156 <            q.add(new Integer(i));
155 >            mustEqual(i, q.size());
156 >            mustAdd(q, i);
157          }
158      }
159  
# Line 173 | Line 161 | public class TreeSetTest extends JSR166T
161       * add(null) throws NPE if nonempty
162       */
163      public void testAddNull() {
164 <        try {
165 <            TreeSet q = populatedSet(SIZE);
164 >        TreeSet<Item> q = populatedSet(SIZE);
165 >        try {
166              q.add(null);
167              shouldThrow();
168 <        } catch (NullPointerException success) { }  
168 >        } catch (NullPointerException success) {}
169      }
170  
171      /**
172       * Add of comparable element succeeds
173       */
174      public void testAdd() {
175 <        TreeSet q = new TreeSet();
175 >        TreeSet<Item> q = new TreeSet<Item>();
176          assertTrue(q.add(zero));
177          assertTrue(q.add(one));
178      }
# Line 193 | Line 181 | public class TreeSetTest extends JSR166T
181       * Add of duplicate element fails
182       */
183      public void testAddDup() {
184 <        TreeSet q = new TreeSet();
184 >        TreeSet<Item> q = new TreeSet<Item>();
185          assertTrue(q.add(zero));
186          assertFalse(q.add(zero));
187      }
# Line 202 | Line 190 | public class TreeSetTest extends JSR166T
190       * Add of non-Comparable throws CCE
191       */
192      public void testAddNonComparable() {
193 +        TreeSet<Object> q = new TreeSet<Object>();
194          try {
206            TreeSet q = new TreeSet();
207            q.add(new Object());
195              q.add(new Object());
196              q.add(new Object());
197              shouldThrow();
198 <        }
212 <        catch(ClassCastException success) {}
198 >        } catch (ClassCastException success) {}
199      }
200  
201      /**
202       * addAll(null) throws NPE
203       */
204      public void testAddAll1() {
205 +        TreeSet<Item> q = new TreeSet<Item>();
206          try {
220            TreeSet q = new TreeSet();
207              q.addAll(null);
208              shouldThrow();
209 <        }
224 <        catch (NullPointerException success) {}
209 >        } catch (NullPointerException success) {}
210      }
211 +
212      /**
213       * addAll of a collection with null elements throws NPE
214       */
215      public void testAddAll2() {
216 +        TreeSet<Item> q = new TreeSet<Item>();
217 +        Item[] items = new Item[2];
218          try {
219 <            TreeSet q = new TreeSet();
232 <            Integer[] ints = new Integer[SIZE];
233 <            q.addAll(Arrays.asList(ints));
219 >            q.addAll(Arrays.asList(items));
220              shouldThrow();
221 <        }
236 <        catch (NullPointerException success) {}
221 >        } catch (NullPointerException success) {}
222      }
223 +
224      /**
225       * addAll of a collection with any null elements throws NPE after
226       * possibly adding some elements
227       */
228      public void testAddAll3() {
229 +        TreeSet<Item> q = new TreeSet<Item>();
230 +        Item[] items = new Item[2];
231 +        items[0] = zero;
232          try {
233 <            TreeSet q = new TreeSet();
245 <            Integer[] ints = new Integer[SIZE];
246 <            for (int i = 0; i < SIZE-1; ++i)
247 <                ints[i] = new Integer(i);
248 <            q.addAll(Arrays.asList(ints));
233 >            q.addAll(Arrays.asList(items));
234              shouldThrow();
235 <        }
251 <        catch (NullPointerException success) {}
235 >        } catch (NullPointerException success) {}
236      }
237  
238      /**
239       * Set contains all elements of successful addAll
240       */
241      public void testAddAll5() {
242 <        try {
243 <            Integer[] empty = new Integer[0];
244 <            Integer[] ints = new Integer[SIZE];
245 <            for (int i = 0; i < SIZE; ++i)
246 <                ints[i] = new Integer(SIZE-1-i);
247 <            TreeSet q = new TreeSet();
248 <            assertFalse(q.addAll(Arrays.asList(empty)));
265 <            assertTrue(q.addAll(Arrays.asList(ints)));
266 <            for (int i = 0; i < SIZE; ++i)
267 <                assertEquals(new Integer(i), q.pollFirst());
268 <        }
269 <        finally {}
242 >        Item[] empty = new Item[0];
243 >        Item[] items = defaultItems;
244 >        TreeSet<Item> q = new TreeSet<Item>();
245 >        assertFalse(q.addAll(Arrays.asList(empty)));
246 >        assertTrue(q.addAll(Arrays.asList(items)));
247 >        for (int i = 0; i < SIZE; ++i)
248 >            mustEqual(i, q.pollFirst());
249      }
250  
251      /**
252       * pollFirst succeeds unless empty
253       */
254      public void testPollFirst() {
255 <        TreeSet q = populatedSet(SIZE);
255 >        TreeSet<Item> q = populatedSet(SIZE);
256          for (int i = 0; i < SIZE; ++i) {
257 <            assertEquals(i, ((Integer)q.pollFirst()).intValue());
257 >            mustEqual(i, q.pollFirst());
258          }
259 <        assertNull(q.pollFirst());
259 >        assertNull(q.pollFirst());
260      }
261  
262      /**
263       * pollLast succeeds unless empty
264       */
265      public void testPollLast() {
266 <        TreeSet q = populatedSet(SIZE);
267 <        for (int i = SIZE-1; i >= 0; --i) {
268 <            assertEquals(i, ((Integer)q.pollLast()).intValue());
266 >        TreeSet<Item> q = populatedSet(SIZE);
267 >        for (int i = SIZE - 1; i >= 0; --i) {
268 >            mustEqual(i, q.pollLast());
269          }
270 <        assertNull(q.pollFirst());
270 >        assertNull(q.pollFirst());
271      }
272  
294
273      /**
274       * remove(x) removes x and returns true if present
275       */
276      public void testRemoveElement() {
277 <        TreeSet q = populatedSet(SIZE);
278 <        for (int i = 1; i < SIZE; i+=2) {
279 <            assertTrue(q.remove(new Integer(i)));
280 <        }
281 <        for (int i = 0; i < SIZE; i+=2) {
282 <            assertTrue(q.remove(new Integer(i)));
283 <            assertFalse(q.remove(new Integer(i+1)));
277 >        TreeSet<Item> q = populatedSet(SIZE);
278 >        for (int i = 1; i < SIZE; i += 2) {
279 >            mustContain(q, i);
280 >            mustRemove(q, i);
281 >            mustNotContain(q, i);
282 >            mustContain(q, i - 1);
283 >        }
284 >        for (int i = 0; i < SIZE; i += 2) {
285 >            mustContain(q, i);
286 >            mustRemove(q, i);
287 >            mustNotContain(q, i);
288 >            mustNotRemove(q, i + 1);
289 >            mustNotContain(q, i + 1);
290          }
291          assertTrue(q.isEmpty());
292      }
293 <        
293 >
294      /**
295       * contains(x) reports true when elements added but not yet removed
296       */
297      public void testContains() {
298 <        TreeSet q = populatedSet(SIZE);
298 >        TreeSet<Item> q = populatedSet(SIZE);
299          for (int i = 0; i < SIZE; ++i) {
300 <            assertTrue(q.contains(new Integer(i)));
300 >            mustContain(q, i);
301              q.pollFirst();
302 <            assertFalse(q.contains(new Integer(i)));
302 >            mustNotContain(q, i);
303          }
304      }
305  
# Line 323 | Line 307 | public class TreeSetTest extends JSR166T
307       * clear removes all elements
308       */
309      public void testClear() {
310 <        TreeSet q = populatedSet(SIZE);
310 >        TreeSet<Item> q = populatedSet(SIZE);
311          q.clear();
312          assertTrue(q.isEmpty());
313 <        assertEquals(0, q.size());
314 <        q.add(new Integer(1));
313 >        mustEqual(0, q.size());
314 >        q.add(one);
315          assertFalse(q.isEmpty());
316          q.clear();
317          assertTrue(q.isEmpty());
# Line 337 | Line 321 | public class TreeSetTest extends JSR166T
321       * containsAll(c) is true when c contains a subset of elements
322       */
323      public void testContainsAll() {
324 <        TreeSet q = populatedSet(SIZE);
325 <        TreeSet p = new TreeSet();
324 >        TreeSet<Item> q = populatedSet(SIZE);
325 >        TreeSet<Item> p = new TreeSet<Item>();
326          for (int i = 0; i < SIZE; ++i) {
327              assertTrue(q.containsAll(p));
328              assertFalse(p.containsAll(q));
329 <            p.add(new Integer(i));
329 >            mustAdd(p, i);
330          }
331          assertTrue(p.containsAll(q));
332      }
# Line 351 | Line 335 | public class TreeSetTest extends JSR166T
335       * retainAll(c) retains only those elements of c and reports true if changed
336       */
337      public void testRetainAll() {
338 <        TreeSet q = populatedSet(SIZE);
339 <        TreeSet p = populatedSet(SIZE);
338 >        TreeSet<Item> q = populatedSet(SIZE);
339 >        TreeSet<Item> p = populatedSet(SIZE);
340          for (int i = 0; i < SIZE; ++i) {
341              boolean changed = q.retainAll(p);
342              if (i == 0)
# Line 361 | Line 345 | public class TreeSetTest extends JSR166T
345                  assertTrue(changed);
346  
347              assertTrue(q.containsAll(p));
348 <            assertEquals(SIZE-i, q.size());
348 >            mustEqual(SIZE - i, q.size());
349              p.pollFirst();
350          }
351      }
# Line 371 | Line 355 | public class TreeSetTest extends JSR166T
355       */
356      public void testRemoveAll() {
357          for (int i = 1; i < SIZE; ++i) {
358 <            TreeSet q = populatedSet(SIZE);
359 <            TreeSet p = populatedSet(i);
358 >            TreeSet<Item> q = populatedSet(SIZE);
359 >            TreeSet<Item> p = populatedSet(i);
360              assertTrue(q.removeAll(p));
361 <            assertEquals(SIZE-i, q.size());
361 >            mustEqual(SIZE - i, q.size());
362              for (int j = 0; j < i; ++j) {
363 <                Integer I = (Integer)(p.pollFirst());
380 <                assertFalse(q.contains(I));
363 >                mustNotContain(q, p.pollFirst());
364              }
365          }
366      }
367  
385    
386
368      /**
369       * lower returns preceding element
370       */
371      public void testLower() {
372 <        TreeSet q = set5();
372 >        TreeSet<Item> q = set5();
373          Object e1 = q.lower(three);
374 <        assertEquals(two, e1);
374 >        mustEqual(two, e1);
375  
376          Object e2 = q.lower(six);
377 <        assertEquals(five, e2);
377 >        mustEqual(five, e2);
378  
379          Object e3 = q.lower(one);
380          assertNull(e3);
381  
382          Object e4 = q.lower(zero);
383          assertNull(e4);
403
384      }
385  
386      /**
387       * higher returns next element
388       */
389      public void testHigher() {
390 <        TreeSet q = set5();
390 >        TreeSet<Item> q = set5();
391          Object e1 = q.higher(three);
392 <        assertEquals(four, e1);
392 >        mustEqual(four, e1);
393  
394          Object e2 = q.higher(zero);
395 <        assertEquals(one, e2);
395 >        mustEqual(one, e2);
396  
397          Object e3 = q.higher(five);
398          assertNull(e3);
399  
400          Object e4 = q.higher(six);
401          assertNull(e4);
422
402      }
403  
404      /**
405       * floor returns preceding element
406       */
407      public void testFloor() {
408 <        TreeSet q = set5();
408 >        TreeSet<Item> q = set5();
409          Object e1 = q.floor(three);
410 <        assertEquals(three, e1);
410 >        mustEqual(three, e1);
411  
412          Object e2 = q.floor(six);
413 <        assertEquals(five, e2);
413 >        mustEqual(five, e2);
414  
415          Object e3 = q.floor(one);
416 <        assertEquals(one, e3);
416 >        mustEqual(one, e3);
417  
418          Object e4 = q.floor(zero);
419          assertNull(e4);
441
420      }
421  
422      /**
423       * ceiling returns next element
424       */
425      public void testCeiling() {
426 <        TreeSet q = set5();
426 >        TreeSet<Item> q = set5();
427          Object e1 = q.ceiling(three);
428 <        assertEquals(three, e1);
428 >        mustEqual(three, e1);
429  
430          Object e2 = q.ceiling(zero);
431 <        assertEquals(one, e2);
431 >        mustEqual(one, e2);
432  
433          Object e3 = q.ceiling(five);
434 <        assertEquals(five, e3);
434 >        mustEqual(five, e3);
435  
436          Object e4 = q.ceiling(six);
437          assertNull(e4);
460
438      }
439  
440      /**
441 <     * toArray contains all elements
441 >     * toArray contains all elements in sorted order
442       */
443      public void testToArray() {
444 <        TreeSet q = populatedSet(SIZE);
445 <        Object[] o = q.toArray();
446 <        Arrays.sort(o);
447 <        for(int i = 0; i < o.length; i++)
448 <            assertEquals(o[i], q.pollFirst());
444 >        TreeSet<Item> q = populatedSet(SIZE);
445 >        Object[] a = q.toArray();
446 >        assertSame(Object[].class, a.getClass());
447 >        for (Object o : a)
448 >            assertSame(o, q.pollFirst());
449 >        assertTrue(q.isEmpty());
450      }
451  
452      /**
453 <     * toArray(a) contains all elements
453 >     * toArray(a) contains all elements in sorted order
454       */
455      public void testToArray2() {
456 <        TreeSet q = populatedSet(SIZE);
457 <        Integer[] ints = new Integer[SIZE];
458 <        ints = (Integer[])q.toArray(ints);
459 <        Arrays.sort(ints);
460 <        for(int i = 0; i < ints.length; i++)
461 <            assertEquals(ints[i], q.pollFirst());
456 >        TreeSet<Item> q = populatedSet(SIZE);
457 >        Item[] items = new Item[SIZE];
458 >        Item[] array = q.toArray(items);
459 >        assertSame(items, array);
460 >        for (Item o : items)
461 >            assertSame(o, q.pollFirst());
462 >        assertTrue(q.isEmpty());
463      }
464 <    
464 >
465      /**
466       * iterator iterates through all elements
467       */
468      public void testIterator() {
469 <        TreeSet q = populatedSet(SIZE);
470 <        int i = 0;
471 <        Iterator it = q.iterator();
472 <        while(it.hasNext()) {
469 >        TreeSet<Item> q = populatedSet(SIZE);
470 >        Iterator<? extends Item> it = q.iterator();
471 >        int i;
472 >        for (i = 0; it.hasNext(); i++)
473              assertTrue(q.contains(it.next()));
474 <            ++i;
475 <        }
497 <        assertEquals(i, SIZE);
474 >        mustEqual(i, SIZE);
475 >        assertIteratorExhausted(it);
476      }
477  
478      /**
479       * iterator of empty set has no elements
480       */
481      public void testEmptyIterator() {
482 <        TreeSet q = new TreeSet();
505 <        int i = 0;
506 <        Iterator it = q.iterator();
507 <        while(it.hasNext()) {
508 <            assertTrue(q.contains(it.next()));
509 <            ++i;
510 <        }
511 <        assertEquals(i, 0);
482 >        assertIteratorExhausted(new TreeSet<Item>().iterator());
483      }
484  
485      /**
486       * iterator.remove removes current element
487       */
488 <    public void testIteratorRemove () {
489 <        final TreeSet q = new TreeSet();
490 <        q.add(new Integer(2));
491 <        q.add(new Integer(1));
492 <        q.add(new Integer(3));
488 >    public void testIteratorRemove() {
489 >        final TreeSet<Item> q = new TreeSet<Item>();
490 >        q.add(two);
491 >        q.add(one);
492 >        q.add(three);
493  
494 <        Iterator it = q.iterator();
494 >        Iterator<? extends Item> it = q.iterator();
495          it.next();
496          it.remove();
497  
498          it = q.iterator();
499 <        assertEquals(it.next(), new Integer(2));
500 <        assertEquals(it.next(), new Integer(3));
499 >        mustEqual(it.next(), two);
500 >        mustEqual(it.next(), three);
501          assertFalse(it.hasNext());
502      }
503  
533
504      /**
505       * toString contains toStrings of elements
506       */
507      public void testToString() {
508 <        TreeSet q = populatedSet(SIZE);
508 >        TreeSet<Item> q = populatedSet(SIZE);
509          String s = q.toString();
510          for (int i = 0; i < SIZE; ++i) {
511 <            assertTrue(s.indexOf(String.valueOf(i)) >= 0);
511 >            assertTrue(s.contains(String.valueOf(i)));
512          }
513 <    }        
513 >    }
514  
515      /**
516 <     * A deserialized serialized set has same elements
516 >     * A deserialized/reserialized set equals original
517       */
518 <    public void testSerialization() {
519 <        TreeSet q = populatedSet(SIZE);
520 <        try {
521 <            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
522 <            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
523 <            out.writeObject(q);
524 <            out.close();
525 <
526 <            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
527 <            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
528 <            TreeSet r = (TreeSet)in.readObject();
559 <            assertEquals(q.size(), r.size());
560 <            while (!q.isEmpty())
561 <                assertEquals(q.pollFirst(), r.pollFirst());
562 <        } catch(Exception e){
563 <            e.printStackTrace();
564 <            unexpectedException();
518 >    public void testSerialization() throws Exception {
519 >        NavigableSet<Item> x = populatedSet(SIZE);
520 >        NavigableSet<Item> y = serialClone(x);
521 >
522 >        assertNotSame(x, y);
523 >        mustEqual(x.size(), y.size());
524 >        mustEqual(x, y);
525 >        mustEqual(y, x);
526 >        while (!x.isEmpty()) {
527 >            assertFalse(y.isEmpty());
528 >            mustEqual(x.pollFirst(), y.pollFirst());
529          }
530 +        assertTrue(y.isEmpty());
531      }
532  
533      /**
534       * subSet returns set with keys in requested range
535       */
536      public void testSubSetContents() {
537 <        TreeSet set = set5();
538 <        SortedSet sm = set.subSet(two, four);
539 <        assertEquals(two, sm.first());
540 <        assertEquals(three, sm.last());
541 <        assertEquals(2, sm.size());
542 <        assertFalse(sm.contains(one));
543 <        assertTrue(sm.contains(two));
544 <        assertTrue(sm.contains(three));
545 <        assertFalse(sm.contains(four));
546 <        assertFalse(sm.contains(five));
547 <        Iterator i = sm.iterator();
548 <        Object k;
549 <        k = (Integer)(i.next());
550 <        assertEquals(two, k);
551 <        k = (Integer)(i.next());
587 <        assertEquals(three, k);
537 >        TreeSet<Item> set = set5();
538 >        SortedSet<Item> sm = set.subSet(two, four);
539 >        mustEqual(two, sm.first());
540 >        mustEqual(three, sm.last());
541 >        mustEqual(2, sm.size());
542 >        mustNotContain(sm, one);
543 >        mustContain(sm, two);
544 >        mustContain(sm, three);
545 >        mustNotContain(sm, four);
546 >        mustNotContain(sm, five);
547 >        Iterator<? extends Item> i = sm.iterator();
548 >        Item k = i.next();
549 >        mustEqual(two, k);
550 >        k = i.next();
551 >        mustEqual(three, k);
552          assertFalse(i.hasNext());
553 <        Iterator j = sm.iterator();
553 >        Iterator<? extends Item> j = sm.iterator();
554          j.next();
555          j.remove();
556 <        assertFalse(set.contains(two));
557 <        assertEquals(4, set.size());
558 <        assertEquals(1, sm.size());
559 <        assertEquals(three, sm.first());
560 <        assertEquals(three, sm.last());
561 <        assertTrue(sm.remove(three));
556 >        mustNotContain(set, two);
557 >        mustEqual(4, set.size());
558 >        mustEqual(1, sm.size());
559 >        mustEqual(three, sm.first());
560 >        mustEqual(three, sm.last());
561 >        mustRemove(sm, three);
562          assertTrue(sm.isEmpty());
563 <        assertEquals(3, set.size());
563 >        mustEqual(3, set.size());
564      }
565  
566      public void testSubSetContents2() {
567 <        TreeSet set = set5();
568 <        SortedSet sm = set.subSet(two, three);
569 <        assertEquals(1, sm.size());
570 <        assertEquals(two, sm.first());
571 <        assertEquals(two, sm.last());
572 <        assertFalse(sm.contains(one));
573 <        assertTrue(sm.contains(two));
574 <        assertFalse(sm.contains(three));
575 <        assertFalse(sm.contains(four));
576 <        assertFalse(sm.contains(five));
577 <        Iterator i = sm.iterator();
578 <        Object k;
579 <        k = (Integer)(i.next());
616 <        assertEquals(two, k);
567 >        TreeSet<Item> set = set5();
568 >        SortedSet<Item> sm = set.subSet(two, three);
569 >        mustEqual(1, sm.size());
570 >        mustEqual(two, sm.first());
571 >        mustEqual(two, sm.last());
572 >        mustNotContain(sm, one);
573 >        mustContain(sm, two);
574 >        mustNotContain(sm, three);
575 >        mustNotContain(sm, four);
576 >        mustNotContain(sm, five);
577 >        Iterator<? extends Item> i = sm.iterator();
578 >        Item k = i.next();
579 >        mustEqual(two, k);
580          assertFalse(i.hasNext());
581 <        Iterator j = sm.iterator();
581 >        Iterator<? extends Item> j = sm.iterator();
582          j.next();
583          j.remove();
584 <        assertFalse(set.contains(two));
585 <        assertEquals(4, set.size());
586 <        assertEquals(0, sm.size());
584 >        mustNotContain(set, two);
585 >        mustEqual(4, set.size());
586 >        mustEqual(0, sm.size());
587          assertTrue(sm.isEmpty());
588 <        assertFalse(sm.remove(three));
589 <        assertEquals(4, set.size());
588 >        mustNotRemove(sm, three);
589 >        mustEqual(4, set.size());
590      }
591  
592      /**
593       * headSet returns set with keys in requested range
594       */
595      public void testHeadSetContents() {
596 <        TreeSet set = set5();
597 <        SortedSet sm = set.headSet(four);
598 <        assertTrue(sm.contains(one));
599 <        assertTrue(sm.contains(two));
600 <        assertTrue(sm.contains(three));
601 <        assertFalse(sm.contains(four));
602 <        assertFalse(sm.contains(five));
603 <        Iterator i = sm.iterator();
604 <        Object k;
605 <        k = (Integer)(i.next());
606 <        assertEquals(one, k);
607 <        k = (Integer)(i.next());
608 <        assertEquals(two, k);
609 <        k = (Integer)(i.next());
647 <        assertEquals(three, k);
596 >        TreeSet<Item> set = set5();
597 >        SortedSet<Item> sm = set.headSet(four);
598 >        mustContain(sm, one);
599 >        mustContain(sm, two);
600 >        mustContain(sm, three);
601 >        mustNotContain(sm, four);
602 >        mustNotContain(sm, five);
603 >        Iterator<? extends Item> i = sm.iterator();
604 >        Item k = i.next();
605 >        mustEqual(one, k);
606 >        k = i.next();
607 >        mustEqual(two, k);
608 >        k = i.next();
609 >        mustEqual(three, k);
610          assertFalse(i.hasNext());
611          sm.clear();
612          assertTrue(sm.isEmpty());
613 <        assertEquals(2, set.size());
614 <        assertEquals(four, set.first());
613 >        mustEqual(2, set.size());
614 >        mustEqual(four, set.first());
615      }
616  
617      /**
618       * tailSet returns set with keys in requested range
619       */
620      public void testTailSetContents() {
621 <        TreeSet set = set5();
622 <        SortedSet sm = set.tailSet(two);
623 <        assertFalse(sm.contains(one));
624 <        assertTrue(sm.contains(two));
625 <        assertTrue(sm.contains(three));
626 <        assertTrue(sm.contains(four));
627 <        assertTrue(sm.contains(five));
628 <        Iterator i = sm.iterator();
629 <        Object k;
630 <        k = (Integer)(i.next());
631 <        assertEquals(two, k);
632 <        k = (Integer)(i.next());
633 <        assertEquals(three, k);
634 <        k = (Integer)(i.next());
635 <        assertEquals(four, k);
636 <        k = (Integer)(i.next());
675 <        assertEquals(five, k);
621 >        TreeSet<Item> set = set5();
622 >        SortedSet<Item> sm = set.tailSet(two);
623 >        mustNotContain(sm, one);
624 >        mustContain(sm, two);
625 >        mustContain(sm, three);
626 >        mustContain(sm, four);
627 >        mustContain(sm, five);
628 >        Iterator<? extends Item> i = sm.iterator();
629 >        Item k = i.next();
630 >        mustEqual(two, k);
631 >        k = i.next();
632 >        mustEqual(three, k);
633 >        k = i.next();
634 >        mustEqual(four, k);
635 >        k = i.next();
636 >        mustEqual(five, k);
637          assertFalse(i.hasNext());
638  
639 <        SortedSet ssm = sm.tailSet(four);
640 <        assertEquals(four, ssm.first());
641 <        assertEquals(five, ssm.last());
642 <        assertTrue(ssm.remove(four));
643 <        assertEquals(1, ssm.size());
644 <        assertEquals(3, sm.size());
645 <        assertEquals(4, set.size());
639 >        SortedSet<Item> ssm = sm.tailSet(four);
640 >        mustEqual(four, ssm.first());
641 >        mustEqual(five, ssm.last());
642 >        mustRemove(ssm, four);
643 >        mustEqual(1, ssm.size());
644 >        mustEqual(3, sm.size());
645 >        mustEqual(4, set.size());
646 >    }
647 >
648 >    Random rnd = new Random(666);
649 >    BitSet bs;
650 >
651 >    /**
652 >     * Subsets of subsets subdivide correctly
653 >     */
654 >    public void testRecursiveSubSets() throws Exception {
655 >        int setSize = expensiveTests ? 1000 : 100;
656 >        Class<?> cl = TreeSet.class;
657 >
658 >        NavigableSet<Item> set = newSet(cl);
659 >        bs = new BitSet(setSize);
660 >
661 >        populate(set, setSize);
662 >        check(set,                 0, setSize - 1, true);
663 >        check(set.descendingSet(), 0, setSize - 1, false);
664 >
665 >        mutateSet(set, 0, setSize - 1);
666 >        check(set,                 0, setSize - 1, true);
667 >        check(set.descendingSet(), 0, setSize - 1, false);
668 >
669 >        bashSubSet(set.subSet(zero, true, itemFor(setSize), false),
670 >                   0, setSize - 1, true);
671 >    }
672 >
673 >    /**
674 >     * addAll is idempotent
675 >     */
676 >    public void testAddAll_idempotent() throws Exception {
677 >        Set<Item> x = populatedSet(SIZE);
678 >        Set<Item> y = new TreeSet<Item>(x);
679 >        y.addAll(x);
680 >        mustEqual(x, y);
681 >        mustEqual(y, x);
682 >    }
683 >
684 >    static NavigableSet<Item> newSet(Class<?> cl) throws Exception {
685 >        @SuppressWarnings("unchecked")
686 >        NavigableSet<Item> result =
687 >            (NavigableSet<Item>) cl.getConstructor().newInstance();
688 >        mustEqual(0, result.size());
689 >        assertFalse(result.iterator().hasNext());
690 >        return result;
691 >    }
692 >
693 >    void populate(NavigableSet<Item> set, int limit) {
694 >        for (int i = 0, n = 2 * limit / 3; i < n; i++) {
695 >            int element = rnd.nextInt(limit);
696 >            put(set, element);
697 >        }
698 >    }
699 >
700 >    void mutateSet(NavigableSet<Item> set, int min, int max) {
701 >        int size = set.size();
702 >        int rangeSize = max - min + 1;
703 >
704 >        // Remove a bunch of entries directly
705 >        for (int i = 0, n = rangeSize / 2; i < n; i++) {
706 >            remove(set, min - 5 + rnd.nextInt(rangeSize + 10));
707 >        }
708 >
709 >        // Remove a bunch of entries with iterator
710 >        for (Iterator<Item> it = set.iterator(); it.hasNext(); ) {
711 >            if (rnd.nextBoolean()) {
712 >                bs.clear(it.next().value);
713 >                it.remove();
714 >            }
715 >        }
716 >
717 >        // Add entries till we're back to original size
718 >        while (set.size() < size) {
719 >            int element = min + rnd.nextInt(rangeSize);
720 >            assertTrue(element >= min && element <= max);
721 >            put(set, element);
722 >        }
723 >    }
724 >
725 >    void mutateSubSet(NavigableSet<Item> set, int min, int max) {
726 >        int size = set.size();
727 >        int rangeSize = max - min + 1;
728 >
729 >        // Remove a bunch of entries directly
730 >        for (int i = 0, n = rangeSize / 2; i < n; i++) {
731 >            remove(set, min - 5 + rnd.nextInt(rangeSize + 10));
732 >        }
733 >
734 >        // Remove a bunch of entries with iterator
735 >        for (Iterator<Item> it = set.iterator(); it.hasNext(); ) {
736 >            if (rnd.nextBoolean()) {
737 >                bs.clear(it.next().value);
738 >                it.remove();
739 >            }
740 >        }
741 >
742 >        // Add entries till we're back to original size
743 >        while (set.size() < size) {
744 >            int element = min - 5 + rnd.nextInt(rangeSize + 10);
745 >            if (element >= min && element <= max) {
746 >                put(set, element);
747 >            } else {
748 >                try {
749 >                    set.add(itemFor(element));
750 >                    shouldThrow();
751 >                } catch (IllegalArgumentException success) {}
752 >            }
753 >        }
754 >    }
755 >
756 >    void put(NavigableSet<Item> set, int element) {
757 >        if (set.add(itemFor(element)))
758 >            bs.set(element);
759 >    }
760 >
761 >    void remove(NavigableSet<Item> set, int element) {
762 >        if (set.remove(itemFor(element)))
763 >            bs.clear(element);
764 >    }
765 >
766 >    void bashSubSet(NavigableSet<Item> set,
767 >                    int min, int max, boolean ascending) {
768 >        check(set, min, max, ascending);
769 >        check(set.descendingSet(), min, max, !ascending);
770 >
771 >        mutateSubSet(set, min, max);
772 >        check(set, min, max, ascending);
773 >        check(set.descendingSet(), min, max, !ascending);
774 >
775 >        // Recurse
776 >        if (max - min < 2)
777 >            return;
778 >        int midPoint = (min + max) / 2;
779 >
780 >        // headSet - pick direction and endpoint inclusion randomly
781 >        boolean incl = rnd.nextBoolean();
782 >        NavigableSet<Item> hm = set.headSet(itemFor(midPoint), incl);
783 >        if (ascending) {
784 >            if (rnd.nextBoolean())
785 >                bashSubSet(hm, min, midPoint - (incl ? 0 : 1), true);
786 >            else
787 >                bashSubSet(hm.descendingSet(), min, midPoint - (incl ? 0 : 1),
788 >                           false);
789 >        } else {
790 >            if (rnd.nextBoolean())
791 >                bashSubSet(hm, midPoint + (incl ? 0 : 1), max, false);
792 >            else
793 >                bashSubSet(hm.descendingSet(), midPoint + (incl ? 0 : 1), max,
794 >                           true);
795 >        }
796 >
797 >        // tailSet - pick direction and endpoint inclusion randomly
798 >        incl = rnd.nextBoolean();
799 >        NavigableSet<Item> tm = set.tailSet(itemFor(midPoint),incl);
800 >        if (ascending) {
801 >            if (rnd.nextBoolean())
802 >                bashSubSet(tm, midPoint + (incl ? 0 : 1), max, true);
803 >            else
804 >                bashSubSet(tm.descendingSet(), midPoint + (incl ? 0 : 1), max,
805 >                           false);
806 >        } else {
807 >            if (rnd.nextBoolean()) {
808 >                bashSubSet(tm, min, midPoint - (incl ? 0 : 1), false);
809 >            } else {
810 >                bashSubSet(tm.descendingSet(), min, midPoint - (incl ? 0 : 1),
811 >                           true);
812 >            }
813 >        }
814 >
815 >        // subSet - pick direction and endpoint inclusion randomly
816 >        int rangeSize = max - min + 1;
817 >        int[] endpoints = new int[2];
818 >        endpoints[0] = min + rnd.nextInt(rangeSize);
819 >        endpoints[1] = min + rnd.nextInt(rangeSize);
820 >        Arrays.sort(endpoints);
821 >        boolean lowIncl = rnd.nextBoolean();
822 >        boolean highIncl = rnd.nextBoolean();
823 >        if (ascending) {
824 >            NavigableSet<Item> sm = set.subSet(
825 >                itemFor(endpoints[0]), lowIncl, itemFor(endpoints[1]), highIncl);
826 >            if (rnd.nextBoolean())
827 >                bashSubSet(sm, endpoints[0] + (lowIncl ? 0 : 1),
828 >                           endpoints[1] - (highIncl ? 0 : 1), true);
829 >            else
830 >                bashSubSet(sm.descendingSet(), endpoints[0] + (lowIncl ? 0 : 1),
831 >                           endpoints[1] - (highIncl ? 0 : 1), false);
832 >        } else {
833 >            NavigableSet<Item> sm = set.subSet(
834 >                itemFor(endpoints[1]), highIncl, itemFor(endpoints[0]), lowIncl);
835 >            if (rnd.nextBoolean())
836 >                bashSubSet(sm, endpoints[0] + (lowIncl ? 0 : 1),
837 >                           endpoints[1] - (highIncl ? 0 : 1), false);
838 >            else
839 >                bashSubSet(sm.descendingSet(), endpoints[0] + (lowIncl ? 0 : 1),
840 >                           endpoints[1] - (highIncl ? 0 : 1), true);
841 >        }
842 >    }
843 >
844 >    /**
845 >     * min and max are both inclusive.  If max < min, interval is empty.
846 >     */
847 >    void check(NavigableSet<Item> set,
848 >                      final int min, final int max, final boolean ascending) {
849 >        class ReferenceSet {
850 >            int lower(int element) {
851 >                return ascending ?
852 >                    lowerAscending(element) : higherAscending(element);
853 >            }
854 >            int floor(int element) {
855 >                return ascending ?
856 >                    floorAscending(element) : ceilingAscending(element);
857 >            }
858 >            int ceiling(int element) {
859 >                return ascending ?
860 >                    ceilingAscending(element) : floorAscending(element);
861 >            }
862 >            int higher(int element) {
863 >                return ascending ?
864 >                    higherAscending(element) : lowerAscending(element);
865 >            }
866 >            int first() {
867 >                return ascending ? firstAscending() : lastAscending();
868 >            }
869 >            int last() {
870 >                return ascending ? lastAscending() : firstAscending();
871 >            }
872 >            int lowerAscending(int element) {
873 >                return floorAscending(element - 1);
874 >            }
875 >            int floorAscending(int element) {
876 >                if (element < min)
877 >                    return -1;
878 >                else if (element > max)
879 >                    element = max;
880 >
881 >                // BitSet should support this! Test would run much faster
882 >                while (element >= min) {
883 >                    if (bs.get(element))
884 >                        return element;
885 >                    element--;
886 >                }
887 >                return -1;
888 >            }
889 >            int ceilingAscending(int element) {
890 >                if (element < min)
891 >                    element = min;
892 >                else if (element > max)
893 >                    return -1;
894 >                int result = bs.nextSetBit(element);
895 >                return (result > max) ? -1 : result;
896 >            }
897 >            int higherAscending(int element) {
898 >                return ceilingAscending(element + 1);
899 >            }
900 >            private int firstAscending() {
901 >                int result = ceilingAscending(min);
902 >                return (result > max) ? -1 : result;
903 >            }
904 >            private int lastAscending() {
905 >                int result = floorAscending(max);
906 >                return (result < min) ? -1 : result;
907 >            }
908 >        }
909 >        ReferenceSet rs = new ReferenceSet();
910 >
911 >        // Test contents using containsElement
912 >        int size = 0;
913 >        for (int i = min; i <= max; i++) {
914 >            boolean bsContainsI = bs.get(i);
915 >            mustEqual(bsContainsI, set.contains(itemFor(i)));
916 >            if (bsContainsI)
917 >                size++;
918 >        }
919 >        mustEqual(size, set.size());
920 >
921 >        // Test contents using contains elementSet iterator
922 >        int size2 = 0;
923 >        int previousElement = -1;
924 >        for (Item element : set) {
925 >            assertTrue(bs.get(element.value));
926 >            size2++;
927 >            assertTrue(previousElement < 0 || (ascending ?
928 >                element.value - previousElement > 0 : element.value - previousElement < 0));
929 >            previousElement = element.value;
930 >        }
931 >        mustEqual(size2, size);
932 >
933 >        // Test navigation ops
934 >        for (int element = min - 1; element <= max + 1; element++) {
935 >            Item e = itemFor(element);
936 >            assertEq(set.lower(e), rs.lower(element));
937 >            assertEq(set.floor(e), rs.floor(element));
938 >            assertEq(set.higher(e), rs.higher(element));
939 >            assertEq(set.ceiling(e), rs.ceiling(element));
940 >        }
941 >
942 >        // Test extrema
943 >        if (set.size() != 0) {
944 >            assertEq(set.first(), rs.first());
945 >            assertEq(set.last(), rs.last());
946 >        } else {
947 >            mustEqual(rs.first(), -1);
948 >            mustEqual(rs.last(),  -1);
949 >            try {
950 >                set.first();
951 >                shouldThrow();
952 >            } catch (NoSuchElementException success) {}
953 >            try {
954 >                set.last();
955 >                shouldThrow();
956 >            } catch (NoSuchElementException success) {}
957 >        }
958 >    }
959 >
960 >    static void assertEq(Item i, int j) {
961 >        if (i == null)
962 >            mustEqual(j, -1);
963 >        else
964 >            mustEqual(i, j);
965 >    }
966 >
967 >    static boolean eq(Item i, int j) {
968 >        return (i == null) ? j == -1 : i.value == j;
969      }
970  
971   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines