| 1 16 package org.apache.commons.collections.collection; 17 18 import java.io.ByteArrayInputStream ; 19 import java.io.ByteArrayOutputStream ; 20 import java.io.ObjectInputStream ; 21 import java.io.ObjectOutputStream ; 22 import java.io.Serializable ; 23 import java.lang.reflect.Array ; 24 import java.util.ArrayList ; 25 import java.util.Arrays ; 26 import java.util.Collection ; 27 import java.util.Collections ; 28 import java.util.ConcurrentModificationException ; 29 import java.util.HashMap ; 30 import java.util.HashSet ; 31 import java.util.Iterator ; 32 import java.util.List ; 33 import java.util.Map ; 34 import java.util.NoSuchElementException ; 35 36 import org.apache.commons.collections.AbstractTestObject; 37 38 123 public abstract class AbstractTestCollection extends AbstractTestObject { 124 125 135 136 139 142 public Collection collection; 143 144 152 public Collection confirmed; 153 154 159 public AbstractTestCollection(String testName) { 160 super(testName); 161 } 162 163 186 public boolean areEqualElementsDistinguishable() { 187 return false; 188 } 189 190 198 public boolean isAddSupported() { 199 return true; 200 } 201 202 211 public boolean isRemoveSupported() { 212 return true; 213 } 214 215 219 public boolean isNullSupported() { 220 return true; 221 } 222 223 227 public boolean isFailFastSupported() { 228 return false; 229 } 230 231 235 public boolean isEqualsCheckable() { 236 return false; 237 } 238 239 244 public void verify() { 245 int confirmedSize = confirmed.size(); 246 assertEquals("Collection size should match confirmed collection's", 247 confirmedSize, collection.size()); 248 assertEquals("Collection isEmpty() result should match confirmed " + 249 " collection's", 250 confirmed.isEmpty(), collection.isEmpty()); 251 252 261 Object [] confirmedValues = new Object [confirmedSize]; 263 264 Iterator iter; 265 266 iter = confirmed.iterator(); 267 int pos = 0; 268 while(iter.hasNext()) { 269 confirmedValues[pos++] = iter.next(); 270 } 271 272 boolean[] matched = new boolean[confirmedSize]; 275 276 iter = collection.iterator(); 279 while(iter.hasNext()) { 280 Object o = iter.next(); 281 boolean match = false; 282 for(int i = 0; i < confirmedSize; i++) { 283 if(matched[i]) { 284 continue; 286 } 287 if(o == confirmedValues[i] || 288 (o != null && o.equals(confirmedValues[i]))) { 289 matched[i] = true; 291 match = true; 292 break; 293 } 294 } 295 if(!match) { 297 fail("Collection should not contain a value that the " + 298 "confirmed collection does not have: " + o + 299 "\nTest: " + collection + "\nReal: " + confirmed); 300 } 301 } 302 303 for(int i = 0; i < confirmedSize; i++) { 305 if(!matched[i]) { 306 fail("Collection should contain all values that are in the confirmed collection" + 308 "\nTest: " + collection + "\nReal: " + confirmed); 309 } 310 } 311 } 312 313 319 public void resetEmpty() { 320 this.collection = makeCollection(); 321 this.confirmed = makeConfirmedCollection(); 322 } 323 324 329 public void resetFull() { 330 this.collection = makeFullCollection(); 331 this.confirmed = makeConfirmedFullCollection(); 332 } 333 334 342 public abstract Collection makeConfirmedCollection(); 343 344 352 public abstract Collection makeConfirmedFullCollection(); 353 354 357 public abstract Collection makeCollection(); 358 359 367 public Collection makeFullCollection() { 368 Collection c = makeCollection(); 369 c.addAll(Arrays.asList(getFullElements())); 370 return c; 371 } 372 373 376 public Object makeObject() { 377 return makeCollection(); 378 } 379 380 383 public Map.Entry cloneMapEntry(Map.Entry entry) { 384 HashMap map = new HashMap (); 385 map.put(entry.getKey(), entry.getValue()); 386 return (Map.Entry ) map.entrySet().iterator().next(); 387 } 388 389 400 public Object [] getFullElements() { 401 if (isNullSupported()) { 402 ArrayList list = new ArrayList (); 403 list.addAll(Arrays.asList(getFullNonNullElements())); 404 list.add(4, null); 405 return list.toArray(); 406 } else { 407 return (Object []) getFullNonNullElements().clone(); 408 } 409 } 410 411 420 public Object [] getOtherElements() { 421 return getOtherNonNullElements(); 422 } 423 424 433 public Object [] getFullNonNullElements() { 434 return new Object [] { 435 new String (""), 436 new String ("One"), 437 new Integer (2), 438 "Three", 439 new Integer (4), 440 "One", 441 new Double (5), 442 new Float (6), 443 "Seven", 444 "Eight", 445 new String ("Nine"), 446 new Integer (10), 447 new Short ((short)11), 448 new Long (12), 449 "Thirteen", 450 "14", 451 "15", 452 new Byte ((byte)16) 453 }; 454 } 455 456 461 public Object [] getOtherNonNullElements() { 462 return new Object [] { 463 new Integer (0), 464 new Float (0), 465 new Double (0), 466 "Zero", 467 new Short ((short)0), 468 new Byte ((byte)0), 469 new Long (0), 470 new Character ('\u0000'), 471 "0" 472 }; 473 } 474 475 481 public Object [] getFullNonNullStringElements() { 482 return new Object [] { 483 "If","the","dull","substance","of","my","flesh","were","thought", 484 "Injurious","distance","could","not","stop","my","way", 485 }; 486 } 487 488 494 public Object [] getOtherNonNullStringElements() { 495 return new Object [] { 496 "For","then","despite","space","I","would","be","brought", 497 "From","limits","far","remote","where","thou","dost","stay" 498 }; 499 } 500 501 506 public void testCollectionAdd() { 507 if (!isAddSupported()) return; 508 509 Object [] elements = getFullElements(); 510 for (int i = 0; i < elements.length; i++) { 511 resetEmpty(); 512 boolean r = collection.add(elements[i]); 513 confirmed.add(elements[i]); 514 verify(); 515 assertTrue("Empty collection changed after add", r); 516 assertEquals("Collection size is 1 after first add", 1, collection.size()); 517 } 518 519 resetEmpty(); 520 int size = 0; 521 for (int i = 0; i < elements.length; i++) { 522 boolean r = collection.add(elements[i]); 523 confirmed.add(elements[i]); 524 verify(); 525 if (r) size++; 526 assertEquals("Collection size should grow after add", 527 size, collection.size()); 528 assertTrue("Collection should contain added element", 529 collection.contains(elements[i])); 530 } 531 } 532 533 534 537 public void testCollectionAddAll() { 538 if (!isAddSupported()) return; 539 540 resetEmpty(); 541 Object [] elements = getFullElements(); 542 boolean r = collection.addAll(Arrays.asList(elements)); 543 confirmed.addAll(Arrays.asList(elements)); 544 verify(); 545 assertTrue("Empty collection should change after addAll", r); 546 for (int i = 0; i < elements.length; i++) { 547 assertTrue("Collection should contain added element", 548 collection.contains(elements[i])); 549 } 550 551 resetFull(); 552 int size = collection.size(); 553 elements = getOtherElements(); 554 r = collection.addAll(Arrays.asList(elements)); 555 confirmed.addAll(Arrays.asList(elements)); 556 verify(); 557 assertTrue("Full collection should change after addAll", r); 558 for (int i = 0; i < elements.length; i++) { 559 assertTrue("Full collection should contain added element", 560 collection.contains(elements[i])); 561 } 562 assertEquals("Size should increase after addAll", 563 size + elements.length, collection.size()); 564 565 resetFull(); 566 size = collection.size(); 567 r = collection.addAll(Arrays.asList(getFullElements())); 568 confirmed.addAll(Arrays.asList(getFullElements())); 569 verify(); 570 if (r) { 571 assertTrue("Size should increase if addAll returns true", 572 size < collection.size()); 573 } else { 574 assertEquals("Size should not change if addAll returns false", 575 size, collection.size()); 576 } 577 } 578 579 580 584 public void testUnsupportedAdd() { 585 if (isAddSupported()) return; 586 587 resetEmpty(); 588 try { 589 collection.add(new Object ()); 590 fail("Emtpy collection should not support add."); 591 } catch (UnsupportedOperationException e) { 592 } 594 verify(); 597 598 try { 599 collection.addAll(Arrays.asList(getFullElements())); 600 fail("Emtpy collection should not support addAll."); 601 } catch (UnsupportedOperationException e) { 602 } 604 verify(); 607 608 resetFull(); 609 try { 610 collection.add(new Object ()); 611 fail("Full collection should not support add."); 612 } catch (UnsupportedOperationException e) { 613 } 615 verify(); 618 619 try { 620 collection.addAll(Arrays.asList(getOtherElements())); 621 fail("Full collection should not support addAll."); 622 } catch (UnsupportedOperationException e) { 623 } 625 verify(); 628 } 629 630 631 634 public void testCollectionClear() { 635 if (!isRemoveSupported()) return; 636 637 resetEmpty(); 638 collection.clear(); verify(); 640 641 resetFull(); 642 collection.clear(); 643 confirmed.clear(); 644 verify(); 645 } 646 647 648 651 public void testCollectionContains() { 652 Object [] elements; 653 654 resetEmpty(); 655 elements = getFullElements(); 656 for(int i = 0; i < elements.length; i++) { 657 assertTrue("Empty collection shouldn't contain element[" + i + "]", 658 !collection.contains(elements[i])); 659 } 660 verify(); 662 663 elements = getOtherElements(); 664 for(int i = 0; i < elements.length; i++) { 665 assertTrue("Empty collection shouldn't contain element[" + i + "]", 666 !collection.contains(elements[i])); 667 } 668 verify(); 670 671 resetFull(); 672 elements = getFullElements(); 673 for(int i = 0; i < elements.length; i++) { 674 assertTrue("Full collection should contain element[" + i + "]", 675 collection.contains(elements[i])); 676 } 677 verify(); 679 680 resetFull(); 681 elements = getOtherElements(); 682 for(int i = 0; i < elements.length; i++) { 683 assertTrue("Full collection shouldn't contain element", 684 !collection.contains(elements[i])); 685 } 686 } 687 688 689 692 public void testCollectionContainsAll() { 693 resetEmpty(); 694 Collection col = new HashSet (); 695 assertTrue("Every Collection should contain all elements of an " + 696 "empty Collection.", collection.containsAll(col)); 697 col.addAll(Arrays.asList(getOtherElements())); 698 assertTrue("Empty Collection shouldn't contain all elements of " + 699 "a non-empty Collection.", !collection.containsAll(col)); 700 verify(); 702 703 resetFull(); 704 assertTrue("Full collection shouldn't contain other elements", 705 !collection.containsAll(col)); 706 707 col.clear(); 708 col.addAll(Arrays.asList(getFullElements())); 709 assertTrue("Full collection should containAll full elements", 710 collection.containsAll(col)); 711 verify(); 713 714 int min = (getFullElements().length < 2 ? 0 : 2); 715 int max = (getFullElements().length == 1 ? 1 : 716 (getFullElements().length <= 5 ? getFullElements().length - 1 : 5)); 717 col = Arrays.asList(getFullElements()).subList(min, max); 718 assertTrue("Full collection should containAll partial full " + 719 "elements", collection.containsAll(col)); 720 assertTrue("Full collection should containAll itself", 721 collection.containsAll(collection)); 722 verify(); 724 725 col = new ArrayList (); 726 col.addAll(Arrays.asList(getFullElements())); 727 col.addAll(Arrays.asList(getFullElements())); 728 assertTrue("Full collection should containAll duplicate full " + 729 "elements", collection.containsAll(col)); 730 731 verify(); 733 } 734 735 738 public void testCollectionIsEmpty() { 739 resetEmpty(); 740 assertEquals("New Collection should be empty.", 741 true, collection.isEmpty()); 742 verify(); 744 745 resetFull(); 746 assertEquals("Full collection shouldn't be empty", 747 false, collection.isEmpty()); 748 verify(); 750 } 751 752 753 756 public void testCollectionIterator() { 757 resetEmpty(); 758 Iterator it1 = collection.iterator(); 759 assertEquals("Iterator for empty Collection shouldn't have next.", 760 false, it1.hasNext()); 761 try { 762 it1.next(); 763 fail("Iterator at end of Collection should throw " + 764 "NoSuchElementException when next is called."); 765 } catch(NoSuchElementException e) { 766 } 768 verify(); 770 771 resetFull(); 772 it1 = collection.iterator(); 773 for (int i = 0; i < collection.size(); i++) { 774 assertTrue("Iterator for full collection should haveNext", 775 it1.hasNext()); 776 it1.next(); 777 } 778 assertTrue("Iterator should be finished", !it1.hasNext()); 779 780 ArrayList list = new ArrayList (); 781 it1 = collection.iterator(); 782 for (int i = 0; i < collection.size(); i++) { 783 Object next = it1.next(); 784 assertTrue("Collection should contain element returned by " + 785 "its iterator", collection.contains(next)); 786 list.add(next); 787 } 788 try { 789 it1.next(); 790 fail("iterator.next() should raise NoSuchElementException " + 791 "after it finishes"); 792 } catch (NoSuchElementException e) { 793 } 795 verify(); 797 } 798 799 800 803 public void testCollectionIteratorRemove() { 804 if (!isRemoveSupported()) return; 805 806 resetEmpty(); 807 try { 808 collection.iterator().remove(); 809 fail("New iterator.remove should raise IllegalState"); 810 } catch (IllegalStateException e) { 811 } 813 verify(); 814 815 try { 816 Iterator iter = collection.iterator(); 817 iter.hasNext(); 818 iter.remove(); 819 fail("New iterator.remove should raise IllegalState " + 820 "even after hasNext"); 821 } catch (IllegalStateException e) { 822 } 824 verify(); 825 826 resetFull(); 827 int size = collection.size(); 828 Iterator iter = collection.iterator(); 829 while (iter.hasNext()) { 830 Object o = iter.next(); 831 if (o instanceof Map.Entry ) { 834 o = cloneMapEntry((Map.Entry ) o); 835 } 836 iter.remove(); 837 838 if(!areEqualElementsDistinguishable()) { 847 confirmed.remove(o); 848 verify(); 849 } 850 851 size--; 852 assertEquals("Collection should shrink by one after " + 853 "iterator.remove", size, collection.size()); 854 } 855 assertTrue("Collection should be empty after iterator purge", 856 collection.isEmpty()); 857 858 resetFull(); 859 iter = collection.iterator(); 860 iter.next(); 861 iter.remove(); 862 try { 863 iter.remove(); 864 fail("Second iter.remove should raise IllegalState"); 865 } catch (IllegalStateException |