Skip to content

Commit

Permalink
More coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
edmundnoble committed Jun 30, 2017
1 parent bbc97b8 commit eaeb096
Show file tree
Hide file tree
Showing 11 changed files with 145 additions and 51 deletions.
63 changes: 46 additions & 17 deletions core/src/main/scala/cats/data/IdT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,18 @@ final case class IdT[F[_], A](value: F[A]) {
def foldRight[B](lb: Eval[B])(f: (A, Eval[B]) => Eval[B])(implicit F: Foldable[F]): Eval[B] =
F.foldRight(value, lb)(f)

def reduceLeftTo[B](f: A => B)(g: (B, A) => B)(implicit F: Reducible[F]): B =
F.reduceLeftTo(value)(f)(g)

def reduceRightTo[B](f: A => B)(g: (A, Eval[B]) => Eval[B])(implicit F: Reducible[F]): Eval[B] =
F.reduceRightTo(value)(f)(g)

def traverse[G[_], B](f: A => G[B])(implicit F: Traverse[F], G: Applicative[G]): G[IdT[F, B]] =
G.map(F.traverse(value)(f))(IdT(_))

def nonEmptyTraverse[G[_], B](f: A => G[B])(implicit F: NonEmptyTraverse[F], G: Apply[G]): G[IdT[F, B]] =
G.map(F.nonEmptyTraverse(value)(f))(IdT(_))

def ap[B](f: IdT[F, A => B])(implicit F: Apply[F]): IdT[F, B] =
IdT(F.ap(f.value)(value))

Expand Down Expand Up @@ -78,15 +87,42 @@ private[data] sealed trait IdTTraverse[F[_]] extends Traverse[IdT[F, ?]] with Id
fa.traverse(f)
}

private[data] sealed abstract class IdTInstances1 {
implicit def catsDataFunctorForIdT[F[_]](implicit F: Functor[F]): Functor[IdT[F, ?]] =
new IdTFunctor[F] {
implicit val F0: Functor[F] = F
}
private[data] sealed trait IdTNonEmptyTraverse[F[_]] extends NonEmptyTraverse[IdT[F, ?]] with IdTFoldable[F] {
implicit val F0: NonEmptyTraverse[F]

def nonEmptyTraverse[G[_]: Apply, A, B](fa: IdT[F, A])(f: A => G[B]): G[IdT[F, B]] =
fa.nonEmptyTraverse(f)

def reduceLeftTo[A, B](fa: IdT[F, A])(f: A => B)(g: (B, A) => B): B = fa.reduceLeftTo(f)(g)

def reduceRightTo[A, B](fa: IdT[F, A])(f: A => B)(g: (A, Eval[B]) => Eval[B]): Eval[B] = fa.reduceRightTo(f)(g)
}

private[data] sealed abstract class IdTInstances extends IdTInstances0 {

implicit def catsDataNonEmptyTraverseForIdT[F[_]](implicit F: NonEmptyTraverse[F]): NonEmptyTraverse[IdT[F, ?]] =
new IdTNonEmptyTraverse[F] {
implicit val F0: NonEmptyTraverse[F] = F
}

implicit def catsDataEqForIdT[F[_], A](implicit F: Eq[F[A]]): Eq[IdT[F, A]] =
F.on(_.value)

implicit def catsDataShowForIdT[F[_], A](implicit F: Show[F[A]]): Show[IdT[F, A]] =
functor.Contravariant[Show].contramap(F)(_.value)
}

private[data] sealed abstract class IdTInstances0 extends IdTInstances1 {
implicit def catsDataTraverseForIdT[F[_]](implicit F: Traverse[F]): Traverse[IdT[F, ?]] =
new IdTTraverse[F] {
implicit val F0: Traverse[F] = F
}

implicit def catsDataOrderForIdT[F[_], A](implicit F: Order[F[A]]): Order[IdT[F, A]] =
F.on(_.value)
}

private[data] sealed abstract class IdTInstances1 extends IdTInstances2 {
implicit def catsDataMonadForIdT[F[_]](implicit F: Monad[F]): Monad[IdT[F, ?]] =
new IdTMonad[F] {
implicit val F0: Monad[F] = F
Expand All @@ -96,21 +132,14 @@ private[data] sealed abstract class IdTInstances0 extends IdTInstances1 {
new IdTFoldable[F] {
implicit val F0: Foldable[F] = F
}

implicit def catsDataOrderForIdT[F[_], A](implicit F: Order[F[A]]): Order[IdT[F, A]] =
F.on(_.value)
}

private[data] sealed abstract class IdTInstances extends IdTInstances0 {

implicit def catsDataTraverseForIdT[F[_]](implicit F: Traverse[F]): Traverse[IdT[F, ?]] =
new IdTTraverse[F] {
implicit val F0: Traverse[F] = F
private[data] sealed abstract class IdTInstances2 {
implicit def catsDataFunctorForIdT[F[_]](implicit F: Functor[F]): Functor[IdT[F, ?]] =
new IdTFunctor[F] {
implicit val F0: Functor[F] = F
}
}

implicit def catsDataEqForIdT[F[_], A](implicit F: Eq[F[A]]): Eq[IdT[F, A]] =
F.on(_.value)

implicit def catsDataShowForIdT[F[_], A](implicit F: Show[F[A]]): Show[IdT[F, A]] =
functor.Contravariant[Show].contramap(F)(_.value)
}
18 changes: 8 additions & 10 deletions core/src/main/scala/cats/data/NonEmptyList.scala
Original file line number Diff line number Diff line change
Expand Up @@ -276,11 +276,10 @@ final case class NonEmptyList[+A](head: A, tail: List[A]) {
* res0: cats.data.NonEmptyList[(Char, Int)] = NonEmptyList((z,1), (a,4), (e,22))
* }}}
*/
def sortBy[B](f: A => B)(implicit B: Order[B]): NonEmptyList[A] =
toList.sortBy(f)(B.toOrdering) match {
case x :: xs => NonEmptyList(x, xs)
case Nil => sys.error("unreachable: sorting a NonEmptyList cannot produce an empty List")
}
def sortBy[B](f: A => B)(implicit B: Order[B]): NonEmptyList[A] = {
// safe: sorting a NonEmptyList cannot produce an empty List
NonEmptyList.fromListUnsafe(toList.sortBy(f)(B.toOrdering))
}

/**
* Sorts this `NonEmptyList` according to an `Order`
Expand All @@ -293,11 +292,10 @@ final case class NonEmptyList[+A](head: A, tail: List[A]) {
* res0: cats.data.NonEmptyList[Int] = NonEmptyList(3, 4, 9, 12)
* }}}
*/
def sorted[AA >: A](implicit AA: Order[AA]): NonEmptyList[AA] =
toList.sorted(AA.toOrdering) match {
case x :: xs => NonEmptyList(x, xs)
case Nil => sys.error("unreachable: sorting a NonEmptyList cannot produce an empty List")
}
def sorted[AA >: A](implicit AA: Order[AA]): NonEmptyList[AA] = {
// safe: sorting a NonEmptyList cannot produce an empty List
NonEmptyList.fromListUnsafe(toList.sorted(AA.toOrdering))
}

/**
* Groups elements inside of this `NonEmptyList` using a mapping function
Expand Down
8 changes: 8 additions & 0 deletions free/src/test/scala/cats/free/FreeTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,14 @@ class FreeTests extends CatsSuite {
assert(res == List(112358))
}

test(".run") {
val r = Free.pure[Id, Int](12358)
def recurse(r: Free[Id, Int], n: Int): Free[Id, Int] =
if (n > 0) recurse(r.flatMap(x => Free.pure(x + 1)), n - 1) else r
val res = recurse(r, 100000).run
assert(res == 112358)
}

sealed trait Test1Algebra[A]

case class Test1[A](value : Int, f: Int => A) extends Test1Algebra[A]
Expand Down
2 changes: 0 additions & 2 deletions macros/src/main/scala/cats/macros/Ops.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import scala.reflect.NameTransformer

object Ops extends machinist.Ops {

def uesc(c: Char): String = "$u%04X".format(c.toInt)

val operatorNames: Map[String, String] =
List(
("===", "eqv"),
Expand Down
4 changes: 4 additions & 0 deletions tests/src/test/scala/cats/tests/EitherTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class EitherTests extends CatsSuite {
implicit val iso = CartesianTests.Isomorphisms.invariant[Either[Int, ?]]

checkAll("Either[String, Int]", GroupLaws[Either[String, Int]].monoid)
checkAll("Semigroup[Either[String, Int]]", SerializableTests.serializable(Semigroup[Either[String, Int]]))

checkAll("Either[Int, Int]", CartesianTests[Either[Int, ?]].cartesian[Int, Int, Int])
checkAll("Cartesian[Either[Int, ?]]", SerializableTests.serializable(Cartesian[Either[Int, ?]]))
Expand All @@ -28,6 +29,9 @@ class EitherTests extends CatsSuite {
checkAll("Either[ListWrapper[String], ?]", SemigroupKTests[Either[ListWrapper[String], ?]].semigroupK[Int])
checkAll("SemigroupK[Either[ListWrapper[String], ?]]", SerializableTests.serializable(SemigroupK[Either[ListWrapper[String], ?]]))

checkAll("Either[ListWrapper[String], Int]", GroupLaws[Either[ListWrapper[String], Int]].semigroup)
checkAll("Semigroup[Either[ListWrapper[String], Int]]", SerializableTests.serializable(Semigroup[Either[ListWrapper[String], Int]]))

val partialOrder = catsStdPartialOrderForEither[Int, String]
val order = implicitly[Order[Either[Int, String]]]
val monad = implicitly[Monad[Either[Int, ?]]]
Expand Down
25 changes: 25 additions & 0 deletions tests/src/test/scala/cats/tests/GroupTests.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package cats
package tests

import cats.kernel.laws.GroupLaws

class GroupTests extends CatsSuite {
test("combine minValue") {
Group[Int].combineN(1, Int.MinValue) should ===(Int.MinValue)
}

test("combine negative") {
Group[Int].combineN(1, -1) should ===(-1)
Group[Int].combineN(1, -10) should ===(-10)
}

test("companion object syntax") {
Group[Int].inverse(1) should ===(-1)
Group[Int].remove(1, 2) should ===(-1)
}

checkAll("Int", GroupLaws[Int].group)
checkAll("Double", GroupLaws[Double].group)
checkAll("Float", GroupLaws[Float].group)
checkAll("Long", GroupLaws[Long].group)
}
9 changes: 6 additions & 3 deletions tests/src/test/scala/cats/tests/IdTTests.scala
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package cats.tests

import cats.{Foldable, Functor, Monad, Traverse}
import cats.data.IdT
import cats.laws.discipline.{CartesianTests, FoldableTests, FunctorTests, MonadTests, SerializableTests, TraverseTests}
import cats.{Foldable, Functor, Monad, NonEmptyTraverse, Traverse}
import cats.data.{IdT, NonEmptyList}
import cats.laws.discipline.{CartesianTests, FoldableTests, FunctorTests, MonadTests, SerializableTests, NonEmptyTraverseTests, TraverseTests}
import cats.laws.discipline.arbitrary._

class IdTTests extends CatsSuite {
Expand All @@ -21,4 +21,7 @@ class IdTTests extends CatsSuite {
checkAll("IdT[Option, Int]", TraverseTests[IdT[Option, ?]].traverse[Int, Int, Int, Int, Option, Option])
checkAll("Traverse[IdT[Option, ?]]", SerializableTests.serializable(Traverse[IdT[Option, ?]]))

checkAll("IdT[NonEmptyList, Int]", NonEmptyTraverseTests[IdT[NonEmptyList, ?]].nonEmptyTraverse[Option, Int, Int, Int, Int, Option, Option])
checkAll("NonEmptyTraverse[IdT[NonEmptyList, ?]]", SerializableTests.serializable(NonEmptyTraverse[IdT[NonEmptyList, ?]]))

}
17 changes: 12 additions & 5 deletions tests/src/test/scala/cats/tests/MonoidTests.scala
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@
package cats
package tests

import org.scalatest._

import cats.functor._

class MonoidTests extends FunSuite {
class MonoidTests extends CatsSuite {
{
import cats.implicits._
Invariant[Monoid]
Cartesian[Monoid]
InvariantMonoidal[Monoid]
}

{
test("companion object syntax") {
Monoid.empty[Int] should ===(0)
Monoid.isEmpty(1) should ===(false)
Monoid.isEmpty(0) should ===(true)
}
}

object MonoidTests {
def summonInstance(): Unit = {
import cats.instances.monoid._
Invariant[Monoid]
Cartesian[Monoid]
InvariantMonoidal[Monoid]
()
}

}
11 changes: 8 additions & 3 deletions tests/src/test/scala/cats/tests/NonEmptyListTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ package cats
package tests

import cats.kernel.laws.{GroupLaws, OrderLaws}

import cats.data.NonEmptyList
import cats.laws.discipline.{ComonadTests, SemigroupKTests, MonadTests, SerializableTests, NonEmptyTraverseTests, ReducibleTests}
import cats.data.{NonEmptyList, NonEmptyVector}
import cats.laws.discipline.{ComonadTests, MonadTests, NonEmptyTraverseTests, ReducibleTests, SemigroupKTests, SerializableTests}
import cats.laws.discipline.arbitrary._

class NonEmptyListTests extends CatsSuite {
Expand Down Expand Up @@ -274,6 +273,12 @@ class NonEmptyListTests extends CatsSuite {
NonEmptyList.fromList(xs) should === (NonEmptyList.fromFoldable(xs))
}
}

test("NonEmptyList#fromReducible is consistent with Reducible#toNonEmptyList") {
forAll { (xs: NonEmptyVector[Int]) =>
NonEmptyList.fromReducible(xs) should === (Reducible[NonEmptyVector].toNonEmptyList(xs))
}
}
}

class ReducibleNonEmptyListCheck extends ReducibleCheck[NonEmptyList]("NonEmptyList") {
Expand Down
18 changes: 12 additions & 6 deletions tests/src/test/scala/cats/tests/OrderTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,25 @@ package cats
package tests

import cats.functor._
import cats.kernel.laws.OrderLaws

import org.scalatest._

class OrderTests extends FunSuite {
class OrderTests extends CatsSuite {
{
import cats.implicits._
Invariant[Order]
Contravariant[Order]
}

{
checkAll("Int", OrderLaws[Int].order)
checkAll("Double", OrderLaws[Double].order)
checkAll("Float", OrderLaws[Float].order)
checkAll("Long", OrderLaws[Long].order)
}

object OrderTests {
def summonInstance(): Unit = {
import cats.instances.order._
Invariant[Order]
Contravariant[Order]
()
}
}
}
21 changes: 16 additions & 5 deletions tests/src/test/scala/cats/tests/PartialOrderTests.scala
Original file line number Diff line number Diff line change
@@ -1,20 +1,31 @@
package cats
package tests

import org.scalatest._

import cats.functor._

class PartialOrderTests extends FunSuite {
class PartialOrderTests extends CatsSuite {
{
import cats.implicits._
Invariant[PartialOrder]
Contravariant[PartialOrder]
}

{
test("companion object syntax") {
PartialOrder.partialCompare(1, 2) should ===(catsKernelStdOrderForInt.partialCompare(1, 2))
PartialOrder.tryCompare(1, 2) should ===(catsKernelStdOrderForInt.tryCompare(1, 2))
PartialOrder.pmin(1, 2) should ===(catsKernelStdOrderForInt.pmin(1, 2))
PartialOrder.pmax(1, 2) should ===(catsKernelStdOrderForInt.pmax(1, 2))
PartialOrder.lteqv(1, 2) should ===(catsKernelStdOrderForInt.lteqv(1, 2))
PartialOrder.lt(1, 2) should ===(catsKernelStdOrderForInt.lt(1, 2))
PartialOrder.gteqv(1, 2) should ===(catsKernelStdOrderForInt.gteqv(1, 2))
PartialOrder.gt(1, 2) should ===(catsKernelStdOrderForInt.gt(1, 2))
}
}

object PartialOrderTests {
def summonInstance(): Unit = {
import cats.instances.partialOrder._
Invariant[PartialOrder]
Contravariant[PartialOrder]
()
}
}

0 comments on commit eaeb096

Please sign in to comment.