// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.collections;
import org.junit.Test;
import org.mockito.Mockito;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Set;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
* @author Simon Thoresen Hult
*/
public class LazySetTest {
@Test
public void requireThatInitialDelegateIsEmpty() {
LazySet set = newLazySet(new HashSet());
assertEquals(LazySet.EmptySet.class, set.getDelegate().getClass());
}
@Test
public void requireThatEmptySetAddUpgradesToSingletonSet() {
LazySet set = newLazySet(new HashSet());
assertTrue(set.add("foo"));
assertEquals(LazySet.SingletonSet.class, set.getDelegate().getClass());
set = newLazySet(new HashSet());
assertTrue(set.addAll(Arrays.asList("foo")));
assertEquals(LazySet.SingletonSet.class, set.getDelegate().getClass());
}
@Test
public void requireThatEmptySetAddAllEmptySetDoesNotUpgradeToSingletonSet() {
LazySet set = newLazySet(new HashSet());
assertFalse(set.addAll(Collections.emptySet()));
assertEquals(LazySet.EmptySet.class, set.getDelegate().getClass());
}
@Test
public void requireThatEmptySetAddAllUpgradesToFinalSet() {
Set delegate = new HashSet<>();
LazySet set = newLazySet(delegate);
assertTrue(set.addAll(Arrays.asList("foo", "bar")));
assertSame(delegate, set.getDelegate());
assertEquals(2, delegate.size());
assertTrue(delegate.contains("foo"));
assertTrue(delegate.contains("bar"));
}
@Test
public void requireThatSingletonSetRemoveEntryDowngradesToEmptySet() {
LazySet set = newSingletonSet("foo");
assertTrue(set.remove("foo"));
assertEquals(LazySet.EmptySet.class, set.getDelegate().getClass());
}
@Test
public void requireThatSingletonSetRemoveUnknownDoesNotDowngradesToEmptySet() {
LazySet set = newSingletonSet("foo");
assertFalse(set.remove("bar"));
assertEquals(LazySet.SingletonSet.class, set.getDelegate().getClass());
}
@Test
public void requireThatSingletonSetAddAllEmptySetDoesNotUpgradeToFinalSet() {
LazySet set = newSingletonSet("foo");
assertFalse(set.addAll(Collections.emptySet()));
assertEquals(LazySet.SingletonSet.class, set.getDelegate().getClass());
}
@Test
public void requireThatSingletonSetAddKnownDoesNotUpgradeToFinalSet() {
LazySet set = newSingletonSet("foo");
assertFalse(set.add("foo"));
assertEquals(LazySet.SingletonSet.class, set.getDelegate().getClass());
}
@Test
public void requireThatSingletonSetAddUpgradesToFinalSet() {
Set delegate = new HashSet<>();
LazySet set = newSingletonSet(delegate, "foo");
assertTrue(set.add("bar"));
assertSame(delegate, set.getDelegate());
assertEquals(2, delegate.size());
assertTrue(delegate.contains("foo"));
assertTrue(delegate.contains("bar"));
}
@Test
public void requireThatSingletonSetAddAllUpgradesToFinalSet() {
Set delegate = new HashSet<>();
LazySet set = newSingletonSet(delegate, "foo");
assertTrue(set.addAll(Arrays.asList("bar")));
assertSame(delegate, set.getDelegate());
assertEquals(2, delegate.size());
assertTrue(delegate.contains("foo"));
assertTrue(delegate.contains("bar"));
delegate = new HashSet<>();
set = newSingletonSet(delegate, "foo");
assertTrue(set.addAll(Arrays.asList("bar", "baz")));
assertSame(delegate, set.getDelegate());
assertEquals(3, delegate.size());
assertTrue(delegate.contains("foo"));
assertTrue(delegate.contains("bar"));
assertTrue(delegate.contains("baz"));
}
@Test
public void requireThatSingletonIteratorNextThrowsIfInvokedMoreThanOnce() {
LazySet set = newSingletonSet("foo");
Iterator it = set.iterator();
it.next();
try {
it.next();
fail();
} catch (NoSuchElementException e) {
}
try {
it.next();
fail();
} catch (NoSuchElementException e) {
}
}
@Test
public void requireThatSingletonIteratorRemoveDowngradesToEmptySet() {
LazySet set = newSingletonSet("foo");
Iterator it = set.iterator();
it.next();
it.remove();
assertEquals(LazySet.EmptySet.class, set.getDelegate().getClass());
}
@Test
public void requireThatSingletonIteratorRemoveThrowsIfInvokedBeforeNext() {
LazySet set = newSingletonSet("foo");
Iterator it = set.iterator();
try {
it.remove();
fail();
} catch (IllegalStateException e) {
}
}
@SuppressWarnings("unchecked")
private static Set makeMockSet() {
return Mockito.mock(Set.class);
}
@Test
public void requireThatSetDelegates() {
Set delegate = makeMockSet();
Set set = newLazySet(delegate);
set.add("foo");
set.add("bar"); // trigger the assignment of the delegate
Mockito.verify(delegate).add("foo");
Mockito.verify(delegate).add("bar");
Set addAllArg = Collections.singleton("foo");
set.addAll(addAllArg);
Mockito.verify(delegate).addAll(addAllArg);
assertEquals(0, set.size());
Mockito.verify(delegate).size();
assertFalse(set.isEmpty());
Mockito.verify(delegate).isEmpty();
assertFalse(set.contains("foo"));
Mockito.verify(delegate).contains("foo");
assertNull(set.iterator());
Mockito.verify(delegate).iterator();
assertNull(set.toArray());
Mockito.verify(delegate).toArray();
String[] toArrayArg = new String[69];
assertNull(set.toArray(toArrayArg));
Mockito.verify(delegate).toArray(toArrayArg);
assertFalse(set.remove("foo"));
Mockito.verify(delegate).remove("foo");
Collection containsAllArg = Collections.singletonList("foo");
assertFalse(set.containsAll(containsAllArg));
Mockito.verify(delegate).containsAll(containsAllArg);
Collection retainAllArg = Collections.singletonList("foo");
assertFalse(set.retainAll(retainAllArg));
Mockito.verify(delegate).retainAll(retainAllArg);
Collection removeAllArg = Collections.singletonList("foo");
assertFalse(set.removeAll(removeAllArg));
Mockito.verify(delegate).removeAll(removeAllArg);
set.clear();
Mockito.verify(delegate).clear();
}
@Test
public void requireThatHashCodeIsImplemented() {
assertEquals(newLazySet(null).hashCode(),
newLazySet(null).hashCode());
}
@Test
public void requireThatEqualsIsImplemented() {
Set