/*
* Copyright 2001-2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections.bag;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import org.apache.commons.collections.AbstractTestObject;
import org.apache.commons.collections.Bag;
/**
* Abstract test class for {@link org.apache.commons.collections.Bag Bag} methods and contracts.
* <p>
* To use, simply extend this class, and implement
* the {@link #makeBag} method.
* <p>
* If your bag fails one of these tests by design,
* you may still use this base set of cases. Simply override the
* test case (method) your bag fails.
*
* @version $Revision: 219131 $ $Date: 2005-07-15 00:11:12 +0100 (Fri, 15 Jul 2005) $
*
* @author Chuck Burdick
* @author Stephen Colebourne
*/
public abstract class AbstractTestBag extends AbstractTestObject {
// TODO: this class should really extend from TestCollection, but the bag
// implementations currently do not conform to the Collection interface. Once
// those are fixed or at least a strategy is made for resolving the issue, this
// can be changed back to extend TestCollection instead.
/**
* JUnit constructor.
*
* @param testName the test class name
*/
public AbstractTestBag(String testName) {
super(testName);
}
//-----------------------------------------------------------------------
/**
* Return a new, empty bag to used for testing.
*
* @return the bag to be tested
*/
public abstract Bag makeBag();
/**
* Implements the superclass method to return the Bag.
*
* @return the bag to be tested
*/
public Object makeObject() {
return makeBag();
}
//-----------------------------------------------------------------------
public void testBagAdd() {
Bag bag = makeBag();
bag.add("A");
assertTrue("Should contain 'A'", bag.contains("A"));
assertEquals("Should have count of 1", 1, bag.getCount("A"));
bag.add("A");
assertTrue("Should contain 'A'", bag.contains("A"));
assertEquals("Should have count of 2", 2, bag.getCount("A"));
bag.add("B");
assertTrue(bag.contains("A"));
assertTrue(bag.contains("B"));
}
public void testBagEqualsSelf() {
Bag bag = makeBag();
assertTrue(bag.equals(bag));
bag.add("elt");
assertTrue(bag.equals(bag));
bag.add("elt"); // again
assertTrue(bag.equals(bag));
bag.add("elt2");
assertTrue(bag.equals(bag));
}
public void testRemove() {
Bag bag = makeBag();
bag.add("A");
assertEquals("Should have count of 1", 1, bag.getCount("A"));
bag.remove("A");
assertEquals("Should have count of 0", 0, bag.getCount("A"));
bag.add("A");
bag.add("A");
bag.add("A");
bag.add("A");
assertEquals("Should have count of 4", 4, bag.getCount("A"));
bag.remove("A", 0);
assertEquals("Should have count of 4", 4, bag.getCount("A"));
bag.remove("A", 2);
assertEquals("Should have count of 2", 2, bag.getCount("A"));
bag.remove("A");
assertEquals("Should have count of 0", 0, bag.getCount("A"));
}
public void testRemoveAll() {
Bag bag = makeBag();
bag.add("A", 2);
assertEquals("Should have count of 2", 2, bag.getCount("A"));
bag.add("B");
bag.add("C");
assertEquals("Should have count of 4", 4, bag.size());
List delete = new ArrayList();
delete.add("A");
delete.add("B");
bag.removeAll(delete);
assertEquals("Should have count of 1", 1, bag.getCount("A"));
assertEquals("Should have count of 0", 0, bag.getCount("B"));
assertEquals("Should have count of 1", 1, bag.getCount("C"));
assertEquals("Should have count of 2", 2, bag.size());
}
public void testContains() {
Bag bag = makeBag();
assertEquals("Bag does not have at least 1 'A'", false, bag.contains("A"));
assertEquals("Bag does not have at least 1 'B'", false, bag.contains("B"));
bag.add("A"); // bag 1A
assertEquals("Bag has at least 1 'A'", true, bag.contains("A"));
assertEquals("Bag does not have at least 1 'B'", false, bag.contains("B"));
bag.add("A"); // bag 2A
assertEquals("Bag has at least 1 'A'", true, bag.contains("A"));
assertEquals("Bag does not have at least 1 'B'", false, bag.contains("B"));
bag.add("B"); // bag 2A,1B
assertEquals("Bag has at least 1 'A'", true, bag.contains("A"));
assertEquals("Bag has at least 1 'B'", true, bag.contains("B"));
}
public void testContainsAll() {
Bag bag = makeBag();
List known = new ArrayList();
List known1A = new ArrayList();
known1A.add("A");
List known2A = new ArrayList();
known2A.add("A");
known2A.add("A");
List known1B = new ArrayList();
known1B.add("B");
List known1A1B = new ArrayList();
known1A1B.add("A");
known1A1B.add("B");
assertEquals("Bag containsAll of empty", true, bag.containsAll(known));
assertEquals("Bag does not containsAll of 1 'A'", false, bag.containsAll(known1A));
assertEquals("Bag does not containsAll of 2 'A'", false, bag.containsAll(known2A));
assertEquals("Bag does not containsAll of 1 'B'", false, bag.containsAll(known1B));
assertEquals("Bag does not containsAll of 1 'A' 1 'B'", false, bag.containsAll(known1A1B));
bag.add("A"); // bag 1A
assertEquals("Bag containsAll of empty", true, bag.containsAll(known));
assertEquals("Bag containsAll of 1 'A'", true, bag.containsAll(known1A));
assertEquals("Bag does not containsAll of 2 'A'", false, bag.containsAll(known2A));
assertEquals("Bag does not containsAll of 1 'B'", false, bag.containsAll(known1B));
assertEquals("Bag does not containsAll of 1 'A' 1 'B'", false, bag.containsAll(known1A1B));
bag.add("A"); // bag 2A
assertEquals("Bag containsAll of empty", true, bag.containsAll(known));
assertEquals("Bag containsAll of 1 'A'", true, bag.containsAll(known1A));
assertEquals("Bag containsAll of 2 'A'", true, bag.containsAll(known2A));
assertEquals("Bag does not containsAll of 1 'B'", false, bag.containsAll(known1B));
assertEquals("Bag does not containsAll of 1 'A' 1 'B'", false, bag.containsAll(known1A1B));
bag.add("A"); // bag 3A
assertEquals("Bag containsAll of empty", true, bag.containsAll(known));
assertEquals("Bag containsAll of 1 'A'", true, bag.containsAll(known1A));
assertEquals("Bag containsAll of 2 'A'", true, bag.containsAll(known2A));
assertEquals("Bag does not containsAll of 1 'B'", false, bag.containsAll(known1B));
assertEquals("Bag does not containsAll of 1 'A' 1 'B'", false, bag.containsAll(known1A1B));
bag.add("B"); // bag 3A1B
assertEquals("Bag containsAll of empty", true, bag.containsAll(known));
assertEquals("Bag containsAll of 1 'A'", true, bag.containsAll(known1A));
assertEquals("Bag containsAll of 2 'A'", true, bag.containsAll(known2A));
assertEquals("Bag containsAll of 1 'B'", true, bag.containsAll(known1B));
assertEquals("Bag containsAll of 1 'A' 1 'B'", true, bag.containsAll(known1A1B));
}
public void testSize() {
Bag bag = makeBag();
assertEquals("Should have 0 total items", 0, bag.size());
bag.add("A");
assertEquals("Should have 1 total items", 1, bag.size());
bag.add("A");
assertEquals("Should have 2 total items", 2, bag.size());
bag.add("A");
assertEquals("Should have 3 total items", 3, bag.size());
bag.add("B");
assertEquals("Should have 4 total items", 4, bag.size());
bag.add("B");
assertEquals("Should have 5 total items", 5, bag.size());
bag.remove("A", 2);
assertEquals("Should have 1 'A'", 1, bag.getCount("A"));
assertEquals("Should have 3 total items", 3, bag.size());
bag.remove("B");
assertEquals("Should have 1 total item", 1, bag.size());
}
public void testRetainAll() {
Bag bag = makeBag();
bag.add("A");
bag.add("A");
bag.add("A");
bag.add("B");
bag.add("B");
bag.add("C");
List retains = new ArrayList();
retains.add("B");
retains.add("C");
bag.retainAll(retains);
assertEquals("Should have 2 total items", 2, bag.size());
}
public void testIterator() {
Bag bag = makeBag();
bag.add("A");
bag.add("A");
bag.add("B");
assertEquals("Bag should have 3 items", 3, bag.size());
Iterator i = bag.iterator();
boolean foundA = false;
while (i.hasNext()) {
String element = (String) i.next();
// ignore the first A, remove the second via Iterator.remove()
if (element.equals("A")) {
if (foundA == false) {
foundA = true;
} else {
i.remove();
}
}
}
assertTrue("Bag should still contain 'A'", bag.contains("A"));
assertEquals("Bag should have 2 items", 2, bag.size());
assertEquals("Bag should have 1 'A'", 1, bag.getCount("A"));
}
public void testIteratorFail() {
Bag bag = makeBag();
bag.add("A");
bag.add("A");
bag.add("B");
Iterator it = bag.iterator();
it.next();
bag.remove("A");
try {
it.next();
fail("Should throw ConcurrentModificationException");
} catch (ConcurrentModificationException e) {
// expected
}
}
public void testIteratorFailNoMore() {
Bag bag = makeBag();
bag.add("A");
bag.add("A");
bag.add("B");
Iterator it = bag.iterator();
it.next();
it.next();
it.next();
try {
it.next();
fail("Should throw NoSuchElementException");
} catch (NoSuchElementException ex) {
// expected
}
}
public void testIteratorFailDoubleRemove() {
Bag bag = makeBag();
bag.add("A");
bag.add("A");
bag.add("B");
Iterator it = bag.iterator();
it.next();
it.next();
assertEquals(3, bag.size());
it.remove();
assertEquals(2, bag.size());
try {
it.remove();
fail("Should throw IllegalStateException");
} catch (IllegalStateException ex) {
// expected
}
assertEquals(2, bag.size());
it.next();
it.remove();
assertEquals(1, bag.size());
}
public void testIteratorRemoveProtectsInvariants() {
Bag bag = makeBag();
bag.add("A");
bag.add("A");
assertEquals(2, bag.size());
Iterator it = bag.iterator();
assertEquals("A", it.next());
assertEquals(true, it.hasNext());
it.remove();
assertEquals(1, bag.size());
assertEquals(true, it.hasNext());
assertEquals("A", it.next());
assertEquals(false, it.hasNext());
it.remove();
assertEquals(0, bag.size());
assertEquals(false, it.hasNext());
Iterator it2 = bag.iterator();
assertEquals(false, it2.hasNext());
}
public void testToArray() {
Bag bag = makeBag();
bag.add("A");
bag.add("A");
bag.add("B");
bag.add("B");
bag.add("C");
Object[] array = bag.toArray();
int a = 0, b = 0, c = 0;
for (int i = 0; i < array.length; i++) {
a += (array[i].equals("A") ? 1 : 0);
b += (array[i].equals("B") ? 1 : 0);
c += (array[i].equals("C") ? 1 : 0);
}
assertEquals(2, a);
assertEquals(2, b);
assertEquals(1, c);
}
public void testToArrayPopulate() {
Bag bag = makeBag();
bag.add("A");
bag.add("A");
bag.add("B");
bag.add("B");
bag.add("C");
String[] array = (String[]) bag.toArray(new String[0]);
int a = 0, b = 0, c = 0;
for (int i = 0; i < array.length; i++) {
a += (array[i].equals("A") ? 1 : 0);
b += (array[i].equals("B") ? 1 : 0);
c += (array[i].equals("C") ? 1 : 0);
}
assertEquals(2, a);
assertEquals(2, b);
assertEquals(1, c);
}
//-----------------------------------------------------------------------
public void testEquals() {
Bag bag = makeBag();
Bag bag2 = makeBag();
assertEquals(true, bag.equals(bag2));
bag.add("A");
assertEquals(false, bag.equals(bag2));
bag2.add("A");
assertEquals(true, bag.equals(bag2));
bag.add("A");
bag.add("B");
bag.add("B");
bag.add("C");
bag2.add("A");
bag2.add("B");
bag2.add("B");
bag2.add("C");
assertEquals(true, bag.equals(bag2));
}
public void testEqualsHashBag() {
Bag bag = makeBag();
Bag bag2 = new HashBag();
assertEquals(true, bag.equals(bag2));
bag.add("A");
assertEquals(false, bag.equals(bag2));
bag2.add("A");
assertEquals(true, bag.equals(bag2));
bag.add("A");
bag.add("B");
bag.add("B");
bag.add("C");
bag2.add("A");
bag2.add("B");
bag2.add("B");
bag2.add("C");
assertEquals(true, bag.equals(bag2));
}
public void testHashCode() {
Bag bag = makeBag();
Bag bag2 = makeBag();
assertEquals(0, bag.hashCode());
assertEquals(0, bag2.hashCode());
assertEquals(bag.hashCode(), bag2.hashCode());
bag.add("A");
bag.add("A");
bag.add("B");
bag.add("B");
bag.add("C");
bag2.add("A");
bag2.add("A");
bag2.add("B");
bag2.add("B");
bag2.add("C");
assertEquals(bag.hashCode(), bag2.hashCode());
int total = 0;
total += ("A".hashCode() ^ 2);
total += ("B".hashCode() ^ 2);
total += ("C".hashCode() ^ 1);
assertEquals(total, bag.hashCode());
assertEquals(total, bag2.hashCode());
}
//-----------------------------------------------------------------------
public void testEmptyBagSerialization() throws IOException, ClassNotFoundException {
Bag bag = makeBag();
if (!(bag instanceof Serializable && isTestSerialization())) return;
byte[] objekt = writeExternalFormToBytes((Serializable) bag);
Bag bag2 = (Bag) readExternalFormFromBytes(objekt);
assertEquals("Bag should be empty",0, bag.size());
assertEquals("Bag should be empty",0, bag2.size());
}
public void testFullBagSerialization() throws IOException, ClassNotFoundException {
Bag bag = makeBag();
bag.add("A");
bag.add("A");
bag.add("B");
bag.add("B");
bag.add("C");
int size = bag.size();
if (!(bag instanceof Serializable && isTestSerialization())) return;
byte[] objekt = writeExternalFormToBytes((Serializable) bag);
Bag bag2 = (Bag) readExternalFormFromBytes(objekt);
assertEquals("Bag should be same size", size, bag.size());
assertEquals("Bag should be same size", size, bag2.size());
}
/**
* Compare the current serialized form of the Bag
* against the canonical version in CVS.
*/
public void testEmptyBagCompatibility() throws IOException, ClassNotFoundException {
// test to make sure the canonical form has been preserved
Bag bag = makeBag();
if(bag instanceof Serializable && !skipSerializedCanonicalTests() && isTestSerialization()) {
Bag bag2 = (Bag) readExternalFormFromDisk(getCanonicalEmptyCollectionName(bag));
assertTrue("Bag is empty",bag2.size() == 0);
assertEquals(bag, bag2);
}
}
/**
* Compare the current serialized form of the Bag
* against the canonical version in CVS.
*/
public void testFullBagCompatibility() throws IOException, ClassNotFoundException {
// test to make sure the canonical form has been preserved
Bag bag = makeBag();
bag.add("A");
bag.add("A");
bag.add("B");
bag.add("B");
bag.add("C");
if(bag instanceof Serializable && !skipSerializedCanonicalTests() && isTestSerialization()) {
Bag bag2 = (Bag) readExternalFormFromDisk(getCanonicalFullCollectionName(bag));
assertEquals("Bag is the right size",bag.size(), bag2.size());
assertEquals(bag, bag2);
}
}
}