Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bump ScalaCheck to 1.13.1, and fix the fallout. #1345

Merged
merged 9 commits into from
Sep 18, 2016
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ lazy val commonJsSettings = Seq(
botBuild := scala.sys.env.get("TRAVIS").isDefined,
// batch mode decreases the amount of memory needed to compile scala.js code
scalaJSOptimizerOptions := scalaJSOptimizerOptions.value.withBatchMode(botBuild.value),
doctestGenTests := Seq.empty
doctestGenTests := Seq.empty,
doctestWithDependencies := false
)

lazy val commonJvmSettings = Seq(
Expand All @@ -114,16 +115,18 @@ lazy val includeGeneratedSrc: Setting[_] = {

lazy val catsSettings = buildSettings ++ commonSettings ++ publishSettings ++ scoverageSettings ++ javadocSettings

lazy val scalacheckVersion = "1.12.5"
lazy val scalaCheckVersion = "1.13.2"
lazy val scalaTestVersion = "3.0.0"
lazy val disciplineVersion = "0.6"

lazy val disciplineDependencies = Seq(
libraryDependencies += "org.scalacheck" %%% "scalacheck" % scalacheckVersion,
libraryDependencies += "org.typelevel" %%% "discipline" % "0.4")
libraryDependencies += "org.scalacheck" %%% "scalacheck" % scalaCheckVersion,
libraryDependencies += "org.typelevel" %%% "discipline" % disciplineVersion)

lazy val testingDependencies = Seq(
libraryDependencies += "org.typelevel" %%% "catalysts-platform" % "0.0.2",
libraryDependencies += "org.typelevel" %%% "catalysts-macros" % "0.0.2" % "test",
libraryDependencies += "org.scalatest" %%% "scalatest" % "3.0.0-M8" % "test")
libraryDependencies += "org.scalatest" %%% "scalatest" % scalaTestVersion % "test")


/**
Expand Down Expand Up @@ -246,7 +249,7 @@ lazy val core = crossProject.crossType(CrossType.Pure)
.settings(catsSettings:_*)
.settings(sourceGenerators in Compile <+= (sourceManaged in Compile).map(Boilerplate.gen))
.settings(includeGeneratedSrc)
.settings(libraryDependencies += "org.scalacheck" %%% "scalacheck" % scalacheckVersion % "test")
.settings(libraryDependencies += "org.scalacheck" %%% "scalacheck" % scalaCheckVersion % "test")
.jsSettings(commonJsSettings:_*)
.jvmSettings(commonJvmSettings:_*)

Expand Down
4 changes: 2 additions & 2 deletions free/src/test/scala/cats/free/FreeTTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import cats.laws.discipline._
import cats.tests.CatsSuite
import cats.instances.option._

import org.scalacheck.{Arbitrary, Gen}
import org.scalacheck.{Arbitrary, Gen, Cogen}

class FreeTTests extends CatsSuite {

Expand Down Expand Up @@ -165,7 +165,7 @@ object FreeTTests extends FreeTTestsInstances {
def withFlatMapped = for {
fDepth <- nextDepth
freeDepth <- nextDepth
f <- arbFunction1[A, FreeT[F, G, A]](Arbitrary(freeTGen[F, G, A](fDepth))).arbitrary
f <- arbFunction1[A, FreeT[F, G, A]](Arbitrary(freeTGen[F, G, A](fDepth)), Cogen[Unit].contramap(_ => ())).arbitrary
freeFGA <- freeTGen[F, G, A](freeDepth)
} yield freeFGA.flatMap(f)

Expand Down
4 changes: 2 additions & 2 deletions free/src/test/scala/cats/free/FreeTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import cats.arrow.FunctionK
import cats.laws.discipline.{CartesianTests, MonadTests, SerializableTests}
import cats.laws.discipline.arbitrary.catsLawsArbitraryForFn0

import org.scalacheck.{Arbitrary, Gen}
import org.scalacheck.{Arbitrary, Gen, Cogen}
import Arbitrary.arbFunction1

class FreeTests extends CatsSuite {
Expand Down Expand Up @@ -131,7 +131,7 @@ sealed trait FreeTestsInstances {
def withFlatMapped = for {
fDepth <- nextDepth
freeDepth <- nextDepth
f <- arbFunction1[A, Free[F, A]](Arbitrary(freeGen[F, A](fDepth))).arbitrary
f <- arbFunction1[A, Free[F, A]](Arbitrary(freeGen[F, A](fDepth)), Cogen[Unit].contramap(_ => ())).arbitrary
freeFA <- freeGen[F, A](freeDepth)
} yield freeFA.flatMap(f)

Expand Down
11 changes: 9 additions & 2 deletions js/src/test/scala/cats/tests/FutureTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ import cats.tests.CatsSuite
import scala.concurrent.Future
import scala.concurrent.duration._

import org.scalacheck.Arbitrary
import org.scalacheck.{Arbitrary, Cogen}
import org.scalacheck.Arbitrary.arbitrary
import cats.laws.discipline.arbitrary._

// https://issues.scala-lang.org/browse/SI-7934
@deprecated("", "")
Expand All @@ -36,14 +37,20 @@ class FutureTests extends CatsSuite {
}

implicit val throwableEq: Eq[Throwable] =
Eq.fromUniversalEquals
Eq[String].on(_.toString)

implicit val comonad: Comonad[Future] = futureComonad(timeout)

// Need non-fatal Throwables for Future recoverWith/handleError
implicit val nonFatalArbitrary: Arbitrary[Throwable] =
Arbitrary(arbitrary[Exception].map(identity))

// We can't block on futures in JS, so we can't create interesting
// cogen instances. This will allow the tests to run in a
// less-useful way.
implicit def cogenForFuture[A]: Cogen[Future[A]] =
Cogen[Unit].contramap(_ => ())

checkAll("Future[Int]", MonadErrorTests[Future, Throwable].monadError[Int, Int, Int])
checkAll("Future[Int]", ComonadTests[Future].comonad[Int, Int, Int])
checkAll("Future", MonadTests[Future].monad[Int, Int, Int])
Expand Down
3 changes: 2 additions & 1 deletion jvm/src/test/scala/cats/tests/FutureTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package jvm
package tests

import cats.laws.discipline._
import cats.laws.discipline.arbitrary._
import cats.tests.CatsSuite

import scala.concurrent.{Await, Future}
Expand All @@ -27,7 +28,7 @@ class FutureTests extends CatsSuite {
}

implicit val throwableEq: Eq[Throwable] =
Eq.fromUniversalEquals
Eq[String].on(_.toString)

// Need non-fatal Throwables for Future recoverWith/handleError
implicit val nonFatalArbitrary: Arbitrary[Throwable] =
Expand Down
13 changes: 8 additions & 5 deletions kernel-laws/src/main/scala/cats/kernel/laws/OrderLaws.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,25 @@ package laws

import org.typelevel.discipline.Laws

import org.scalacheck.{Arbitrary, Prop}
import org.scalacheck.{Arbitrary, Cogen, Prop}
import org.scalacheck.Prop._

import cats.kernel.instances.all._

object OrderLaws {
def apply[A: Eq: Arbitrary]: OrderLaws[A] = new OrderLaws[A] {
def Equ = Eq[A]
def Arb = implicitly[Arbitrary[A]]
}
def apply[A: Eq: Arbitrary: Cogen]: OrderLaws[A] =
new OrderLaws[A] {
def Equ = Eq[A]
def Arb = implicitly[Arbitrary[A]]
def Cog = implicitly[Cogen[A]]
}
}

trait OrderLaws[A] extends Laws {

implicit def Equ: Eq[A]
implicit def Arb: Arbitrary[A]
implicit def Cog: Cogen[A]

def eqv: OrderProperties = new OrderProperties(
name = "eq",
Expand Down
30 changes: 26 additions & 4 deletions kernel-laws/src/test/scala/cats/kernel/laws/LawTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import cats.kernel.instances.all._

import org.typelevel.discipline.{ Laws }
import org.typelevel.discipline.scalatest.Discipline
import org.scalacheck.{ Arbitrary, Gen }
import org.scalacheck.{ Arbitrary, Cogen, Gen }
import Arbitrary.arbitrary
import org.scalatest.FunSuite

Expand All @@ -24,13 +24,24 @@ class LawTests extends FunSuite with Discipline {
implicit override val generatorDrivenConfig: PropertyCheckConfiguration =
PropertyCheckConfig(maxSize = PropMaxSize, minSuccessful = PropMinSuccessful)

implicit def orderLaws[A: Eq: Arbitrary] = OrderLaws[A]
implicit def groupLaws[A: Eq: Arbitrary] = GroupLaws[A]
implicit def orderLaws[A: Cogen: Eq: Arbitrary]: OrderLaws[A] = OrderLaws[A]
implicit def groupLaws[A: Cogen: Eq: Arbitrary]: GroupLaws[A] = GroupLaws[A]

implicit val arbitraryBitSet: Arbitrary[BitSet] =
Arbitrary(arbitrary[List[Short]].map(ns => BitSet(ns.map(_ & 0xffff): _*)))

laws[OrderLaws, Map[String, HasEq[Int]]].check(_.eqv)
implicit val cogenBigInt: Cogen[BigInt] =
Cogen[Long].contramap(_.toLong)

implicit val cogenBigDecimal: Cogen[BigDecimal] =
Cogen[Double].contramap(_.toDouble)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like scalacheck has Cogen instances for BigInt and BigDecimal. Is there a reason we need separate instances here? If so, we probably should document it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those are only in master and were added (by me) recently in a just-merged PR. I think we still need them until another release is out.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah okay.


{
// needed for Cogen[Map[...]]
implicit val ohe: Ordering[HasEq[Int]] = Ordering[Int].on(_.a)
laws[OrderLaws, Map[String, HasEq[Int]]].check(_.eqv)
}

laws[OrderLaws, List[HasEq[Int]]].check(_.eqv)
laws[OrderLaws, Option[HasEq[Int]]].check(_.eqv)
laws[OrderLaws, Vector[HasEq[Int]]].check(_.eqv)
Expand Down Expand Up @@ -114,6 +125,9 @@ class LawTests extends FunSuite with Discipline {
implicit val arbitraryComparison: Arbitrary[Comparison] =
Arbitrary(Gen.oneOf(Comparison.GreaterThan, Comparison.EqualTo, Comparison.LessThan))

implicit val cogenComparison: Cogen[Comparison] =
Cogen[Int].contramap(_.toInt)

laws[OrderLaws, Comparison].check(_.eqv)

test("comparison") {
Expand Down Expand Up @@ -168,12 +182,16 @@ class LawTests extends FunSuite with Discipline {
val order = new Random(seed).shuffle(Vector.range(0, nMax))
Order.by { (n: N) => order(n.n) }
})
implicit val cogNOrder: Cogen[Order[N]] =
Cogen[Unit].contramap(_ => ())
// The arbitrary `Eq[N]` values are created by mapping N values to random
// integers.
implicit val arbNEq: Arbitrary[Eq[N]] = Arbitrary(arbitrary[Int].map { seed =>
val mapping = new Random(seed).shuffle(Vector.range(0, nMax))
Eq.by { (n: N) => mapping(n.n) }
})
implicit val cogNEq: Cogen[Eq[N]] =
Cogen[Unit].contramap(_ => ())
// needed because currently we don't have Vector instances
implicit val vectorNEq: Eq[Vector[N]] = Eq.fromUniversalEquals
// The `Eq[Order[N]]` instance enumerates all possible `N` values in a
Expand Down Expand Up @@ -210,6 +228,8 @@ class LawTests extends FunSuite with Discipline {
Eq[A].on(_.a)
implicit def hasEqArbitrary[A: Arbitrary]: Arbitrary[HasEq[A]] =
Arbitrary(arbitrary[A].map(HasEq(_)))
implicit def hasCogen[A: Cogen]: Cogen[HasEq[A]] =
Cogen[A].contramap(_.a)
}

case class HasPartialOrder[A](a: A)
Expand All @@ -219,6 +239,8 @@ class LawTests extends FunSuite with Discipline {
PartialOrder[A].on(_.a)
implicit def hasPartialOrderArbitrary[A: Arbitrary]: Arbitrary[HasPartialOrder[A]] =
Arbitrary(arbitrary[A].map(HasPartialOrder(_)))
implicit def hasCogen[A: Cogen]: Cogen[HasPartialOrder[A]] =
Cogen[A].contramap(_.a)
}

case class LawChecker[L <: Laws](name: String, laws: L) {
Expand Down
14 changes: 11 additions & 3 deletions laws/src/main/scala/cats/laws/MonadCombineLaws.scala
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
package cats
package laws

import cats.syntax.all._
// import cats.syntax.all._

/**
* Laws that must be obeyed by any `MonadCombine`.
*/
trait MonadCombineLaws[F[_]] extends MonadFilterLaws[F] with AlternativeLaws[F] {
implicit override def F: MonadCombine[F]

def monadCombineLeftDistributivity[A, B](fa: F[A], fa2: F[A], f: A => F[B]): IsEq[F[B]] =
F.combineK(fa, fa2).flatMap(f) <-> F.combineK(fa flatMap f, fa2 flatMap f)
// the left distributivity law does not hold for things like
// MonadCombine[Option]; here's a counter-example:
//
// def f(x: Int): Option[Int] = if (x == 0) None else Some(x)
// val a = Option(0)
// val b = Option(1)
// (a <+> b).flatMap(f) != (a.flatMap(f) <+> b.flatMap(f))
//
// def monadCombineLeftDistributivity[A, B](fa: F[A], fa2: F[A], f: A => F[B]): IsEq[F[B]] =
// F.combineK(fa, fa2).flatMap(f) <-> F.combineK(fa flatMap f, fa2 flatMap f)
}

object MonadCombineLaws {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ package laws
package discipline

import cats.laws.discipline.CartesianTests.Isomorphisms
import org.scalacheck.Arbitrary
import org.scalacheck.Prop
import org.scalacheck.{Arbitrary, Cogen, Prop}
import Prop._

trait AlternativeTests[F[_]] extends ApplicativeTests[F] with MonoidKTests[F] {
Expand All @@ -16,6 +15,9 @@ trait AlternativeTests[F[_]] extends ApplicativeTests[F] with MonoidKTests[F] {
ArbFC: Arbitrary[F[C]],
ArbFAtoB: Arbitrary[F[A => B]],
ArbFBtoC: Arbitrary[F[B => C]],
CogenA: Cogen[A],
CogenB: Cogen[B],
CogenC: Cogen[C],
EqFA: Eq[F[A]],
EqFB: Eq[F[B]],
EqFC: Eq[F[C]],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ package discipline
import cats.data.EitherT
import cats.laws.discipline.CartesianTests.Isomorphisms
import cats.laws.discipline.arbitrary._
import org.scalacheck.{Arbitrary, Prop}
import org.scalacheck.{Arbitrary, Cogen, Prop}
import org.scalacheck.Prop.forAll

trait ApplicativeErrorTests[F[_], E] extends ApplicativeTests[F] {
Expand All @@ -18,6 +18,10 @@ trait ApplicativeErrorTests[F[_], E] extends ApplicativeTests[F] {
ArbFAtoB: Arbitrary[F[A => B]],
ArbFBtoC: Arbitrary[F[B => C]],
ArbE: Arbitrary[E],
CogenA: Cogen[A],
CogenB: Cogen[B],
CogenC: Cogen[C],
CogenE: Cogen[E],
EqFA: Eq[F[A]],
EqFB: Eq[F[B]],
EqFC: Eq[F[C]],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ package laws
package discipline

import cats.laws.discipline.CartesianTests.Isomorphisms
import org.scalacheck.Arbitrary
import org.scalacheck.Prop
import org.scalacheck.{Arbitrary, Cogen, Prop}
import Prop._

trait ApplicativeTests[F[_]] extends ApplyTests[F] {
Expand All @@ -16,6 +15,9 @@ trait ApplicativeTests[F[_]] extends ApplyTests[F] {
ArbFC: Arbitrary[F[C]],
ArbFAtoB: Arbitrary[F[A => B]],
ArbFBtoC: Arbitrary[F[B => C]],
CogenA: Cogen[A],
CogenB: Cogen[B],
CogenC: Cogen[C],
EqFA: Eq[F[A]],
EqFB: Eq[F[B]],
EqFC: Eq[F[C]],
Expand Down
6 changes: 4 additions & 2 deletions laws/src/main/scala/cats/laws/discipline/ApplyTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ package laws
package discipline

import cats.laws.discipline.CartesianTests.Isomorphisms
import org.scalacheck.Arbitrary
import org.scalacheck.Prop
import org.scalacheck.{Arbitrary, Cogen, Prop}
import Prop._

trait ApplyTests[F[_]] extends FunctorTests[F] with CartesianTests[F] {
Expand All @@ -16,6 +15,9 @@ trait ApplyTests[F[_]] extends FunctorTests[F] with CartesianTests[F] {
ArbFC: Arbitrary[F[C]],
ArbFAtoB: Arbitrary[F[A => B]],
ArbFBtoC: Arbitrary[F[B => C]],
CogenA: Cogen[A],
CogenB: Cogen[B],
CogenC: Cogen[C],
EqFA: Eq[F[A]],
EqFC: Eq[F[C]],
EqFABC: Eq[F[(A, B, C)]],
Expand Down
Loading