/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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: 646780 $ $Date: 2008-04-10 13:48:07 +0100 (Thu, 10 Apr 2008) $ * * @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); } } }