blob: 945335a7fe3aca17a0a67dc333154f36dc267d11 [file] [log] [blame]
duke6e45e102007-12-01 00:00:00 +00001/*
ohairbf91ea12011-04-06 22:06:11 -07002 * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
duke6e45e102007-12-01 00:00:00 +00003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
ohair2283b9d2010-05-25 15:58:33 -070019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
duke6e45e102007-12-01 00:00:00 +000022 */
23
24/*
25 * @test
26 * @bug 6207984 6272521 6192552 6269713 6197726 6260652 5073546 4137464
27 * 4155650 4216399 4294891 6282555 6318622 6355327 6383475 6420753
martin4d0abcd2008-05-10 12:14:53 -070028 * 6431845 4802633 6570566 6570575 6570631 6570924 6691185 6691215
mduigou0d7f6cc2013-05-07 12:05:52 -070029 * 4802647 7123424
duke6e45e102007-12-01 00:00:00 +000030 * @summary Run many tests on many Collection and Map implementations
31 * @author Martin Buchholz
mduigou431aace2011-02-21 14:53:11 -080032 * @run main MOAT
duke6e45e102007-12-01 00:00:00 +000033 */
34
35/* Mother Of All (Collection) Tests
36 *
37 * Testing of collection classes is often spotty, because many tests
38 * need to be performed on many implementations, but the onus on
39 * writing the tests falls on the engineer introducing the new
40 * implementation.
41 *
42 * The idea of this mega-test is that:
43 *
44 * An engineer adding a new collection implementation could simply add
45 * their new implementation to a list of implementations in this
46 * test's main method. Any general purpose Collection<Integer> or
47 * Map<Integer,Integer> class is appropriate.
48 *
49 * An engineer fixing a regression could add their regression test here and
50 * simultaneously test all other implementations.
51 */
52
53import java.io.*;
54import java.util.*;
55import java.util.concurrent.*;
56import static java.util.Collections.*;
57
58public class MOAT {
59 public static void realMain(String[] args) {
60
mduigou0d7f6cc2013-05-07 12:05:52 -070061 testCollection(new NewAbstractCollection<Integer>());
62 testCollection(new NewAbstractSet<Integer>());
duke6e45e102007-12-01 00:00:00 +000063 testCollection(new LinkedHashSet<Integer>());
64 testCollection(new HashSet<Integer>());
65 testCollection(new Vector<Integer>());
66 testCollection(new Vector<Integer>().subList(0,0));
67 testCollection(new ArrayDeque<Integer>());
68 testCollection(new ArrayList<Integer>());
69 testCollection(new ArrayList<Integer>().subList(0,0));
70 testCollection(new LinkedList<Integer>());
71 testCollection(new LinkedList<Integer>().subList(0,0));
72 testCollection(new TreeSet<Integer>());
mduigoua7d2d192013-07-12 11:11:30 -070073 testCollection(Collections.checkedList(new ArrayList<Integer>(), Integer.class));
74 testCollection(Collections.synchronizedList(new ArrayList<Integer>()));
75 testCollection(Collections.checkedSet(new HashSet<Integer>(), Integer.class));
76 testCollection(Collections.checkedSortedSet(new TreeSet<Integer>(), Integer.class));
77 testCollection(Collections.checkedNavigableSet(new TreeSet<Integer>(), Integer.class));
78 testCollection(Collections.synchronizedSet(new HashSet<Integer>()));
79 testCollection(Collections.synchronizedSortedSet(new TreeSet<Integer>()));
80 testCollection(Collections.synchronizedNavigableSet(new TreeSet<Integer>()));
duke6e45e102007-12-01 00:00:00 +000081
82 testCollection(new CopyOnWriteArrayList<Integer>());
83 testCollection(new CopyOnWriteArrayList<Integer>().subList(0,0));
84 testCollection(new CopyOnWriteArraySet<Integer>());
85 testCollection(new PriorityQueue<Integer>());
86 testCollection(new PriorityBlockingQueue<Integer>());
87 testCollection(new ArrayBlockingQueue<Integer>(20));
88 testCollection(new LinkedBlockingQueue<Integer>(20));
89 testCollection(new LinkedBlockingDeque<Integer>(20));
dlb818e9d2010-09-20 18:05:09 -070090 testCollection(new ConcurrentLinkedDeque<Integer>());
duke6e45e102007-12-01 00:00:00 +000091 testCollection(new ConcurrentLinkedQueue<Integer>());
dl54d3afc2009-11-02 17:25:38 -080092 testCollection(new LinkedTransferQueue<Integer>());
duke6e45e102007-12-01 00:00:00 +000093 testCollection(new ConcurrentSkipListSet<Integer>());
94 testCollection(Arrays.asList(new Integer(42)));
95 testCollection(Arrays.asList(1,2,3));
96 testCollection(nCopies(25,1));
97 testImmutableList(nCopies(25,1));
98 testImmutableList(unmodifiableList(Arrays.asList(1,2,3)));
99
100 testMap(new HashMap<Integer,Integer>());
101 testMap(new LinkedHashMap<Integer,Integer>());
102 testMap(new WeakHashMap<Integer,Integer>());
103 testMap(new IdentityHashMap<Integer,Integer>());
104 testMap(new TreeMap<Integer,Integer>());
105 testMap(new Hashtable<Integer,Integer>());
106 testMap(new ConcurrentHashMap<Integer,Integer>(10, 0.5f));
107 testMap(new ConcurrentSkipListMap<Integer,Integer>());
mduigoua7d2d192013-07-12 11:11:30 -0700108 testMap(Collections.checkedMap(new HashMap<Integer,Integer>(), Integer.class, Integer.class));
109 testMap(Collections.checkedSortedMap(new TreeMap<Integer,Integer>(), Integer.class, Integer.class));
110 testMap(Collections.checkedNavigableMap(new TreeMap<Integer,Integer>(), Integer.class, Integer.class));
111 testMap(Collections.synchronizedMap(new HashMap<Integer,Integer>()));
112 testMap(Collections.synchronizedSortedMap(new TreeMap<Integer,Integer>()));
113 testMap(Collections.synchronizedNavigableMap(new TreeMap<Integer,Integer>()));
duke6e45e102007-12-01 00:00:00 +0000114
115 // Empty collections
116 final List<Integer> emptyArray = Arrays.asList(new Integer[]{});
117 testCollection(emptyArray);
118 testEmptyList(emptyArray);
119 THROWS(IndexOutOfBoundsException.class,
120 new Fun(){void f(){ emptyArray.set(0,1); }});
121 THROWS(UnsupportedOperationException.class,
122 new Fun(){void f(){ emptyArray.add(0,1); }});
123
124 List<Integer> noOne = nCopies(0,1);
125 testCollection(noOne);
126 testEmptyList(noOne);
127 testImmutableList(noOne);
128
129 Set<Integer> emptySet = emptySet();
130 testCollection(emptySet);
131 testEmptySet(emptySet);
132 testEmptySet(EMPTY_SET);
mduigoua7d2d192013-07-12 11:11:30 -0700133 testEmptySet(Collections.emptySet());
134 testEmptySet(Collections.emptySortedSet());
135 testEmptySet(Collections.emptyNavigableSet());
duke6e45e102007-12-01 00:00:00 +0000136 testImmutableSet(emptySet);
137
138 List<Integer> emptyList = emptyList();
139 testCollection(emptyList);
140 testEmptyList(emptyList);
141 testEmptyList(EMPTY_LIST);
mduigoua7d2d192013-07-12 11:11:30 -0700142 testEmptyList(Collections.emptyList());
duke6e45e102007-12-01 00:00:00 +0000143 testImmutableList(emptyList);
144
145 Map<Integer,Integer> emptyMap = emptyMap();
146 testMap(emptyMap);
147 testEmptyMap(emptyMap);
148 testEmptyMap(EMPTY_MAP);
mduigoua7d2d192013-07-12 11:11:30 -0700149 testEmptyMap(Collections.emptyMap());
150 testEmptyMap(Collections.emptySortedMap());
151 testEmptyMap(Collections.emptyNavigableMap());
duke6e45e102007-12-01 00:00:00 +0000152 testImmutableMap(emptyMap);
mduigoua7d2d192013-07-12 11:11:30 -0700153 testImmutableMap(Collections.emptyMap());
154 testImmutableMap(Collections.emptySortedMap());
155 testImmutableMap(Collections.emptyNavigableMap());
duke6e45e102007-12-01 00:00:00 +0000156
157 // Singleton collections
158 Set<Integer> singletonSet = singleton(1);
159 equal(singletonSet.size(), 1);
160 testCollection(singletonSet);
161 testImmutableSet(singletonSet);
162
163 List<Integer> singletonList = singletonList(1);
164 equal(singletonList.size(), 1);
165 testCollection(singletonList);
166 testImmutableList(singletonList);
167 testImmutableList(singletonList.subList(0,1));
168 testImmutableList(singletonList.subList(0,1).subList(0,1));
169 testEmptyList(singletonList.subList(0,0));
170 testEmptyList(singletonList.subList(0,0).subList(0,0));
171
172 Map<Integer,Integer> singletonMap = singletonMap(1,2);
173 equal(singletonMap.size(), 1);
174 testMap(singletonMap);
175 testImmutableMap(singletonMap);
176 }
177
178 private static void checkContainsSelf(Collection<Integer> c) {
179 check(c.containsAll(c));
180 check(c.containsAll(Arrays.asList(c.toArray())));
181 check(c.containsAll(Arrays.asList(c.toArray(new Integer[0]))));
182 }
183
184 private static void checkContainsEmpty(Collection<Integer> c) {
185 check(c.containsAll(new ArrayList<Integer>()));
186 }
187
martineb76fa62008-05-10 11:49:25 -0700188 private static <T> void testEmptyCollection(Collection<T> c) {
duke6e45e102007-12-01 00:00:00 +0000189 check(c.isEmpty());
190 equal(c.size(), 0);
191 equal(c.toString(),"[]");
192 equal(c.toArray().length, 0);
193 equal(c.toArray(new Object[0]).length, 0);
dlb1e19572009-08-25 19:19:42 -0700194 check(c.toArray(new Object[]{42})[0] == null);
duke6e45e102007-12-01 00:00:00 +0000195
196 Object[] a = new Object[1]; a[0] = Boolean.TRUE;
197 equal(c.toArray(a), a);
198 equal(a[0], null);
martineb76fa62008-05-10 11:49:25 -0700199 testEmptyIterator(c.iterator());
200 }
201
202 static <T> void testEmptyIterator(final Iterator<T> it) {
203 if (rnd.nextBoolean())
204 check(! it.hasNext());
205
206 THROWS(NoSuchElementException.class,
207 new Fun(){void f(){ it.next(); }});
208
209 try { it.remove(); }
mduigou30634432013-09-27 13:30:31 -0700210 catch (IllegalStateException ignored) { pass(); }
211 catch (UnsupportedOperationException ignored) { pass(); }
martineb76fa62008-05-10 11:49:25 -0700212 catch (Throwable t) { unexpected(t); }
213
214 if (rnd.nextBoolean())
215 check(! it.hasNext());
duke6e45e102007-12-01 00:00:00 +0000216 }
217
218 private static void testEmptyList(List<?> c) {
219 testEmptyCollection(c);
220 equal(c.hashCode(), 1);
221 equal2(c, Collections.<Integer>emptyList());
222 }
223
martineb76fa62008-05-10 11:49:25 -0700224 private static <T> void testEmptySet(Set<T> c) {
duke6e45e102007-12-01 00:00:00 +0000225 testEmptyCollection(c);
226 equal(c.hashCode(), 0);
227 equal2(c, Collections.<Integer>emptySet());
martineb76fa62008-05-10 11:49:25 -0700228 if (c instanceof NavigableSet<?>)
229 testEmptyIterator(((NavigableSet<T>)c).descendingIterator());
duke6e45e102007-12-01 00:00:00 +0000230 }
231
232 private static void testImmutableCollection(final Collection<Integer> c) {
233 THROWS(UnsupportedOperationException.class,
234 new Fun(){void f(){ c.add(99); }},
235 new Fun(){void f(){ c.addAll(singleton(99)); }});
236 if (! c.isEmpty()) {
237 final Integer first = c.iterator().next();
238 THROWS(UnsupportedOperationException.class,
239 new Fun(){void f(){ c.clear(); }},
240 new Fun(){void f(){ c.remove(first); }},
241 new Fun(){void f(){ c.removeAll(singleton(first)); }},
242 new Fun(){void f(){ c.retainAll(emptyList()); }}
243 );
244 }
245 }
246
247 private static void testImmutableSet(final Set<Integer> c) {
248 testImmutableCollection(c);
249 }
250
251 private static void testImmutableList(final List<Integer> c) {
252 testList(c);
253 testImmutableCollection(c);
254 THROWS(UnsupportedOperationException.class,
255 new Fun(){void f(){ c.set(0,42); }},
256 new Fun(){void f(){ c.add(0,42); }},
257 new Fun(){void f(){ c.addAll(0,singleton(86)); }});
258 if (! c.isEmpty())
259 THROWS(UnsupportedOperationException.class,
260 new Fun(){void f(){
261 Iterator<Integer> it = c.iterator();
262 it.next(); it.remove();}},
263 new Fun(){void f(){
264 ListIterator<Integer> it = c.listIterator();
265 it.next(); it.remove();}});
266 }
267
268 private static void clear(Collection<Integer> c) {
269 try { c.clear(); }
270 catch (Throwable t) { unexpected(t); }
271 testEmptyCollection(c);
272 }
273
martineb76fa62008-05-10 11:49:25 -0700274 private static <K,V> void testEmptyMap(final Map<K,V> m) {
duke6e45e102007-12-01 00:00:00 +0000275 check(m.isEmpty());
276 equal(m.size(), 0);
277 equal(m.toString(),"{}");
278 testEmptySet(m.keySet());
279 testEmptySet(m.entrySet());
280 testEmptyCollection(m.values());
martin4d0abcd2008-05-10 12:14:53 -0700281
282 try { check(! m.containsValue(null)); }
mduigou30634432013-09-27 13:30:31 -0700283 catch (NullPointerException ignored) { /* OK */ }
martin4d0abcd2008-05-10 12:14:53 -0700284 try { check(! m.containsKey(null)); }
mduigou30634432013-09-27 13:30:31 -0700285 catch (NullPointerException ignored) { /* OK */ }
martin4d0abcd2008-05-10 12:14:53 -0700286 check(! m.containsValue(1));
287 check(! m.containsKey(1));
duke6e45e102007-12-01 00:00:00 +0000288 }
289
290 private static void testImmutableMap(final Map<Integer,Integer> m) {
291 THROWS(UnsupportedOperationException.class,
292 new Fun(){void f(){ m.put(1,1); }},
293 new Fun(){void f(){ m.putAll(singletonMap(1,1)); }});
294 if (! m.isEmpty()) {
295 final Integer first = m.keySet().iterator().next();
296 THROWS(UnsupportedOperationException.class,
297 new Fun(){void f(){ m.remove(first); }},
298 new Fun(){void f(){ m.clear(); }});
299 final Map.Entry<Integer,Integer> me
300 = m.entrySet().iterator().next();
301 Integer key = me.getKey();
302 Integer val = me.getValue();
303 THROWS(UnsupportedOperationException.class,
304 new Fun(){void f(){ me.setValue(3); }});
305 equal(key, me.getKey());
306 equal(val, me.getValue());
307 }
308 testImmutableSet(m.keySet());
309 testImmutableCollection(m.values());
310 //testImmutableSet(m.entrySet());
311 }
312
313 private static void clear(Map<?,?> m) {
314 try { m.clear(); }
315 catch (Throwable t) { unexpected(t); }
316 testEmptyMap(m);
317 }
318
319 private static void oneElement(Collection<Integer> c) {
320 clear(c);
321 try {
322 check(c.add(-42));
323 equal(c.toString(), "[-42]");
324 if (c instanceof Set) check(! c.add(-42));
325 } catch (Throwable t) { unexpected(t); }
326 check(! c.isEmpty()); check(c.size() == 1);
327 }
328
329 private static boolean supportsAdd(Collection<Integer> c) {
330 try { check(c.add(778347983)); }
331 catch (UnsupportedOperationException t) { return false; }
332 catch (Throwable t) { unexpected(t); }
333
334 try {
335 check(c.contains(778347983));
336 check(c.remove(778347983));
337 } catch (Throwable t) { unexpected(t); }
338 return true;
339 }
340
341 private static boolean supportsRemove(Collection<Integer> c) {
342 try { check(! c.remove(19134032)); }
343 catch (UnsupportedOperationException t) { return false; }
344 catch (Throwable t) { unexpected(t); }
345 return true;
346 }
347
348 private static void checkFunctionalInvariants(Collection<Integer> c) {
349 try {
350 checkContainsSelf(c);
351 checkContainsEmpty(c);
352 check(c.size() != 0 ^ c.isEmpty());
353
354 {
355 int size = 0;
356 for (Integer i : c) size++;
357 check(c.size() == size);
358 }
359
360 check(c.toArray().length == c.size());
361 check(c.toArray().getClass() == Object[].class
362 ||
363 // !!!!
364 // 6260652: (coll) Arrays.asList(x).toArray().getClass()
365 // should be Object[].class
366 (c.getClass().getName().equals("java.util.Arrays$ArrayList"))
367 );
368 for (int size : new int[]{0,1,c.size(), c.size()+1}) {
369 Integer[] a = c.toArray(new Integer[size]);
370 check((size > c.size()) || a.length == c.size());
371 int i = 0; for (Integer j : c) check(a[i++] == j);
372 check((size <= c.size()) || (a[c.size()] == null));
373 check(a.getClass() == Integer[].class);
374 }
375
376 check(c.equals(c));
377 if (c instanceof Serializable) {
378 //System.out.printf("Serializing %s%n", c.getClass().getName());
379 try {
380 Object clone = serialClone(c);
381 equal(c instanceof Serializable,
382 clone instanceof Serializable);
383 equal(c instanceof RandomAccess,
384 clone instanceof RandomAccess);
385 if ((c instanceof List) || (c instanceof Set))
386 equal(c, clone);
387 else
388 equal(new HashSet<Integer>(c),
389 new HashSet<Integer>(serialClone(c)));
390 } catch (Error xxx) {
391 if (! (xxx.getCause() instanceof NotSerializableException))
392 throw xxx;
393 }
394 }
395 }
396 catch (Throwable t) { unexpected(t); }
397 }
398
399 //----------------------------------------------------------------
400 // If add(null) succeeds, contains(null) & remove(null) should succeed
401 //----------------------------------------------------------------
402 private static void testNullElement(Collection<Integer> c) {
duke6e45e102007-12-01 00:00:00 +0000403
404 try {
405 check(c.add(null));
406 if (c.size() == 1)
407 equal(c.toString(), "[null]");
408 try {
409 checkFunctionalInvariants(c);
410 check(c.contains(null));
411 check(c.remove(null));
412 }
413 catch (Throwable t) { unexpected(t); }
414 }
415 catch (NullPointerException e) { /* OK */ }
416 catch (Throwable t) { unexpected(t); }
417 }
418
419
420 //----------------------------------------------------------------
421 // If add("x") succeeds, contains("x") & remove("x") should succeed
422 //----------------------------------------------------------------
423 @SuppressWarnings("unchecked")
424 private static void testStringElement(Collection<Integer> c) {
425 Collection x = (Collection)c; // Make type-unsafe
426 try {
427 check(x.add("x"));
428 try {
429 check(x.contains("x"));
430 check(x.remove("x"));
431 } catch (Throwable t) { unexpected(t); }
432 }
433 catch (ClassCastException e) { /* OK */ }
434 catch (Throwable t) { unexpected(t); }
435 }
436
437 private static void testConcurrentCollection(Collection<Integer> c) {
438 try {
439 c.add(1);
440 Iterator<Integer> it = c.iterator();
441 check(it.hasNext());
442 clear(c);
443 check(it.next() instanceof Integer); // No CME
444 check(c.isEmpty());
445 }
446 catch (Throwable t) { unexpected(t); }
447 }
448
449 private static void testQueue(Queue<Integer> q) {
450 q.clear();
martinffd2d052009-11-05 16:12:45 -0800451 for (int i = 0; i < 5; i++) {
452 testQueueAddRemove(q, null);
453 testQueueAddRemove(q, 537);
duke6e45e102007-12-01 00:00:00 +0000454 q.add(i);
martinffd2d052009-11-05 16:12:45 -0800455 }
duke6e45e102007-12-01 00:00:00 +0000456 equal(q.size(), 5);
457 checkFunctionalInvariants(q);
458 q.poll();
459 equal(q.size(), 4);
460 checkFunctionalInvariants(q);
dlb818e9d2010-09-20 18:05:09 -0700461 if ((q instanceof LinkedBlockingQueue) ||
462 (q instanceof LinkedBlockingDeque) ||
463 (q instanceof ConcurrentLinkedDeque) ||
dl8e56eb52009-07-28 17:17:55 -0700464 (q instanceof ConcurrentLinkedQueue)) {
465 testQueueIteratorRemove(q);
466 }
467 }
468
martinffd2d052009-11-05 16:12:45 -0800469 private static void testQueueAddRemove(final Queue<Integer> q,
470 final Integer e) {
471 final List<Integer> originalContents = new ArrayList<Integer>(q);
472 final boolean isEmpty = q.isEmpty();
473 final boolean isList = (q instanceof List);
474 final List asList = isList ? (List) q : null;
475 check(!q.contains(e));
476 try {
477 q.add(e);
478 } catch (NullPointerException npe) {
479 check(e == null);
480 return; // Null elements not supported
481 }
482 check(q.contains(e));
483 check(q.remove(e));
484 check(!q.contains(e));
485 equal(new ArrayList<Integer>(q), originalContents);
486
487 if (q instanceof Deque<?>) {
488 final Deque<Integer> deq = (Deque<Integer>) q;
489 final List<Integer> singleton = Collections.singletonList(e);
490
491 // insert, query, remove element at head
492 if (isEmpty) {
493 THROWS(NoSuchElementException.class,
494 new Fun(){void f(){ deq.getFirst(); }},
495 new Fun(){void f(){ deq.element(); }},
496 new Fun(){void f(){ deq.iterator().next(); }});
497 check(deq.peekFirst() == null);
498 check(deq.peek() == null);
499 } else {
500 check(deq.getFirst() != e);
501 check(deq.element() != e);
502 check(deq.iterator().next() != e);
503 check(deq.peekFirst() != e);
504 check(deq.peek() != e);
505 }
506 check(!deq.contains(e));
507 check(!deq.removeFirstOccurrence(e));
508 check(!deq.removeLastOccurrence(e));
509 if (isList) {
510 check(asList.indexOf(e) == -1);
511 check(asList.lastIndexOf(e) == -1);
512 }
513 switch (rnd.nextInt(isList ? 4 : 3)) {
514 case 0: deq.addFirst(e); break;
515 case 1: check(deq.offerFirst(e)); break;
516 case 2: deq.push(e); break;
517 case 3: asList.add(0, e); break;
518 default: throw new AssertionError();
519 }
520 check(deq.peekFirst() == e);
521 check(deq.getFirst() == e);
522 check(deq.element() == e);
523 check(deq.peek() == e);
524 check(deq.iterator().next() == e);
525 check(deq.contains(e));
526 if (isList) {
527 check(asList.get(0) == e);
528 check(asList.indexOf(e) == 0);
529 check(asList.lastIndexOf(e) == 0);
530 check(asList.subList(0, 1).equals(singleton));
531 }
532 switch (rnd.nextInt(isList ? 11 : 9)) {
533 case 0: check(deq.pollFirst() == e); break;
534 case 1: check(deq.removeFirst() == e); break;
535 case 2: check(deq.remove() == e); break;
536 case 3: check(deq.pop() == e); break;
537 case 4: check(deq.removeFirstOccurrence(e)); break;
538 case 5: check(deq.removeLastOccurrence(e)); break;
539 case 6: check(deq.remove(e)); break;
540 case 7: check(deq.removeAll(singleton)); break;
541 case 8: Iterator it = deq.iterator(); it.next(); it.remove(); break;
542 case 9: asList.remove(0); break;
543 case 10: asList.subList(0, 1).clear(); break;
544 default: throw new AssertionError();
545 }
546 if (isEmpty) {
547 THROWS(NoSuchElementException.class,
548 new Fun(){void f(){ deq.getFirst(); }},
549 new Fun(){void f(){ deq.element(); }},
550 new Fun(){void f(){ deq.iterator().next(); }});
551 check(deq.peekFirst() == null);
552 check(deq.peek() == null);
553 } else {
554 check(deq.getFirst() != e);
555 check(deq.element() != e);
556 check(deq.iterator().next() != e);
557 check(deq.peekFirst() != e);
558 check(deq.peek() != e);
559 }
560 check(!deq.contains(e));
561 check(!deq.removeFirstOccurrence(e));
562 check(!deq.removeLastOccurrence(e));
563 if (isList) {
564 check(isEmpty || asList.get(0) != e);
565 check(asList.indexOf(e) == -1);
566 check(asList.lastIndexOf(e) == -1);
567 }
568 equal(new ArrayList<Integer>(deq), originalContents);
569
570 // insert, query, remove element at tail
571 if (isEmpty) {
572 check(deq.peekLast() == null);
573 THROWS(NoSuchElementException.class,
574 new Fun(){void f(){ deq.getLast(); }});
575 } else {
576 check(deq.peekLast() != e);
577 check(deq.getLast() != e);
578 }
579 switch (rnd.nextInt(isList ? 6 : 4)) {
580 case 0: deq.addLast(e); break;
581 case 1: check(deq.offerLast(e)); break;
582 case 2: check(deq.add(e)); break;
583 case 3: deq.addAll(singleton); break;
584 case 4: asList.addAll(deq.size(), singleton); break;
585 case 5: asList.add(deq.size(), e); break;
586 default: throw new AssertionError();
587 }
588 check(deq.peekLast() == e);
589 check(deq.getLast() == e);
590 check(deq.contains(e));
591 if (isList) {
592 ListIterator it = asList.listIterator(asList.size());
593 check(it.previous() == e);
594 check(asList.get(asList.size() - 1) == e);
595 check(asList.indexOf(e) == asList.size() - 1);
596 check(asList.lastIndexOf(e) == asList.size() - 1);
597 int size = asList.size();
598 check(asList.subList(size - 1, size).equals(singleton));
599 }
600 switch (rnd.nextInt(isList ? 8 : 6)) {
601 case 0: check(deq.pollLast() == e); break;
602 case 1: check(deq.removeLast() == e); break;
603 case 2: check(deq.removeFirstOccurrence(e)); break;
604 case 3: check(deq.removeLastOccurrence(e)); break;
605 case 4: check(deq.remove(e)); break;
606 case 5: check(deq.removeAll(singleton)); break;
607 case 6: asList.remove(asList.size() - 1); break;
608 case 7:
609 ListIterator it = asList.listIterator(asList.size());
610 it.previous();
611 it.remove();
612 break;
613 default: throw new AssertionError();
614 }
615 if (isEmpty) {
616 check(deq.peekLast() == null);
617 THROWS(NoSuchElementException.class,
618 new Fun(){void f(){ deq.getLast(); }});
619 } else {
620 check(deq.peekLast() != e);
621 check(deq.getLast() != e);
622 }
623 check(!deq.contains(e));
624 equal(new ArrayList<Integer>(deq), originalContents);
625
626 // Test operations on empty deque
627 switch (rnd.nextInt(isList ? 4 : 2)) {
628 case 0: deq.clear(); break;
629 case 1:
630 Iterator it = deq.iterator();
631 while (it.hasNext()) {
632 it.next();
633 it.remove();
634 }
635 break;
636 case 2: asList.subList(0, asList.size()).clear(); break;
637 case 3:
638 ListIterator lit = asList.listIterator(asList.size());
639 while (lit.hasPrevious()) {
640 lit.previous();
641 lit.remove();
642 }
643 break;
644 default: throw new AssertionError();
645 }
646 testEmptyCollection(deq);
647 check(!deq.iterator().hasNext());
648 if (isList) {
649 check(!asList.listIterator().hasPrevious());
650 THROWS(NoSuchElementException.class,
651 new Fun(){void f(){ asList.listIterator().previous(); }});
652 }
653 THROWS(NoSuchElementException.class,
654 new Fun(){void f(){ deq.iterator().next(); }},
655 new Fun(){void f(){ deq.element(); }},
656 new Fun(){void f(){ deq.getFirst(); }},
657 new Fun(){void f(){ deq.getLast(); }},
658 new Fun(){void f(){ deq.pop(); }},
659 new Fun(){void f(){ deq.remove(); }},
660 new Fun(){void f(){ deq.removeFirst(); }},
661 new Fun(){void f(){ deq.removeLast(); }});
662
663 check(deq.poll() == null);
664 check(deq.pollFirst() == null);
665 check(deq.pollLast() == null);
666 check(deq.peek() == null);
667 check(deq.peekFirst() == null);
668 check(deq.peekLast() == null);
669 check(!deq.removeFirstOccurrence(e));
670 check(!deq.removeLastOccurrence(e));
671
672 check(deq.addAll(originalContents) == !isEmpty);
673 equal(new ArrayList<Integer>(deq), originalContents);
674 check(!deq.addAll(Collections.<Integer>emptyList()));
675 equal(new ArrayList<Integer>(deq), originalContents);
676 }
677 }
678
dl8e56eb52009-07-28 17:17:55 -0700679 private static void testQueueIteratorRemove(Queue<Integer> q) {
680 System.err.printf("testQueueIteratorRemove %s%n",
681 q.getClass().getSimpleName());
682 q.clear();
683 for (int i = 0; i < 5; i++)
684 q.add(i);
685 Iterator<Integer> it = q.iterator();
686 check(it.hasNext());
687 for (int i = 3; i >= 0; i--)
688 q.remove(i);
689 equal(it.next(), 0);
690 equal(it.next(), 4);
691
692 q.clear();
693 for (int i = 0; i < 5; i++)
694 q.add(i);
695 it = q.iterator();
696 equal(it.next(), 0);
697 check(it.hasNext());
698 for (int i = 1; i < 4; i++)
699 q.remove(i);
700 equal(it.next(), 1);
701 equal(it.next(), 4);
duke6e45e102007-12-01 00:00:00 +0000702 }
703
704 private static void testList(final List<Integer> l) {
705 //----------------------------------------------------------------
706 // 4802633: (coll) AbstractList.addAll(-1,emptyCollection)
707 // doesn't throw IndexOutOfBoundsException
708 //----------------------------------------------------------------
709 try {
710 l.addAll(-1, Collections.<Integer>emptyList());
711 fail("Expected IndexOutOfBoundsException not thrown");
712 }
mduigou30634432013-09-27 13:30:31 -0700713 catch (UnsupportedOperationException ignored) {/* OK */}
714 catch (IndexOutOfBoundsException ignored) {/* OK */}
duke6e45e102007-12-01 00:00:00 +0000715 catch (Throwable t) { unexpected(t); }
716
717// equal(l instanceof Serializable,
718// l.subList(0,0) instanceof Serializable);
719 if (l.subList(0,0) instanceof Serializable)
720 check(l instanceof Serializable);
721
722 equal(l instanceof RandomAccess,
723 l.subList(0,0) instanceof RandomAccess);
724 }
725
726 private static void testCollection(Collection<Integer> c) {
dl8e56eb52009-07-28 17:17:55 -0700727 try { testCollection1(c); }
728 catch (Throwable t) { unexpected(t); }
729 }
730
731 private static void testCollection1(Collection<Integer> c) {
duke6e45e102007-12-01 00:00:00 +0000732
733 System.out.println("\n==> " + c.getClass().getName());
734
735 checkFunctionalInvariants(c);
736
737 if (! supportsAdd(c)) return;
738 //System.out.println("add() supported");
739
martineb76fa62008-05-10 11:49:25 -0700740 if (c instanceof NavigableSet) {
741 System.out.println("NavigableSet tests...");
742
743 NavigableSet<Integer> ns = (NavigableSet<Integer>)c;
744 testNavigableSet(ns);
745 testNavigableSet(ns.headSet(6, false));
746 testNavigableSet(ns.headSet(5, true));
747 testNavigableSet(ns.tailSet(0, false));
748 testNavigableSet(ns.tailSet(1, true));
749 testNavigableSet(ns.subSet(0, false, 5, true));
750 testNavigableSet(ns.subSet(1, true, 6, false));
751 }
duke6e45e102007-12-01 00:00:00 +0000752
753 if (c instanceof Queue)
754 testQueue((Queue<Integer>)c);
755
756 if (c instanceof List)
757 testList((List<Integer>)c);
758
759 check(supportsRemove(c));
760
761 try {
762 oneElement(c);
763 checkFunctionalInvariants(c);
764 }
765 catch (Throwable t) { unexpected(t); }
766
767 clear(c); testNullElement(c);
768 oneElement(c); testNullElement(c);
769
770 clear(c); testStringElement(c);
771 oneElement(c); testStringElement(c);
772
773 if (c.getClass().getName().matches(".*concurrent.*"))
774 testConcurrentCollection(c);
775
776 //----------------------------------------------------------------
777 // The "all" operations should throw NPE when passed null
778 //----------------------------------------------------------------
779 {
mduigou0d7f6cc2013-05-07 12:05:52 -0700780 clear(c);
781 try {
782 c.removeAll(null);
783 fail("Expected NullPointerException");
784 }
785 catch (NullPointerException e) { pass(); }
786 catch (Throwable t) { unexpected(t); }
787
duke6e45e102007-12-01 00:00:00 +0000788 oneElement(c);
789 try {
790 c.removeAll(null);
791 fail("Expected NullPointerException");
792 }
793 catch (NullPointerException e) { pass(); }
794 catch (Throwable t) { unexpected(t); }
795
mduigou0d7f6cc2013-05-07 12:05:52 -0700796 clear(c);
797 try {
798 c.retainAll(null);
799 fail("Expected NullPointerException");
800 }
801 catch (NullPointerException e) { pass(); }
802 catch (Throwable t) { unexpected(t); }
803
duke6e45e102007-12-01 00:00:00 +0000804 oneElement(c);
805 try {
806 c.retainAll(null);
807 fail("Expected NullPointerException");
808 }
809 catch (NullPointerException e) { pass(); }
810 catch (Throwable t) { unexpected(t); }
811
812 oneElement(c);
813 try {
814 c.addAll(null);
815 fail("Expected NullPointerException");
816 }
817 catch (NullPointerException e) { pass(); }
818 catch (Throwable t) { unexpected(t); }
819
820 oneElement(c);
821 try {
822 c.containsAll(null);
823 fail("Expected NullPointerException");
824 }
825 catch (NullPointerException e) { pass(); }
826 catch (Throwable t) { unexpected(t); }
827 }
828 }
829
830 //----------------------------------------------------------------
831 // Map
832 //----------------------------------------------------------------
833 private static void checkFunctionalInvariants(Map<Integer,Integer> m) {
834 check(m.keySet().size() == m.entrySet().size());
835 check(m.keySet().size() == m.size());
836 checkFunctionalInvariants(m.keySet());
837 checkFunctionalInvariants(m.values());
838 check(m.size() != 0 ^ m.isEmpty());
839 }
840
841 private static void testMap(Map<Integer,Integer> m) {
842 System.out.println("\n==> " + m.getClass().getName());
843
844 if (m instanceof ConcurrentMap)
845 testConcurrentMap((ConcurrentMap<Integer,Integer>) m);
846
martineb76fa62008-05-10 11:49:25 -0700847 if (m instanceof NavigableMap) {
848 System.out.println("NavigableMap tests...");
849
850 NavigableMap<Integer,Integer> nm =
851 (NavigableMap<Integer,Integer>) m;
dl0ad61612009-03-24 19:42:23 -0700852 testNavigableMapRemovers(nm);
martineb76fa62008-05-10 11:49:25 -0700853 testNavigableMap(nm);
854 testNavigableMap(nm.headMap(6, false));
855 testNavigableMap(nm.headMap(5, true));
856 testNavigableMap(nm.tailMap(0, false));
857 testNavigableMap(nm.tailMap(1, true));
858 testNavigableMap(nm.subMap(1, true, 6, false));
859 testNavigableMap(nm.subMap(0, false, 5, true));
860 }
duke6e45e102007-12-01 00:00:00 +0000861
862 checkFunctionalInvariants(m);
863
864 if (supportsClear(m)) {
865 try { clear(m); }
866 catch (Throwable t) { unexpected(t); }
867 }
868
869 if (supportsPut(m)) {
870 try {
871 check(m.put(3333, 77777) == null);
872 check(m.put(9134, 74982) == null);
873 check(m.get(9134) == 74982);
874 check(m.put(9134, 1382) == 74982);
875 check(m.get(9134) == 1382);
876 check(m.size() == 2);
877 checkFunctionalInvariants(m);
878 checkNPEConsistency(m);
879 }
880 catch (Throwable t) { unexpected(t); }
881 }
882 }
883
884 private static boolean supportsPut(Map<Integer,Integer> m) {
885 // We're asking for .equals(...) semantics
886 if (m instanceof IdentityHashMap) return false;
887
888 try { check(m.put(778347983,12735) == null); }
889 catch (UnsupportedOperationException t) { return false; }
890 catch (Throwable t) { unexpected(t); }
891
892 try {
893 check(m.containsKey(778347983));
894 check(m.remove(778347983) != null);
895 } catch (Throwable t) { unexpected(t); }
896 return true;
897 }
898
899 private static boolean supportsClear(Map<?,?> m) {
900 try { m.clear(); }
901 catch (UnsupportedOperationException t) { return false; }
902 catch (Throwable t) { unexpected(t); }
903 return true;
904 }
905
906 //----------------------------------------------------------------
907 // ConcurrentMap
908 //----------------------------------------------------------------
909 private static void testConcurrentMap(ConcurrentMap<Integer,Integer> m) {
910 System.out.println("ConcurrentMap tests...");
911
912 try {
913 clear(m);
914
915 check(m.putIfAbsent(18357,7346) == null);
916 check(m.containsKey(18357));
917 check(m.putIfAbsent(18357,8263) == 7346);
918 try { m.putIfAbsent(18357,null); fail("NPE"); }
919 catch (NullPointerException t) { }
920 check(m.containsKey(18357));
921
922 check(! m.replace(18357,8888,7777));
923 check(m.containsKey(18357));
924 try { m.replace(18357,null,7777); fail("NPE"); }
925 catch (NullPointerException t) { }
926 check(m.containsKey(18357));
927 check(m.get(18357) == 7346);
928 check(m.replace(18357,7346,5555));
929 check(m.replace(18357,5555,7346));
930 check(m.get(18357) == 7346);
931
932 check(m.replace(92347,7834) == null);
933 try { m.replace(18357,null); fail("NPE"); }
934 catch (NullPointerException t) { }
935 check(m.replace(18357,7346) == 7346);
936 check(m.replace(18357,5555) == 7346);
937 check(m.get(18357) == 5555);
938 check(m.replace(18357,7346) == 5555);
939 check(m.get(18357) == 7346);
940
941 check(! m.remove(18357,9999));
942 check(m.get(18357) == 7346);
943 check(m.containsKey(18357));
944 check(! m.remove(18357,null)); // 6272521
945 check(m.get(18357) == 7346);
946 check(m.remove(18357,7346));
947 check(m.get(18357) == null);
948 check(! m.containsKey(18357));
949 check(m.isEmpty());
950
951 m.putIfAbsent(1,2);
952 check(m.size() == 1);
953 check(! m.remove(1,null));
954 check(! m.remove(1,null));
955 check(! m.remove(1,1));
956 check(m.remove(1,2));
957 check(m.isEmpty());
958
959 testEmptyMap(m);
960 }
961 catch (Throwable t) { unexpected(t); }
962 }
963
964 private static void throwsConsistently(Class<? extends Throwable> k,
965 Iterable<Fun> fs) {
966 List<Class<? extends Throwable>> threw
967 = new ArrayList<Class<? extends Throwable>>();
968 for (Fun f : fs)
969 try { f.f(); threw.add(null); }
970 catch (Throwable t) {
971 check(k.isAssignableFrom(t.getClass()));
972 threw.add(t.getClass());
973 }
974 if (new HashSet<Object>(threw).size() != 1)
975 fail(threw.toString());
976 }
977
978 private static <T> void checkNPEConsistency(final Map<T,Integer> m) {
979 m.clear();
980 final ConcurrentMap<T,Integer> cm = (m instanceof ConcurrentMap)
981 ? (ConcurrentMap<T,Integer>) m
982 : null;
983 List<Fun> fs = new ArrayList<Fun>();
984 fs.add(new Fun(){void f(){ check(! m.containsKey(null));}});
985 fs.add(new Fun(){void f(){ equal(m.remove(null), null);}});
986 fs.add(new Fun(){void f(){ equal(m.get(null), null);}});
987 if (cm != null) {
988 fs.add(new Fun(){void f(){ check(! cm.remove(null,null));}});}
989 throwsConsistently(NullPointerException.class, fs);
990
991 fs.clear();
992 final Map<T,Integer> sm = singletonMap(null,1);
993 fs.add(new Fun(){void f(){ equal(m.put(null,1), null); m.clear();}});
994 fs.add(new Fun(){void f(){ m.putAll(sm); m.clear();}});
995 if (cm != null) {
996 fs.add(new Fun(){void f(){ check(! cm.remove(null,null));}});
997 fs.add(new Fun(){void f(){ equal(cm.putIfAbsent(null,1), 1);}});
998 fs.add(new Fun(){void f(){ equal(cm.replace(null,1), null);}});
999 fs.add(new Fun(){void f(){ equal(cm.replace(null,1, 1), 1);}});
1000 }
1001 throwsConsistently(NullPointerException.class, fs);
1002 }
1003
1004 //----------------------------------------------------------------
1005 // NavigableMap
1006 //----------------------------------------------------------------
1007 private static void
1008 checkNavigableMapKeys(NavigableMap<Integer,Integer> m,
1009 Integer i,
1010 Integer lower,
1011 Integer floor,
1012 Integer ceiling,
1013 Integer higher) {
1014 equal(m.lowerKey(i), lower);
1015 equal(m.floorKey(i), floor);
1016 equal(m.ceilingKey(i), ceiling);
1017 equal(m.higherKey(i), higher);
1018 }
1019
1020 private static void
1021 checkNavigableSetKeys(NavigableSet<Integer> m,
1022 Integer i,
1023 Integer lower,
1024 Integer floor,
1025 Integer ceiling,
1026 Integer higher) {
1027 equal(m.lower(i), lower);
1028 equal(m.floor(i), floor);
1029 equal(m.ceiling(i), ceiling);
1030 equal(m.higher(i), higher);
1031 }
1032
1033 static final Random rnd = new Random();
1034 static void equalNext(final Iterator<?> it, Object expected) {
1035 if (rnd.nextBoolean())
1036 check(it.hasNext());
1037 equal(it.next(), expected);
1038 }
1039
dl0ad61612009-03-24 19:42:23 -07001040 static void equalMaps(Map m1, Map m2) {
1041 equal(m1, m2);
1042 equal(m2, m1);
1043 equal(m1.size(), m2.size());
1044 equal(m1.isEmpty(), m2.isEmpty());
1045 equal(m1.toString(), m2.toString());
1046 check(Arrays.equals(m1.entrySet().toArray(), m2.entrySet().toArray()));
1047 }
1048
1049 @SuppressWarnings({"unchecked", "rawtypes"})
1050 static void testNavigableMapRemovers(NavigableMap m)
1051 {
1052 final Map emptyMap = new HashMap();
1053
1054 final Map singletonMap = new HashMap();
1055 singletonMap.put(1, 2);
1056
1057 abstract class NavigableMapView {
1058 abstract NavigableMap view(NavigableMap m);
1059 }
1060
1061 NavigableMapView[] views = {
1062 new NavigableMapView() { NavigableMap view(NavigableMap m) {
1063 return m; }},
1064 new NavigableMapView() { NavigableMap view(NavigableMap m) {
1065 return m.headMap(99, true); }},
1066 new NavigableMapView() { NavigableMap view(NavigableMap m) {
1067 return m.tailMap(-99, false); }},
1068 new NavigableMapView() { NavigableMap view(NavigableMap m) {
1069 return m.subMap(-99, true, 99, false); }},
1070 };
1071
1072 abstract class Remover {
1073 abstract void remove(NavigableMap m, Object k, Object v);
1074 }
1075
1076 Remover[] removers = {
1077 new Remover() { void remove(NavigableMap m, Object k, Object v) {
1078 equal(m.remove(k), v); }},
1079
1080 new Remover() { void remove(NavigableMap m, Object k, Object v) {
1081 equal(m.descendingMap().remove(k), v); }},
1082 new Remover() { void remove(NavigableMap m, Object k, Object v) {
1083 equal(m.descendingMap().headMap(-86, false).remove(k), v); }},
1084 new Remover() { void remove(NavigableMap m, Object k, Object v) {
1085 equal(m.descendingMap().tailMap(86, true).remove(k), v); }},
1086
1087 new Remover() { void remove(NavigableMap m, Object k, Object v) {
1088 equal(m.headMap(86, true).remove(k), v); }},
1089 new Remover() { void remove(NavigableMap m, Object k, Object v) {
1090 equal(m.tailMap(-86, true).remove(k), v); }},
1091 new Remover() { void remove(NavigableMap m, Object k, Object v) {
1092 equal(m.subMap(-86, false, 86, true).remove(k), v); }},
1093
1094 new Remover() { void remove(NavigableMap m, Object k, Object v) {
1095 check(m.keySet().remove(k)); }},
1096 new Remover() { void remove(NavigableMap m, Object k, Object v) {
1097 check(m.navigableKeySet().remove(k)); }},
1098
1099 new Remover() { void remove(NavigableMap m, Object k, Object v) {
1100 check(m.navigableKeySet().headSet(86, true).remove(k)); }},
1101 new Remover() { void remove(NavigableMap m, Object k, Object v) {
1102 check(m.navigableKeySet().tailSet(-86, false).remove(k)); }},
1103 new Remover() { void remove(NavigableMap m, Object k, Object v) {
1104 check(m.navigableKeySet().subSet(-86, true, 86, false)
1105 .remove(k)); }},
1106
1107 new Remover() { void remove(NavigableMap m, Object k, Object v) {
1108 check(m.descendingKeySet().headSet(-86, false).remove(k)); }},
1109 new Remover() { void remove(NavigableMap m, Object k, Object v) {
1110 check(m.descendingKeySet().tailSet(86, true).remove(k)); }},
1111 new Remover() { void remove(NavigableMap m, Object k, Object v) {
1112 check(m.descendingKeySet().subSet(86, true, -86, false)
1113 .remove(k)); }},
1114 };
1115
1116 for (NavigableMapView view : views) {
1117 for (Remover remover : removers) {
1118 try {
1119 m.clear();
1120 equalMaps(m, emptyMap);
1121 equal(m.put(1, 2), null);
1122 equalMaps(m, singletonMap);
1123 NavigableMap v = view.view(m);
1124 remover.remove(v, 1, 2);
1125 equalMaps(m, emptyMap);
1126 } catch (Throwable t) { unexpected(t); }
1127 }
1128 }
1129 }
1130
duke6e45e102007-12-01 00:00:00 +00001131 private static void testNavigableMap(NavigableMap<Integer,Integer> m)
1132 {
duke6e45e102007-12-01 00:00:00 +00001133 clear(m);
1134 checkNavigableMapKeys(m, 1, null, null, null, null);
1135
1136 equal(m.put(1, 2), null);
1137 equal(m.put(3, 4), null);
1138 equal(m.put(5, 9), null);
1139
1140 equal(m.put(1, 2), 2);
1141 equal(m.put(3, 4), 4);
1142 equal(m.put(5, 6), 9);
1143
1144 checkNavigableMapKeys(m, 0, null, null, 1, 1);
1145 checkNavigableMapKeys(m, 1, null, 1, 1, 3);
1146 checkNavigableMapKeys(m, 2, 1, 1, 3, 3);
1147 checkNavigableMapKeys(m, 3, 1, 3, 3, 5);
1148 checkNavigableMapKeys(m, 5, 3, 5, 5, null);
1149 checkNavigableMapKeys(m, 6, 5, 5, null, null);
1150
martineb76fa62008-05-10 11:49:25 -07001151 for (final Iterator<Integer> it :
1152 (Iterator<Integer>[])
1153 new Iterator<?>[] {
1154 m.descendingKeySet().iterator(),
1155 m.navigableKeySet().descendingIterator()}) {
duke6e45e102007-12-01 00:00:00 +00001156 equalNext(it, 5);
1157 equalNext(it, 3);
1158 equalNext(it, 1);
1159 check(! it.hasNext());
1160 THROWS(NoSuchElementException.class,
1161 new Fun(){void f(){it.next();}});
1162 }
1163
1164 {
1165 final Iterator<Map.Entry<Integer,Integer>> it
1166 = m.descendingMap().entrySet().iterator();
1167 check(it.hasNext()); equal(it.next().getKey(), 5);
1168 check(it.hasNext()); equal(it.next().getKey(), 3);
1169 check(it.hasNext()); equal(it.next().getKey(), 1);
1170 check(! it.hasNext());
1171 THROWS(NoSuchElementException.class,
1172 new Fun(){void f(){it.next();}});
1173 }
1174 }
1175
1176
1177 private static void testNavigableSet(NavigableSet<Integer> s) {
duke6e45e102007-12-01 00:00:00 +00001178 clear(s);
1179 checkNavigableSetKeys(s, 1, null, null, null, null);
1180
1181 check(s.add(1));
1182 check(s.add(3));
1183 check(s.add(5));
1184
1185 check(! s.add(1));
1186 check(! s.add(3));
1187 check(! s.add(5));
1188
1189 checkNavigableSetKeys(s, 0, null, null, 1, 1);
1190 checkNavigableSetKeys(s, 1, null, 1, 1, 3);
1191 checkNavigableSetKeys(s, 2, 1, 1, 3, 3);
1192 checkNavigableSetKeys(s, 3, 1, 3, 3, 5);
1193 checkNavigableSetKeys(s, 5, 3, 5, 5, null);
1194 checkNavigableSetKeys(s, 6, 5, 5, null, null);
1195
martineb76fa62008-05-10 11:49:25 -07001196 for (final Iterator<Integer> it :
1197 (Iterator<Integer>[])
1198 new Iterator<?>[] {
1199 s.descendingIterator(),
1200 s.descendingSet().iterator()}) {
duke6e45e102007-12-01 00:00:00 +00001201 equalNext(it, 5);
1202 equalNext(it, 3);
1203 equalNext(it, 1);
1204 check(! it.hasNext());
1205 THROWS(NoSuchElementException.class,
1206 new Fun(){void f(){it.next();}});
1207 }
1208 }
1209
1210 //--------------------- Infrastructure ---------------------------
1211 static volatile int passed = 0, failed = 0;
1212 static void pass() { passed++; }
1213 static void fail() { failed++; Thread.dumpStack(); }
1214 static void fail(String msg) { System.out.println(msg); fail(); }
1215 static void unexpected(Throwable t) { failed++; t.printStackTrace(); }
1216 static void check(boolean cond) { if (cond) pass(); else fail(); }
1217 static void equal(Object x, Object y) {
1218 if (x == null ? y == null : x.equals(y)) pass();
1219 else {System.out.println(x + " not equal to " + y); fail();}}
1220 static void equal2(Object x, Object y) {equal(x, y); equal(y, x);}
1221 public static void main(String[] args) throws Throwable {
1222 try { realMain(args); } catch (Throwable t) { unexpected(t); }
1223
1224 System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
1225 if (failed > 0) throw new Exception("Some tests failed");
1226 }
1227 private static abstract class Fun {abstract void f() throws Throwable;}
1228 private static void THROWS(Class<? extends Throwable> k, Fun... fs) {
1229 for (Fun f : fs)
1230 try { f.f(); fail("Expected " + k.getName() + " not thrown"); }
1231 catch (Throwable t) {
1232 if (k.isAssignableFrom(t.getClass())) pass();
1233 else unexpected(t);}}
1234 static byte[] serializedForm(Object obj) {
1235 try {
1236 ByteArrayOutputStream baos = new ByteArrayOutputStream();
1237 new ObjectOutputStream(baos).writeObject(obj);
1238 return baos.toByteArray();
1239 } catch (IOException e) { throw new Error(e); }}
1240 static Object readObject(byte[] bytes)
1241 throws IOException, ClassNotFoundException {
1242 InputStream is = new ByteArrayInputStream(bytes);
1243 return new ObjectInputStream(is).readObject();}
1244 @SuppressWarnings("unchecked")
1245 static <T> T serialClone(T obj) {
1246 try { return (T) readObject(serializedForm(obj)); }
1247 catch (Exception e) { throw new Error(e); }}
mduigou0d7f6cc2013-05-07 12:05:52 -07001248 private static class NewAbstractCollection<E> extends AbstractCollection<E> {
1249 ArrayList<E> list = new ArrayList<>();
1250 public boolean remove(Object obj) {
1251 return list.remove(obj);
1252 }
1253 public boolean add(E e) {
1254 return list.add(e);
1255 }
1256 public Iterator<E> iterator() {
1257 return list.iterator();
1258 }
1259 public int size() {
1260 return list.size();
1261 }
1262 }
1263 private static class NewAbstractSet<E> extends AbstractSet<E> {
1264 HashSet<E> set = new HashSet<>();
1265 public boolean remove(Object obj) {
1266 return set.remove(obj);
1267 }
1268 public boolean add(E e) {
1269 return set.add(e);
1270 }
1271 public Iterator<E> iterator() {
1272 return set.iterator();
1273 }
1274 public int size() {
1275 return set.size();
1276 }
1277 }
1278
duke6e45e102007-12-01 00:00:00 +00001279}