| /******************************************************************************* |
| * Copyright (c) 2007, 2010 Oracle. All rights reserved. |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v1.0, which accompanies this distribution |
| * and is available at http://www.eclipse.org/legal/epl-v10.html. |
| * |
| * Contributors: |
| * Oracle - initial API and implementation |
| ******************************************************************************/ |
| package org.eclipse.jpt.common.utility.tests.internal; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.ConcurrentModificationException; |
| import java.util.Iterator; |
| import java.util.NoSuchElementException; |
| |
| import junit.framework.TestCase; |
| |
| import org.eclipse.jpt.common.utility.internal.ArrayTools; |
| import org.eclipse.jpt.common.utility.internal.CollectionTools; |
| import org.eclipse.jpt.common.utility.internal.IdentityHashBag; |
| import org.eclipse.jpt.common.utility.internal.Tools; |
| |
| @SuppressWarnings("nls") |
| public class IdentityHashBagTests extends TestCase { |
| private IdentityHashBag<String> bag; |
| private String one = "one"; |
| private String two = "two"; |
| private String three = "three"; |
| private String four = "four"; |
| private String foo = "foo"; |
| private String bar = "bar"; |
| |
| public IdentityHashBagTests(String name) { |
| super(name); |
| } |
| |
| @Override |
| protected void setUp() throws Exception { |
| super.setUp(); |
| this.bag = this.buildBag(); |
| } |
| |
| protected IdentityHashBag<String> buildBag() { |
| IdentityHashBag<String> result = new IdentityHashBag<String>(); |
| result.add(null); |
| result.add(this.one); |
| result.add(this.two); |
| result.add(this.two); |
| result.add(this.three); |
| result.add(this.three); |
| result.add(this.three); |
| result.add(this.four); |
| result.add(this.four); |
| result.add(this.four); |
| result.add(this.four); |
| return result; |
| } |
| |
| @Override |
| protected void tearDown() throws Exception { |
| TestTools.clear(this); |
| super.tearDown(); |
| } |
| |
| private Collection<String> buildCollection() { |
| Collection<String> c = new ArrayList<String>(); |
| c.add(this.foo); |
| c.add(this.foo); |
| c.add(this.bar); |
| c.add(this.bar); |
| c.add(this.bar); |
| return c; |
| } |
| |
| public void testCtorCollection() { |
| Collection<String> c = this.buildCollection(); |
| IdentityHashBag<String> localBag = new IdentityHashBag<String>(c); |
| for (String s : c) { |
| assertTrue(localBag.contains(s)); |
| } |
| } |
| |
| public void testCtorIntFloat() { |
| boolean exCaught; |
| |
| exCaught = false; |
| try { |
| this.bag = new IdentityHashBag<String>(-20, 0.66f); |
| } catch (IllegalArgumentException ex) { |
| exCaught = true; |
| } |
| assertTrue("IllegalArgumentException not thrown", exCaught); |
| |
| exCaught = false; |
| try { |
| this.bag = new IdentityHashBag<String>(20, -0.66f); |
| } catch (IllegalArgumentException ex) { |
| exCaught = true; |
| } |
| assertTrue("IllegalArgumentException not thrown", exCaught); |
| } |
| |
| public void testAdd() { |
| // the other adds took place in setUp |
| String five = "five"; |
| assertTrue(this.bag.add(five)); |
| |
| assertTrue(this.bag.contains(this.one)); |
| assertTrue(this.bag.contains(this.two)); |
| assertTrue(this.bag.contains(this.three)); |
| assertTrue(this.bag.contains(this.four)); |
| assertTrue(this.bag.contains(five)); |
| } |
| |
| public void testAddCount() { |
| String minus3 = "minus3"; |
| String zero = "zero"; |
| String five = "five"; |
| // the other adds took place in setUp |
| this.bag.add(minus3, -3); |
| this.bag.add(zero, 0); |
| this.bag.add(five, 5); |
| |
| assertFalse(this.bag.contains(minus3)); |
| assertFalse(this.bag.contains(zero)); |
| assertEquals(1, this.bag.count(this.one)); |
| assertEquals(2, this.bag.count(this.two)); |
| assertEquals(3, this.bag.count(this.three)); |
| assertEquals(4, this.bag.count(this.four)); |
| assertEquals(5, this.bag.count(five)); |
| |
| this.bag.add(this.three, 2); |
| assertEquals(5, this.bag.count(this.three)); |
| } |
| |
| public void testAddAll() { |
| Collection<String> c = this.buildCollection(); |
| assertTrue(this.bag.addAll(c)); |
| for (String s : c) { |
| assertTrue(this.bag.contains(s)); |
| } |
| } |
| |
| public void testClear() { |
| assertTrue(this.bag.contains(this.one)); |
| assertTrue(this.bag.contains(this.two)); |
| assertTrue(this.bag.contains(this.three)); |
| assertTrue(this.bag.contains(this.four)); |
| assertTrue(this.bag.contains(null)); |
| assertEquals(11, this.bag.size()); |
| this.bag.clear(); |
| assertFalse(this.bag.contains(this.one)); |
| assertFalse(this.bag.contains(this.two)); |
| assertFalse(this.bag.contains(this.three)); |
| assertFalse(this.bag.contains(this.four)); |
| assertFalse(this.bag.contains(null)); |
| assertEquals(0, this.bag.size()); |
| } |
| |
| public void testClone() { |
| IdentityHashBag<String> bag2 = 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(this.bag.contains(null)); |
| assertTrue(this.bag.contains(this.one)); |
| assertTrue(this.bag.contains(this.two)); |
| assertTrue(this.bag.contains(this.three)); |
| assertTrue(this.bag.contains(this.four)); |
| |
| assertFalse(this.bag.contains(new String("four"))); |
| assertFalse(this.bag.contains("five")); |
| } |
| |
| public void testContainsAll() { |
| Collection<String> c = new ArrayList<String>(); |
| c.add(null); |
| c.add(this.one); |
| c.add(this.two); |
| c.add(this.three); |
| c.add(this.four); |
| assertTrue(this.bag.containsAll(c)); |
| c.add(new String(this.four)); |
| assertFalse(this.bag.containsAll(c)); |
| } |
| |
| public void testCount() { |
| assertEquals(0, this.bag.count("zero")); |
| assertEquals(1, this.bag.count("one")); |
| assertEquals(2, this.bag.count("two")); |
| assertEquals(3, this.bag.count("three")); |
| assertEquals(4, this.bag.count("four")); |
| assertEquals(0, this.bag.count("five")); |
| } |
| |
| public void testEquals() { |
| IdentityHashBag<String> bag2 = this.buildBag(); |
| assertEquals(this.bag, bag2); |
| bag2.add("five"); |
| assertFalse(this.bag.equals(bag2)); |
| Collection<String> c = new ArrayList<String>(this.bag); |
| assertFalse(this.bag.equals(c)); |
| } |
| |
| public void testHashCode() { |
| IdentityHashBag<String> bag2 = this.buildBag(); |
| assertEquals(this.bag.hashCode(), bag2.hashCode()); |
| } |
| |
| public void testIsEmpty() { |
| assertFalse(this.bag.isEmpty()); |
| this.bag.clear(); |
| assertTrue(this.bag.isEmpty()); |
| this.bag.add("foo"); |
| assertFalse(this.bag.isEmpty()); |
| } |
| |
| public void testEmptyIterator() { |
| this.bag.clear(); |
| Iterator<String> iterator = this.bag.iterator(); |
| assertFalse(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<String> iterator = this.bag.iterator(); |
| assertTrue(iterator.hasNext()); |
| while (iterator.hasNext()) { |
| iterator.next(); |
| i++; |
| } |
| assertEquals(11, i); |
| assertFalse(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(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<String> iterator = this.bag.uniqueIterator(); |
| assertTrue(iterator.hasNext()); |
| while (iterator.hasNext()) { |
| iterator.next(); |
| i++; |
| } |
| assertEquals(5, i); |
| assertFalse(iterator.hasNext()); |
| |
| boolean exCaught = false; |
| Object element = null; |
| try { |
| element = iterator.next(); |
| fail(element.toString()); |
| } catch (NoSuchElementException ex) { |
| exCaught = true; |
| } |
| assertTrue(exCaught); |
| |
| // start over |
| iterator = this.bag.uniqueIterator(); |
| Object next = null; |
| while (iterator.hasNext() && !this.four.equals(next)) { |
| next = iterator.next(); |
| } |
| iterator.remove(); |
| assertEquals(7, this.bag.size()); |
| |
| exCaught = false; |
| try { |
| iterator.remove(); |
| } catch (IllegalStateException ex) { |
| exCaught = true; |
| } |
| assertTrue(exCaught); |
| |
| // start over |
| iterator = this.bag.uniqueIterator(); |
| String five = "five"; |
| this.bag.add(five); |
| exCaught = false; |
| try { |
| iterator.next(); |
| } catch (ConcurrentModificationException ex) { |
| exCaught = true; |
| } |
| assertTrue(exCaught); |
| } |
| |
| public void testEntries() { |
| int i = 0; |
| Iterator<org.eclipse.jpt.common.utility.internal.Bag.Entry<String>> iterator = this.bag.entries(); |
| assertTrue(iterator.hasNext()); |
| while (iterator.hasNext()) { |
| iterator.next(); |
| i++; |
| } |
| assertEquals(5, i); |
| assertFalse(iterator.hasNext()); |
| |
| boolean exCaught = false; |
| Object element = null; |
| try { |
| element = iterator.next(); |
| fail(element.toString()); |
| } catch (NoSuchElementException ex) { |
| exCaught = true; |
| } |
| assertTrue(exCaught); |
| |
| // start over |
| iterator = this.bag.entries(); |
| org.eclipse.jpt.common.utility.internal.Bag.Entry<String> next = null; |
| while (iterator.hasNext()) { |
| next = iterator.next(); |
| if (next.getElement().equals(this.four)) { |
| iterator.remove(); |
| break; |
| } |
| } |
| assertEquals(7, this.bag.size()); |
| |
| exCaught = false; |
| try { |
| iterator.remove(); |
| } catch (IllegalStateException ex) { |
| exCaught = true; |
| } |
| assertTrue(exCaught); |
| |
| // start over |
| iterator = this.bag.entries(); |
| String five = "five"; |
| this.bag.add(five); |
| exCaught = false; |
| try { |
| iterator.next(); |
| } catch (ConcurrentModificationException ex) { |
| exCaught = true; |
| } |
| assertTrue(exCaught); |
| } |
| |
| public void testHashingDistribution() throws Exception { |
| IdentityHashBag<String> bigBag = new IdentityHashBag<String>(); |
| 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); |
| if ((loadFactor < 0.20) || (loadFactor > 0.80)) { |
| String msg = "poor load factor: " + loadFactor; |
| if (Tools.jvmIsSun()) { |
| fail(msg); |
| } else { |
| // poor load factor is seen in the Eclipse build environment for some reason... |
| System.out.println(this.getClass().getName() + '.' + this.getName() + " - " + msg); |
| TestTools.printSystemProperties(); |
| } |
| } |
| } |
| |
| public void testRemove() { |
| assertTrue(this.bag.remove(this.one)); |
| assertFalse(this.bag.contains(this.one)); |
| assertFalse(this.bag.remove(this.one)); |
| |
| assertTrue(this.bag.remove(this.two)); |
| assertTrue(this.bag.remove(this.two)); |
| assertFalse(this.bag.contains(this.two)); |
| assertFalse(this.bag.remove(this.two)); |
| |
| assertFalse(this.bag.remove(new String(this.three))); |
| } |
| |
| public void testRemoveCount() { |
| assertFalse(this.bag.remove(this.one, 0)); |
| assertTrue(this.bag.contains(this.one)); |
| |
| assertTrue(this.bag.remove(this.one, 1)); |
| assertFalse(this.bag.contains(this.one)); |
| assertFalse(this.bag.remove(this.one)); |
| |
| assertFalse(this.bag.remove(this.two, -3)); |
| assertTrue(this.bag.remove(this.two, 1)); |
| assertTrue(this.bag.contains(this.two)); |
| |
| assertTrue(this.bag.remove(this.two, 1)); |
| assertFalse(this.bag.contains(this.two)); |
| assertFalse(this.bag.remove(this.two)); |
| |
| assertTrue(this.bag.remove(this.three, 3)); |
| assertFalse(this.bag.contains(this.three)); |
| assertFalse(this.bag.remove(this.three)); |
| } |
| |
| public void testRemoveAll() { |
| Collection<String> c = new ArrayList<String>(); |
| c.add(this.one); |
| c.add(new String(this.two)); |
| c.add(this.three); |
| assertTrue(this.bag.removeAll(c)); |
| assertFalse(this.bag.contains(this.one)); |
| assertTrue(this.bag.contains(this.two)); |
| assertFalse(this.bag.contains(this.three)); |
| assertFalse(this.bag.remove(this.one)); |
| assertTrue(this.bag.remove(this.two)); |
| assertFalse(this.bag.remove(this.three)); |
| assertFalse(this.bag.removeAll(c)); |
| } |
| |
| public void testRetainAll() { |
| Collection<String> c = new ArrayList<String>(); |
| c.add(this.one); |
| c.add(new String(this.two)); |
| c.add(this.three); |
| assertTrue(this.bag.retainAll(c)); |
| assertTrue(this.bag.contains(this.one)); |
| assertFalse(this.bag.contains(this.two)); |
| assertTrue(this.bag.contains(this.three)); |
| assertFalse(this.bag.contains(this.four)); |
| assertFalse(this.bag.remove(this.two)); |
| assertFalse(this.bag.remove(this.four)); |
| assertFalse(this.bag.retainAll(c)); |
| } |
| |
| public void testSize() { |
| assertTrue(this.bag.size() == 11); |
| String five = "five"; |
| this.bag.add(five); |
| this.bag.add(five); |
| this.bag.add(five); |
| this.bag.add(five); |
| this.bag.add(new String(five)); |
| assertEquals(16, this.bag.size()); |
| } |
| |
| public void testSerialization() throws Exception { |
| IdentityHashBag<String> bag2 = TestTools.serialize(this.bag); |
| |
| assertTrue("same object?", this.bag != bag2); |
| assertEquals(11, bag2.size()); |
| assertEquals(CollectionTools.bag(this.bag.iterator()), CollectionTools.bag(bag2.iterator())); |
| // look for similar elements |
| assertTrue(CollectionTools.bag(bag2.iterator()).contains(null)); |
| assertTrue(CollectionTools.bag(bag2.iterator()).contains("one")); |
| assertTrue(CollectionTools.bag(bag2.iterator()).contains("two")); |
| assertTrue(CollectionTools.bag(bag2.iterator()).contains("three")); |
| assertTrue(CollectionTools.bag(bag2.iterator()).contains("four")); |
| |
| int nullCount = 0, oneCount = 0, twoCount = 0, threeCount = 0, fourCount = 0; |
| for (String next : bag2) { |
| 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(1, nullCount); |
| assertEquals(1, oneCount); |
| assertEquals(2, twoCount); |
| assertEquals(3, threeCount); |
| assertEquals(4, fourCount); |
| } |
| |
| public void testToArray() { |
| Object[] a = this.bag.toArray(); |
| assertEquals(11, a.length); |
| assertTrue(ArrayTools.contains(a, null)); |
| assertTrue(ArrayTools.contains(a, this.one)); |
| assertTrue(ArrayTools.contains(a, this.two)); |
| assertTrue(ArrayTools.contains(a, this.three)); |
| assertTrue(ArrayTools.contains(a, this.four)); |
| } |
| |
| public void testToArrayObjectArray() { |
| String[] a = new String[12]; |
| a[11] = "not null"; |
| String[] b = this.bag.toArray(a); |
| assertEquals(a, b); |
| assertEquals(12, a.length); |
| assertTrue(ArrayTools.contains(a, null)); |
| assertTrue(ArrayTools.contains(a, this.one)); |
| assertTrue(ArrayTools.contains(a, this.two)); |
| assertTrue(ArrayTools.contains(a, this.three)); |
| assertTrue(ArrayTools.contains(a, this.four)); |
| assertTrue(a[11] == null); |
| } |
| |
| public void testToString() { |
| String s = this.bag.toString(); |
| assertTrue(s.startsWith("[")); |
| assertTrue(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(s.indexOf("one") != -1); |
| assertTrue(s.indexOf("two") != -1); |
| assertTrue(s.indexOf("three") != -1); |
| assertTrue(s.indexOf("four") != -1); |
| assertTrue(s.indexOf("null") != -1); |
| } |
| |
| } |