Skip to content

Commit a513e40

Browse files
committed
Merge pull request #158 from orionll/master
Added Seq.isNotEmpty(). Properties for List, Stream and Array.
2 parents 46153ea + 478b519 commit a513e40

File tree

6 files changed

+698
-56
lines changed

6 files changed

+698
-56
lines changed

core/src/main/java/fj/data/Seq.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,15 @@ public boolean isEmpty() {
189189
return ftree.isEmpty();
190190
}
191191

192+
/**
193+
* Checks if this sequence is not empty.
194+
*
195+
* @return True if this sequence is not empty, otherwise false.
196+
*/
197+
public boolean isNotEmpty() {
198+
return !ftree.isEmpty();
199+
}
200+
192201
/**
193202
* Returns the number of elements in this sequence.
194203
*

props-core/src/test/java/fj/data/StreamProperties.java

Lines changed: 0 additions & 30 deletions
This file was deleted.
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
package fj.data.properties;
2+
3+
import fj.*;
4+
import fj.data.Array;
5+
import fj.data.Either;
6+
import fj.test.Arbitrary;
7+
import fj.test.Gen;
8+
import fj.test.Property;
9+
import fj.test.reflect.CheckParams;
10+
import fj.test.runner.PropertyTestRunner;
11+
import org.junit.runner.RunWith;
12+
13+
import java.util.HashMap;
14+
import java.util.Map;
15+
import java.util.Set;
16+
17+
import static fj.Equal.arrayEqual;
18+
import static fj.Equal.intEqual;
19+
import static fj.Function.compose;
20+
import static fj.Function.identity;
21+
import static fj.data.Array.array;
22+
import static fj.data.Array.empty;
23+
import static fj.test.Arbitrary.*;
24+
import static fj.test.Property.implies;
25+
import static fj.test.Property.prop;
26+
import static fj.test.Property.property;
27+
28+
@RunWith(PropertyTestRunner.class)
29+
@CheckParams(maxSize = 10000)
30+
public class ArrayProperties {
31+
32+
private static final Equal<Array<Integer>> eq = arrayEqual(intEqual);
33+
34+
private static final Arbitrary<P2<Array<Integer>, Integer>> arbArrayWithIndex = arbitrary(arbArray(arbInteger).gen
35+
.filter(Array::isNotEmpty)
36+
.bind(array -> Gen.choose(0, array.length() - 1).map(i -> P.p(array, i))));
37+
38+
public Property isEmpty() {
39+
return property(arbArray(arbInteger), array -> prop(array.isEmpty() != array.isNotEmpty()));
40+
}
41+
42+
public Property isNotEmpty() {
43+
return property(arbArray(arbInteger), array -> prop(array.length() > 0 == array.isNotEmpty()));
44+
}
45+
46+
public Property toOption() {
47+
return property(arbArray(arbInteger), array ->
48+
prop(array.toOption().isNone() || intEqual.eq(array.toOption().some(), array.get(0))));
49+
}
50+
51+
public Property toEither() {
52+
return property(arbArray(arbInteger), arbP1(arbInteger), (array, n) -> {
53+
final Either<Integer, Integer> e = array.toEither(n);
54+
return prop(e.isLeft() && intEqual.eq(e.left().value(), n._1()) ||
55+
intEqual.eq(e.right().value(), array.get(0)));
56+
});
57+
}
58+
59+
public Property mapId() {
60+
return property(arbArray(arbInteger), array -> prop(eq.eq(array.map(identity()), array)));
61+
}
62+
63+
public Property mapCompose() {
64+
final F<Integer, Integer> f = x -> x + 3;
65+
final F<Integer, Integer> g = x -> x * 4;
66+
return property(arbArray(arbInteger), array ->
67+
prop(eq.eq(array.map(compose(f, g)), array.map(g).map(f))));
68+
}
69+
70+
public Property foreachDoEffect() {
71+
return property(arbArray(arbInteger), array -> {
72+
int[] acc = {0};
73+
array.foreachDoEffect(x -> acc[0] += x);
74+
75+
int acc2 = 0;
76+
for (int x : array) { acc2 += x; }
77+
78+
return prop(intEqual.eq(acc[0], acc2));
79+
});
80+
}
81+
82+
public Property filter() {
83+
final F<Integer, Boolean> predicate = (x -> x % 2 == 0);
84+
return property(arbArray(arbInteger), array -> prop(array.filter(predicate).forall(predicate)));
85+
}
86+
87+
public Property filterLength() {
88+
final F<Integer, Boolean> predicate = (x -> x % 2 == 0);
89+
return property(arbArray(arbInteger), array -> prop(array.filter(predicate).length() <= array.length()));
90+
}
91+
92+
public Property bindLeftIdentity() {
93+
final F<Integer, Array<Integer>> f = (i -> array(-i));
94+
return property(arbArray(arbInteger), arbInteger, (array, i) ->
95+
prop(eq.eq(array(i).bind(f), f.f(i))));
96+
}
97+
98+
public Property bindRightIdentity() {
99+
return property(arbArray(arbInteger), array -> prop(eq.eq(array.bind(Array::array), array)));
100+
}
101+
102+
public Property bindAssociativity() {
103+
final F<Integer, Array<Integer>> f = x -> array(x + 3);
104+
final F<Integer, Array<Integer>> g = x -> array(x * 4);
105+
return property(arbArray(arbInteger), array ->
106+
prop(eq.eq(array.bind(f).bind(g), array.bind(i -> f.f(i).bind(g)))));
107+
}
108+
109+
public Property foldRight() {
110+
return property(arbArray(arbInteger), array ->
111+
prop(eq.eq(array.foldRight((i, s) -> array(i).append(s), empty()), array)));
112+
}
113+
114+
public Property foldLeft() {
115+
return property(arbArray(arbInteger), array ->
116+
prop(eq.eq(array.foldLeft((s, i) -> array(i).append(s), empty()),
117+
array.reverse().foldRight((i, s) -> array(i).append(s), empty()))));
118+
}
119+
120+
public Property scans() {
121+
return property(arbArray(arbInteger), arbInteger, (array, z) -> {
122+
final F<Integer, F<Integer, Integer>> add = x -> y -> x + y;
123+
final Array<Integer> left = array.scanLeft(add, z);
124+
final Array<Integer> right = array.reverse().scanRight(add, z).reverse();
125+
return prop(eq.eq(left, right));
126+
});
127+
}
128+
129+
public Property scans1() {
130+
return property(arbArray(arbInteger), array ->
131+
implies(array.isNotEmpty(), () -> {
132+
final F<Integer, F<Integer, Integer>> add = x -> y -> x + y;
133+
final Array<Integer> left = array.scanLeft1(add);
134+
final Array<Integer> right = array.reverse().scanRight1(add).reverse();
135+
return prop(eq.eq(left, right));
136+
}));
137+
}
138+
139+
@CheckParams(maxSize = 100)
140+
public Property sequence() {
141+
return property(arbArray(arbInteger), arbArray(arbInteger), (array1, array2) ->
142+
prop(eq.eq(array1.sequence(array2), array1.bind(__ -> array2))));
143+
}
144+
145+
public Property reverseIdentity() {
146+
return property(arbArray(arbInteger), array ->
147+
prop(eq.eq(array.reverse().reverse(), array)));
148+
}
149+
150+
public Property reverse() {
151+
return property(arbArray(arbInteger), arbArray(arbInteger), (array1, array2) ->
152+
prop(eq.eq(array1.append(array2).reverse(), array2.reverse().append(array1.reverse()))));
153+
}
154+
155+
@CheckParams(minSize = 1)
156+
public Property reverseIndex() {
157+
return property(arbArrayWithIndex, p -> {
158+
final Array<Integer> array = p._1();
159+
final Integer i = p._2();
160+
return prop(intEqual.eq(array.reverse().get(i), array.get(array.length() - i - 1)));
161+
});
162+
}
163+
164+
public Property appendLeftIdentity() {
165+
return property(arbArray(arbInteger), array -> prop(eq.eq(Array.<Integer> empty().append(array), array)));
166+
}
167+
168+
public Property appendRightIdentity() {
169+
return property(arbArray(arbInteger), array -> prop(eq.eq(array.append(empty()), array)));
170+
}
171+
172+
public Property appendAssociativity() {
173+
return property(arbArray(arbInteger), arbArray(arbInteger), arbArray(arbInteger), (array1, array2, array3) ->
174+
prop(eq.eq(array1.append(array2).append(array3), array1.append(array2.append(array3)))));
175+
}
176+
177+
public Property appendLength() {
178+
return property(arbArray(arbInteger), arbArray(arbInteger), (array1, array2) ->
179+
prop(array1.append(array2).length() == array1.length() + array2.length()));
180+
}
181+
182+
public Property arrayLength() {
183+
return property(arbArray(arbInteger), array -> prop(array.length() == array.array().length));
184+
}
185+
186+
@CheckParams(minSize = 1)
187+
public Property index() {
188+
return property(arbArrayWithIndex, p -> {
189+
final Array<Integer> array = p._1();
190+
final Integer i = p._2();
191+
return prop(intEqual.eq(array.get(i), array.array(Integer[].class)[i]));
192+
});
193+
}
194+
195+
public Property forallExists() {
196+
return property(arbArray(arbInteger), array ->
197+
prop(array.forall(x -> x % 2 == 0) == !array.exists(x -> x % 2 != 0)));
198+
}
199+
200+
public Property find() {
201+
return property(arbArray(arbInteger), array -> prop(array.find(x -> x % 2 == 0).forall(x -> x % 2 == 0)));
202+
}
203+
204+
@CheckParams(maxSize = 500)
205+
public Property join() {
206+
return property(arbArray(arbArray(arbInteger)), (Array<Array<Integer>> array) ->
207+
prop(eq.eq(array.foldRight(Array::append, empty()), Array.join(array))));
208+
}
209+
}

0 commit comments

Comments
 (0)