package fj.data.hamt;
import fj.Equal;
import fj.Hash;
import fj.Ord;
import fj.P2;
import fj.data.List;
import fj.data.Option;
import fj.data.Set;
import fj.test.Gen;
import fj.test.Property;
import fj.test.reflect.CheckParams;
import fj.test.runner.PropertyTestRunner;
import org.junit.runner.RunWith;
import static fj.Equal.intEqual;
import static fj.Equal.optionEqual;
import static fj.Ord.intOrd;
import static fj.Ord.p2Ord;
import static fj.Ord.p2Ord2;
import static fj.data.Option.some;
import static fj.test.Arbitrary.arbInteger;
import static fj.test.Arbitrary.arbList;
import static fj.test.Arbitrary.arbListInteger;
import static fj.test.Arbitrary.arbP2;
import static fj.test.Arbitrary.arbSet;
import static fj.test.Property.prop;
import static fj.test.Property.property;
/**
* @author Mark Perry
*/
@RunWith(PropertyTestRunner.class)
@CheckParams(maxSize = 100)
public class HashArrayMappedTrieProperties {
private static final HashArrayMappedTrie<Integer, Integer> empty = HashArrayMappedTrie.emptyKeyInteger();
private static final Gen<List<P2<Integer, Integer>>> arbListProducts = arbSet(intOrd, arbInteger).bind(s -> Gen.listOf(arbInteger, s.size()).map(list -> s.toList().zip(list)));
private static final Gen<HashArrayMappedTrie<Integer, Integer>> arbHamt = arbListProducts.map(l -> empty.set(l));
Property empty() {
return prop(empty.isEmpty());
}
Property setFromList() {
return property(arbListProducts, list -> {
List<P2<Integer, Integer>> actual = empty.set(list).toList(intOrd);
List<P2<Integer, Integer>> expected = list.sort(p2Ord(intOrd, intOrd));
boolean b = actual.equals(expected);
return prop(b);
});
}
Property overwriteKey() {
return property(arbHamt, arbInteger, arbInteger, arbInteger, (h, k, v1, v2) -> {
Option<Integer> actual = h.set(k, v1).set(k, v2).find(k);
return prop(optionEqual(intEqual).eq(actual, some(v2)));
});
}
Property allIn() {
return property(arbListProducts, list -> {
HashArrayMappedTrie<Integer, Integer> h = empty.set(list);
Boolean b = list.foldLeft((acc, p) -> h.find(p._1()).option(false, i -> true && acc), true);
return prop(b);
});
}
Property sampleInts() {
return property(arbListProducts, arbInteger, (ps, i) -> {
HashArrayMappedTrie<Integer, Integer> h = empty.set(ps);
Option<Integer> o1 = ps.find(p -> intEqual.eq(p._1(), i)).map(p -> p._2());
Option<Integer> o2 = h.find(i);
return prop(optionEqual(intEqual).eq(o1, o2));
});
}
Property fold() {
return property(arbListProducts, list -> {
Integer actual = empty.set(list).foldLeft((acc, p) -> acc + p._2(), 0);
Integer expected = list.foldLeft((acc, p) -> acc + p._2(), 0);
return prop(intEqual.eq(actual, expected));
});
}
Property length() {
return property(arbListProducts, list -> {
Integer actual = empty.set(list).length();
Integer expected = list.length();
return prop(intEqual.eq(actual, expected));
});
}
}