package org.infinispan.util;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.assertTrue;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.infinispan.commons.equivalence.ByteArrayEquivalence;
import org.infinispan.commons.equivalence.Equivalence;
import org.infinispan.commons.equivalence.EquivalentHashSet;
import org.testng.annotations.Test;
/**
* Tests that {@link EquivalentHashSet} is functionally correct.
*
* @author Galder ZamarreƱo
* @since 5.3
*/
@Test(groups = "functional", testName = "util.EquivalentHashSetTest")
public class EquivalentHashSetTest {
protected static final Equivalence<byte[]> EQUIVALENCE =
new DebugByteArrayEquivalence();
public void testJdkMapExpectations() {
byteArrayContainsKey(createStandardSet(), false);
byteArrayRemove(createStandardSet(), false);
byteArrayAddSameValueTwice(createStandardSet(), false);
byteArrayAddAll(createStandardSet(), 3);
byteArrayContainsAll(createStandardSet(), false);
byteArrayEquals(createStandardSet(), createStandardSet(), false);
byteArrayIteratorRemove(createStandardSet(), true);
}
public void testByteArrayContainsKey() {
byteArrayContainsKey(createEquivalentSet(), true);
}
public void testByteArrayRemove() {
byteArrayRemove(createEquivalentSet(), true);
}
public void testByteArrayAddSameValueTwice() {
byteArrayAddSameValueTwice(createEquivalentSet(), true);
}
public void testByteArrayAddAll() {
byteArrayAddAll(createEquivalentSet(), 2);
}
public void testByteArrayContainsAll() {
byteArrayContainsAll(createEquivalentSet(), true);
}
public void testByteArrayEquals() {
byteArrayEquals(createEquivalentSet(), createEquivalentSet(), true);
}
public void testByteArrayIteratorRemove() {
byteArrayIteratorRemove(createEquivalentSet(), true);
}
protected void byteArrayContainsKey(
Set<byte[]> set, boolean expectFound) {
byte[] entry = {1, 2, 3};
set.add(entry);
byte[] lookup = {1, 2, 3}; // on purpose, different instance required
if (expectFound)
assertTrue(String.format(
"Expected entry=%s to be in collection", str(lookup)),
set.contains(lookup));
else
assertFalse(set.contains(lookup));
}
protected void byteArrayRemove(
Set<byte[]> set, boolean expectRemove) {
byte[] entry = {1, 2, 3};
set.add(entry);
byte[] remove = {1, 2, 3}; // on purpose, different instance required
if (expectRemove)
assertTrue(String.format(
"Expected entry=%s to be removed", str(remove)),
set.remove(remove));
else
assertFalse(set.remove(remove));
}
protected void byteArrayAddSameValueTwice(
Set<byte[]> set, boolean expectFound) {
byte[] entry = {1, 2, 3};
set.add(entry);
byte[] entry2 = {1, 2, 3}; // on purpose, different instance required
if (expectFound)
assertFalse(String.format(
"Expected putting %s again to return true", str(entry)),
set.add(entry2));
else
assertTrue(set.add(entry2));
}
protected void byteArrayAddAll(Set<byte[]> set, int expectCount) {
byte[] entry = {1, 2, 3};
set.add(entry);
Set<byte[]> data = new HashSet<byte[]>();
data.add(new byte[]{1, 2, 3});
data.add(new byte[]{11, 22, 33});
set.addAll(data);
assertEquals(expectCount, set.size());
}
protected void byteArrayContainsAll(
Set<byte[]> set, boolean expectFound) {
byte[] entry = {1, 2, 3};
set.add(entry);
Set<byte[]> data = new HashSet<byte[]>();
data.add(new byte[]{1, 2, 3});
if (expectFound)
assertTrue(set.containsAll(data));
else
assertFalse(set.containsAll(data));
}
protected void byteArrayEquals(Set<byte[]> set1,
Set<byte[]> set2, boolean expectEquals) {
set1.add(new byte[]{1, 2, 3});
set1.add(new byte[]{4, 5, 6});
set2.add(new byte[]{1, 2, 3});
set2.add(new byte[]{4, 5, 6});
if (expectEquals) {
assertEquals(set1, set2);
assertEquals(set1.hashCode(), set2.hashCode());
} else
assertFalse(String.format(
"Expected set1=%s to be distinct to set2=%s",
set1.toString(), set2.toString()), set1.equals(set2));
}
protected void byteArrayIteratorRemove(Set<byte[]> set1, boolean expectRemove) {
set1.add(new byte[]{1, 2, 3});
Iterator<byte[]> it1 = set1.iterator();
byte[] entry1 = it1.next();
if (expectRemove) {
it1.remove();
assertTrue(set1.isEmpty());
}
else
assertFalse(set1.isEmpty());
}
protected Set<byte[]> createStandardSet() {
return new HashSet<byte[]>();
}
protected Set<byte[]> createEquivalentSet() {
return new EquivalentHashSet<byte[]>(EQUIVALENCE);
}
private String str(byte[] array) {
// Ignore IDE warning about hashCode() call!!
return array != null
? Arrays.toString(array) + "@" + Integer.toHexString(array.hashCode())
: "null";
}
private static class DebugByteArrayEquivalence implements Equivalence<byte[]> {
final Equivalence<byte[]> delegate = ByteArrayEquivalence.INSTANCE;
@Override
public int hashCode(Object obj) {
return delegate.hashCode(obj);
}
@Override
public boolean equals(byte[] obj, Object otherObj) {
return delegate.equals(obj, otherObj);
}
@Override
public String toString(Object obj) {
return delegate.toString(obj) + "@" + Integer.toHexString(obj.hashCode());
}
@Override
public boolean isComparable(Object obj) {
return delegate.isComparable(obj);
}
@Override
public int compare(byte[] obj, byte[] otherObj) {
return delegate.compare(obj, otherObj);
}
}
}