/* __ __ __ __ __ ___
* \ \ / / \ \ / / __/
* \ \/ / /\ \ \/ / /
* \____/__/ \__\____/__/.ɪᴏ
* ᶜᵒᵖʸʳᶦᵍʰᵗ ᵇʸ ᵛᵃᵛʳ ⁻ ˡᶦᶜᵉⁿˢᵉᵈ ᵘⁿᵈᵉʳ ᵗʰᵉ ᵃᵖᵃᶜʰᵉ ˡᶦᶜᵉⁿˢᵉ ᵛᵉʳˢᶦᵒⁿ ᵗʷᵒ ᵈᵒᵗ ᶻᵉʳᵒ
*/
package io.vavr.collection;
import io.vavr.Tuple;
import io.vavr.Value;
import io.vavr.Tuple2;
import org.assertj.core.api.*;
import org.junit.Test;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Spliterator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;
import static org.junit.Assert.assertTrue;
public class HashSetTest extends AbstractSetTest {
@Override
protected <T> IterableAssert<T> assertThat(Iterable<T> actual) {
return new IterableAssert<T>(actual) {
@Override
public IterableAssert<T> isEqualTo(Object obj) {
@SuppressWarnings("unchecked")
final Iterable<T> expected = (Iterable<T>) obj;
final java.util.Map<T, Integer> actualMap = countMap(actual);
final java.util.Map<T, Integer> expectedMap = countMap(expected);
assertThat(actualMap.size()).isEqualTo(expectedMap.size());
actualMap.keySet().forEach(k -> assertThat(actualMap.get(k)).isEqualTo(expectedMap.get(k)));
return this;
}
private java.util.Map<T, Integer> countMap(Iterable<? extends T> it) {
final java.util.HashMap<T, Integer> cnt = new java.util.HashMap<>();
it.forEach(i -> cnt.merge(i, 1, (v1, v2) -> v1 + v2));
return cnt;
}
};
}
@Override
protected <T> ObjectAssert<T> assertThat(T actual) {
return new ObjectAssert<T>(actual) {
};
}
@Override
protected BooleanAssert assertThat(Boolean actual) {
return new BooleanAssert(actual) {
};
}
@Override
protected DoubleAssert assertThat(Double actual) {
return new DoubleAssert(actual) {
};
}
@Override
protected IntegerAssert assertThat(Integer actual) {
return new IntegerAssert(actual) {
};
}
@Override
protected LongAssert assertThat(Long actual) {
return new LongAssert(actual) {
};
}
@Override
protected StringAssert assertThat(String actual) {
return new StringAssert(actual) {
};
}
// -- construction
@Override
protected <T> Collector<T, ArrayList<T>, HashSet<T>> collector() {
return HashSet.collector();
}
@Override
protected <T> HashSet<T> empty() {
return HashSet.empty();
}
@Override
protected <T> HashSet<T> emptyWithNull() {
return empty();
}
@Override
protected <T> HashSet<T> of(T element) {
return HashSet.of(element);
}
@SuppressWarnings("varargs")
@SafeVarargs
@Override
protected final <T> HashSet<T> of(T... elements) {
return HashSet.of(elements);
}
@Override
protected <T> HashSet<T> ofAll(Iterable<? extends T> elements) {
return HashSet.ofAll(elements);
}
@Override
protected <T extends Comparable<? super T>> HashSet<T> ofJavaStream(java.util.stream.Stream<? extends T> javaStream) {
return HashSet.ofAll(javaStream);
}
@Override
protected HashSet<Boolean> ofAll(boolean... elements) {
return HashSet.ofAll(elements);
}
@Override
protected HashSet<Byte> ofAll(byte... elements) {
return HashSet.ofAll(elements);
}
@Override
protected HashSet<Character> ofAll(char... elements) {
return HashSet.ofAll(elements);
}
@Override
protected HashSet<Double> ofAll(double... elements) {
return HashSet.ofAll(elements);
}
@Override
protected HashSet<Float> ofAll(float... elements) {
return HashSet.ofAll(elements);
}
@Override
protected HashSet<Integer> ofAll(int... elements) {
return HashSet.ofAll(elements);
}
@Override
protected HashSet<Long> ofAll(long... elements) {
return HashSet.ofAll(elements);
}
@Override
protected HashSet<Short> ofAll(short... elements) {
return HashSet.ofAll(elements);
}
@Override
protected <T> HashSet<T> tabulate(int n, Function<? super Integer, ? extends T> f) {
return HashSet.tabulate(n, f);
}
@Override
protected <T> HashSet<T> fill(int n, Supplier<? extends T> s) {
return HashSet.fill(n, s);
}
@Override
protected int getPeekNonNilPerformingAnAction() {
return 1;
}
// -- static narrow
@Test
public void shouldNarrowHashSet() {
final HashSet<Double> doubles = of(1.0d);
final HashSet<Number> numbers = HashSet.narrow(doubles);
final int actual = numbers.add(new BigDecimal("2.0")).sum().intValue();
assertThat(actual).isEqualTo(3);
}
// -- slideBy is not expected to work for larger subsequences, due to unspecified iteration order
@Test
public void shouldSlideNonNilBySomeClassifier() {
// ignore
}
// TODO move to traversable
// -- zip
@Test
public void shouldZipNils() {
final HashSet<Tuple2<Object, Object>> actual = empty().zip(empty());
assertThat(actual).isEqualTo(empty());
}
@Test
public void shouldZipEmptyAndNonNil() {
final HashSet<Tuple2<Object, Integer>> actual = empty().zip(of(1));
assertThat(actual).isEqualTo(empty());
}
@Test
public void shouldZipNonEmptyAndNil() {
final HashSet<Tuple2<Integer, Integer>> actual = of(1).zip(empty());
assertThat(actual).isEqualTo(empty());
}
@Test
public void shouldZipNonNilsIfThisIsSmaller() {
final HashSet<Tuple2<Integer, String>> actual = of(1, 2).zip(of("a", "b", "c"));
final HashSet<Tuple2<Integer, String>> expected = of(Tuple.of(1, "a"), Tuple.of(2, "b"));
assertThat(actual).isEqualTo(expected);
}
@Test
public void shouldZipNonNilsIfThatIsSmaller() {
final HashSet<Tuple2<Integer, String>> actual = of(1, 2, 3).zip(of("a", "b"));
final HashSet<Tuple2<Integer, String>> expected = of(Tuple.of(1, "a"), Tuple.of(2, "b"));
assertThat(actual).isEqualTo(expected);
}
@Test
public void shouldZipNonNilsOfSameSize() {
final HashSet<Tuple2<Integer, String>> actual = of(1, 2, 3).zip(of("a", "b", "c"));
final HashSet<Tuple2<Integer, String>> expected = of(Tuple.of(1, "a"), Tuple.of(2, "b"), Tuple.of(3, "c"));
assertThat(actual).isEqualTo(expected);
}
@Test(expected = NullPointerException.class)
public void shouldThrowIfZipWithThatIsNull() {
empty().zip(null);
}
// TODO move to traversable
// -- zipAll
@Test
public void shouldZipAllNils() {
// ignore
}
@Test
public void shouldZipAllEmptyAndNonNil() {
// ignore
}
@Test
public void shouldZipAllNonEmptyAndNil() {
final HashSet<?> actual = of(1).zipAll(empty(), null, null);
final HashSet<Tuple2<Integer, Object>> expected = of(Tuple.of(1, null));
assertThat(actual).isEqualTo(expected);
}
@Test
public void shouldZipAllNonNilsIfThisIsSmaller() {
final HashSet<Tuple2<Integer, String>> actual = of(1, 2).zipAll(of("a", "b", "c"), 9, "z");
final HashSet<Tuple2<Integer, String>> expected = of(Tuple.of(1, "a"), Tuple.of(2, "b"), Tuple.of(9, "c"));
assertThat(actual).isEqualTo(expected);
}
@Test
public void shouldZipAllNonNilsIfThatIsSmaller() {
final HashSet<Tuple2<Integer, String>> actual = of(1, 2, 3).zipAll(of("a", "b"), 9, "z");
final HashSet<Tuple2<Integer, String>> expected = of(Tuple.of(1, "a"), Tuple.of(2, "b"), Tuple.of(3, "z"));
assertThat(actual).isEqualTo(expected);
}
@Test
public void shouldZipAllNonNilsOfSameSize() {
final HashSet<Tuple2<Integer, String>> actual = of(1, 2, 3).zipAll(of("a", "b", "c"), 9, "z");
final HashSet<Tuple2<Integer, String>> expected = of(Tuple.of(1, "a"), Tuple.of(2, "b"), Tuple.of(3, "c"));
assertThat(actual).isEqualTo(expected);
}
@Test(expected = NullPointerException.class)
public void shouldThrowIfZipAllWithThatIsNull() {
empty().zipAll(null, null, null);
}
// TODO move to traversable
// -- zipWithIndex
@Test
public void shouldZipNilWithIndex() {
assertThat(this.<String> empty().zipWithIndex()).isEqualTo(this.<Tuple2<String, Integer>> empty());
}
@Test
public void shouldZipNonNilWithIndex() {
final HashSet<Tuple2<String, Integer>> actual = of("a", "b", "c").zipWithIndex();
final HashSet<Tuple2<String, Integer>> expected = of(Tuple.of("a", 0), Tuple.of("b", 1), Tuple.of("c", 2));
assertThat(actual).isEqualTo(expected);
}
// -- transform()
@Test
public void shouldTransform() {
final String transformed = of(42).transform(v -> String.valueOf(v.get()));
assertThat(transformed).isEqualTo("42");
}
// HashSet special cases
@Override
public void shouldDropRightAsExpectedIfCountIsLessThanSize() {
assertThat(of(1, 2, 3).dropRight(2)).isEqualTo(of(3));
}
@Override
public void shouldTakeRightAsExpectedIfCountIsLessThanSize() {
assertThat(of(1, 2, 3).takeRight(2)).isEqualTo(of(1, 2));
}
@Override
public void shouldGetInitOfNonNil() {
assertThat(of(1, 2, 3).init()).isEqualTo(of(2, 3));
}
@Override
public void shouldFoldRightNonNil() {
final String actual = of('a', 'b', 'c').foldRight("", (x, xs) -> x + xs);
final List<String> expected = List.of('a', 'b', 'c').permutations().map(List::mkString);
assertThat(actual).isIn(expected);
}
@Override
public void shouldReduceRightNonNil() {
final String actual = of("a", "b", "c").reduceRight((x, xs) -> x + xs);
final List<String> expected = List.of("a", "b", "c").permutations().map(List::mkString);
assertThat(actual).isIn(expected);
}
@Override
public void shouldMkStringWithDelimiterNonNil() {
final String actual = of('a', 'b', 'c').mkString(",");
final List<String> expected = List.of('a', 'b', 'c').permutations().map(l -> l.mkString(","));
assertThat(actual).isIn(expected);
}
@Override
public void shouldMkStringWithDelimiterAndPrefixAndSuffixNonNil() {
final String actual = of('a', 'b', 'c').mkString("[", ",", "]");
final List<String> expected = List.of('a', 'b', 'c').permutations().map(l -> l.mkString("[", ",", "]"));
assertThat(actual).isIn(expected);
}
@Override
public void shouldComputeDistinctByOfNonEmptyTraversableUsingComparator() {
// TODO
}
@Override
public void shouldComputeDistinctByOfNonEmptyTraversableUsingKeyExtractor() {
// TODO
}
@Override
public void shouldFindLastOfNonNil() {
final int actual = of(1, 2, 3, 4).findLast(i -> i % 2 == 0).get();
assertThat(actual).isIn(List.of(1, 2, 3, 4));
}
@Override
public void shouldThrowWhenFoldRightNullOperator() {
throw new NullPointerException(); // TODO
}
@Override
public void shouldReturnSomeInitWhenCallingInitOptionOnNonNil() {
// TODO
}
@Test
public void shouldBeEqual() {
assertTrue(HashSet.of(1).equals(HashSet.of(1)));
}
@Override
protected boolean useIsEqualToInsteadOfIsSameAs() {
return false;
}
@Override
protected HashSet<Character> range(char from, char toExclusive) {
return HashSet.range(from, toExclusive);
}
@Override
protected HashSet<Character> rangeBy(char from, char toExclusive, int step) {
return HashSet.rangeBy(from, toExclusive, step);
}
@Override
protected HashSet<Double> rangeBy(double from, double toExclusive, double step) {
return HashSet.rangeBy(from, toExclusive, step);
}
@Override
protected HashSet<Integer> range(int from, int toExclusive) {
return HashSet.range(from, toExclusive);
}
@Override
protected HashSet<Integer> rangeBy(int from, int toExclusive, int step) {
return HashSet.rangeBy(from, toExclusive, step);
}
@Override
protected HashSet<Long> range(long from, long toExclusive) {
return HashSet.range(from, toExclusive);
}
@Override
protected HashSet<Long> rangeBy(long from, long toExclusive, long step) {
return HashSet.rangeBy(from, toExclusive, step);
}
@Override
protected HashSet<Character> rangeClosed(char from, char toInclusive) {
return HashSet.rangeClosed(from, toInclusive);
}
@Override
protected HashSet<Character> rangeClosedBy(char from, char toInclusive, int step) {
return HashSet.rangeClosedBy(from, toInclusive, step);
}
@Override
protected HashSet<Double> rangeClosedBy(double from, double toInclusive, double step) {
return HashSet.rangeClosedBy(from, toInclusive, step);
}
@Override
protected HashSet<Integer> rangeClosed(int from, int toInclusive) {
return HashSet.rangeClosed(from, toInclusive);
}
@Override
protected HashSet<Integer> rangeClosedBy(int from, int toInclusive, int step) {
return HashSet.rangeClosedBy(from, toInclusive, step);
}
@Override
protected HashSet<Long> rangeClosed(long from, long toInclusive) {
return HashSet.rangeClosed(from, toInclusive);
}
@Override
protected HashSet<Long> rangeClosedBy(long from, long toInclusive, long step) {
return HashSet.rangeClosedBy(from, toInclusive, step);
}
// -- toSet
@Test
public void shouldReturnSelfOnConvertToSet() {
final Value<Integer> value = of(1, 2, 3);
assertThat(value.toSet()).isSameAs(value);
}
// -- spliterator
@Test
public void shouldNotHaveSortedSpliterator() {
assertThat(of(1, 2, 3).spliterator().hasCharacteristics(Spliterator.SORTED)).isFalse();
}
@Test
public void shouldNotHaveOrderedSpliterator() {
assertThat(of(1, 2, 3).spliterator().hasCharacteristics(Spliterator.ORDERED)).isFalse();
}
// -- isSequential()
@Test
public void shouldReturnFalseWhenIsSequentialCalled() {
assertThat(of(1, 2, 3).isSequential()).isFalse();
}
}