1 /* 2 * Copyright (C) 2008 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.common.collect.testing; 18 19 import static java.util.Collections.singleton; 20 21 import junit.framework.TestCase; 22 23 import java.util.Arrays; 24 import java.util.Collection; 25 import java.util.Collections; 26 import java.util.HashSet; 27 import java.util.Iterator; 28 import java.util.Map; 29 import java.util.Map.Entry; 30 import java.util.Set; 31 32 /** 33 * Tests representing the contract of {@link Map}. Concrete subclasses of this 34 * base class test conformance of concrete {@link Map} subclasses to that 35 * contract. 36 * 37 * TODO: Descriptive assertion messages, with hints as to probable 38 * fixes. 39 * TODO: Add another constructor parameter indicating whether the 40 * class under test is ordered, and check the order if so. 41 * TODO: Refactor to share code with SetTestBuilder &c. 42 * 43 * <p>This class is GWT compatible. 44 * 45 * @param <K> the type of keys used by the maps under test 46 * @param <V> the type of mapped values used the maps under test 47 * 48 * @author George van den Driessche 49 */ 50 public abstract class MapInterfaceTest<K, V> extends TestCase { 51 52 /** A key type that is not assignable to any classes but Object. */ 53 private static final class IncompatibleKeyType { 54 @Override public String toString() { 55 return "IncompatibleKeyType"; 56 } 57 } 58 59 protected final boolean supportsPut; 60 protected final boolean supportsRemove; 61 protected final boolean supportsClear; 62 protected final boolean allowsNullKeys; 63 protected final boolean allowsNullValues; 64 protected final boolean supportsIteratorRemove; 65 66 /** 67 * Creates a new, empty instance of the class under test. 68 * 69 * @return a new, empty map instance. 70 * @throws UnsupportedOperationException if it's not possible to make an 71 * empty instance of the class under test. 72 */ 73 protected abstract Map<K, V> makeEmptyMap() 74 throws UnsupportedOperationException; 75 76 /** 77 * Creates a new, non-empty instance of the class under test. 78 * 79 * @return a new, non-empty map instance. 80 * @throws UnsupportedOperationException if it's not possible to make a 81 * non-empty instance of the class under test. 82 */ 83 protected abstract Map<K, V> makePopulatedMap() 84 throws UnsupportedOperationException; 85 86 /** 87 * Creates a new key that is not expected to be found 88 * in {@link #makePopulatedMap()}. 89 * 90 * @return a key. 91 * @throws UnsupportedOperationException if it's not possible to make a key 92 * that will not be found in the map. 93 */ 94 protected abstract K getKeyNotInPopulatedMap() 95 throws UnsupportedOperationException; 96 97 /** 98 * Creates a new value that is not expected to be found 99 * in {@link #makePopulatedMap()}. 100 * 101 * @return a value. 102 * @throws UnsupportedOperationException if it's not possible to make a value 103 * that will not be found in the map. 104 */ 105 protected abstract V getValueNotInPopulatedMap() 106 throws UnsupportedOperationException; 107 108 /** 109 * Constructor that assigns {@code supportsIteratorRemove} the same value as 110 * {@code supportsRemove}. 111 */ 112 protected MapInterfaceTest( 113 boolean allowsNullKeys, 114 boolean allowsNullValues, 115 boolean supportsPut, 116 boolean supportsRemove, 117 boolean supportsClear) { 118 this(allowsNullKeys, allowsNullValues, supportsPut, supportsRemove, 119 supportsClear, supportsRemove); 120 } 121 122 /** 123 * Constructor with an explicit {@code supportsIteratorRemove} parameter. 124 */ 125 protected MapInterfaceTest( 126 boolean allowsNullKeys, 127 boolean allowsNullValues, 128 boolean supportsPut, 129 boolean supportsRemove, 130 boolean supportsClear, 131 boolean supportsIteratorRemove) { 132 this.supportsPut = supportsPut; 133 this.supportsRemove = supportsRemove; 134 this.supportsClear = supportsClear; 135 this.allowsNullKeys = allowsNullKeys; 136 this.allowsNullValues = allowsNullValues; 137 this.supportsIteratorRemove = supportsIteratorRemove; 138 } 139 140 /** 141 * Used by tests that require a map, but don't care whether it's 142 * populated or not. 143 * 144 * @return a new map instance. 145 */ 146 protected Map<K, V> makeEitherMap() { 147 try { 148 return makePopulatedMap(); 149 } catch (UnsupportedOperationException e) { 150 return makeEmptyMap(); 151 } 152 } 153 154 protected final boolean supportsValuesHashCode(Map<K, V> map) { 155 // get the first non-null value 156 Collection<V> values = map.values(); 157 for (V value : values) { 158 if (value != null) { 159 try { 160 value.hashCode(); 161 } catch (Exception e) { 162 return false; 163 } 164 return true; 165 } 166 } 167 return true; 168 } 169 170 /** 171 * Checks all the properties that should always hold of a map. Also calls 172 * {@link #assertMoreInvariants} to check invariants that are peculiar to 173 * specific implementations. 174 * 175 * @see #assertMoreInvariants 176 * @param map the map to check. 177 */ 178 protected final void assertInvariants(Map<K, V> map) { 179 Set<K> keySet = map.keySet(); 180 Collection<V> valueCollection = map.values(); 181 Set<Entry<K, V>> entrySet = map.entrySet(); 182 183 assertEquals(map.size() == 0, map.isEmpty()); 184 assertEquals(map.size(), keySet.size()); 185 assertEquals(keySet.size() == 0, keySet.isEmpty()); 186 assertEquals(!keySet.isEmpty(), keySet.iterator().hasNext()); 187 188 int expectedKeySetHash = 0; 189 for (K key : keySet) { 190 V value = map.get(key); 191 expectedKeySetHash += key != null ? key.hashCode() : 0; 192 assertTrue(map.containsKey(key)); 193 assertTrue(map.containsValue(value)); 194 assertTrue(valueCollection.contains(value)); 195 assertTrue(valueCollection.containsAll(Collections.singleton(value))); 196 assertTrue(entrySet.contains(mapEntry(key, value))); 197 assertTrue(allowsNullKeys || (key != null)); 198 } 199 assertEquals(expectedKeySetHash, keySet.hashCode()); 200 201 assertEquals(map.size(), valueCollection.size()); 202 assertEquals(valueCollection.size() == 0, valueCollection.isEmpty()); 203 assertEquals( 204 !valueCollection.isEmpty(), valueCollection.iterator().hasNext()); 205 for (V value : valueCollection) { 206 assertTrue(map.containsValue(value)); 207 assertTrue(allowsNullValues || (value != null)); 208 } 209 210 assertEquals(map.size(), entrySet.size()); 211 assertEquals(entrySet.size() == 0, entrySet.isEmpty()); 212 assertEquals(!entrySet.isEmpty(), entrySet.iterator().hasNext()); 213 assertFalse(entrySet.contains("foo")); 214 215 boolean supportsValuesHashCode = supportsValuesHashCode(map); 216 if (supportsValuesHashCode) { 217 int expectedEntrySetHash = 0; 218 for (Entry<K, V> entry : entrySet) { 219 assertTrue(map.containsKey(entry.getKey())); 220 assertTrue(map.containsValue(entry.getValue())); 221 int expectedHash = 222 (entry.getKey() == null ? 0 : entry.getKey().hashCode()) ^ 223 (entry.getValue() == null ? 0 : entry.getValue().hashCode()); 224 assertEquals(expectedHash, entry.hashCode()); 225 expectedEntrySetHash += expectedHash; 226 } 227 assertEquals(expectedEntrySetHash, entrySet.hashCode()); 228 assertTrue(entrySet.containsAll(new HashSet<Entry<K, V>>(entrySet))); 229 assertTrue(entrySet.equals(new HashSet<Entry<K, V>>(entrySet))); 230 } 231 232 Object[] entrySetToArray1 = entrySet.toArray(); 233 assertEquals(map.size(), entrySetToArray1.length); 234 assertTrue(Arrays.asList(entrySetToArray1).containsAll(entrySet)); 235 236 Entry<?, ?>[] entrySetToArray2 = new Entry<?, ?>[map.size() + 2]; 237 entrySetToArray2[map.size()] = mapEntry("foo", 1); 238 assertSame(entrySetToArray2, entrySet.toArray(entrySetToArray2)); 239 assertNull(entrySetToArray2[map.size()]); 240 assertTrue(Arrays.asList(entrySetToArray2).containsAll(entrySet)); 241 242 Object[] valuesToArray1 = valueCollection.toArray(); 243 assertEquals(map.size(), valuesToArray1.length); 244 assertTrue(Arrays.asList(valuesToArray1).containsAll(valueCollection)); 245 246 Object[] valuesToArray2 = new Object[map.size() + 2]; 247 valuesToArray2[map.size()] = "foo"; 248 assertSame(valuesToArray2, valueCollection.toArray(valuesToArray2)); 249 assertNull(valuesToArray2[map.size()]); 250 assertTrue(Arrays.asList(valuesToArray2).containsAll(valueCollection)); 251 252 if (supportsValuesHashCode) { 253 int expectedHash = 0; 254 for (Entry<K, V> entry : entrySet) { 255 expectedHash += entry.hashCode(); 256 } 257 assertEquals(expectedHash, map.hashCode()); 258 } 259 260 assertMoreInvariants(map); 261 } 262 263 /** 264 * Override this to check invariants which should hold true for a particular 265 * implementation, but which are not generally applicable to every instance 266 * of Map. 267 * 268 * @param map the map whose additional invariants to check. 269 */ 270 protected void assertMoreInvariants(Map<K, V> map) { 271 } 272 273 public void testClear() { 274 final Map<K, V> map; 275 try { 276 map = makePopulatedMap(); 277 } catch (UnsupportedOperationException e) { 278 return; 279 } 280 281 if (supportsClear) { 282 map.clear(); 283 assertTrue(map.isEmpty()); 284 } else { 285 try { 286 map.clear(); 287 fail("Expected UnsupportedOperationException."); 288 } catch (UnsupportedOperationException e) { 289 // Expected. 290 } 291 } 292 assertInvariants(map); 293 } 294 295 public void testContainsKey() { 296 final Map<K, V> map; 297 final K unmappedKey; 298 try { 299 map = makePopulatedMap(); 300 unmappedKey = getKeyNotInPopulatedMap(); 301 } catch (UnsupportedOperationException e) { 302 return; 303 } 304 assertFalse(map.containsKey(unmappedKey)); 305 try { 306 assertFalse(map.containsKey(new IncompatibleKeyType())); 307 } catch (ClassCastException tolerated) {} 308 assertTrue(map.containsKey(map.keySet().iterator().next())); 309 if (allowsNullKeys) { 310 map.containsKey(null); 311 } else { 312 try { 313 map.containsKey(null); 314 } catch (NullPointerException optional) { 315 } 316 } 317 assertInvariants(map); 318 } 319 320 public void testContainsValue() { 321 final Map<K, V> map; 322 final V unmappedValue; 323 try { 324 map = makePopulatedMap(); 325 unmappedValue = getValueNotInPopulatedMap(); 326 } catch (UnsupportedOperationException e) { 327 return; 328 } 329 assertFalse(map.containsValue(unmappedValue)); 330 assertTrue(map.containsValue(map.values().iterator().next())); 331 if (allowsNullValues) { 332 map.containsValue(null); 333 } else { 334 try { 335 map.containsKey(null); 336 } catch (NullPointerException optional) { 337 } 338 } 339 assertInvariants(map); 340 } 341 342 public void testEntrySet() { 343 final Map<K, V> map; 344 final Set<Entry<K, V>> entrySet; 345 try { 346 map = makePopulatedMap(); 347 } catch (UnsupportedOperationException e) { 348 return; 349 } 350 assertInvariants(map); 351 352 entrySet = map.entrySet(); 353 final K unmappedKey; 354 final V unmappedValue; 355 try { 356 unmappedKey = getKeyNotInPopulatedMap(); 357 unmappedValue = getValueNotInPopulatedMap(); 358 } catch (UnsupportedOperationException e) { 359 return; 360 } 361 for (Entry<K, V> entry : entrySet) { 362 assertFalse(unmappedKey.equals(entry.getKey())); 363 assertFalse(unmappedValue.equals(entry.getValue())); 364 } 365 } 366 367 public void testEntrySetForEmptyMap() { 368 final Map<K, V> map; 369 try { 370 map = makeEmptyMap(); 371 } catch (UnsupportedOperationException e) { 372 return; 373 } 374 assertInvariants(map); 375 } 376 377 public void testEntrySetContainsEntryIncompatibleKey() { 378 final Map<K, V> map; 379 final Set<Entry<K, V>> entrySet; 380 try { 381 map = makeEitherMap(); 382 } catch (UnsupportedOperationException e) { 383 return; 384 } 385 assertInvariants(map); 386 387 entrySet = map.entrySet(); 388 final V unmappedValue; 389 try { 390 unmappedValue = getValueNotInPopulatedMap(); 391 } catch (UnsupportedOperationException e) { 392 return; 393 } 394 Entry<IncompatibleKeyType, V> entry 395 = mapEntry(new IncompatibleKeyType(), unmappedValue); 396 try { 397 assertFalse(entrySet.contains(entry)); 398 } catch (ClassCastException tolerated) {} 399 } 400 401 public void testEntrySetContainsEntryNullKeyPresent() { 402 if (!allowsNullKeys || !supportsPut) { 403 return; 404 } 405 final Map<K, V> map; 406 final Set<Entry<K, V>> entrySet; 407 try { 408 map = makeEitherMap(); 409 } catch (UnsupportedOperationException e) { 410 return; 411 } 412 assertInvariants(map); 413 414 entrySet = map.entrySet(); 415 final V unmappedValue; 416 try { 417 unmappedValue = getValueNotInPopulatedMap(); 418 } catch (UnsupportedOperationException e) { 419 return; 420 } 421 422 map.put(null, unmappedValue); 423 Entry<K, V> entry = mapEntry(null, unmappedValue); 424 assertTrue(entrySet.contains(entry)); 425 assertFalse(entrySet.contains(mapEntry(null, null))); 426 } 427 428 public void testEntrySetContainsEntryNullKeyMissing() { 429 final Map<K, V> map; 430 final Set<Entry<K, V>> entrySet; 431 try { 432 map = makeEitherMap(); 433 } catch (UnsupportedOperationException e) { 434 return; 435 } 436 assertInvariants(map); 437 438 entrySet = map.entrySet(); 439 final V unmappedValue; 440 try { 441 unmappedValue = getValueNotInPopulatedMap(); 442 } catch (UnsupportedOperationException e) { 443 return; 444 } 445 Entry<K, V> entry = mapEntry(null, unmappedValue); 446 try { 447 assertFalse(entrySet.contains(entry)); 448 } catch (NullPointerException e) { 449 assertFalse(allowsNullKeys); 450 } 451 try { 452 assertFalse(entrySet.contains(mapEntry(null, null))); 453 } catch (NullPointerException e) { 454 assertFalse(allowsNullKeys && allowsNullValues); 455 } 456 } 457 458 public void testEntrySetIteratorRemove() { 459 final Map<K, V> map; 460 try { 461 map = makePopulatedMap(); 462 } catch (UnsupportedOperationException e) { 463 return; 464 } 465 466 Set<Entry<K, V>> entrySet = map.entrySet(); 467 Iterator<Entry<K, V>> iterator = entrySet.iterator(); 468 if (supportsIteratorRemove) { 469 int initialSize = map.size(); 470 Entry<K, V> entry = iterator.next(); 471 Entry<K, V> entryCopy = Helpers.mapEntry( 472 entry.getKey(), entry.getValue()); 473 474 iterator.remove(); 475 assertEquals(initialSize - 1, map.size()); 476 477 // Use "entryCopy" instead of "entry" because "entry" might be invalidated after 478 // iterator.remove(). 479 assertFalse(entrySet.contains(entryCopy)); 480 assertInvariants(map); 481 try { 482 iterator.remove(); 483 fail("Expected IllegalStateException."); 484 } catch (IllegalStateException e) { 485 // Expected. 486 } 487 } else { 488 try { 489 iterator.next(); 490 iterator.remove(); 491 fail("Expected UnsupportedOperationException."); 492 } catch (UnsupportedOperationException e) { 493 // Expected. 494 } 495 } 496 assertInvariants(map); 497 } 498 499 public void testEntrySetRemove() { 500 final Map<K, V> map; 501 try { 502 map = makePopulatedMap(); 503 } catch (UnsupportedOperationException e) { 504 return; 505 } 506 507 Set<Entry<K, V>> entrySet = map.entrySet(); 508 if (supportsRemove) { 509 int initialSize = map.size(); 510 boolean didRemove = entrySet.remove(entrySet.iterator().next()); 511 assertTrue(didRemove); 512 assertEquals(initialSize - 1, map.size()); 513 } else { 514 try { 515 entrySet.remove(entrySet.iterator().next()); 516 fail("Expected UnsupportedOperationException."); 517 } catch (UnsupportedOperationException e) { 518 // Expected. 519 } 520 } 521 assertInvariants(map); 522 } 523 524 public void testEntrySetRemoveMissingKey() { 525 final Map<K, V> map; 526 final K key; 527 try { 528 map = makeEitherMap(); 529 key = getKeyNotInPopulatedMap(); 530 } catch (UnsupportedOperationException e) { 531 return; 532 } 533 534 Set<Entry<K, V>> entrySet = map.entrySet(); 535 Entry<K, V> entry 536 = mapEntry(key, getValueNotInPopulatedMap()); 537 int initialSize = map.size(); 538 if (supportsRemove) { 539 boolean didRemove = entrySet.remove(entry); 540 assertFalse(didRemove); 541 } else { 542 try { 543 boolean didRemove = entrySet.remove(entry); 544 assertFalse(didRemove); 545 } catch (UnsupportedOperationException optional) {} 546 } 547 assertEquals(initialSize, map.size()); 548 assertFalse(map.containsKey(key)); 549 assertInvariants(map); 550 } 551 552 public void testEntrySetRemoveDifferentValue() { 553 final Map<K, V> map; 554 try { 555 map = makePopulatedMap(); 556 } catch (UnsupportedOperationException e) { 557 return; 558 } 559 560 Set<Entry<K, V>> entrySet = map.entrySet(); 561 K key = map.keySet().iterator().next(); 562 Entry<K, V> entry 563 = mapEntry(key, getValueNotInPopulatedMap()); 564 int initialSize = map.size(); 565 if (supportsRemove) { 566 boolean didRemove = entrySet.remove(entry); 567 assertFalse(didRemove); 568 } else { 569 try { 570 boolean didRemove = entrySet.remove(entry); 571 assertFalse(didRemove); 572 } catch (UnsupportedOperationException optional) {} 573 } 574 assertEquals(initialSize, map.size()); 575 assertTrue(map.containsKey(key)); 576 assertInvariants(map); 577 } 578 579 public void testEntrySetRemoveNullKeyPresent() { 580 if (!allowsNullKeys || !supportsPut || !supportsRemove) { 581 return; 582 } 583 final Map<K, V> map; 584 final Set<Entry<K, V>> entrySet; 585 try { 586 map = makeEitherMap(); 587 } catch (UnsupportedOperationException e) { 588 return; 589 } 590 assertInvariants(map); 591 592 entrySet = map.entrySet(); 593 final V unmappedValue; 594 try { 595 unmappedValue = getValueNotInPopulatedMap(); 596 } catch (UnsupportedOperationException e) { 597 return; 598 } 599 600 map.put(null, unmappedValue); 601 assertEquals(unmappedValue, map.get(null)); 602 assertTrue(map.containsKey(null)); 603 Entry<K, V> entry = mapEntry(null, unmappedValue); 604 assertTrue(entrySet.remove(entry)); 605 assertNull(map.get(null)); 606 assertFalse(map.containsKey(null)); 607 } 608 609 public void testEntrySetRemoveNullKeyMissing() { 610 final Map<K, V> map; 611 try { 612 map = makeEitherMap(); 613 } catch (UnsupportedOperationException e) { 614 return; 615 } 616 617 Set<Entry<K, V>> entrySet = map.entrySet(); 618 Entry<K, V> entry 619 = mapEntry(null, getValueNotInPopulatedMap()); 620 int initialSize = map.size(); 621 if (supportsRemove) { 622 try { 623 boolean didRemove = entrySet.remove(entry); 624 assertFalse(didRemove); 625 } catch (NullPointerException e) { 626 assertFalse(allowsNullKeys); 627 } 628 } else { 629 try { 630 boolean didRemove = entrySet.remove(entry); 631 assertFalse(didRemove); 632 } catch (UnsupportedOperationException optional) {} 633 } 634 assertEquals(initialSize, map.size()); 635 assertInvariants(map); 636 } 637 638 public void testEntrySetRemoveAll() { 639 final Map<K, V> map; 640 try { 641 map = makePopulatedMap(); 642 } catch (UnsupportedOperationException e) { 643 return; 644 } 645 646 Set<Entry<K, V>> entrySet = map.entrySet(); 647 648 Entry<K, V> entryToRemove = entrySet.iterator().next(); 649 Set<Entry<K, V>> entriesToRemove = singleton(entryToRemove); 650 if (supportsRemove) { 651 // We use a copy of "entryToRemove" in the assertion because "entryToRemove" might be 652 // invalidated and have undefined behavior after entrySet.removeAll(entriesToRemove), 653 // for example entryToRemove.getValue() might be null. 654 Entry<K, V> entryToRemoveCopy = Helpers.mapEntry( 655 entryToRemove.getKey(), entryToRemove.getValue()); 656 657 int initialSize = map.size(); 658 boolean didRemove = entrySet.removeAll(entriesToRemove); 659 assertTrue(didRemove); 660 assertEquals(initialSize - entriesToRemove.size(), map.size()); 661 662 // Use "entryToRemoveCopy" instead of "entryToRemove" because it might be invalidated and 663 // have undefined behavior after entrySet.removeAll(entriesToRemove), 664 assertFalse(entrySet.contains(entryToRemoveCopy)); 665 } else { 666 try { 667 entrySet.removeAll(entriesToRemove); 668 fail("Expected UnsupportedOperationException."); 669 } catch (UnsupportedOperationException e) { 670 // Expected. 671 } 672 } 673 assertInvariants(map); 674 } 675 676 public void testEntrySetRemoveAllNullFromEmpty() { 677 final Map<K, V> map; 678 try { 679 map = makeEmptyMap(); 680 } catch (UnsupportedOperationException e) { 681 return; 682 } 683 684 Set<Entry<K, V>> entrySet = map.entrySet(); 685 if (supportsRemove) { 686 try { 687 entrySet.removeAll(null); 688 fail("Expected NullPointerException."); 689 } catch (NullPointerException e) { 690 // Expected. 691 } 692 } else { 693 try { 694 entrySet.removeAll(null); 695 fail("Expected UnsupportedOperationException or NullPointerException."); 696 } catch (UnsupportedOperationException e) { 697 // Expected. 698 } catch (NullPointerException e) { 699 // Expected. 700 } 701 } 702 assertInvariants(map); 703 } 704 705 public void testEntrySetRetainAll() { 706 final Map<K, V> map; 707 try { 708 map = makePopulatedMap(); 709 } catch (UnsupportedOperationException e) { 710 return; 711 } 712 713 Set<Entry<K, V>> entrySet = map.entrySet(); 714 Set<Entry<K, V>> entriesToRetain = 715 singleton(entrySet.iterator().next()); 716 if (supportsRemove) { 717 boolean shouldRemove = (entrySet.size() > entriesToRetain.size()); 718 boolean didRemove = entrySet.retainAll(entriesToRetain); 719 assertEquals(shouldRemove, didRemove); 720 assertEquals(entriesToRetain.size(), map.size()); 721 for (Entry<K, V> entry : entriesToRetain) { 722 assertTrue(entrySet.contains(entry)); 723 } 724 } else { 725 try { 726 entrySet.retainAll(entriesToRetain); 727 fail("Expected UnsupportedOperationException."); 728 } catch (UnsupportedOperationException e) { 729 // Expected. 730 } 731 } 732 assertInvariants(map); 733 } 734 735 public void testEntrySetRetainAllNullFromEmpty() { 736 final Map<K, V> map; 737 try { 738 map = makeEmptyMap(); 739 } catch (UnsupportedOperationException e) { 740 return; 741 } 742 743 Set<Entry<K, V>> entrySet = map.entrySet(); 744 if (supportsRemove) { 745 try { 746 entrySet.retainAll(null); 747 // Returning successfully is not ideal, but tolerated. 748 } catch (NullPointerException e) { 749 // Expected. 750 } 751 } else { 752 try { 753 entrySet.retainAll(null); 754 // We have to tolerate a successful return (Sun bug 4802647) 755 } catch (UnsupportedOperationException e) { 756 // Expected. 757 } catch (NullPointerException e) { 758 // Expected. 759 } 760 } 761 assertInvariants(map); 762 } 763 764 public void testEntrySetClear() { 765 final Map<K, V> map; 766 try { 767 map = makePopulatedMap(); 768 } catch (UnsupportedOperationException e) { 769 return; 770 } 771 772 Set<Entry<K, V>> entrySet = map.entrySet(); 773 if (supportsClear) { 774 entrySet.clear(); 775 assertTrue(entrySet.isEmpty()); 776 } else { 777 try { 778 entrySet.clear(); 779 fail("Expected UnsupportedOperationException."); 780 } catch (UnsupportedOperationException e) { 781 // Expected. 782 } 783 } 784 assertInvariants(map); 785 } 786 787 public void testEntrySetAddAndAddAll() { 788 final Map<K, V> map = makeEitherMap(); 789 790 Set<Entry<K, V>> entrySet = map.entrySet(); 791 final Entry<K, V> entryToAdd = mapEntry(null, null); 792 try { 793 entrySet.add(entryToAdd); 794 fail("Expected UnsupportedOperationException or NullPointerException."); 795 } catch (UnsupportedOperationException e) { 796 // Expected. 797 } catch (NullPointerException e) { 798 // Expected. 799 } 800 assertInvariants(map); 801 802 try { 803 entrySet.addAll(singleton(entryToAdd)); 804 fail("Expected UnsupportedOperationException or NullPointerException."); 805 } catch (UnsupportedOperationException e) { 806 // Expected. 807 } catch (NullPointerException e) { 808 // Expected. 809 } 810 assertInvariants(map); 811 } 812 813 public void testEntrySetSetValue() { 814 // TODO: Investigate the extent to which, in practice, maps that support 815 // put() also support Entry.setValue(). 816 if (!supportsPut) { 817 return; 818 } 819 820 final Map<K, V> map; 821 final V valueToSet; 822 try { 823 map = makePopulatedMap(); 824 valueToSet = getValueNotInPopulatedMap(); 825 } catch (UnsupportedOperationException e) { 826 return; 827 } 828 829 Set<Entry<K, V>> entrySet = map.entrySet(); 830 Entry<K, V> entry = entrySet.iterator().next(); 831 final V oldValue = entry.getValue(); 832 final V returnedValue = entry.setValue(valueToSet); 833 assertEquals(oldValue, returnedValue); 834 assertTrue(entrySet.contains( 835 mapEntry(entry.getKey(), valueToSet))); 836 assertEquals(valueToSet, map.get(entry.getKey())); 837 assertInvariants(map); 838 } 839 840 public void testEntrySetSetValueSameValue() { 841 // TODO: Investigate the extent to which, in practice, maps that support 842 // put() also support Entry.setValue(). 843 if (!supportsPut) { 844 return; 845 } 846 847 final Map<K, V> map; 848 try { 849 map = makePopulatedMap(); 850 } catch (UnsupportedOperationException e) { 851 return; 852 } 853 854 Set<Entry<K, V>> entrySet = map.entrySet(); 855 Entry<K, V> entry = entrySet.iterator().next(); 856 final V oldValue = entry.getValue(); 857 final V returnedValue = entry.setValue(oldValue); 858 assertEquals(oldValue, returnedValue); 859 assertTrue(entrySet.contains( 860 mapEntry(entry.getKey(), oldValue))); 861 assertEquals(oldValue, map.get(entry.getKey())); 862 assertInvariants(map); 863 } 864 865 public void testEqualsForEqualMap() { 866 final Map<K, V> map; 867 try { 868 map = makePopulatedMap(); 869 } catch (UnsupportedOperationException e) { 870 return; 871 } 872 873 assertEquals(map, map); 874 assertEquals(makePopulatedMap(), map); 875 assertFalse(map.equals(Collections.emptyMap())); 876 //no-inspection ObjectEqualsNull 877 assertFalse(map.equals(null)); 878 } 879 880 public void testEqualsForLargerMap() { 881 if (!supportsPut) { 882 return; 883 } 884 885 final Map<K, V> map; 886 final Map<K, V> largerMap; 887 try { 888 map = makePopulatedMap(); 889 largerMap = makePopulatedMap(); 890 largerMap.put(getKeyNotInPopulatedMap(), getValueNotInPopulatedMap()); 891 } catch (UnsupportedOperationException e) { 892 return; 893 } 894 895 assertFalse(map.equals(largerMap)); 896 } 897 898 public void testEqualsForSmallerMap() { 899 if (!supportsRemove) { 900 return; 901 } 902 903 final Map<K, V> map; 904 final Map<K, V> smallerMap; 905 try { 906 map = makePopulatedMap(); 907 smallerMap = makePopulatedMap(); 908 smallerMap.remove(smallerMap.keySet().iterator().next()); 909 } catch (UnsupportedOperationException e) { 910 return; 911 } 912 913 assertFalse(map.equals(smallerMap)); 914 } 915 916 public void testEqualsForEmptyMap() { 917 final Map<K, V> map; 918 try { 919 map = makeEmptyMap(); 920 } catch (UnsupportedOperationException e) { 921 return; 922 } 923 924 assertEquals(map, map); 925 assertEquals(makeEmptyMap(), map); 926 assertEquals(Collections.emptyMap(), map); 927 assertFalse(map.equals(Collections.emptySet())); 928 //noinspection ObjectEqualsNull 929 assertFalse(map.equals(null)); 930 } 931 932 public void testGet() { 933 final Map<K, V> map; 934 try { 935 map = makePopulatedMap(); 936 } catch (UnsupportedOperationException e) { 937 return; 938 } 939 940 for (Entry<K, V> entry : map.entrySet()) { 941 assertEquals(entry.getValue(), map.get(entry.getKey())); 942 } 943 944 K unmappedKey = null; 945 try { 946 unmappedKey = getKeyNotInPopulatedMap(); 947 } catch (UnsupportedOperationException e) { 948 return; 949 } 950 assertNull(map.get(unmappedKey)); 951 } 952 953 public void testGetForEmptyMap() { 954 final Map<K, V> map; 955 K unmappedKey = null; 956 try { 957 map = makeEmptyMap(); 958 unmappedKey = getKeyNotInPopulatedMap(); 959 } catch (UnsupportedOperationException e) { 960 return; 961 } 962 assertNull(map.get(unmappedKey)); 963 } 964 965 public void testGetNull() { 966 Map<K, V> map = makeEitherMap(); 967 if (allowsNullKeys) { 968 if (allowsNullValues) { 969 // TODO: decide what to test here. 970 } else { 971 assertEquals(map.containsKey(null), map.get(null) != null); 972 } 973 } else { 974 try { 975 map.get(null); 976 } catch (NullPointerException optional) { 977 } 978 } 979 assertInvariants(map); 980 } 981 982 public void testHashCode() { 983 final Map<K, V> map; 984 try { 985 map = makePopulatedMap(); 986 } catch (UnsupportedOperationException e) { 987 return; 988 } 989 assertInvariants(map); 990 } 991 992 public void testHashCodeForEmptyMap() { 993 final Map<K, V> map; 994 try { 995 map = makeEmptyMap(); 996 } catch (UnsupportedOperationException e) { 997 return; 998 } 999 assertInvariants(map); 1000 } 1001 1002 public void testPutNewKey() { 1003 final Map<K, V> map = makeEitherMap(); 1004 final K keyToPut; 1005 final V valueToPut; 1006 try { 1007 keyToPut = getKeyNotInPopulatedMap(); 1008 valueToPut = getValueNotInPopulatedMap(); 1009 } catch (UnsupportedOperationException e) { 1010 return; 1011 } 1012 if (supportsPut) { 1013 int initialSize = map.size(); 1014 V oldValue = map.put(keyToPut, valueToPut); 1015 assertEquals(valueToPut, map.get(keyToPut)); 1016 assertTrue(map.containsKey(keyToPut)); 1017 assertTrue(map.containsValue(valueToPut)); 1018 assertEquals(initialSize + 1, map.size()); 1019 assertNull(oldValue); 1020 } else { 1021 try { 1022 map.put(keyToPut, valueToPut); 1023 fail("Expected UnsupportedOperationException."); 1024 } catch (UnsupportedOperationException e) { 1025 // Expected. 1026 } 1027 } 1028 assertInvariants(map); 1029 } 1030 1031 public void testPutExistingKey() { 1032 final Map<K, V> map; 1033 final K keyToPut; 1034 final V valueToPut; 1035 try { 1036 map = makePopulatedMap(); 1037 valueToPut = getValueNotInPopulatedMap(); 1038 } catch (UnsupportedOperationException e) { 1039 return; 1040 } 1041 keyToPut = map.keySet().iterator().next(); 1042 if (supportsPut) { 1043 int initialSize = map.size(); 1044 map.put(keyToPut, valueToPut); 1045 assertEquals(valueToPut, map.get(keyToPut)); 1046 assertTrue(map.containsKey(keyToPut)); 1047 assertTrue(map.containsValue(valueToPut)); 1048 assertEquals(initialSize, map.size()); 1049 } else { 1050 try { 1051 map.put(keyToPut, valueToPut); 1052 fail("Expected UnsupportedOperationException."); 1053 } catch (UnsupportedOperationException e) { 1054 // Expected. 1055 } 1056 } 1057 assertInvariants(map); 1058 } 1059 1060 public void testPutNullKey() { 1061 if (!supportsPut) { 1062 return; 1063 } 1064 final Map<K, V> map = makeEitherMap(); 1065 final V valueToPut; 1066 try { 1067 valueToPut = getValueNotInPopulatedMap(); 1068 } catch (UnsupportedOperationException e) { 1069 return; 1070 } 1071 if (allowsNullKeys) { 1072 final V oldValue = map.get(null); 1073 final V returnedValue = map.put(null, valueToPut); 1074 assertEquals(oldValue, returnedValue); 1075 assertEquals(valueToPut, map.get(null)); 1076 assertTrue(map.containsKey(null)); 1077 assertTrue(map.containsValue(valueToPut)); 1078 } else { 1079 try { 1080 map.put(null, valueToPut); 1081 fail("Expected RuntimeException"); 1082 } catch (RuntimeException e) { 1083 // Expected. 1084 } 1085 } 1086 assertInvariants(map); 1087 } 1088 1089 public void testPutNullValue() { 1090 if (!supportsPut) { 1091 return; 1092 } 1093 final Map<K, V> map = makeEitherMap(); 1094 final K keyToPut; 1095 try { 1096 keyToPut = getKeyNotInPopulatedMap(); 1097 } catch (UnsupportedOperationException e) { 1098 return; 1099 } 1100 if (allowsNullValues) { 1101 int initialSize = map.size(); 1102 final V oldValue = map.get(keyToPut); 1103 final V returnedValue = map.put(keyToPut, null); 1104 assertEquals(oldValue, returnedValue); 1105 assertNull(map.get(keyToPut)); 1106 assertTrue(map.containsKey(keyToPut)); 1107 assertTrue(map.containsValue(null)); 1108 assertEquals(initialSize + 1, map.size()); 1109 } else { 1110 try { 1111 map.put(keyToPut, null); 1112 fail("Expected RuntimeException"); 1113 } catch (RuntimeException e) { 1114 // Expected. 1115 } 1116 } 1117 assertInvariants(map); 1118 } 1119 1120 public void testPutNullValueForExistingKey() { 1121 if (!supportsPut) { 1122 return; 1123 } 1124 final Map<K, V> map; 1125 final K keyToPut; 1126 try { 1127 map = makePopulatedMap(); 1128 keyToPut = map.keySet().iterator().next(); 1129 } catch (UnsupportedOperationException e) { 1130 return; 1131 } 1132 if (allowsNullValues) { 1133 int initialSize = map.size(); 1134 final V oldValue = map.get(keyToPut); 1135 final V returnedValue = map.put(keyToPut, null); 1136 assertEquals(oldValue, returnedValue); 1137 assertNull(map.get(keyToPut)); 1138 assertTrue(map.containsKey(keyToPut)); 1139 assertTrue(map.containsValue(null)); 1140 assertEquals(initialSize, map.size()); 1141 } else { 1142 try { 1143 map.put(keyToPut, null); 1144 fail("Expected RuntimeException"); 1145 } catch (RuntimeException e) { 1146 // Expected. 1147 } 1148 } 1149 assertInvariants(map); 1150 } 1151 1152 public void testPutAllNewKey() { 1153 final Map<K, V> map = makeEitherMap(); 1154 final K keyToPut; 1155 final V valueToPut; 1156 try { 1157 keyToPut = getKeyNotInPopulatedMap(); 1158 valueToPut = getValueNotInPopulatedMap(); 1159 } catch (UnsupportedOperationException e) { 1160 return; 1161 } 1162 final Map<K, V> mapToPut = Collections.singletonMap(keyToPut, valueToPut); 1163 if (supportsPut) { 1164 int initialSize = map.size(); 1165 map.putAll(mapToPut); 1166 assertEquals(valueToPut, map.get(keyToPut)); 1167 assertTrue(map.containsKey(keyToPut)); 1168 assertTrue(map.containsValue(valueToPut)); 1169 assertEquals(initialSize + 1, map.size()); 1170 } else { 1171 try { 1172 map.putAll(mapToPut); 1173 fail("Expected UnsupportedOperationException."); 1174 } catch (UnsupportedOperationException e) { 1175 // Expected. 1176 } 1177 } 1178 assertInvariants(map); 1179 } 1180 1181 public void testPutAllExistingKey() { 1182 final Map<K, V> map; 1183 final K keyToPut; 1184 final V valueToPut; 1185 try { 1186 map = makePopulatedMap(); 1187 valueToPut = getValueNotInPopulatedMap(); 1188 } catch (UnsupportedOperationException e) { 1189 return; 1190 } 1191 keyToPut = map.keySet().iterator().next(); 1192 final Map<K, V> mapToPut = Collections.singletonMap(keyToPut, valueToPut); 1193 int initialSize = map.size(); 1194 if (supportsPut) { 1195 map.putAll(mapToPut); 1196 assertEquals(valueToPut, map.get(keyToPut)); 1197 assertTrue(map.containsKey(keyToPut)); 1198 assertTrue(map.containsValue(valueToPut)); 1199 } else { 1200 try { 1201 map.putAll(mapToPut); 1202 fail("Expected UnsupportedOperationException."); 1203 } catch (UnsupportedOperationException e) { 1204 // Expected. 1205 } 1206 } 1207 assertEquals(initialSize, map.size()); 1208 assertInvariants(map); 1209 } 1210 1211 public void testRemove() { 1212 final Map<K, V> map; 1213 final K keyToRemove; 1214 try { 1215 map = makePopulatedMap(); 1216 } catch (UnsupportedOperationException e) { 1217 return; 1218 } 1219 keyToRemove = map.keySet().iterator().next(); 1220 if (supportsRemove) { 1221 int initialSize = map.size(); 1222 V expectedValue = map.get(keyToRemove); 1223 V oldValue = map.remove(keyToRemove); 1224 assertEquals(expectedValue, oldValue); 1225 assertFalse(map.containsKey(keyToRemove)); 1226 assertEquals(initialSize - 1, map.size()); 1227 } else { 1228 try { 1229 map.remove(keyToRemove); 1230 fail("Expected UnsupportedOperationException."); 1231 } catch (UnsupportedOperationException e) { 1232 // Expected. 1233 } 1234 } 1235 assertInvariants(map); 1236 } 1237 1238 public void testRemoveMissingKey() { 1239 final Map<K, V> map; 1240 final K keyToRemove; 1241 try { 1242 map = makePopulatedMap(); 1243 keyToRemove = getKeyNotInPopulatedMap(); 1244 } catch (UnsupportedOperationException e) { 1245 return; 1246 } 1247 if (supportsRemove) { 1248 int initialSize = map.size(); 1249 assertNull(map.remove(keyToRemove)); 1250 assertEquals(initialSize, map.size()); 1251 } else { 1252 try { 1253 map.remove(keyToRemove); 1254 fail("Expected UnsupportedOperationException."); 1255 } catch (UnsupportedOperationException e) { 1256 // Expected. 1257 } 1258 } 1259 assertInvariants(map); 1260 } 1261 1262 public void testSize() { 1263 assertInvariants(makeEitherMap()); 1264 } 1265 1266 public void testKeySetRemove() { 1267 final Map<K, V> map; 1268 try { 1269 map = makePopulatedMap(); 1270 } catch (UnsupportedOperationException e) { 1271 return; 1272 } 1273 1274 Set<K> keys = map.keySet(); 1275 K key = keys.iterator().next(); 1276 if (supportsRemove) { 1277 int initialSize = map.size(); 1278 keys.remove(key); 1279 assertEquals(initialSize - 1, map.size()); 1280 assertFalse(map.containsKey(key)); 1281 } else { 1282 try { 1283 keys.remove(key); 1284 fail("Expected UnsupportedOperationException."); 1285 } catch (UnsupportedOperationException e) { 1286 // Expected. 1287 } 1288 } 1289 assertInvariants(map); 1290 } 1291 1292 public void testKeySetRemoveAll() { 1293 final Map<K, V> map; 1294 try { 1295 map = makePopulatedMap(); 1296 } catch (UnsupportedOperationException e) { 1297 return; 1298 } 1299 1300 Set<K> keys = map.keySet(); 1301 K key = keys.iterator().next(); 1302 if (supportsRemove) { 1303 int initialSize = map.size(); 1304 assertTrue(keys.removeAll(Collections.singleton(key))); 1305 assertEquals(initialSize - 1, map.size()); 1306 assertFalse(map.containsKey(key)); 1307 } else { 1308 try { 1309 keys.removeAll(Collections.singleton(key)); 1310 fail("Expected UnsupportedOperationException."); 1311 } catch (UnsupportedOperationException e) { 1312 // Expected. 1313 } 1314 } 1315 assertInvariants(map); 1316 } 1317 1318 public void testKeySetRetainAll() { 1319 final Map<K, V> map; 1320 try { 1321 map = makePopulatedMap(); 1322 } catch (UnsupportedOperationException e) { 1323 return; 1324 } 1325 1326 Set<K> keys = map.keySet(); 1327 K key = keys.iterator().next(); 1328 if (supportsRemove) { 1329 keys.retainAll(Collections.singleton(key)); 1330 assertEquals(1, map.size()); 1331 assertTrue(map.containsKey(key)); 1332 } else { 1333 try { 1334 keys.retainAll(Collections.singleton(key)); 1335 fail("Expected UnsupportedOperationException."); 1336 } catch (UnsupportedOperationException e) { 1337 // Expected. 1338 } 1339 } 1340 assertInvariants(map); 1341 } 1342 1343 public void testKeySetClear() { 1344 final Map<K, V> map; 1345 try { 1346 map = makeEitherMap(); 1347 } catch (UnsupportedOperationException e) { 1348 return; 1349 } 1350 1351 Set<K> keySet = map.keySet(); 1352 if (supportsClear) { 1353 keySet.clear(); 1354 assertTrue(keySet.isEmpty()); 1355 } else { 1356 try { 1357 keySet.clear(); 1358 fail("Expected UnsupportedOperationException."); 1359 } catch (UnsupportedOperationException e) { 1360 // Expected. 1361 } 1362 } 1363 assertInvariants(map); 1364 } 1365 1366 public void testKeySetRemoveAllNullFromEmpty() { 1367 final Map<K, V> map; 1368 try { 1369 map = makeEmptyMap(); 1370 } catch (UnsupportedOperationException e) { 1371 return; 1372 } 1373 1374 Set<K> keySet = map.keySet(); 1375 if (supportsRemove) { 1376 try { 1377 keySet.removeAll(null); 1378 fail("Expected NullPointerException."); 1379 } catch (NullPointerException e) { 1380 // Expected. 1381 } 1382 } else { 1383 try { 1384 keySet.removeAll(null); 1385 fail("Expected UnsupportedOperationException or NullPointerException."); 1386 } catch (UnsupportedOperationException e) { 1387 // Expected. 1388 } catch (NullPointerException e) { 1389 // Expected. 1390 } 1391 } 1392 assertInvariants(map); 1393 } 1394 1395 public void testKeySetRetainAllNullFromEmpty() { 1396 final Map<K, V> map; 1397 try { 1398 map = makeEmptyMap(); 1399 } catch (UnsupportedOperationException e) { 1400 return; 1401 } 1402 1403 Set<K> keySet = map.keySet(); 1404 if (supportsRemove) { 1405 try { 1406 keySet.retainAll(null); 1407 // Returning successfully is not ideal, but tolerated. 1408 } catch (NullPointerException e) { 1409 // Expected. 1410 } 1411 } else { 1412 try { 1413 keySet.retainAll(null); 1414 // We have to tolerate a successful return (Sun bug 4802647) 1415 } catch (UnsupportedOperationException e) { 1416 // Expected. 1417 } catch (NullPointerException e) { 1418 // Expected. 1419 } 1420 } 1421 assertInvariants(map); 1422 } 1423 1424 public void testValues() { 1425 final Map<K, V> map; 1426 final Collection<V> valueCollection; 1427 try { 1428 map = makePopulatedMap(); 1429 } catch (UnsupportedOperationException e) { 1430 return; 1431 } 1432 assertInvariants(map); 1433 1434 valueCollection = map.values(); 1435 final V unmappedValue; 1436 try { 1437 unmappedValue = getValueNotInPopulatedMap(); 1438 } catch (UnsupportedOperationException e) { 1439 return; 1440 } 1441 for (V value : valueCollection) { 1442 assertFalse(unmappedValue.equals(value)); 1443 } 1444 } 1445 1446 public void testValuesIteratorRemove() { 1447 final Map<K, V> map; 1448 try { 1449 map = makePopulatedMap(); 1450 } catch (UnsupportedOperationException e) { 1451 return; 1452 } 1453 1454 Collection<V> valueCollection = map.values(); 1455 Iterator<V> iterator = valueCollection.iterator(); 1456 if (supportsIteratorRemove) { 1457 int initialSize = map.size(); 1458 iterator.next(); 1459 iterator.remove(); 1460 assertEquals(initialSize - 1, map.size()); 1461 // (We can't assert that the values collection no longer contains the 1462 // removed value, because the underlying map can have multiple mappings 1463 // to the same value.) 1464 assertInvariants(map); 1465 try { 1466 iterator.remove(); 1467 fail("Expected IllegalStateException."); 1468 } catch (IllegalStateException e) { 1469 // Expected. 1470 } 1471 } else { 1472 try { 1473 iterator.next(); 1474 iterator.remove(); 1475 fail("Expected UnsupportedOperationException."); 1476 } catch (UnsupportedOperationException e) { 1477 // Expected. 1478 } 1479 } 1480 assertInvariants(map); 1481 } 1482 1483 public void testValuesRemove() { 1484 final Map<K, V> map; 1485 try { 1486 map = makePopulatedMap(); 1487 } catch (UnsupportedOperationException e) { 1488 return; 1489 } 1490 1491 Collection<V> valueCollection = map.values(); 1492 if (supportsRemove) { 1493 int initialSize = map.size(); 1494 valueCollection.remove(valueCollection.iterator().next()); 1495 assertEquals(initialSize - 1, map.size()); 1496 // (We can't assert that the values collection no longer contains the 1497 // removed value, because the underlying map can have multiple mappings 1498 // to the same value.) 1499 } else { 1500 try { 1501 valueCollection.remove(valueCollection.iterator().next()); 1502 fail("Expected UnsupportedOperationException."); 1503 } catch (UnsupportedOperationException e) { 1504 // Expected. 1505 } 1506 } 1507 assertInvariants(map); 1508 } 1509 1510 public void testValuesRemoveMissing() { 1511 final Map<K, V> map; 1512 final V valueToRemove; 1513 try { 1514 map = makeEitherMap(); 1515 valueToRemove = getValueNotInPopulatedMap(); 1516 } catch (UnsupportedOperationException e) { 1517 return; 1518 } 1519 1520 Collection<V> valueCollection = map.values(); 1521 int initialSize = map.size(); 1522 if (supportsRemove) { 1523 assertFalse(valueCollection.remove(valueToRemove)); 1524 } else { 1525 try { 1526 assertFalse(valueCollection.remove(valueToRemove)); 1527 } catch (UnsupportedOperationException e) { 1528 // Tolerated. 1529 } 1530 } 1531 assertEquals(initialSize, map.size()); 1532 assertInvariants(map); 1533 } 1534 1535 public void testValuesRemoveAll() { 1536 final Map<K, V> map; 1537 try { 1538 map = makePopulatedMap(); 1539 } catch (UnsupportedOperationException e) { 1540 return; 1541 } 1542 1543 Collection<V> valueCollection = map.values(); 1544 Set<V> valuesToRemove = singleton(valueCollection.iterator().next()); 1545 if (supportsRemove) { 1546 valueCollection.removeAll(valuesToRemove); 1547 for (V value : valuesToRemove) { 1548 assertFalse(valueCollection.contains(value)); 1549 } 1550 for (V value : valueCollection) { 1551 assertFalse(valuesToRemove.contains(value)); 1552 } 1553 } else { 1554 try { 1555 valueCollection.removeAll(valuesToRemove); 1556 fail("Expected UnsupportedOperationException."); 1557 } catch (UnsupportedOperationException e) { 1558 // Expected. 1559 } 1560 } 1561 assertInvariants(map); 1562 } 1563 1564 public void testValuesRemoveAllNullFromEmpty() { 1565 final Map<K, V> map; 1566 try { 1567 map = makeEmptyMap(); 1568 } catch (UnsupportedOperationException e) { 1569 return; 1570 } 1571 1572 Collection<V> values = map.values(); 1573 if (supportsRemove) { 1574 try { 1575 values.removeAll(null); 1576 // Returning successfully is not ideal, but tolerated. 1577 } catch (NullPointerException e) { 1578 // Expected. 1579 } 1580 } else { 1581 try { 1582 values.removeAll(null); 1583 // We have to tolerate a successful return (Sun bug 4802647) 1584 } catch (UnsupportedOperationException e) { 1585 // Expected. 1586 } catch (NullPointerException e) { 1587 // Expected. 1588 } 1589 } 1590 assertInvariants(map); 1591 } 1592 1593 public void testValuesRetainAll() { 1594 final Map<K, V> map; 1595 try { 1596 map = makePopulatedMap(); 1597 } catch (UnsupportedOperationException e) { 1598 return; 1599 } 1600 1601 Collection<V> valueCollection = map.values(); 1602 Set<V> valuesToRetain = singleton(valueCollection.iterator().next()); 1603 if (supportsRemove) { 1604 valueCollection.retainAll(valuesToRetain); 1605 for (V value : valuesToRetain) { 1606 assertTrue(valueCollection.contains(value)); 1607 } 1608 for (V value : valueCollection) { 1609 assertTrue(valuesToRetain.contains(value)); 1610 } 1611 } else { 1612 try { 1613 valueCollection.retainAll(valuesToRetain); 1614 fail("Expected UnsupportedOperationException."); 1615 } catch (UnsupportedOperationException e) { 1616 // Expected. 1617 } 1618 } 1619 assertInvariants(map); 1620 } 1621 1622 public void testValuesRetainAllNullFromEmpty() { 1623 final Map<K, V> map; 1624 try { 1625 map = makeEmptyMap(); 1626 } catch (UnsupportedOperationException e) { 1627 return; 1628 } 1629 1630 Collection<V> values = map.values(); 1631 if (supportsRemove) { 1632 try { 1633 values.retainAll(null); 1634 // Returning successfully is not ideal, but tolerated. 1635 } catch (NullPointerException e) { 1636 // Expected. 1637 } 1638 } else { 1639 try { 1640 values.retainAll(null); 1641 // We have to tolerate a successful return (Sun bug 4802647) 1642 } catch (UnsupportedOperationException e) { 1643 // Expected. 1644 } catch (NullPointerException e) { 1645 // Expected. 1646 } 1647 } 1648 assertInvariants(map); 1649 } 1650 1651 public void testValuesClear() { 1652 final Map<K, V> map; 1653 try { 1654 map = makePopulatedMap(); 1655 } catch (UnsupportedOperationException e) { 1656 return; 1657 } 1658 1659 Collection<V> valueCollection = map.values(); 1660 if (supportsClear) { 1661 valueCollection.clear(); 1662 assertTrue(valueCollection.isEmpty()); 1663 } else { 1664 try { 1665 valueCollection.clear(); 1666 fail("Expected UnsupportedOperationException."); 1667 } catch (UnsupportedOperationException e) { 1668 // Expected. 1669 } 1670 } 1671 assertInvariants(map); 1672 } 1673 1674 static <K, V> Entry<K, V> mapEntry(K key, V value) { 1675 return Collections.singletonMap(key, value).entrySet().iterator().next(); 1676 } 1677 } 1678