package fj.data.properties; import fj.Equal; import fj.Ord; import fj.P2; import fj.data.List; import fj.data.NonEmptyList; import fj.test.reflect.CheckParams; import fj.test.runner.PropertyTestRunner; import fj.test.Property; import org.junit.runner.RunWith; import java.util.ArrayList; import java.util.Collections; import static fj.Equal.intEqual; import static fj.Equal.listEqual; import static fj.Equal.nonEmptyListEqual; import static fj.Function.identity; import static fj.data.NonEmptyList.nel; import static fj.data.NonEmptyList.unzip; import static fj.test.Arbitrary.arbInteger; import static fj.test.Arbitrary.arbNonEmptyList; import static fj.test.Property.prop; import static fj.test.Property.property; import static java.lang.Math.min; /** * Created by Zheka Kozlov on 02.06.2015. */ @RunWith(PropertyTestRunner.class) @CheckParams(maxSize = 10000) public class NonEmptyListProperties { private static final Equal<NonEmptyList<Integer>> eq = nonEmptyListEqual(intEqual); private static final Equal<List<Integer>> listEq = listEqual(intEqual); public Property consHead() { return property(arbNonEmptyList(arbInteger), arbInteger, (list, n) -> prop(intEqual.eq(list.cons(n).head(), n))); } public Property consLength() { return property(arbNonEmptyList(arbInteger), arbInteger, (list, n) -> prop(list.cons(n).length() == list.length() + 1)); } public Property positiveLength() { return property(arbNonEmptyList(arbInteger), list -> prop(list.length() > 0)); } public Property appendLength() { return property(arbNonEmptyList(arbInteger), arbNonEmptyList(arbInteger), (list1, list2) -> prop(list1.append(list2).length() == list1.length() + list2.length())); } public Property appendSingle() { return property(arbNonEmptyList(arbInteger), arbInteger, (list, n) -> prop(eq.eq(nel(n).append(list), list.cons(n)))); } public Property tailLength() { return property(arbNonEmptyList(arbInteger), list -> prop(list.length() == 1 + list.tail().length())); } public Property mapId() { return property(arbNonEmptyList(arbInteger), list -> prop(eq.eq(list.map(identity()), list))); } public Property reverse() { return property(arbNonEmptyList(arbInteger), list -> prop(listEq.eq(list.reverse().toList(), list.tail().reverse().snoc(list.head())))); } public Property doubleReverse() { return property(arbNonEmptyList(arbInteger), list -> prop(eq.eq(list.reverse().reverse(), list))); } public Property sort() { return property(arbNonEmptyList(arbInteger), list -> { java.util.List<Integer> javaList = list.sort(Ord.intOrd).toList().toJavaList(); java.util.List<Integer> copy = new ArrayList<>(javaList); Collections.sort(copy); return prop(javaList.equals(copy)); }); } public Property intersperseLength() { return property(arbNonEmptyList(arbInteger), arbInteger, (list, n) -> prop(list.intersperse(n).length() == 2 * list.length() - 1)); } public Property zip() { return property(arbNonEmptyList(arbInteger), arbNonEmptyList(arbInteger), (list1, list2) -> { final int size = min(list1.length(), list2.length()); final NonEmptyList<P2<Integer, Integer>> zipped = list1.zip(list2); return prop(listEq.eq(zipped.map(P2::_1).toList(), list1.toList().take(size))) .and(prop(listEq.eq(zipped.map(P2::_2).toList(), list2.toList().take(size)))); }); } public Property zipUnzip() { return property(arbNonEmptyList(arbInteger), arbNonEmptyList(arbInteger), (list1, list2) -> { final P2<NonEmptyList<Integer>, NonEmptyList<Integer>> unzipped = unzip(list1.zip(list2)); final int size = min(list1.length(), list2.length()); return prop(listEq.eq(unzipped._1().toList(), list1.toList().take(size))) .and(prop(listEq.eq(unzipped._2().toList(), list2.toList().take(size)))); }); } }