blob: 9725bc72cad57cbbb705e2dc834e2fa8c254b30c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 1998, 2013 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Oracle - initial API and implementation from Oracle TopLink
******************************************************************************/
package org.eclipse.persistence.tools.workbench.test.utility;
import java.util.ArrayList;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.eclipse.persistence.tools.workbench.utility.Bag;
import org.eclipse.persistence.tools.workbench.utility.CollectionTools;
import org.eclipse.persistence.tools.workbench.utility.HashBag;
public class HashBagTests extends TestCase {
private HashBag bag;
public static Test suite() {
return new TestSuite(HashBagTests.class);
}
public HashBagTests(String name) {
super(name);
}
protected void setUp() throws Exception {
super.setUp();
this.bag = this.buildBag();
}
private HashBag buildBag() {
HashBag b = new HashBag();
b.add(null);
b.add(new String("one"));
b.add(new String("two"));
b.add(new String("two"));
b.add(new String("three"));
b.add(new String("three"));
b.add(new String("three"));
b.add(new String("four"));
b.add(new String("four"));
b.add(new String("four"));
b.add(new String("four"));
return b;
}
protected void tearDown() throws Exception {
TestTools.clear(this);
super.tearDown();
}
private Collection buildCollection() {
Collection c = new ArrayList();
c.add(new String("foo"));
c.add(new String("foo"));
c.add(new String("bar"));
c.add(new String("bar"));
c.add(new String("bar"));
return c;
}
public void testCtorCollection() {
Collection c = this.buildCollection();
Bag b = new HashBag(c);
for (Iterator stream = c.iterator(); stream.hasNext(); ) {
assertTrue("missing element", b.contains(stream.next()));
}
}
public void testCtorIntFloat() {
boolean exCaught;
exCaught = false;
try {
this.bag = new HashBag(-20, 0.66f);
} catch (IllegalArgumentException ex) {
exCaught = true;
}
assertTrue("IllegalArgumentException not thrown", exCaught);
exCaught = false;
try {
this.bag = new HashBag(20, -0.66f);
} catch (IllegalArgumentException ex) {
exCaught = true;
}
assertTrue("IllegalArgumentException not thrown", exCaught);
}
public void testAdd() {
// the other adds took place in setUp
assertTrue("incorrect return value", this.bag.add("five"));
assertTrue("missing element", this.bag.contains("one"));
assertTrue("missing element", this.bag.contains("two"));
assertTrue("missing element", this.bag.contains("three"));
assertTrue("missing element", this.bag.contains("four"));
assertTrue("missing element", this.bag.contains("five"));
}
public void testAddAll() {
Collection c = this.buildCollection();
assertTrue("incorrect return value", this.bag.addAll(c));
for (Iterator stream = c.iterator(); stream.hasNext(); ) {
assertTrue("missing element", this.bag.contains(stream.next()));
}
}
public void testClear() {
assertTrue("missing element", this.bag.contains("one"));
assertTrue("missing element", this.bag.contains("two"));
assertTrue("missing element", this.bag.contains("three"));
assertTrue("missing element", this.bag.contains("four"));
assertTrue("missing element", this.bag.contains(null));
assertEquals("invalid size", 11, this.bag.size());
this.bag.clear();
assertFalse("malingering element", this.bag.contains("one"));
assertFalse("malingering element", this.bag.contains("two"));
assertFalse("malingering element", this.bag.contains("three"));
assertFalse("malingering element", this.bag.contains("four"));
assertFalse("malingering element", this.bag.contains(null));
assertEquals("invalid size", 0, this.bag.size());
}
public void testClone() {
Bag bag2 = (Bag) this.bag.clone();
assertTrue("bad clone", this.bag != bag2);
assertEquals("bad clone", this.bag, bag2);
assertTrue("bad clone", this.bag.hashCode() == bag2.hashCode());
}
public void testContains() {
assertTrue("missing element", this.bag.contains(null));
assertTrue("missing element", this.bag.contains("one"));
assertTrue("missing element", this.bag.contains("two"));
assertTrue("missing element", this.bag.contains("three"));
assertTrue("missing element", this.bag.contains("four"));
assertTrue("missing element", this.bag.contains(new String("four")));
assertTrue("missing element", this.bag.contains("fo"+"ur"));
assertFalse("element found", this.bag.contains("five"));
}
public void testContainsAll() {
Collection c = new ArrayList();
c.add(null);
c.add(new String("one"));
c.add(new String("two"));
c.add(new String("three"));
c.add(new String("four"));
assertTrue("missing element(s)", this.bag.containsAll(c));
}
public void testCount() {
assertEquals("bad count", 0, this.bag.count("zero"));
assertEquals("bad count", 1, this.bag.count("one"));
assertEquals("bad count", 2, this.bag.count("two"));
assertEquals("bad count", 3, this.bag.count("three"));
assertEquals("bad count", 4, this.bag.count("four"));
assertEquals("bad count", 0, this.bag.count("five"));
}
public void testEquals() {
Bag bag2 = this.buildBag();
assertEquals("bags are not equal", this.bag, bag2);
bag2.add("five");
assertFalse("bags are equal", this.bag.equals(bag2));
Collection c = new ArrayList(this.bag);
assertFalse("bags are not equal to collections", this.bag.equals(c));
}
public void testHashCode() {
Bag bag2 = this.buildBag();
assertEquals("bad hash code", this.bag.hashCode(), bag2.hashCode());
}
public void testIsEmpty() {
assertFalse("bag is empty", this.bag.isEmpty());
this.bag.clear();
assertTrue("bag is not empty", this.bag.isEmpty());
this.bag.add("foo");
assertFalse("bag is empty", this.bag.isEmpty());
}
public void testEmptyIterator() {
this.bag.clear();
Iterator iterator = this.bag.iterator();
assertFalse("iterator is not empty", iterator.hasNext());
boolean exCaught = false;
Object element = null;
try {
element = iterator.next();
} catch (NoSuchElementException ex) {
exCaught = true;
}
assertTrue("NoSuchElementException not thrown: " + element, exCaught);
exCaught = false;
try {
iterator.remove();
} catch (IllegalStateException ex) {
exCaught = true;
}
assertTrue("IllegalStateException not thrown", exCaught);
}
public void testIterator() {
int i = 0;
Iterator iterator = this.bag.iterator();
assertTrue("iterator is empty", iterator.hasNext());
while (iterator.hasNext()) {
iterator.next();
i++;
}
assertEquals("invalid hasNext() loop", 11, i);
assertFalse("iterator should be empty now", iterator.hasNext());
boolean exCaught = false;
Object element = null;
try {
element = iterator.next();
} catch (NoSuchElementException ex) {
exCaught = true;
}
assertTrue("NoSuchElementException not thrown: " + element, exCaught);
iterator.remove();
assertEquals("iterator did not remove element", 10, this.bag.size());
exCaught = false;
try {
iterator.remove();
} catch (IllegalStateException ex) {
exCaught = true;
}
assertTrue("IllegalStateException not thrown", exCaught);
// start over
iterator = this.bag.iterator();
this.bag.add("five");
exCaught = false;
try {
iterator.next();
} catch (ConcurrentModificationException ex) {
exCaught = true;
}
assertTrue("ConcurrentModificationException not thrown", exCaught);
}
public void testUniqueIterator() {
int i = 0;
Iterator iterator = this.bag.uniqueIterator();
assertTrue("iterator is empty", iterator.hasNext());
while (iterator.hasNext()) {
iterator.next();
i++;
}
assertEquals("invalid hasNext() loop", 5, i);
assertFalse("iterator should be empty now", iterator.hasNext());
boolean exCaught = false;
Object element = null;
try {
element = iterator.next();
} catch (NoSuchElementException ex) {
exCaught = true;
}
assertTrue("NoSuchElementException not thrown: " + element, exCaught);
// start over
iterator = this.bag.uniqueIterator();
Object next = null;
while (iterator.hasNext() && ! "four".equals(next)) {
next = iterator.next();
}
iterator.remove();
assertEquals("iterator did not remove all copies of element", 7, this.bag.size());
exCaught = false;
try {
iterator.remove();
} catch (IllegalStateException ex) {
exCaught = true;
}
assertTrue("IllegalStateException not thrown", exCaught);
// start over
iterator = this.bag.uniqueIterator();
this.bag.add("five");
exCaught = false;
try {
iterator.next();
} catch (ConcurrentModificationException ex) {
exCaught = true;
}
assertTrue("ConcurrentModificationException not thrown", exCaught);
}
public void testHashingDistribution() throws Exception {
Bag bigBag = new HashBag();
for (int i = 0; i < 10000; i++) {
bigBag.add("object" + i);
}
java.lang.reflect.Field field = bigBag.getClass().getDeclaredField("table");
field.setAccessible(true);
Object[] table = (Object[]) field.get(bigBag);
int bucketCount = table.length;
int filledBucketCount = 0;
for (int i = 0; i < bucketCount; i++) {
if (table[i] != null) {
filledBucketCount++;
}
}
float loadFactor = ((float) filledBucketCount)/((float) bucketCount);
assertTrue("WARNING - poor load factor: " + loadFactor, loadFactor > 0.20);
assertTrue("WARNING - poor load factor: " + loadFactor, loadFactor < 0.75);
}
public void testRemove() {
assertTrue("incorrect return value", this.bag.remove("one"));
assertFalse("element still present", this.bag.contains("one"));
assertFalse("incorrect return value", this.bag.remove("one"));
assertTrue("incorrect return value", this.bag.remove("two"));
assertTrue("incorrect return value", this.bag.remove("two"));
assertFalse("element still present", this.bag.contains("one"));
assertFalse("incorrect return value", this.bag.remove("one"));
}
public void testRemoveAll() {
Collection c = new ArrayList();
c.add("one");
c.add("three");
assertTrue("incorrect return value", this.bag.removeAll(c));
assertFalse("element still present", this.bag.contains("one"));
assertFalse("element still present", this.bag.contains("three"));
assertFalse("incorrect return value", this.bag.remove("one"));
assertFalse("incorrect return value", this.bag.remove("three"));
assertFalse("incorrect return value", this.bag.removeAll(c));
}
public void testRetainAll() {
Collection c = new ArrayList();
c.add("one");
c.add("three");
assertTrue("incorrect return value", this.bag.retainAll(c));
assertTrue("element removed", this.bag.contains("one"));
assertTrue("element removed", this.bag.contains("three"));
assertFalse("element still present", this.bag.contains("two"));
assertFalse("element still present", this.bag.contains("four"));
assertFalse("incorrect return value", this.bag.remove("two"));
assertFalse("incorrect return value", this.bag.remove("four"));
assertFalse("incorrect return value", this.bag.retainAll(c));
}
public void testSize() {
assertTrue("incorrect size", this.bag.size() == 11);
this.bag.add("five");
this.bag.add("five");
this.bag.add("five");
this.bag.add("five");
this.bag.add("five");
assertEquals("incorrect size", 16, this.bag.size());
}
public void testSerialization() throws Exception {
Bag bag2 = (Bag) TestTools.serialize(this.bag);
assertTrue("same object?", this.bag != bag2);
assertEquals("incorrect size", 11, bag2.size());
assertEquals("unequal bag", this.bag, bag2);
// look for similar elements
assertTrue("missing element", bag2.contains(null));
assertTrue("missing element", bag2.contains("one"));
assertTrue("missing element", bag2.contains("two"));
assertTrue("missing element", bag2.contains("three"));
assertTrue("missing element", bag2.contains("four"));
int nullCount = 0, oneCount = 0, twoCount = 0, threeCount = 0, fourCount = 0;
for (Iterator stream = bag2.iterator(); stream.hasNext(); ) {
String next = (String) stream.next();
if (next == null)
nullCount++;
else if (next.equals("one"))
oneCount++;
else if (next.equals("two"))
twoCount++;
else if (next.equals("three"))
threeCount++;
else if (next.equals("four"))
fourCount++;
}
assertEquals("bad element count", 1, nullCount);
assertEquals("bad element count", 1, oneCount);
assertEquals("bad element count", 2, twoCount);
assertEquals("bad element count", 3, threeCount);
assertEquals("bad element count", 4, fourCount);
}
public void testToArray() {
Object[] a = this.bag.toArray();
assertEquals("incorrect length", 11, a.length);
assertTrue("missing element", CollectionTools.contains(a, null));
assertTrue("missing element", CollectionTools.contains(a, "one"));
assertTrue("missing element", CollectionTools.contains(a, "two"));
assertTrue("missing element", CollectionTools.contains(a, "three"));
assertTrue("missing element", CollectionTools.contains(a, "four"));
}
public void testToArrayObjectArray() {
String[] a = new String[12];
a[11] = "not null";
String[] b = (String[]) this.bag.toArray(a);
assertEquals("different array", a, b);
assertEquals("incorrect length", 12, a.length);
assertTrue("missing element", CollectionTools.contains(a, null));
assertTrue("missing element", CollectionTools.contains(a, "one"));
assertTrue("missing element", CollectionTools.contains(a, "two"));
assertTrue("missing element", CollectionTools.contains(a, "three"));
assertTrue("missing element", CollectionTools.contains(a, "four"));
assertTrue("missing null element", a[11] == null);
}
public void testToString() {
String s = this.bag.toString();
assertTrue("invalid string prefix", s.startsWith("["));
assertTrue("invalid string suffix", s.endsWith("]"));
int commaCount = 0;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == ',') {
commaCount++;
}
}
assertEquals("invalid number of commas", 10, commaCount);
assertTrue("missing element toString()", s.indexOf("one") != -1);
assertTrue("missing element toString()", s.indexOf("two") != -1);
assertTrue("missing element toString()", s.indexOf("three") != -1);
assertTrue("missing element toString()", s.indexOf("four") != -1);
assertTrue("missing element toString()", s.indexOf("null") != -1);
}
}