package fj.data; import fj.Equal; import fj.F; import fj.data.test.PropertyAssert; import fj.test.Arbitrary; import fj.test.Gen; import fj.test.Property; import org.junit.Assert; import org.junit.Test; import static fj.data.test.PropertyAssert.assertResult; import static fj.test.Arbitrary.*; import static fj.test.Cogen.cogenInteger; import static fj.test.Property.prop; import static fj.test.Property.property; import static org.junit.Assert.assertTrue; /** * Created by MarkPerry on 17/12/2014. */ public class WriterTest { @Test public void base() { Assert.assertTrue(tellTruth("a", "b", 0)); } boolean tellTruth(String s1, String s2, int i) { Writer<String, Integer> w = defaultWriter.f(i); Writer<String, Integer> w1 = w.tell(s1).tell(s2); Writer<String, Integer> w2 = w.tell(w.monoid().sum(s1, s2)); boolean b = eq.eq(w1, w2); // System.out.println(String.format("p1: %s, p2: %s, b: %s", w1, w2, b)); return b; } final Equal<Writer<String, Integer>> eq = Equal.writerEqual(Equal.stringEqual, Equal.intEqual); final F<Integer, Writer<String, Integer>> defaultWriter = Writer.<Integer>stringLogger(); @Test public void testTellProp() { Property p = property(arbString, arbString, arbInteger, (s1, s2, i) -> prop(tellTruth(s1, s2, i))); assertResult(p); } @Test public void testMap() { Property p = property(arbInteger, arbF(cogenInteger, arbInteger), (i, f) -> { boolean b = eq.eq(defaultWriter.f(i).map(f), defaultWriter.f(f.f(i))); return prop(b); }); assertResult(p); } @Test public void testFlatMap() { Property p = property(arbInteger,arbF(cogenInteger, arbWriterStringInt()), (i, f) -> { boolean b = eq.eq(Writer.<Integer>stringLogger().f(i).flatMap(f), f.f(i)); return prop(b); }); assertResult(p); } public Gen<Writer<String, Integer>> arbWriterStringInt() { return arbWriterString(arbInteger); } public <A> Gen<Writer<String, A>> arbWriterString(Gen<A> arb) { return arb.map(a -> Writer.<A>stringLogger().f(a)); } // Left identity: return a >>= f == f a @Test public void testLeftIdentity() { Property p = Property.property( arbInteger, arbF(cogenInteger, arbWriterStringInt()), (i, f) -> { return prop(eq.eq(defaultWriter.f(i).flatMap(f), f.f(i))); }); assertResult(p); } // Right identity: m >>= return == m @Test public void testRightIdentity() { Property p = Property.property( arbWriterStringInt(), (w) -> prop(eq.eq(w.flatMap(a -> defaultWriter.f(a)), w)) ); assertResult(p); } // Associativity: (m >>= f) >>= g == m >>= (\x -> f x >>= g) @Test public void testAssociativity() { Property p = Property.property( arbWriterStringInt(), arbF(cogenInteger, arbWriterStringInt()), arbF(cogenInteger, arbWriterStringInt()), (w, f, g) -> { boolean t = eq.eq(w.flatMap(f).flatMap(g), w.flatMap(x -> f.f(x).flatMap(g))); return prop(t); }); assertResult(p); } }