/* __ __ __ __ __ ___
* \ \ / / \ \ / / __/
* \ \/ / /\ \ \/ / /
* \____/__/ \__\____/__/.ɪᴏ
* ᶜᵒᵖʸʳᶦᵍʰᵗ ᵇʸ ᵛᵃᵛʳ ⁻ ˡᶦᶜᵉⁿˢᵉᵈ ᵘⁿᵈᵉʳ ᵗʰᵉ ᵃᵖᵃᶜʰᵉ ˡᶦᶜᵉⁿˢᵉ ᵛᵉʳˢᶦᵒⁿ ᵗʷᵒ ᵈᵒᵗ ᶻᵉʳᵒ
*/
package io.vavr.collection;
import io.vavr.Function1;
import io.vavr.Tuple;
import io.vavr.Tuple2;
import io.vavr.control.Option;
import org.assertj.core.api.IterableAssert;
import org.junit.Test;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.*;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.regex.Pattern;
import java.util.stream.Collector;
import static java.util.Arrays.asList;
import static io.vavr.API.Some;
import static io.vavr.Serializables.deserialize;
import static io.vavr.Serializables.serialize;
public abstract class AbstractMapTest extends AbstractTraversableTest {
@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.forEach((k, v) -> assertThat(v).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> Collector<T, ArrayList<T>, IntMap<T>> collector() {
final Collector<Tuple2<Integer, T>, ArrayList<Tuple2<Integer, T>>, ? extends Map<Integer, T>> mapCollector = mapCollector();
return new Collector<T, ArrayList<T>, IntMap<T>>() {
@Override
public Supplier<ArrayList<T>> supplier() {
return ArrayList::new;
}
@Override
public BiConsumer<ArrayList<T>, T> accumulator() {
return ArrayList::add;
}
@Override
public BinaryOperator<ArrayList<T>> combiner() {
return (left, right) -> fromTuples(mapCollector.combiner().apply(toTuples(left), toTuples(right)));
}
@Override
public Function<ArrayList<T>, IntMap<T>> finisher() {
return AbstractMapTest.this::ofAll;
}
@Override
public Set<Characteristics> characteristics() {
return mapCollector.characteristics();
}
private ArrayList<Tuple2<Integer, T>> toTuples(java.util.List<T> list) {
final ArrayList<Tuple2<Integer, T>> result = new ArrayList<>();
Stream.ofAll(list)
.zipWithIndex()
.map(tu -> Tuple.of(tu._2, tu._1))
.forEach(result::add);
return result;
}
private ArrayList<T> fromTuples(java.util.List<Tuple2<Integer, T>> list) {
final ArrayList<T> result = new ArrayList<>();
Stream.ofAll(list)
.map(tu -> tu._2)
.forEach(result::add);
return result;
}
};
}
@Override
protected <T> IntMap<T> empty() {
return IntMap.of(emptyMap());
}
@Override
protected boolean emptyShouldBeSingleton() {
return false;
}
private <T> Map<Integer, T> emptyInt() {
return emptyMap();
}
protected Map<Integer, Integer> emptyIntInt() {
return emptyMap();
}
private Map<Integer, String> emptyIntString() {
return emptyMap();
}
protected abstract String className();
abstract <T1, T2> java.util.Map<T1, T2> javaEmptyMap();
protected abstract <T1 extends Comparable<? super T1>, T2> Map<T1, T2> emptyMap();
protected boolean emptyMapShouldBeSingleton() {
return true;
}
protected abstract <T> Collector<Tuple2<Integer, T>, ArrayList<Tuple2<Integer, T>>, ? extends Map<Integer, T>> mapCollector();
@SuppressWarnings("unchecked")
protected abstract <K extends Comparable<? super K>, V> Map<K, V> mapOfTuples(Tuple2<? extends K, ? extends V>... entries);
@SuppressWarnings("unchecked")
protected abstract <K extends Comparable<? super K>, V> Map<K, V> mapOfEntries(java.util.Map.Entry<? extends K, ? extends V>... entries);
protected abstract <K extends Comparable<? super K>, V> Map<K, V> mapOf(K k1, V v1);
protected abstract <K extends Comparable<? super K>, V> Map<K, V> mapOf(K k1, V v1, K k2, V v2);
protected abstract <K extends Comparable<? super K>, V> Map<K, V> mapOf(K k1, V v1, K k2, V v2, K k3, V v3);
protected abstract <K extends Comparable<? super K>, V> Map<K, V> mapOf(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4);
protected abstract <K extends Comparable<? super K>, V> Map<K, V> mapOf(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5);
protected abstract <K extends Comparable<? super K>, V> Map<K, V> mapOf(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6);
protected abstract <K extends Comparable<? super K>, V> Map<K, V> mapOf(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7);
protected abstract <K extends Comparable<? super K>, V> Map<K, V> mapOf(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8);
protected abstract <K extends Comparable<? super K>, V> Map<K, V> mapOf(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9);
protected abstract <K extends Comparable<? super K>, V> Map<K, V> mapOf(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9, K k10, V v10);
protected abstract <T, K extends Comparable<? super K>, V> Map<K, V> mapOf(java.util.stream.Stream<? extends T> stream,
Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends V> valueMapper);
protected abstract <T, K extends Comparable<? super K>, V> Map<K, V> mapOf(java.util.stream.Stream<? extends T> stream,
Function<? super T, Tuple2<? extends K, ? extends V>> f);
protected abstract <K extends Comparable<? super K>, V> Map<K, V> mapOfNullKey(K k1, V v1, K k2, V v2);
protected abstract <K extends Comparable<? super K>, V> Map<K, V> mapOfNullKey(K k1, V v1, K k2, V v2, K k3, V v3);
protected abstract <K extends Comparable<? super K>, V> Map<K, V> mapTabulate(int n, Function<? super Integer, ? extends Tuple2<? extends K, ? extends V>> f);
protected abstract <K extends Comparable<? super K>, V> Map<K, V> mapFill(int n, Supplier<? extends Tuple2<? extends K, ? extends V>> s);
@Override
protected boolean useIsEqualToInsteadOfIsSameAs() {
return true;
}
@Override
protected int getPeekNonNilPerformingAnAction() {
return 1;
}
@Override
protected <T> IntMap<T> of(T element) {
Map<Integer, T> map = emptyMap();
map = map.put(0, element);
return IntMap.of(map);
}
@SuppressWarnings("unchecked")
@Override
protected <T> IntMap<T> of(T... elements) {
Map<Integer, T> map = emptyMap();
for (T element : elements) {
map = map.put(map.size(), element);
}
return IntMap.of(map);
}
@Override
protected <T> IntMap<T> ofAll(Iterable<? extends T> elements) {
Map<Integer, T> map = emptyMap();
for (T element : elements) {
map = map.put(map.size(), element);
}
return IntMap.of(map);
}
@Override
protected <T extends Comparable<? super T>> IntMap<T> ofJavaStream(java.util.stream.Stream<? extends T> javaStream) {
return ofAll(io.vavr.collection.Iterator.ofAll(javaStream.iterator()));
}
@Override
protected IntMap<Boolean> ofAll(boolean... elements) {
return ofAll(io.vavr.collection.Iterator.ofAll(elements));
}
@Override
protected IntMap<Byte> ofAll(byte... elements) {
return ofAll(io.vavr.collection.Iterator.ofAll(elements));
}
@Override
protected IntMap<Character> ofAll(char... elements) {
return ofAll(io.vavr.collection.Iterator.ofAll(elements));
}
@Override
protected IntMap<Double> ofAll(double... elements) {
return ofAll(io.vavr.collection.Iterator.ofAll(elements));
}
@Override
protected IntMap<Float> ofAll(float... elements) {
return ofAll(io.vavr.collection.Iterator.ofAll(elements));
}
@Override
protected IntMap<Integer> ofAll(int... elements) {
return ofAll(io.vavr.collection.Iterator.ofAll(elements));
}
@Override
protected IntMap<Long> ofAll(long... elements) {
return ofAll(io.vavr.collection.Iterator.ofAll(elements));
}
@Override
protected IntMap<Short> ofAll(short... elements) {
return ofAll(io.vavr.collection.Iterator.ofAll(elements));
}
@Override
protected <T> IntMap<T> tabulate(int n, Function<? super Integer, ? extends T> f) {
Map<Integer, T> map = emptyMap();
for (int i = 0; i < n; i++) {
map = map.put(map.size(), f.apply(i));
}
return IntMap.of(map);
}
@Override
protected <T> IntMap<T> fill(int n, Supplier<? extends T> s) {
return tabulate(n, anything -> s.get());
}
// -- narrow
@Test
public void shouldNarrowMap() {
final Map<Integer, Double> int2doubleMap = mapOf(1, 1.0d);
final Map<Number, Number> number2numberMap = Map.narrow(int2doubleMap);
final int actual = number2numberMap.put(new BigDecimal("2"), new BigDecimal("2.0")).values().sum().intValue();
assertThat(actual).isEqualTo(3);
}
// -- construction
@Test
public void shouldBeTheSame() {
assertThat(mapOf(1, 2)).isEqualTo(emptyInt().put(1, 2));
}
protected static java.util.Map.Entry<Integer, String> asJavaEntry(int key, String value) {
return new java.util.AbstractMap.SimpleEntry<>(key, value);
}
@SafeVarargs
protected final <K, V> java.util.Map<K, V> asJavaMap(java.util.Map.Entry<K, V>... entries) {
final java.util.Map<K, V> results = javaEmptyMap();
for (java.util.Map.Entry<K, V> entry : entries) {
results.put(entry.getKey(), entry.getValue());
}
return results;
}
@Test
public void shouldConstructFrom1Entry() {
final Map<Integer, String> actual = mapOf(1, "1");
final java.util.Map<Integer, String> expected = asJavaMap(asJavaEntry(1, "1"));
assertThat(actual.toJavaMap()).isEqualTo(expected);
}
@Test
public void shouldConstructFrom2Entries() {
final Map<Integer, String> actual = mapOf(1, "1", 2, "2");
final java.util.Map<Integer, String> expected = asJavaMap(asJavaEntry(1, "1"), asJavaEntry(2, "2"));
assertThat(actual.toJavaMap()).isEqualTo(expected);
}
@Test
public void shouldConstructFrom3Entries() {
final Map<Integer, String> actual = mapOf(1, "1", 2, "2", 3, "3");
final java.util.Map<Integer, String> expected = asJavaMap(asJavaEntry(1, "1"), asJavaEntry(2, "2"), asJavaEntry(3, "3"));
assertThat(actual.toJavaMap()).isEqualTo(expected);
}
@Test
public void shouldConstructFrom4Entries() {
final Map<Integer, String> actual = mapOf(1, "1", 2, "2", 3, "3", 4, "4");
final java.util.Map<Integer, String> expected = asJavaMap(asJavaEntry(1, "1"), asJavaEntry(2, "2"), asJavaEntry(3, "3"), asJavaEntry(4, "4"));
assertThat(actual.toJavaMap()).isEqualTo(expected);
}
@Test
public void shouldConstructFrom5Entries() {
final Map<Integer, String> actual = mapOf(1, "1", 2, "2", 3, "3", 4, "4", 5, "5");
final java.util.Map<Integer, String> expected = asJavaMap(asJavaEntry(1, "1"), asJavaEntry(2, "2"), asJavaEntry(3, "3"), asJavaEntry(4, "4"), asJavaEntry(5, "5"));
assertThat(actual.toJavaMap()).isEqualTo(expected);
}
@Test
public void shouldConstructFrom6Entries() {
final Map<Integer, String> actual = mapOf(1, "1", 2, "2", 3, "3", 4, "4", 5, "5", 6, "6");
final java.util.Map<Integer, String> expected = asJavaMap(asJavaEntry(1, "1"), asJavaEntry(2, "2"), asJavaEntry(3, "3"), asJavaEntry(4, "4"), asJavaEntry(5, "5"), asJavaEntry(6, "6"));
assertThat(actual.toJavaMap()).isEqualTo(expected);
}
@Test
public void shouldConstructFrom7Entries() {
final Map<Integer, String> actual = mapOf(1, "1", 2, "2", 3, "3", 4, "4", 5, "5", 6, "6", 7, "7");
final java.util.Map<Integer, String> expected = asJavaMap(asJavaEntry(1, "1"), asJavaEntry(2, "2"), asJavaEntry(3, "3"), asJavaEntry(4, "4"), asJavaEntry(5, "5"), asJavaEntry(6, "6"), asJavaEntry(7, "7"));
assertThat(actual.toJavaMap()).isEqualTo(expected);
}
@Test
public void shouldConstructFrom8Entries() {
final Map<Integer, String> actual = mapOf(1, "1", 2, "2", 3, "3", 4, "4", 5, "5", 6, "6", 7, "7", 8, "8");
final java.util.Map<Integer, String> expected = asJavaMap(asJavaEntry(1, "1"), asJavaEntry(2, "2"), asJavaEntry(3, "3"), asJavaEntry(4, "4"), asJavaEntry(5, "5"), asJavaEntry(6, "6"), asJavaEntry(7, "7"), asJavaEntry(8, "8"));
assertThat(actual.toJavaMap()).isEqualTo(expected);
}
@Test
public void shouldConstructFrom9Entries() {
final Map<Integer, String> actual = mapOf(1, "1", 2, "2", 3, "3", 4, "4", 5, "5", 6, "6", 7, "7", 8, "8", 9, "9");
final java.util.Map<Integer, String> expected = asJavaMap(asJavaEntry(1, "1"), asJavaEntry(2, "2"), asJavaEntry(3, "3"), asJavaEntry(4, "4"), asJavaEntry(5, "5"), asJavaEntry(6, "6"), asJavaEntry(7, "7"), asJavaEntry(8, "8"), asJavaEntry(9, "9"));
assertThat(actual.toJavaMap()).isEqualTo(expected);
}
@Test
public void shouldConstructFrom10Entries() {
final Map<Integer, String> actual = mapOf(1, "1", 2, "2", 3, "3", 4, "4", 5, "5", 6, "6", 7, "7", 8, "8", 9, "9", 10, "10");
final java.util.Map<Integer, String> expected = asJavaMap(asJavaEntry(1, "1"), asJavaEntry(2, "2"), asJavaEntry(3, "3"), asJavaEntry(4, "4"), asJavaEntry(5, "5"), asJavaEntry(6, "6"), asJavaEntry(7, "7"), asJavaEntry(8, "8"), asJavaEntry(9, "9"), asJavaEntry(10, "10"));
assertThat(actual.toJavaMap()).isEqualTo(expected);
}
@Test
public void shouldConstructFromJavaStream() {
final java.util.stream.Stream<Integer> javaStream = java.util.stream.Stream.of(1, 2, 3);
final Map<String, Integer> map = mapOf(javaStream, String::valueOf, Function.identity());
assertThat(map).isEqualTo(this.<String, Integer> emptyMap().put("1", 1).put("2", 2).put("3", 3));
}
@Test
public void shouldConstructFromJavaStreamEntries() {
final java.util.stream.Stream<Integer> javaStream = java.util.stream.Stream.of(1, 2, 3);
final Map<String, Integer> map = mapOf(javaStream, i -> Tuple.of(String.valueOf(i), i));
assertThat(map).isEqualTo(this.<String, Integer> emptyMap().put("1", 1).put("2", 2).put("3", 3));
}
@Test
@SuppressWarnings("unchecked")
public void shouldConstructFromUtilEntries() {
final Map<Integer, String> actual = mapOfEntries(asJavaEntry(1, "1"), asJavaEntry(2, "2"), asJavaEntry(3, "3"));
final Map<Integer, String> expected = this.<Integer, String>emptyMap().put(1, "1").put(2, "2").put(3, "3");
assertThat(actual).isEqualTo(expected);
}
@Test
@SuppressWarnings("unchecked")
public void shouldConstructFromEntries() {
final Map<String, Integer> actual = mapOfTuples(Map.entry("1", 1), Map.entry("2", 2), Map.entry("3", 3));
final Map<String, Integer> expected = this.<String, Integer>emptyMap().put("1", 1).put("2", 2).put("3", 3);
assertThat(actual).isEqualTo(expected);
}
@Test
public void shouldConstructFromPairs() {
final Map<String, Integer> actual = mapOf("1", 1, "2", 2, "3", 3);
final Map<String, Integer> expected = this.<String, Integer>emptyMap().put("1", 1).put("2", 2).put("3", 3);
assertThat(actual).isEqualTo(expected);
}
// -- equality
@Test
public void shouldObeyEqualityConstraints() {
// sequential collections
assertThat(emptyMap().equals(io.vavr.collection.HashMap.empty())).isTrue();
assertThat(mapOf(1, "a").equals(io.vavr.collection.HashMap.of(1, "a"))).isTrue();
assertThat(mapOf(1, "a", 2, "b", 3, "c").equals(io.vavr.collection.HashMap.of(1, "a", 2, "b",3, "c"))).isTrue();
assertThat(mapOf(1, "a", 2, "b", 3, "c").equals(io.vavr.collection.HashMap.of(3, "c", 2, "b",1, "a"))).isTrue();
// other classes
assertThat(empty().equals(io.vavr.collection.List.empty())).isFalse();
assertThat(empty().equals(HashMultimap.withSeq().empty())).isFalse();
assertThat(empty().equals(io.vavr.collection.HashSet.empty())).isFalse();
assertThat(empty().equals(LinkedHashMultimap.withSeq().empty())).isFalse();
assertThat(empty().equals(io.vavr.collection.LinkedHashSet.empty())).isFalse();
assertThat(empty().equals(TreeMultimap.withSeq().empty())).isFalse();
assertThat(empty().equals(io.vavr.collection.TreeSet.empty())).isFalse();
}
// -- head
@Test(expected = NoSuchElementException.class)
public void shouldThrowWhenHeadEmpty() {
emptyMap().head();
}
// -- init
@Test(expected = UnsupportedOperationException.class)
public void shouldThrowWhenInitEmpty() {
emptyMap().init();
}
// -- tail
@Test(expected = UnsupportedOperationException.class)
public void shouldThrowWhenTailEmpty() {
emptyMap().tail();
}
// -- toString
@Test
public void shouldMakeString() {
assertThat(emptyMap().toString()).isEqualTo(className() + "()");
assertThat(emptyInt().put(1, 2).toString()).isEqualTo(className() + "(" + Tuple.of(1, 2) + ")");
}
// -- toJavaMap
@Test
public void shouldConvertToJavaMap() {
final Map<Integer, String> actual = mapOf(1, "1", 2, "2", 3, "3");
final java.util.Map<Integer, String> expected = asJavaMap(asJavaEntry(1, "1"), asJavaEntry(2, "2"), asJavaEntry(3, "3"));
assertThat(actual.toJavaMap()).isEqualTo(expected);
}
// -- apply
@Test
public void shouldApplyExistingKey() {
assertThat(emptyInt().put(1, 2).apply(1)).isEqualTo(2);
}
@Test(expected = NoSuchElementException.class)
public void shouldApplyNonExistingKey() {
emptyInt().put(1, 2).apply(3);
}
// -- contains
@Test
public void shouldFindKey() {
assertThat(emptyInt().put(1, 2).containsKey(1)).isTrue();
assertThat(emptyInt().put(1, 2).containsKey(2)).isFalse();
}
@Test
public void shouldFindValue() {
assertThat(emptyInt().put(1, 2).containsValue(2)).isTrue();
assertThat(emptyInt().put(1, 2).containsValue(1)).isFalse();
}
@Test
public void shouldRecognizeNotContainedKeyValuePair() {
final io.vavr.collection.TreeMap<String, Integer> testee = io.vavr.collection.TreeMap.of(Tuple.of("one", 1));
assertThat(testee.contains(Tuple.of("one", 0))).isFalse();
}
@Test
public void shouldRecognizeContainedKeyValuePair() {
final io.vavr.collection.TreeMap<String, Integer> testee = io.vavr.collection.TreeMap.of(Tuple.of("one", 1));
assertThat(testee.contains(Tuple.of("one", 1))).isTrue();
}
// -- flatMap
@SuppressWarnings("unchecked")
@Test
public void shouldFlatMapUsingBiFunction() {
final Map<Integer, Integer> testee = mapOfTuples(Tuple.of(1, 11), Tuple.of(2, 22), Tuple.of(3, 33));
final Map<String, String> actual = testee
.flatMap((k, v) -> io.vavr.collection.List.of(Tuple.of(String.valueOf(k), String.valueOf(v)),
Tuple.of(String.valueOf(k * 10), String.valueOf(v * 10))));
final Map<String, String> expected = mapOfTuples(Tuple.of("1", "11"), Tuple.of("10", "110"), Tuple.of("2", "22"),
Tuple.of("20", "220"), Tuple.of("3", "33"), Tuple.of("30", "330"));
assertThat(actual).isEqualTo(expected);
}
// -- keySet
@Test
@SuppressWarnings("unchecked")
public void shouldReturnsKeySet() {
final io.vavr.collection.Set<Integer> actual = mapOfTuples(Tuple.of(1, 11), Tuple.of(2, 22), Tuple.of(3, 33)).keySet();
assertThat(actual).isEqualTo(io.vavr.collection.HashSet.of(1, 2, 3));
}
// -- biMap
@Test
public void shouldBiMapEmpty() {
assertThat(emptyInt().bimap(i -> i + 1, o -> o)).isEqualTo(io.vavr.collection.Vector.empty());
}
@Test
public void shouldBiMapNonEmpty() {
final Seq<Tuple2<Integer, String>> expected = Stream.of(Tuple.of(2, "1!"), Tuple.of(3, "2!"));
final Seq<Tuple2<Integer, String>> actual = emptyInt().put(1, "1").put(2, "2").bimap(i -> i + 1, s -> s + "!").toStream();
assertThat(actual).isEqualTo(expected);
}
// -- orElse
// DEV-Note: IntMap converts `other` to map
@Override
@Test
public void shouldCaclEmptyOrElseSameOther() {
Iterable<Integer> other = of(42);
assertThat(empty().orElse(other)).isEqualTo(other);
}
@Test
public void shouldCaclEmptyOrElseSameSupplier() {
Iterable<Integer> other = of(42);
Supplier<Iterable<Integer>> supplier = () -> other;
assertThat(empty().orElse(supplier)).isEqualTo(other);
}
// -- map
@Test
public void shouldMapEmpty() {
assertThat(emptyInt().map(Tuple2::_1)).isEqualTo(io.vavr.collection.Vector.empty());
}
@Test
public void shouldMapNonEmpty() {
final Seq<Integer> expected = io.vavr.collection.Vector.of(1, 2);
final Seq<Integer> actual = emptyInt().put(1, "1").put(2, "2").map(Tuple2::_1);
assertThat(actual).isEqualTo(expected);
}
@Test
public void shouldReturnEmptySetWhenAskedForTuple2SetOfAnEmptyMap() {
assertThat(emptyMap().toSet()).isEqualTo(io.vavr.collection.HashSet.empty());
}
@Test
public void shouldReturnTuple2SetOfANonEmptyMap() {
assertThat(emptyInt().put(1, "1").put(2, "2").toSet()).isEqualTo(io.vavr.collection.HashSet.of(Tuple.of(1, "1"), Tuple.of(2, "2")));
}
@Test
public void shouldReturnModifiedKeysMap() {
final Map<String, String> actual = emptyIntString().put(1, "1").put(2, "2").mapKeys(k -> k * 12).mapKeys(Integer::toHexString).mapKeys(String::toUpperCase);
final Map<String, String> expected = this.<String, String> emptyMap().put("C", "1").put("18", "2");
assertThat(actual).isEqualTo(expected);
}
@Test
public void shouldReturnModifiedKeysMapWithNonUniqueMapper() {
final Map<Integer, String> actual = emptyIntString()
.put(1, "1").put(2, "2").put(3, "3")
.mapKeys(k -> k * 118).mapKeys(Integer::toHexString).mapKeys(AbstractMapTest::md5).mapKeys(String::length);
assertThat(actual).hasSize(1);
assertThat(actual.values()).hasSize(1);
//In different cases (based on items order) transformed map may contain different values
assertThat(actual.values().head()).isIn("1", "2", "3");
}
public static String md5(String src) {
try {
final MessageDigest md = MessageDigest.getInstance("MD5");
md.update(src.getBytes(StandardCharsets.UTF_8));
return toHexString(md.digest());
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
/**
* Returns a string in the hexadecimal format.
*
* @param bytes the converted bytes
* @return the hexadecimal string representing the bytes data
* @throws IllegalArgumentException if the byte array is null
*/
public static String toHexString(byte[] bytes) {
if (bytes == null) {
throw new IllegalArgumentException("byte array must not be null");
}
final StringBuilder hex = new StringBuilder(bytes.length * 2);
for (byte aByte : bytes) {
hex.append(Character.forDigit((aByte & 0XF0) >> 4, 16));
hex.append(Character.forDigit((aByte & 0X0F), 16));
}
return hex.toString();
}
@Test
public void shouldReturnModifiedKeysMapWithNonUniqueMapperAndMergedValus() {
final Map<Integer, String> actual = emptyIntString()
.put(1, "1").put(2, "2").put(3, "3")
.mapKeys(k -> k * 118).mapKeys(Integer::toHexString).mapKeys(AbstractMapTest::md5)//Unique key mappers
.mapKeys(String::length, (v1, v2) -> io.vavr.collection.List.of(v1.split("#")).append(v2).sorted().mkString("#"));
final Map<Integer, String> expected = emptyIntString().put(32, "1#2#3");
assertThat(actual).isEqualTo(expected);
}
@Test
public void shouldReturnModifiedValuesMap() {
assertThat(emptyIntString().put(1, "1").put(2, "2").mapValues(Integer::parseInt)).isEqualTo(emptyInt().put(1, 1).put(2, 2));
}
@Test
public void shouldReturnListWithMappedValues() {
assertThat(emptyIntInt().put(1, 1).put(2, 2).iterator((a, b) -> a + b).toList()).isEqualTo(io.vavr.collection.List.of(2, 4));
}
// -- merge(Map)
@Test
public void shouldMerge() {
final Map<Integer, Integer> m1 = emptyIntInt().put(1, 1).put(2, 2);
final Map<Integer, Integer> m2 = emptyIntInt().put(1, 1).put(4, 4);
final Map<Integer, Integer> m3 = emptyIntInt().put(3, 3).put(4, 4);
assertThat(m1.merge(m2)).isEqualTo(emptyIntInt().put(1, 1).put(2, 2).put(4, 4));
assertThat(m1.merge(m3)).isEqualTo(emptyIntInt().put(1, 1).put(2, 2).put(3, 3).put(4, 4));
}
@Test
public void shouldReturnSameMapWhenMergeNonEmptyWithEmpty() {
final Map<Integer, String> map = mapOf(1, "a", 2, "b", 3, "c");
assertThat(map.merge(emptyMap())).isSameAs(map);
}
@Test
public void shouldReturnSameMapWhenMergeEmptyWithNonEmpty() {
final Map<Integer, String> map = mapOf(1, "a", 2, "b", 3, "c");
if (map.isOrdered()) {
assertThat(this.<Integer, String> emptyMap().merge(map)).isEqualTo(map);
} else {
assertThat(this.<Integer, String> emptyMap().merge(map)).isSameAs(map);
}
}
// -- merge(Map, BiFunction)
@Test
public void shouldMergeCollisions() {
final Map<Integer, Integer> m1 = emptyIntInt().put(1, 1).put(2, 2);
final Map<Integer, Integer> m2 = emptyIntInt().put(1, 2).put(4, 4);
final Map<Integer, Integer> m3 = emptyIntInt().put(3, 3).put(4, 4);
assertThat(emptyIntInt().merge(m2, Math::max)).isEqualTo(m2);
assertThat(m2.merge(emptyIntInt(), Math::max)).isEqualTo(m2);
assertThat(m1.merge(m2, Math::max)).isEqualTo(emptyIntInt().put(1, 2).put(2, 2).put(4, 4));
assertThat(m1.merge(m3, Math::max)).isEqualTo(emptyIntInt().put(1, 1).put(2, 2).put(3, 3).put(4, 4));
}
@Test
public void shouldReturnSameMapWhenMergeNonEmptyWithEmptyUsingCollisionResolution() {
final Map<Integer, Integer> map = mapOf(1, 1, 2, 2, 3, 3);
assertThat(map.merge(emptyMap(), Math::max)).isSameAs(map);
}
@Test
public void shouldReturnSameMapWhenMergeEmptyWithNonEmptyUsingCollisionResolution() {
final Map<Integer, Integer> map = mapOf(1, 1, 2, 2, 3, 3);
if (map.isOrdered()) {
assertThat(this.<Integer, Integer> emptyMap().merge(map, Math::max)).isEqualTo(map);
} else {
assertThat(this.<Integer, Integer> emptyMap().merge(map, Math::max)).isSameAs(map);
}
}
// -- equality
@Test
public void shouldIgnoreOrderOfEntriesWhenComparingForEquality() {
final Map<?, ?> map1 = emptyInt().put(1, 'a').put(2, 'b').put(3, 'c');
final Map<?, ?> map2 = emptyInt().put(3, 'c').put(2, 'b').put(1, 'a').remove(2).put(2, 'b');
assertThat(map1).isEqualTo(map2);
}
// -- put
@Test
public void shouldPutTuple() {
assertThat(emptyIntInt().put(Tuple.of(1, 2))).isEqualTo(emptyIntInt().put(1, 2));
}
@Test
public void shouldPutNullKeyIntoMapThatContainsNullKey() {
final Map<Integer, String> map = mapOfNullKey(1, "a", null, "b", 2, "c");
assertThat(map.put(null, "!")).isEqualTo(mapOfNullKey(1, "a", null, "!", 2, "c"));
}
@Test
public void shouldPutExistingKeyAndNonEqualValue() {
final Map<IntMod2, String> map = mapOf(new IntMod2(1), "a");
// we need to compare Strings because equals (intentionally) does not work for IntMod2
final String actual = map.put(new IntMod2(3), "b").toString();
final String expected = map.stringPrefix() + "((3, b))";
assertThat(actual).isEqualTo(expected);
}
@Test
public void shouldPutExistingKeyAndEqualValue() {
final Map<IntMod2, String> map = mapOf(new IntMod2(1), "a");
// we need to compare Strings because equals (intentionally) does not work for IntMod2
final String actual = map.put(new IntMod2(3), "a").toString();
final String expected = map.stringPrefix() + "((3, a))";
assertThat(actual).isEqualTo(expected);
}
// -- remove
@Test
public void shouldRemoveKey() {
final Map<Integer, Object> src = emptyInt().put(1, 'a').put(2, 'b').put(3, 'c');
assertThat(src.remove(2)).isEqualTo(emptyInt().put(1, 'a').put(3, 'c'));
assertThat(src.remove(33)).isSameAs(src);
}
@Test
public void shouldRemoveFromMapThatContainsFirstEntryHavingNullKey() {
final Map<Integer, String> map = mapOfNullKey(null, "a", 1, "b", 2, "c");
assertThat(map.remove(1)).isEqualTo(mapOfNullKey(null, "a", 2, "c"));
}
// -- removeAll
@Test
public void shouldRemoveAllKeys() {
final Map<Integer, Object> src = emptyInt().put(1, 'a').put(2, 'b').put(3, 'c');
assertThat(src.removeAll(io.vavr.collection.List.of(1, 3))).isEqualTo(emptyInt().put(2, 'b'));
assertThat(src.removeAll(io.vavr.collection.List.of(33))).isSameAs(src);
assertThat(src.removeAll(io.vavr.collection.List.empty())).isSameAs(src);
}
@Test
public void shouldReturnSameMapWhenNonEmptyRemoveAllEmpty() {
final Map<Integer, String> map = mapOf(1, "a", 2, "b", 3, "c");
assertThat(map.removeAll(io.vavr.collection.List.empty())).isSameAs(map);
}
@Test
public void shouldReturnSameMapWhenEmptyRemoveAllNonEmpty() {
final Map<Integer, String> empty = emptyMap();
assertThat(empty.removeAll(io.vavr.collection.List.of(1, 2, 3))).isSameAs(empty);
}
// -- transform
@Test
public void shouldTransform() {
final Map<?, ?> actual = emptyIntInt().put(1, 11).transform(map -> map.put(2, 22));
assertThat(actual).isEqualTo(emptyIntInt().put(1, 11).put(2, 22));
}
// -- unzip
@Test
public void shouldUnzipIdentityNil() {
assertThat(emptyMap().unzip()).isEqualTo(Tuple.of(Stream.empty(), Stream.empty()));
}
@Test
public void shouldUnzipIdentityNonNil() {
final Map<Integer, Integer> map = emptyIntInt().put(0, 10).put(1, 11).put(2, 12);
final Tuple actual = map.unzip();
final Tuple expected = Tuple.of(Stream.of(0, 1, 2), Stream.of(10, 11, 12));
assertThat(actual).isEqualTo(expected);
}
@Test
public void shouldUnzipNil() {
assertThat(emptyMap().unzip(x -> Tuple.of(x, x))).isEqualTo(Tuple.of(Stream.empty(), Stream.empty()));
assertThat(emptyMap().unzip((k, v) -> Tuple.of(Tuple.of(k, v), Tuple.of(k, v))))
.isEqualTo(Tuple.of(Stream.empty(), Stream.empty()));
}
@Test
public void shouldUnzipNonNil() {
final Map<Integer, Integer> map = emptyIntInt().put(0, 0).put(1, 1);
final Tuple actual = map.unzip(entry -> Tuple.of(entry._1, entry._2 + 1));
final Tuple expected = Tuple.of(Stream.of(0, 1), Stream.of(1, 2));
assertThat(actual).isEqualTo(expected);
}
@Test
public void shouldUnzip3Nil() {
assertThat(emptyMap().unzip3(x -> Tuple.of(x, x, x))).isEqualTo(Tuple.of(Stream.empty(), Stream.empty(), Stream.empty()));
assertThat(emptyMap().unzip3((k, v) -> Tuple.of(Tuple.of(k, v), Tuple.of(k, v), Tuple.of(k, v))))
.isEqualTo(Tuple.of(Stream.empty(), Stream.empty(), Stream.empty()));
}
@Test
public void shouldUnzip3NonNil() {
final Map<Integer, Integer> map = emptyIntInt().put(0, 0).put(1, 1);
final Tuple actual = map.unzip3(entry -> Tuple.of(entry._1, entry._2 + 1, entry._2 + 5));
final Tuple expected = Tuple.of(Stream.of(0, 1), Stream.of(1, 2), Stream.of(5, 6));
assertThat(actual).isEqualTo(expected);
}
// -- zip
@Test
public void shouldZipNils() {
final Seq<Tuple2<Tuple2<Integer, Object>, Object>> actual = emptyInt().zip(io.vavr.collection.List.empty());
assertThat(actual).isEqualTo(Stream.empty());
}
@Test
public void shouldZipEmptyAndNonNil() {
final Seq<Tuple2<Tuple2<Integer, Object>, Integer>> actual = emptyInt().zip(io.vavr.collection.List.of(1));
assertThat(actual).isEqualTo(Stream.empty());
}
@Test
public void shouldZipNonEmptyAndNil() {
final Seq<Tuple2<Tuple2<Integer, Integer>, Object>> actual = emptyIntInt().put(0, 1).zip(io.vavr.collection.List.empty());
assertThat(actual).isEqualTo(Stream.empty());
}
@Test
public void shouldZipNonNilsIfThisIsSmaller() {
final Seq<Tuple2<Tuple2<Integer, Integer>, Integer>> actual = emptyIntInt()
.put(0, 0)
.put(1, 1)
.zip(io.vavr.collection.List.of(5, 6, 7));
assertThat(actual).isEqualTo(Stream.of(Tuple.of(Tuple.of(0, 0), 5), Tuple.of(Tuple.of(1, 1), 6)));
}
@Test
public void shouldZipNonNilsIfThatIsSmaller() {
final Seq<Tuple2<Tuple2<Integer, Integer>, Integer>> actual = emptyIntInt()
.put(0, 0)
.put(1, 1)
.put(2, 2)
.zip(io.vavr.collection.List.of(5, 6));
assertThat(actual).isEqualTo(Stream.of(Tuple.of(Tuple.of(0, 0), 5), Tuple.of(Tuple.of(1, 1), 6)));
}
@Test
public void shouldZipNonNilsOfSameSize() {
final Seq<Tuple2<Tuple2<Integer, Integer>, Integer>> actual = emptyIntInt()
.put(0, 0)
.put(1, 1)
.put(2, 2)
.zip(io.vavr.collection.List.of(5, 6, 7));
assertThat(actual).isEqualTo(
Stream.of(Tuple.of(Tuple.of(0, 0), 5), Tuple.of(Tuple.of(1, 1), 6), Tuple.of(Tuple.of(2, 2), 7)));
}
@Test(expected = NullPointerException.class)
public void shouldThrowIfZipWithThatIsNull() {
emptyMap().zip(null);
}
// -- zipWithIndex
@Test
public void shouldZipNilWithIndex() {
assertThat(emptyMap().zipWithIndex()).isEqualTo(Stream.empty());
}
@Test
public void shouldZipNonNilWithIndex() {
final Seq<Tuple2<Tuple2<Integer, Integer>, Integer>> actual = emptyIntInt()
.put(0, 0)
.put(1, 1)
.put(2, 2)
.zipWithIndex();
assertThat(actual).isEqualTo(
Stream.of(Tuple.of(Tuple.of(0, 0), 0), Tuple.of(Tuple.of(1, 1), 1), Tuple.of(Tuple.of(2, 2), 2)));
}
// -- zipAll
@Test
public void shouldZipAllNils() {
final Seq<Tuple2<Tuple2<Integer, Object>, Object>> actual = emptyInt().zipAll(empty(), null, null);
assertThat(actual).isEqualTo(Stream.empty());
}
@Test
public void shouldZipAllEmptyAndNonNil() {
final Seq<Tuple2<Tuple2<Integer, Object>, Object>> actual = emptyInt().zipAll(io.vavr.collection.List.of(1), null, null);
assertThat(actual).isEqualTo(Stream.of(Tuple.of(null, 1)));
}
@Test
public void shouldZipAllNonEmptyAndNil() {
final Seq<Tuple2<Tuple2<Integer, Object>, Object>> actual = emptyInt().put(0, 1).zipAll(empty(), null, null);
assertThat(actual).isEqualTo(Stream.of(Tuple.of(Tuple.of(0, 1), null)));
}
@Test
public void shouldZipAllNonNilsIfThisIsSmaller() {
final Seq<Tuple2<Tuple2<Integer, Integer>, String>> actual = emptyIntInt()
.put(1, 1)
.put(2, 2)
.zipAll(of("a", "b", "c"), Tuple.of(9, 10), "z");
final Seq<Tuple2<Tuple2<Object, Object>, String>> expected = Stream.of(Tuple.of(Tuple.of(1, 1), "a"),
Tuple.of(Tuple.of(2, 2), "b"), Tuple.of(Tuple.of(9, 10), "c"));
assertThat(actual).isEqualTo(expected);
}
@Test
public void shouldZipAllNonNilsIfThisIsMoreSmaller() {
final Seq<Tuple2<Tuple2<Integer, Integer>, String>> actual = emptyIntInt()
.put(1, 1)
.put(2, 2)
.zipAll(of("a", "b", "c", "d"), Tuple.of(9, 10), "z");
final Seq<Tuple2<Tuple2<Object, Object>, String>> expected = Stream.of(Tuple.of(Tuple.of(1, 1), "a"),
Tuple.of(Tuple.of(2, 2), "b"), Tuple.of(Tuple.of(9, 10), "c"), Tuple.of(Tuple.of(9, 10), "d"));
assertThat(actual).isEqualTo(expected);
}
@Test
public void shouldZipAllNonNilsIfThatIsSmaller() {
final Seq<Tuple2<Tuple2<Integer, Integer>, String>> actual = emptyIntInt()
.put(1, 1)
.put(2, 2)
.put(3, 3)
.zipAll(this.of("a", "b"), Tuple.of(9, 10), "z");
final Seq<Tuple2<Tuple2<Object, Object>, String>> expected = Stream.of(Tuple.of(Tuple.of(1, 1), "a"),
Tuple.of(Tuple.of(2, 2), "b"), Tuple.of(Tuple.of(3, 3), "z"));
assertThat(actual).isEqualTo(expected);
}
@Test
public void shouldZipAllNonNilsIfThatIsMoreSmaller() {
final Seq<Tuple2<Tuple2<Integer, Integer>, String>> actual = emptyIntInt()
.put(1, 1)
.put(2, 2)
.put(3, 3)
.put(4, 4)
.zipAll(of("a", "b"), Tuple.of(9, 10), "z");
final Seq<Tuple2<Tuple2<Object, Object>, String>> expected = Stream.of(Tuple.of(Tuple.of(1, 1), "a"),
Tuple.of(Tuple.of(2, 2), "b"), Tuple.of(Tuple.of(3, 3), "z"), Tuple.of(Tuple.of(4, 4), "z"));
assertThat(actual).isEqualTo(expected);
}
@Test
public void shouldZipAllNonNilsOfSameSize() {
final Seq<Tuple2<Tuple2<Integer, Integer>, String>> actual = emptyIntInt()
.put(1, 1)
.put(2, 2)
.put(3, 3)
.zipAll(of("a", "b", "c"), Tuple.of(9, 10), "z");
final Seq<Tuple2<Tuple2<Object, Object>, String>> expected = Stream.of(Tuple.of(Tuple.of(1, 1), "a"),
Tuple.of(Tuple.of(2, 2), "b"), Tuple.of(Tuple.of(3, 3), "c"));
assertThat(actual).isEqualTo(expected);
}
@Test(expected = NullPointerException.class)
public void shouldThrowIfZipAllWithThatIsNull() {
emptyMap().zipAll(null, null, null);
}
// -- special cases
@Override
public void shouldComputeDistinctOfNonEmptyTraversable() {
final Map<Integer, Object> testee = emptyInt().put(1, 1).put(2, 2).put(3, 3);
assertThat(testee.distinct()).isEqualTo(testee);
}
@Override
public void shouldReturnSomeTailWhenCallingTailOptionOnNonNil() {
assertThat(of(1, 2, 3).tailOption().get()).isEqualTo(Option.some(of(2, 3)).get());
}
@Override
public void shouldPreserveSingletonInstanceOnDeserialization() {
final Map<?, ?> obj = deserialize(serialize(emptyMap()));
final boolean actual = obj == emptyMap();
assertThat(actual).isTrue();
}
@Test
public void shouldSerializeDeserializeNonEmptyMap() {
final Object expected = of('a', 'b', 'c');
final Object actual = deserialize(serialize(expected));
assertThat(actual).isEqualTo(expected);
}
@Override
public void shouldFoldRightNonNil() {
final String actual = of('a', 'b', 'c').foldRight("", (x, xs) -> x + xs);
final io.vavr.collection.List<String> expected = io.vavr.collection.List.of('a', 'b', 'c').permutations().map(io.vavr.collection.List::mkString);
assertThat(actual).isIn(expected);
}
// -- forEach
@Test
public void forEachByKeyValue() {
final Map<Integer, Integer> map = mapOf(1, 2).put(3, 4);
final int[] result = { 0 };
map.forEach((k, v) -> {
result[0] += k + v;
});
assertThat(result[0]).isEqualTo(10);
}
@Test
public void forEachByTuple() {
final Map<Integer, Integer> map = mapOf(1, 2).put(3, 4);
final int[] result = { 0 };
map.forEach(t -> {
result[0] += t._1 + t._2;
});
assertThat(result[0]).isEqualTo(10);
}
// -- put with merge function
@Test
public void putWithWasntPresent() {
final Map<Integer, Integer> map = mapOf(1, 2)
.put(2, 3, (x, y) -> x + y);
assertThat(map).isEqualTo(emptyIntInt().put(1, 2).put(2, 3));
}
@Test
public void putWithWasPresent() {
final Map<Integer, Integer> map = mapOf(1, 2)
.put(1, 3, (x, y) -> x + y);
assertThat(map).isEqualTo(emptyIntInt().put(1, 5));
}
@Test
public void putWithTupleWasntPresent() {
final Map<Integer, Integer> map = mapOf(1, 2)
.put(Tuple.of(2, 3), (x, y) -> x + y);
assertThat(map).isEqualTo(emptyIntInt().put(1, 2).put(2, 3));
}
@Test
public void putWithTupleWasPresent() {
final Map<Integer, Integer> map = mapOf(1, 2)
.put(Tuple.of(1, 3), (x, y) -> x + y);
assertThat(map).isEqualTo(emptyIntInt().put(1, 5));
}
@SuppressWarnings("unchecked")
@Test
public void shouldTabulateTheSeq() {
final Function<Number, Tuple2<Long, Float>> f = i -> new Tuple2<>(i.longValue(), i.floatValue());
final Map<Long, Float> map = mapTabulate(3, f);
assertThat(map).isEqualTo(mapOfTuples(new Tuple2<>(0l, 0f), new Tuple2<>(1l, 1f), new Tuple2<>(2l, 2f)));
}
@SuppressWarnings("unchecked")
@Test
public void shouldTabulateTheSeqCallingTheFunctionInTheRightOrder() {
final LinkedList<Integer> ints = new LinkedList<>(asList(0, 0, 1, 1, 2, 2));
final Function<Integer, Tuple2<Long, Float>> f = i -> new Tuple2<>(ints.remove().longValue(), ints.remove().floatValue());
final Map<Long, Float> map = mapTabulate(3, f);
assertThat(map).isEqualTo(mapOfTuples(new Tuple2<>(0l, 0f), new Tuple2<>(1l, 1f), new Tuple2<>(2l, 2f)));
}
@Test
public void shouldTabulateTheSeqWith0Elements() {
assertThat(mapTabulate(0, i -> new Tuple2<>(i, i))).isEqualTo(empty());
}
@Test
public void shouldTabulateTheSeqWith0ElementsWhenNIsNegative() {
assertThat(mapTabulate(-1, i -> new Tuple2<>(i, i))).isEqualTo(empty());
}
@SuppressWarnings("unchecked")
@Test
public void shouldFillTheSeqCallingTheSupplierInTheRightOrder() {
final LinkedList<Integer> ints = new LinkedList<>(asList(0, 0, 1, 1, 2, 2));
final Supplier<Tuple2<Long, Float>> s = () -> new Tuple2<>(ints.remove().longValue(), ints.remove().floatValue());
final Map<Long, Float> actual = mapFill(3, s);
assertThat(actual).isEqualTo(mapOfTuples(new Tuple2<>(0l, 0f), new Tuple2<>(1l, 1f), new Tuple2<>(2l, 2f)));
}
@Test
public void shouldFillTheSeqWith0Elements() {
assertThat(mapFill(0, () -> new Tuple2<>(1, 1))).isEqualTo(empty());
}
@Test
public void shouldFillTheSeqWith0ElementsWhenNIsNegative() {
assertThat(mapFill(-1, () -> new Tuple2<>(1, 1))).isEqualTo(empty());
}
@SuppressWarnings("unchecked")
@Test
public void mapOfTuplesShouldReturnTheSingletonEmpty() {
if (!emptyMapShouldBeSingleton()) { return; }
assertThat(mapOfTuples()).isSameAs(emptyMap());
}
@SuppressWarnings("unchecked")
@Test
public void mapOfEntriesShouldReturnTheSingletonEmpty() {
if (!emptyMapShouldBeSingleton()) { return; }
assertThat(mapOfEntries()).isSameAs(emptyMap());
}
@Test
public void lift() {
final Function1<String, Option<Integer>> lifted = mapOf("A", 1).lift();
assertThat(lifted.apply("A").get()).isEqualTo(1);
assertThat(lifted.apply("a").isEmpty()).isTrue();
}
@Test
public void withDefaultValue() {
final Function1<String, Integer> withDef = mapOf("A", 1).withDefaultValue(2);
assertThat(withDef.apply("A")).isEqualTo(1);
assertThat(withDef.apply("a")).isEqualTo(2);
}
@Test
public void withDefault() {
final Function1<String, Integer> withDef = mapOf("A", 1).withDefault(String::length);
assertThat(withDef.apply("A")).isEqualTo(1);
assertThat(withDef.apply("aaa")).isEqualTo(3);
}
// -- filter
@Test
public void shouldBiFilterWork() throws Exception {
final Map<Integer, String> src = mapTabulate(20, n -> Tuple.of(n, Integer.toHexString(n)));
final Pattern isDigits = Pattern.compile("^\\d+$");
final Map<Integer, String> dst = src.filter((k, v) -> k % 2 == 0 && isDigits.matcher(v).matches());
assertThat(dst).isEqualTo(emptyIntString().put(0, "0").put(2, "2").put(4, "4").put(6, "6").put(8, "8").put(16, "10").put(18, "12"));
}
@Test
public void shouldKeyFilterWork() throws Exception {
final Map<Integer, String> src = mapTabulate(20, n -> Tuple.of(n, Integer.toHexString(n)));
final Map<Integer, String> dst = src.filterKeys(k -> k % 2 == 0);
assertThat(dst).isEqualTo(emptyIntString().put(0, "0").put(2, "2").put(4, "4").put(6, "6").put(8, "8").put(10, "a").put(12, "c").put(14, "e").put(16, "10").put(18, "12"));
}
@Test
public void shouldValueFilterWork() throws Exception {
final Map<Integer, String> src = mapTabulate(10, n -> Tuple.of(n, Integer.toHexString(n)));
final Pattern isDigits = Pattern.compile("^\\d+$");
final Map<Integer, String> dst = src.filterValues(v -> isDigits.matcher(v).matches());
assertThat(dst).isEqualTo(emptyIntString().put(0, "0").put(1, "1").put(2, "2").put(3, "3").put(4, "4").put(5, "5").put(6, "6").put(7, "7").put(8, "8").put(9, "9"));
}
// -- remove by filter
@Test
public void shouldBiRemoveWork() throws Exception {
final Map<Integer, String> src = mapTabulate(20, n -> Tuple.of(n, Integer.toHexString(n)));
final Pattern isDigits = Pattern.compile("^\\d+$");
final Map<Integer, String> dst = src.removeAll((k, v) -> k % 2 == 0 && isDigits.matcher(v).matches());
assertThat(dst).isEqualTo(emptyIntString().put(1, "1").put(3, "3").put(5, "5").put(7, "7").put(9, "9").put(10, "a").put(11, "b").put(12, "c").put(13, "d").put(14, "e").put(15, "f").put(17, "11").put(19, "13"));
}
@Test
public void shouldKeyRemoveWork() throws Exception {
final Map<Integer, String> src = mapTabulate(20, n -> Tuple.of(n, Integer.toHexString(n)));
final Map<Integer, String> dst = src.removeKeys(k -> k % 2 == 0);
assertThat(dst).isEqualTo(emptyIntString().put(1, "1").put(3, "3").put(5, "5").put(7, "7").put(9, "9").put(11, "b").put(13, "d").put(15, "f").put(17, "11").put(19, "13"));
}
@Test
public void shouldValueRemoveWork() throws Exception {
final Map<Integer, String> src = mapTabulate(20, n -> Tuple.of(n, Integer.toHexString(n)));
final Pattern isDigits = Pattern.compile("^\\d+$");
final Map<Integer, String> dst = src.removeValues(v -> isDigits.matcher(v).matches());
assertThat(dst).isEqualTo(emptyIntString().put(10, "a").put(11, "b").put(12, "c").put(13, "d").put(14, "e").put(15, "f"));
}
// -- computeIfAbsent
@Test
public void shouldComputeIfAbsent() {
final Map<Integer, String> map = emptyIntString().put(1, "v");
assertThat(map.computeIfAbsent(1, k -> "b")).isEqualTo(Tuple.of("v", map));
assertThat(map.computeIfAbsent(2, k -> "n")).isEqualTo(Tuple.of("n", emptyIntString().put(1, "v").put(2, "n")));
}
// -- computeIfAbsent
@Test
public void shouldComputeIfPresent() {
final Map<Integer, String> map = emptyIntString().put(1, "v");
assertThat(map.computeIfPresent(1, (k, v) -> "b")).isEqualTo(Tuple.of(Option.of("b"), emptyIntString().put(1, "b")));
assertThat(map.computeIfPresent(2, (k, v) -> "n")).isEqualTo(Tuple.of(Option.none(), map));
}
// -- get with nulls
@Test
public void shouldReturnOptionOfNullWhenAccessingKeysSetToNull() {
final Map<String, String> map = mapOf("1", null);
assertThat(map.get("1")).isEqualTo(Option.some(null));
}
@Test
public void shouldReturnOptionOfKeyWhenAccessingPresentKeysInAMapWithNulls() {
final Map<String, String> map = mapOf("1", "a").put("2", null);
assertThat(map.get("1")).isEqualTo(Option.of("a"));
}
@Test
public void shouldReturnNoneWhenAccessingAbsentKeysInAMapWithNulls() {
final Map<String, String> map = mapOf("1", "a").put("2", null);
assertThat(map.get("3")).isEqualTo(Option.none());
}
@Test
public void shouldReturnSameInstanceIfReplacingCurrentValueWithNonExistingKey() {
final Map<Integer, String> map = mapOf(1, "a", 2, "b");
final Map<Integer, String> actual = map.replaceValue(3, "?");
assertThat(actual).isSameAs(map);
}
@Test
public void shouldReplaceCurrentValueForExistingKey() {
final Map<Integer, String> map = mapOf(1, "a", 2, "b");
final Map<Integer, String> actual = map.replaceValue(2, "c");
final Map<Integer, String> expected = mapOf(1, "a", 2, "c");
assertThat(actual).isEqualTo(expected);
}
@Test
public void shouldReplaceCurrentValueForExistingKeyAndEqualOldValue() {
final Map<Integer, String> map = mapOf(1, "a", 2, "b");
final Map<Integer, String> actual = map.replace(2, "b", "c");
final Map<Integer, String> expected = mapOf(1, "a", 2, "c");
assertThat(actual).isEqualTo(expected);
}
@Test
public void shouldReturnSameInstanceForExistingKeyAndNonEqualOldValue() {
final Map<Integer, String> map = mapOf(1, "a", 2, "b");
final Map<Integer, String> actual = map.replace(2, "d", "c");
assertThat(actual).isSameAs(map);
}
@Test
public void shouldReturnSameInstanceIfReplacingCurrentValueWithOldValueWithNonExistingKey() {
final Map<Integer, String> map = mapOf(1, "a", 2, "b");
final Map<Integer, String> actual = map.replace(3, "?", "!");
assertThat(actual).isSameAs(map);
}
@Test
public void shouldReplaceAllValuesWithFunctionResult() {
final Map<Integer, String> map = mapOf(1, "a", 2, "b");
final Map<Integer, String> actual = map.replaceAll((integer, s) -> s + integer);
final Map<Integer, String> expected = mapOf(1, "a1", 2, "b2");
assertThat(actual).isEqualTo(expected);
}
@Test
public void shouldGetValueOfNullKeyWhenPutFirstHavingTwoEntries() {
final Map<Integer, String> map = mapOfNullKey(null, "a", 2, "b");
assertThat(map.get(null)).isEqualTo(Some("a"));
}
@Test
public void shouldGetValueOfNullKeyWhenPutLastHavingTwoEntries() {
final Map<Integer, String> map = mapOfNullKey(1, "a", null, "b");
assertThat(map.get(null)).isEqualTo(Some("b"));
}
@Test
public void shouldGetAPresentNullValueWhenPutFirstHavingTwoEntries() {
final Map<Integer, String> map = mapOf(1, null, 2, "b");
assertThat(map.get(1)).isEqualTo(Some(null));
}
@Test
public void shouldGetAPresentNullValueWhenPutLastHavingTwoEntries() {
final Map<Integer, String> map = mapOf(1, "a", 2, null);
assertThat(map.get(2)).isEqualTo(Some(null));
}
// -- getOrElse
@Test
public void shouldReturnDefaultValue() {
final Map<String, String> map = mapOf("1", "a").put("2", "b");
assertThat(map.getOrElse("3", "3")).isEqualTo("3");
}
// -- spliterator
@Test
public void shouldHaveSizedSpliterator() {
assertThat(of(1, 2, 3).spliterator().hasCharacteristics(Spliterator.SIZED | Spliterator.SUBSIZED)).isTrue();
}
@Test
public void shouldHaveDistinctSpliterator() {
assertThat(of(1, 2, 3).spliterator().hasCharacteristics(Spliterator.DISTINCT)).isTrue();
}
@Test
public void shouldReturnSizeWhenSpliterator() {
assertThat(of(1, 2, 3).spliterator().getExactSizeIfKnown()).isEqualTo(3);
}
@Override
@Test
@SuppressWarnings("unchecked")
public void shouldPartitionIntsInOddAndEvenHavingOddAndEvenNumbers() {
assertThat(of(1, 2, 3, 4).partition(i -> i % 2 != 0))
.isEqualTo(Tuple.of(mapOfTuples(Tuple.of(0, 1), Tuple.of(2, 3)),
mapOfTuples(Tuple.of(1, 2), Tuple.of(3, 4))));
}
@Override
@Test
@SuppressWarnings("unchecked")
public void shouldSpanNonNil() {
assertThat(of(0, 1, 2, 3).span(i -> i < 2))
.isEqualTo(Tuple.of(mapOfTuples(Tuple.of(0, 0), Tuple.of(1, 1)),
mapOfTuples(Tuple.of(2, 2), Tuple.of(3, 3))));
}
@Override
@Test
@SuppressWarnings("unchecked")
public void shouldSpanAndNotTruncate() {
assertThat(of(1, 1, 2, 2, 3, 3).span(x -> x % 2 == 1))
.isEqualTo(Tuple.of(mapOfTuples(Tuple.of(0,1), Tuple.of(1, 1)),
mapOfTuples(Tuple.of(2, 2), Tuple.of(3, 2),
Tuple.of(4, 3), Tuple.of(5, 3))));
assertThat(of(1, 1, 2, 2, 4, 4).span(x -> x == 1))
.isEqualTo(Tuple.of(mapOfTuples(Tuple.of(0,1), Tuple.of(1, 1)),
mapOfTuples(Tuple.of(2, 2), Tuple.of(3, 2),
Tuple.of(4, 4), Tuple.of(5, 4))));
}
@Override
@Test
public void shouldNonNilGroupByIdentity() {
final Map<?, ?> actual = of('a', 'b', 'c').groupBy(Function.identity());
final Map<?, ?> expected = io.vavr.collection.LinkedHashMap.empty().put('a', mapOf(0, 'a')).put('b', mapOf(1,'b'))
.put('c', mapOf(2,'c'));
assertThat(actual).isEqualTo(expected);
}
}