Skip to content

Commit aa9a683

Browse files
committed
Added Writer monad tests
1 parent 1a4b4bc commit aa9a683

3 files changed

Lines changed: 131 additions & 10 deletions

File tree

core/src/main/java/fj/Equal.java

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,9 @@
11
package fj;
22

33
import static fj.Function.curry;
4+
5+
import fj.data.*;
46
import fj.data.hlist.HList;
5-
import fj.data.Array;
6-
import fj.data.Either;
7-
import fj.data.LazyString;
8-
import fj.data.List;
9-
import fj.data.NonEmptyList;
10-
import fj.data.Option;
11-
import fj.data.Set;
12-
import fj.data.Stream;
13-
import fj.data.Tree;
14-
import fj.data.Validation;
157
import fj.data.vector.V2;
168
import fj.data.vector.V3;
179
import fj.data.vector.V4;
@@ -667,4 +659,9 @@ public Boolean f(final Set<A> a, final Set<A> b) {
667659
}
668660
}));
669661
}
662+
663+
public static <A, B> Equal<Writer<A, B>> writerEqual(Equal<A> eq1, Equal<B> eq2) {
664+
return new Equal<Writer<A, B>>(w1 -> w2 -> Equal.p2Equal(eq1, eq2).eq(w1.run(), w2.run()));
665+
}
666+
670667
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ public W log() {
2929
return logValue;
3030
}
3131

32+
public Monoid<W> monoid() {
33+
return monoid;
34+
}
35+
3236
public static <W, A> Writer<W, A> unit(A a, W w, Monoid<W> m) {
3337
return new Writer<W, A>(a, w, m);
3438
}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
package fj.data;
2+
3+
import fj.Equal;
4+
import fj.F;
5+
import fj.F2;
6+
import fj.test.Arbitrary;
7+
import fj.test.CheckResult;
8+
import fj.test.Property;
9+
import org.junit.Assert;
10+
import org.junit.Test;
11+
12+
import static fj.F1Functions.map;
13+
import static fj.F2Functions.curry;
14+
import static fj.test.Arbitrary.*;
15+
import static fj.test.Coarbitrary.coarbInteger;
16+
import static fj.test.Property.prop;
17+
import static fj.test.Property.property;
18+
import static org.junit.Assert.assertTrue;
19+
20+
/**
21+
* Created by MarkPerry on 17/12/2014.
22+
*/
23+
public class WriterTest {
24+
25+
@Test
26+
public void base() {
27+
Assert.assertTrue(tellTruth("a", "b", 0));
28+
}
29+
30+
boolean tellTruth(String s1, String s2, int i) {
31+
Writer<String, Integer> w = defaultWriter.f(i);
32+
Writer<String, Integer> w1 = w.tell(s1).tell(s2);
33+
Writer<String, Integer> w2 = w.tell(w.monoid().sum(s1, s2));
34+
boolean b = eq.eq(w1, w2);
35+
// System.out.println(String.format("p1: %s, p2: %s, b: %s", w1, w2, b));
36+
return b;
37+
}
38+
39+
final Equal<Writer<String, Integer>> eq = Equal.writerEqual(Equal.stringEqual, Equal.intEqual);
40+
final F<Integer, Writer<String, Integer>> defaultWriter = Writer.<Integer>stringLogger();
41+
42+
void assertProperty(Property p) {
43+
CheckResult cr = p.check();
44+
CheckResult.summary.println(cr);
45+
assertTrue(cr.isExhausted() || cr.isPassed() || cr.isProven());
46+
}
47+
48+
@Test
49+
public void testTellProp() {
50+
Property p = property(arbString, arbString, arbInteger, (s1, s2, i) -> prop(tellTruth(s1, s2, i)));
51+
assertProperty(p);
52+
}
53+
54+
@Test
55+
public void testMap() {
56+
Property p = property(arbInteger, arbF(coarbInteger, arbInteger), (i, f) -> {
57+
boolean b = eq.eq(defaultWriter.f(i).map(f), defaultWriter.f(f.f(i)));
58+
return prop(b);
59+
});
60+
assertProperty(p);
61+
}
62+
63+
@Test
64+
public void testFlatMap() {
65+
Property p = property(arbInteger,arbF(coarbInteger, arbWriterStringInt()), (i, f) -> {
66+
boolean b = eq.eq(Writer.<Integer>stringLogger().f(i).flatMap(f), f.f(i));
67+
return prop(b);
68+
});
69+
assertProperty(p);
70+
71+
}
72+
73+
public Arbitrary<Writer<String, Integer>> arbWriterStringInt() {
74+
return arbWriterString(arbInteger);
75+
}
76+
77+
public <A> Arbitrary<Writer<String, A>> arbWriterString(Arbitrary<A> arb) {
78+
return Arbitrary.arbitrary(arb.gen.map(a -> Writer.<A>stringLogger().f(a)));
79+
}
80+
81+
// Left identity: return a >>= f == f a
82+
@Test
83+
public void testLeftIdentity() {
84+
Property p = Property.property(
85+
arbInteger,
86+
arbF(coarbInteger, arbWriterStringInt()),
87+
(i, f) -> {
88+
return prop(eq.eq(defaultWriter.f(i).flatMap(f), f.f(i)));
89+
});
90+
assertProperty(p);
91+
}
92+
93+
// Right identity: m >>= return == m
94+
@Test
95+
public void testRightIdentity() {
96+
Property p = Property.property(
97+
arbWriterStringInt(),
98+
(w) -> prop(eq.eq(w.flatMap(a -> defaultWriter.f(a)), w))
99+
);
100+
assertProperty(p);
101+
}
102+
103+
// Associativity: (m >>= f) >>= g == m >>= (\x -> f x >>= g)
104+
@Test
105+
public void testAssociativity() {
106+
Property p = Property.property(
107+
arbWriterStringInt(),
108+
arbF(coarbInteger, arbWriterStringInt()),
109+
arbF(coarbInteger, arbWriterStringInt()),
110+
(w, f, g) -> {
111+
boolean t = eq.eq(w.flatMap(f).flatMap(g), w.flatMap(x -> f.f(x).flatMap(g)));
112+
return prop(t);
113+
});
114+
assertProperty(p);
115+
}
116+
117+
118+
119+
120+
}

0 commit comments

Comments
 (0)