From a21ede97de20a26a4fc184f48cb3c9c535f14762 Mon Sep 17 00:00:00 2001 From: "Frank S. Thomas" Date: Wed, 9 Dec 2015 20:54:39 +0100 Subject: [PATCH] Test associativity of (Co)Kleisli composition closes #732 --- .../test/scala/cats/tests/OptionTests.scala | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tests/src/test/scala/cats/tests/OptionTests.scala b/tests/src/test/scala/cats/tests/OptionTests.scala index 72702002ad..2799ab4ea2 100644 --- a/tests/src/test/scala/cats/tests/OptionTests.scala +++ b/tests/src/test/scala/cats/tests/OptionTests.scala @@ -1,6 +1,7 @@ package cats package tests +import cats.laws.{CoflatMapLaws, FlatMapLaws} import cats.laws.discipline.{TraverseTests, CoflatMapTests, MonadCombineTests, SerializableTests} class OptionTests extends CatsSuite { @@ -21,4 +22,30 @@ class OptionTests extends CatsSuite { fs.show should === (fs.toString) } } + + // The following two tests check the kleisliAssociativity and + // cokleisliAssociativity laws which are a different formulation of + // the flatMapAssociativity and coflatMapAssociativity laws. Since + // these laws are more or less duplicates of existing laws, we don't + // check them for all types that have FlatMap or CoflatMap instances. + + test("Kleisli associativity") { + forAll { (l: Long, + f: Long => Option[Int], + g: Int => Option[Char], + h: Char => Option[String]) => + val isEq = FlatMapLaws[Option].kleisliAssociativity(f, g, h, l) + isEq.lhs should === (isEq.rhs) + } + } + + test("Cokleisli associativity") { + forAll { (l: Option[Long], + f: Option[Long] => Int, + g: Option[Int] => Char, + h: Option[Char] => String) => + val isEq = CoflatMapLaws[Option].cokleisliAssociativity(f, g, h, l) + isEq.lhs should === (isEq.rhs) + } + } }