org.typelevel.discipline.Laws Scala Examples

The following examples show how to use org.typelevel.discipline.Laws. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example.
Example 1
Source File: OdinSpec.scala    From odin   with Apache License 2.0 5 votes vote down vote up
package io.odin

import java.time.LocalDateTime

import cats.effect.{Clock, Timer}
import cats.{Applicative, Eval}
import io.odin.formatter.Formatter
import io.odin.meta.Position
import org.scalacheck.{Arbitrary, Cogen, Gen}
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import org.scalatestplus.scalacheck.{Checkers, ScalaCheckDrivenPropertyChecks}
import org.typelevel.discipline.Laws

import scala.concurrent.duration.{FiniteDuration, TimeUnit}

trait OdinSpec extends AnyFlatSpec with Matchers with Checkers with ScalaCheckDrivenPropertyChecks with EqInstances {
  def checkAll(name: String, ruleSet: Laws#RuleSet): Unit = {
    for ((id, prop) <- ruleSet.all.properties)
      it should (name + "." + id) in {
        check(prop)
      }
  }

  def zeroTimer[F[_]](implicit F: Applicative[F]): Timer[F] = new Timer[F] {
    def clock: Clock[F] = new Clock[F] {
      def realTime(unit: TimeUnit): F[Long] = F.pure(0L)

      def monotonic(unit: TimeUnit): F[Long] = F.pure(0L)
    }

    def sleep(duration: FiniteDuration): F[Unit] = ???
  }

  val lineSeparator: String = System.lineSeparator()

  val nonEmptyStringGen: Gen[String] = Gen.nonEmptyListOf(Gen.alphaNumChar).map(_.mkString)

  val levelGen: Gen[Level] = Gen.oneOf(Level.Trace, Level.Debug, Level.Info, Level.Warn, Level.Error)
  implicit val levelArbitrary: Arbitrary[Level] = Arbitrary(levelGen)

  val positionGen: Gen[Position] = for {
    fileName <- nonEmptyStringGen
    enclosureName <- Gen.uuid.map(_.toString)
    packageName <- nonEmptyStringGen
    line <- Gen.posNum[Int]
  } yield {
    Position(fileName, enclosureName, packageName, line)
  }
  implicit val positionArbitrary: Arbitrary[Position] = Arbitrary(positionGen)

  val loggerMessageGen: Gen[LoggerMessage] = {
    val startTime = System.currentTimeMillis()
    for {
      level <- levelGen
      msg <- Gen.alphaNumStr
      context <- Gen.mapOfN(20, nonEmptyStringGen.flatMap(key => nonEmptyStringGen.map(key -> _)))
      exception <- Gen.option(Arbitrary.arbitrary[Throwable])
      position <- positionGen
      threadName <- nonEmptyStringGen
      timestamp <- Gen.choose(0, startTime)
    } yield {
      LoggerMessage(
        level = level,
        message = Eval.now(msg),
        context = context,
        exception = exception,
        position = position,
        threadName = threadName,
        timestamp = timestamp
      )
    }
  }
  implicit val loggerMessageArbitrary: Arbitrary[LoggerMessage] = Arbitrary(loggerMessageGen)

  implicit val cogenLoggerMessage: Cogen[LoggerMessage] =
    Cogen[LoggerMessage]((msg: LoggerMessage) => msg.level.hashCode().toLong + msg.message.value.hashCode().toLong)

  val formatterGen: Gen[Formatter] = Gen.oneOf(Formatter.default, Formatter.colorful)
  implicit val formatterArbitrary: Arbitrary[Formatter] = Arbitrary(formatterGen)

  val localDateTimeGen: Gen[LocalDateTime] = for {
    year <- Gen.choose(0, LocalDateTime.now().getYear)
    month <- Gen.choose(1, 12)
    day <- Gen.choose(1, 28)
    hour <- Gen.choose(0, 23)
    minute <- Gen.choose(0, 59)
    second <- Gen.choose(0, 59)
  } yield {
    LocalDateTime.of(year, month, day, hour, minute, second)
  }
  implicit val localDateTimeArbitrary: Arbitrary[LocalDateTime] = Arbitrary(localDateTimeGen)
} 
Example 2
Source File: RfcReaderTests.scala    From kantan.csv   with Apache License 2.0 5 votes vote down vote up
package kantan.csv
package laws
package discipline

import org.scalacheck.Prop._
import org.typelevel.discipline.Laws

trait RfcReaderTests extends Laws {
  def laws: RfcReaderLaws

  def rfc4180: RuleSet = new DefaultRuleSet(
    name = "rfc4180",
    parent = None,
    "crlf row separator"        -> forAll(laws.crlfRowSeparator _),
    "lf row separator"          -> forAll(laws.lfRowSeparator _),
    "crlf ending"               -> forAll(laws.crlfEnding _),
    "lf ending"                 -> forAll(laws.lfEnding _),
    "empty ending"              -> forAll(laws.emptyEnding _),
    "leading whitespace"        -> forAll(laws.leadingWhitespace _),
    "trailing whitespace"       -> forAll(laws.trailingWhitespace _),
    "trailing comma"            -> forAll(laws.trailingWhitespace _),
    "unnecessary double quotes" -> forAll(laws.unnecessaryDoubleQuotes _),
    "unescaped double quotes"   -> forAll(laws.unescapedDoubleQuotes _),
    "escaped content"           -> forAll(laws.escapedCells _)
  )
} 
Example 3
Source File: CirceSuite.scala    From circe-optics   with Apache License 2.0 5 votes vote down vote up
package io.circe.optics

import cats.kernel.Eq
import cats.instances.AllInstances
import cats.syntax.{ AllSyntax, EitherOps }
import io.circe.testing.{ ArbitraryInstances, EqInstances }
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatestplus.scalacheck.{ Checkers, ScalaCheckDrivenPropertyChecks }
import org.typelevel.discipline.Laws
import org.typelevel.discipline.scalatest.FlatSpecDiscipline
import scala.language.implicitConversions


trait CirceSuite
    extends AnyFlatSpec
    with FlatSpecDiscipline
    with ScalaCheckDrivenPropertyChecks
    with AllInstances
    with AllSyntax
    with ArbitraryInstances
    with EqInstances {
  override def convertToEqualizer[T](left: T): Equalizer[T] =
    sys.error("Intentionally ambiguous implicit for Equalizer")

  implicit def prioritizedCatsSyntaxEither[A, B](eab: Either[A, B]): EitherOps[A, B] = new EitherOps(eab)

  def checkLaws(name: String, ruleSet: Laws#RuleSet): Unit = ruleSet.all.properties.zipWithIndex.foreach {
    case ((id, prop), 0) => name should s"obey $id" in Checkers.check(prop)
    case ((id, prop), _) => it should s"obey $id" in Checkers.check(prop)
  }

  def assertEq[A: Eq](expected: A, actual: A): Unit =
    assert(
      expected === actual,
      s"""Expected did not match actual:
         |
         |Expected: $expected
         |Actual:   $actual"""
    )
} 
Example 4
Source File: PredicateTests.scala    From cron4s   with Apache License 2.0 5 votes vote down vote up
package cron4s.testkit.discipline

import cats.Foldable
import cats.laws.discipline._
import cats.implicits._

import cron4s.base.Predicate
import cron4s.testkit.laws.PredicateLaws

import org.scalacheck.Arbitrary
import org.scalacheck.Prop._

import org.typelevel.discipline.Laws


object PredicateTests extends Laws {
  def predicate[F[_]: Foldable, A](
      implicit
      arbPred: Arbitrary[Predicate[A]],
      arbFold: Arbitrary[F[Predicate[A]]],
      arbA: Arbitrary[A]
  ): RuleSet =
    new DefaultRuleSet(
      name = "Predicate",
      parent = None,
      "negation"    -> forAll(PredicateLaws.negation[A] _),
      "conjunction" -> forAll(PredicateLaws.conjuction[A] _),
      "disjunction" -> forAll(PredicateLaws.disjunction[A] _),
      "noMatch"     -> forAll(PredicateLaws.noMatch[F, A] _),
      "someMatch"   -> forAll(PredicateLaws.someMatch[F, A] _),
      "allMatch"    -> forAll(PredicateLaws.allMatch[F, A] _)
    )
} 
Example 5
Source File: DateTimeNodeTests.scala    From cron4s   with Apache License 2.0 5 votes vote down vote up
package cron4s.testkit.discipline

import cats.Eq
import cats.laws.discipline._
import cats.implicits._

import cron4s.CronField
import cron4s.datetime.IsDateTime
import cron4s.expr.FieldExpr
import cron4s.testkit.laws.DateTimeNodeLaws

import org.scalacheck.Prop._
import org.scalacheck._
import org.typelevel.discipline.Laws


trait DateTimeNodeTests[E[_ <: CronField], F <: CronField, DateTime] extends Laws {
  def laws: DateTimeNodeLaws[E, F, DateTime]

  def dateTime(
      implicit
      arbNode: Arbitrary[E[F]],
      arbDateTime: Arbitrary[DateTime],
      dateTimeEq: Eq[DateTime]
  ): RuleSet = new DefaultRuleSet(
    name = "dateTimeNode",
    parent = None,
    "forward"   -> forAll(laws.forward _),
    "backwards" -> forAll(laws.backwards _),
    "matchable" -> forAll(laws.matchable _)
  )
}

object DateTimeNodeTests {
  def apply[E[_ <: CronField], F <: CronField, DateTime](
      implicit
      dtEv: IsDateTime[DateTime],
      expr: FieldExpr[E, F]
  ): DateTimeNodeTests[E, F, DateTime] =
    new DateTimeNodeTests[E, F, DateTime] {
      val laws = DateTimeNodeLaws[E, F, DateTime]
    }
} 
Example 6
Source File: EnumeratedTests.scala    From cron4s   with Apache License 2.0 5 votes vote down vote up
package cron4s.testkit.discipline

import cats.laws.discipline._
import cats.implicits._

import cron4s.testkit.laws.EnumeratedLaws
import cron4s.base.Enumerated

import org.scalacheck.Arbitrary
import org.scalacheck.Prop._
import org.typelevel.discipline.Laws


trait EnumeratedTests[A] extends Laws {
  def laws: EnumeratedLaws[A]

  def enumerated(implicit arbAF: Arbitrary[A], arbFrom: Arbitrary[Int]): RuleSet =
    new DefaultRuleSet(
      name = "enumerated",
      parent = None,
      "min"                   -> forAll(laws.min _),
      "max"                   -> forAll(laws.max _),
      "forward"               -> forAll(laws.forward _),
      "backwards"             -> forAll(laws.backwards _),
      "fromMinToMinForwards"  -> forAll(laws.fromMinToMinForwards _),
      "fromMaxToMaxForwards"  -> forAll(laws.fromMaxToMaxForwards _),
      "fromMinToMaxForwards"  -> forAll(laws.fromMinToMaxForwards _),
      "fromMinToMaxBackwards" -> forAll(laws.fromMinToMaxBackwards _),
      "fromMaxToMinForwards"  -> forAll(laws.fromMaxToMinForwards _),
      "fromMaxToMinBackwards" -> forAll(laws.fromMaxToMinBackwards _)
    )
}

object EnumeratedTests {
  def apply[A](implicit ev: Enumerated[A]): EnumeratedTests[A] =
    new EnumeratedTests[A] { val laws = EnumeratedLaws[A] }
} 
Example 7
Source File: DateTimeCronTests.scala    From cron4s   with Apache License 2.0 5 votes vote down vote up
package cron4s.testkit.discipline

import cats.Eq
import cats.laws.discipline._
import cats.implicits._

import cron4s.datetime.{IsDateTime, DateTimeCron}
import cron4s.testkit.laws.DateTimeCronLaws

import org.scalacheck.Prop._
import org.scalacheck._

import org.typelevel.discipline.Laws


trait DateTimeCronTests[E, DateTime] extends Laws {
  def laws: DateTimeCronLaws[E, DateTime]

  def dateTimeCron(
      implicit
      arbE: Arbitrary[E],
      arbDateTime: Arbitrary[DateTime],
      dateTimeEq: Eq[DateTime]
  ): RuleSet = new DefaultRuleSet(
    name = "dateTimeCron",
    parent = None,
    "matchAll"        -> forAll(laws.matchAll _),
    "matchAny"        -> forAll(laws.matchAny _),
    "forwards"        -> forAll(laws.forwards _),
    "backwards"       -> forAll(laws.backwards _),
    "supportedFields" -> forAll(laws.supportedFieldsEquality _)
  )
}

object DateTimeCronTests {
  def apply[E, DateTime](
      implicit
      dtEv: IsDateTime[DateTime],
      cron: DateTimeCron[E]
  ): DateTimeCronTests[E, DateTime] =
    new DateTimeCronTests[E, DateTime] {
      val laws = DateTimeCronLaws[E, DateTime]
    }
} 
Example 8
Source File: IsDateTimeTests.scala    From cron4s   with Apache License 2.0 5 votes vote down vote up
package cron4s.testkit.discipline

import cats.Eq
import cats.laws.discipline._
import cats.implicits._

import cron4s.CronField
import cron4s.datetime.IsDateTime
import cron4s.testkit.CronFieldValue
import cron4s.testkit.laws.IsDateTimeLaws

import org.scalacheck._
import Prop._

import org.typelevel.discipline.Laws


trait IsDateTimeTests[DateTime] extends Laws {
  def laws: IsDateTimeLaws[DateTime]

  def dateTime[F <: CronField](
      implicit
      arbDateTime: Arbitrary[DateTime],
      arbFieldValue: Arbitrary[CronFieldValue[F]],
      arbField: Arbitrary[F]
  ): RuleSet =
    new DefaultRuleSet(
      name = "dateTime",
      parent = None,
      "gettable"     -> forAll(laws.gettable[F] _),
      "immutability" -> forAll(laws.immutability[F] _),
      "settable"     -> forAll(laws.settable[F] _)
    )
}

object IsDateTimeTests {
  def apply[DateTime](
      implicit
      dtEv: IsDateTime[DateTime],
      eqEv: Eq[DateTime]
  ): IsDateTimeTests[DateTime] =
    new IsDateTimeTests[DateTime] {
      val laws: IsDateTimeLaws[DateTime] = IsDateTimeLaws[DateTime]
    }
} 
Example 9
Source File: SemigroupalKTests.scala    From mainecoon   with Apache License 2.0 5 votes vote down vote up
package mainecoon
package laws
package discipline


import cats.{Eq, ~>}
import cats.data.Tuple2K
import mainecoon.laws.discipline.SemigroupalKTests.IsomorphismsK
import org.scalacheck.Prop._
import org.scalacheck.{Arbitrary, Prop}
import org.typelevel.discipline.Laws

trait SemigroupalKTests[F[_[_]]] extends Laws {
  def laws: SemigroupalKLaws[F]

  def semigroupalK[A[_], B[_], C[_]](implicit
                                               ArbCF: Arbitrary[F[A]],
                                               ArbCG: Arbitrary[F[B]],
                                               ArbCH: Arbitrary[F[C]],
                                               iso: IsomorphismsK[F],
                                               EqFGH: Eq[F[Tuple3K[A, B, C]#λ]]
                                              ): RuleSet = {
    new DefaultRuleSet(
      name = "SemigroupalK",
      parent = None,
      "semigroupal associativity" -> forAll((af: F[A], ag: F[B], ah: F[C]) => iso.associativity(laws.semigroupalAssociativity[A, B, C](af, ag, ah))))
  }
}


object SemigroupalKTests {
  def apply[F[_[_]]: SemigroupalK]: SemigroupalKTests[F] =
    new SemigroupalKTests[F] { def laws: SemigroupalKLaws[F] = SemigroupalKLaws[F] }

  import IsomorphismsK._

  trait IsomorphismsK[F[_[_]]] {
    def associativity[A[_], B[_], C[_]](fs: (F[ProdA_BC[A, B, C]#λ], F[ProdAB_C[A, B, C]#λ]))
                                       (implicit EqFGH: Eq[F[Tuple3K[A, B, C]#λ]]): Prop
  }

  object IsomorphismsK {
    
    type ProdA_BC[A[_], B[_], C[_]]  = { type λ[T] = Tuple2K[A, Tuple2K[B, C, ?], T] }
    type ProdAB_C[A[_], B[_], C[_]]  = { type λ[T] = Tuple2K[Tuple2K[A, B, ?], C, T] }

    implicit def invariantK[F[_[_]]](implicit F: InvariantK[F]): IsomorphismsK[F] =
      new IsomorphismsK[F] {
        def associativity[A[_], B[_], C[_]](fs: (F[ProdA_BC[A, B, C]#λ], F[ProdAB_C[A, B, C]#λ]))
                                           (implicit EqFGH: Eq[F[Tuple3K[A, B, C]#λ]]): Prop = {

          val fkA_BC_T3 = λ[ProdA_BC[A, B, C]#λ ~> Tuple3K[A, B, C]#λ ]{ case Tuple2K(a, Tuple2K(b, c)) => (a, b, c) }
          val fkAB_C_T3 = λ[ProdAB_C[A, B, C]#λ ~> Tuple3K[A, B, C]#λ ]{ case Tuple2K(Tuple2K(a, b), c) => (a, b, c) }
          val fkT3_AB_C = λ[Tuple3K[A, B, C]#λ ~> ProdAB_C[A, B, C]#λ]{ case (a, b, c) => Tuple2K(Tuple2K(a, b), c) }
          val fkT3_A_BC = λ[Tuple3K[A, B, C]#λ ~> ProdA_BC[A, B, C]#λ]{ case (a, b, c) => Tuple2K(a, Tuple2K(b, c)) }

          EqFGH.eqv(
            F.imapK[ProdA_BC[A, B, C]#λ, Tuple3K[A, B, C]#λ](fs._1)(fkA_BC_T3)(fkT3_A_BC),
            F.imapK[ProdAB_C[A, B, C]#λ, Tuple3K[A, B, C]#λ](fs._2)(fkAB_C_T3)(fkT3_AB_C)
          )
        }

      }
  }
} 
Example 10
Source File: InvariantKTests.scala    From mainecoon   with Apache License 2.0 5 votes vote down vote up
package mainecoon
package laws
package discipline

import cats.{Eq, ~>}
import org.scalacheck.Prop._
import org.scalacheck.Arbitrary
import org.typelevel.discipline.Laws
import cats.laws.discipline._

trait InvariantKTests[F[_[_]]] extends Laws {
  def laws: InvariantKLaws[F]

  def invariantK[A[_], B[_], C[_]](implicit
                                                          ArbFA: Arbitrary[F[A]],
                                                          ArbAB: Arbitrary[A ~> B],
                                                          ArbBA: Arbitrary[B ~> A],
                                                          ArbBC: Arbitrary[B ~> C],
                                                          ArbCB: Arbitrary[C ~> B],
                                                          EqFA: Eq[F[A]],
                                                          EqFC: Eq[F[C]]
                                                         ): RuleSet = {
    new DefaultRuleSet(
      name = "invariantK",
      parent = None,
      "invariant identity" -> forAll(laws.invariantIdentity[A] _),
      "invariant composition" -> forAll(laws.invariantComposition[A, B, C] _))
  }
}

object InvariantKTests {
  def apply[F[_[_]]: InvariantK]: InvariantKTests[F] =
    new InvariantKTests[F] { def laws: InvariantKLaws[F] = InvariantKLaws[F] }
} 
Example 11
Source File: WriterEngineTests.scala    From kantan.csv   with Apache License 2.0 5 votes vote down vote up
package kantan.csv
package laws
package discipline

import engine.WriterEngine
import org.scalacheck.Prop._
import org.typelevel.discipline.Laws

trait WriterEngineTests extends Laws {
  def laws: WriterEngineLaws

  def writerEngine: RuleSet = new DefaultRuleSet(
    name = "writerEngine",
    parent = None,
    "round-trip"                 -> forAll(laws.roundTrip _),
    "quote all"                  -> forAll(laws.quoteAll _),
    "column separator"           -> forAll(laws.columnSeparator _),
    "no trailing cell separator" -> forAll(laws.noTrailingSeparator _),
    "crlf row separator"         -> forAll(laws.crlfAsRowSeparator _)
  )
}

object WriterEngineTests {
  def apply(engine: WriterEngine): WriterEngineTests = new WriterEngineTests {
    override def laws: WriterEngineLaws = WriterEngineLaws(engine)
  }
} 
Example 12
Source File: LoggerTests.scala    From odin   with Apache License 2.0 5 votes vote down vote up
package io.odin.loggers

import cats.laws.discipline._
import cats.{Eq, Monad}
import io.odin.{Level, Logger, LoggerMessage}
import org.scalacheck.{Arbitrary, Prop}
import org.typelevel.discipline.Laws

trait LoggerTests[F[_]] extends Laws {
  def loggerLaws: LoggerLaws[F]
  def logger: Logger[F]

  def all(
      implicit
      arbMsg: Arbitrary[LoggerMessage],
      arbLvl: Arbitrary[Level],
      eqF: Eq[List[LoggerMessage]]
  ): RuleSet = new SimpleRuleSet(
    "logger",
    "checks minLevel" -> Prop.forAll((msg: LoggerMessage, level: Level) => loggerLaws.checksMinLevel(logger, msg, level)
    ),
    "log(list) <-> list.traverse(log)" -> Prop.forAll((msgs: List[LoggerMessage]) =>
      loggerLaws.batchEqualsToTraverse(logger, msgs)
    )
  )
}

object LoggerTests {
  def apply[F[_]](l: Logger[F], extract: F[_] => List[LoggerMessage])(
      implicit monad: Monad[F]
  ): LoggerTests[F] = new LoggerTests[F] {
    def loggerLaws: LoggerLaws[F] = new LoggerLaws[F] {
      val F: Monad[F] = monad
      val written: F[Unit] => List[LoggerMessage] = extract
    }

    def logger: Logger[F] = l
  }
} 
Example 13
Source File: CirceConfigLaws.scala    From circe-config   with Apache License 2.0 5 votes vote down vote up
package io.circe.config

import cats.instances.either._
import cats.laws._
import cats.laws.discipline._
import io.circe.{Decoder, Json, Parser, ParsingFailure}
import io.circe.testing.ParserTests
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatestplus.scalacheck.Checkers
import org.scalacheck.{Arbitrary, Prop}
import org.typelevel.discipline.Laws
import com.typesafe.config.{parser => _, _}

class CirceConfigLaws extends AnyFlatSpec {

  implicit val arbitraryConfigJson: Arbitrary[Json] = Arbitrary {
    def normalize(json: Json): Json =
      json.mapObject(_.filterKeys(_.nonEmpty).mapValues(normalize)).mapArray(_.map(normalize)).mapNumber { number =>
        // Lower the precision to the types used internally by
        // Lightbend Config to ensure that numbers are representable.
        val double: java.lang.Double = number.toDouble
        val long: java.lang.Long = double.toLong

        val json =
          if (double.isInfinite)
            // While +/+Infinity can be represented, it cannot be round-tripped.
            Json.fromInt(42)
          else if (long == double)
            // Emulate Lightbend Config's internal cast:
            // https://github.com/lightbend/config/blob/v1.3.4/config/src/main/java/com/typesafe/config/impl/ConfigNumber.java#L96-L104
            Json.fromLong(long)
          else
            Json.fromDouble(double).get

        json.asNumber.get
      }

    for (jsonObject <- io.circe.testing.instances.arbitraryJsonObject.arbitrary)
      yield normalize(Json.fromJsonObject(jsonObject))
  }

  def checkLaws(name: String, ruleSet: Laws#RuleSet): Unit = ruleSet.all.properties.zipWithIndex.foreach {
    case ((id, prop), 0) => name should s"obey $id" in Checkers.check(prop)
    case ((id, prop), _) => it should s"obey $id" in Checkers.check(prop)
  }

  checkLaws("Parser", ParserTests(parser).fromString)
  checkLaws(
    "Parser",
    ParserTests(parser).fromFunction[Config]("fromConfig")(
      ConfigFactory.parseString,
      _.parse,
      _.decode[Json],
      _.decodeAccumulating[Json]
    )
  )
  checkLaws("Printer", PrinterTests(parser).fromJson)
  checkLaws("Codec", CodecTests[Config](syntax.configDecoder, parser.parse).fromFunction("fromConfig"))
}

case class PrinterTests(parser: Parser) extends Laws {
  def fromJson(implicit A: Arbitrary[Json]): RuleSet =
    new DefaultRuleSet(
      name = "printer",
      parent = None,
      "roundTrip" -> Prop.forAll { (json: Json) =>
        parser.parse(printer.print(json)) <-> Right(json)
      }
    )
}

case class CodecTests[A](decoder: Decoder[A], parse: A => Either[ParsingFailure, Json]) extends Laws {
  def fromFunction(name: String)(implicit arbitraryJson: Arbitrary[Json]): RuleSet =
    new DefaultRuleSet(
      name = s"codec[$name]",
      parent = None,
      "decodingRoundTrip" -> Prop.forAll { (json: Json) =>
        decoder.decodeJson(json).flatMap(parse) <-> Right(json)
      }
    )
} 
Example 14
Source File: CirceSuite.scala    From circe-generic-extras   with Apache License 2.0 5 votes vote down vote up
package io.circe.generic.extras

import cats.instances._
import cats.syntax._
import io.circe.testing.{ ArbitraryInstances, EqInstances }
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatestplus.scalacheck.{ Checkers, ScalaCheckDrivenPropertyChecks }
import org.typelevel.discipline.Laws
import scala.language.implicitConversions


trait CirceSuite
    extends AnyFlatSpec
    with ScalaCheckDrivenPropertyChecks
    with AllInstances
    with AllInstancesBinCompat0
    with AllInstancesBinCompat1
    with AllInstancesBinCompat2
    with AllInstancesBinCompat3
    with AllInstancesBinCompat4
    with AllInstancesBinCompat5
    with AllInstancesBinCompat6
    with AllSyntax
    with AllSyntaxBinCompat0
    with AllSyntaxBinCompat1
    with AllSyntaxBinCompat2
    with AllSyntaxBinCompat3
    with AllSyntaxBinCompat4
    with AllSyntaxBinCompat5
    with AllSyntaxBinCompat6
    with ArbitraryInstances
    with EqInstances {

  override def convertToEqualizer[T](left: T): Equalizer[T] =
    sys.error("Intentionally ambiguous implicit for Equalizer")

  implicit def prioritizedCatsSyntaxEither[A, B](eab: Either[A, B]): EitherOps[A, B] = new EitherOps(eab)

  def checkLaws(name: String, ruleSet: Laws#RuleSet): Unit = ruleSet.all.properties.zipWithIndex.foreach {
    case ((id, prop), 0) => name should s"obey $id" in Checkers.check(prop)
    case ((id, prop), _) => it should s"obey $id" in Checkers.check(prop)
  }
} 
Example 15
Source File: MonixInstancesLawsSuite.scala    From meow-mtl   with MIT License 5 votes vote down vote up
package com.olegpy.meow.monix


import cats.implicits._
import cats.effect.laws.discipline.arbitrary.genIO
import cats.mtl.laws.discipline._
import minitest.SimpleTestSuite
import minitest.laws.Checkers
import org.typelevel.discipline.Laws
import scala.concurrent.duration._

import cats.Eq
import _root_.monix.eval.{Task, TaskLike, TaskLocal}
import _root_.monix.execution.schedulers.TestScheduler
import org.scalacheck.{Arbitrary, Cogen, Gen}

object MonixInstancesLawsSuite extends SimpleTestSuite with Checkers {
  private def checkAll(name: String)(ruleSet: TestScheduler => Laws#RuleSet) = {
    implicit val ctx = TestScheduler()

    for ((id, prop) <- ruleSet(ctx).all.properties)
      test(name + "." + id) {
        ctx.tick(1.day)
        check(prop)
      }
  }

  implicit val options: Task.Options = Task.Options(
    autoCancelableRunLoops = true,
    localContextPropagation = true
  )

  implicit val eqThrowable: Eq[Throwable] = Eq.allEqual

  implicit def eqTask[A](implicit
    eqA: Eq[A],
    ts: TestScheduler,
    options: Task.Options
  ): Eq[Task[A]] = Eq.instance { (lhs, rhs) =>
    val lf = lhs.runToFutureOpt
    val rf = rhs.runToFutureOpt
    ts.tick(1.day)
    lf.value === rf.value
  }

  implicit def arbitraryTask[A: Arbitrary: Cogen] =
    Arbitrary(Gen.delay(genIO[A].map(TaskLike.fromIO(_))))

  private def unsafeTaskLocal()(implicit ctx: TestScheduler) = {
    val f = TaskLocal(0).runToFutureOpt
    ctx.tick()
    f.value.get.get
  }

  checkAll("TaskLocal.runLocal") { implicit ctx =>
    unsafeTaskLocal().runLocal(ev =>
      ApplicativeLocalTests(ev).applicativeLocal[Int, String])
  }

  checkAll("TaskLocal.runState") { implicit ctx =>
    unsafeTaskLocal().runState(ev =>
      MonadStateTests(ev).monadState[Int]
    )
  }

  checkAll("TaskLocal.runTell") { implicit ctx =>
    unsafeTaskLocal().runTell(ev =>
      FunctorTellTests(ev).functorTell[Int]
    )
  }
} 
Example 16
Source File: EffectInstancesLawsSuite.scala    From meow-mtl   with MIT License 5 votes vote down vote up
package com.olegpy.meow.effects

import cats.effect.IO
import cats.effect.concurrent.Ref
import cats.effect.laws.util.TestContext
import cats.implicits._
import cats.effect.laws.discipline.arbitrary._
import cats.effect.laws.util.TestInstances._
import cats.mtl.laws.discipline._
import minitest.SimpleTestSuite
import minitest.laws.Checkers
import org.typelevel.discipline.Laws
import scala.concurrent.duration._

object EffectInstancesLawsSuite extends SimpleTestSuite with Checkers {
  private def checkAll(name: String)(ruleSet: TestContext => Laws#RuleSet) = {
    implicit val ctx = TestContext()

    for ((id, prop) <- ruleSet(ctx).all.properties)
      test(name + "." + id) {
        ctx.tick(1.day)
        check(prop)
      }
  }

  checkAll("Ref.runAsk") { implicit ctx =>
    Ref.unsafe[IO, Int](0).runAsk(ev =>
      ApplicativeAskTests(ev).applicativeAsk[Int]
    )
  }

  checkAll("Ref.runState") { implicit ctx =>
    Ref.unsafe[IO, Int](0).runState(ev =>
      MonadStateTests(ev).monadState[Int]
    )
  }

  checkAll("Ref.runTell") { implicit ctx =>
    Ref.unsafe[IO, Int](0).runTell(ev =>
      FunctorTellTests(ev).functorTell[Int]
    )
  }

  checkAll("Consumer.runTell") { implicit ctx =>
    case object DummyErr extends Throwable
    def fun(x: Int) =
      if (x == 1) IO.raiseError[Unit](DummyErr)
      else IO.unit
    Consumer(fun _).runTell(ev =>
      FunctorTellTests(ev).functorTell[Int]
    )

  }
} 
Example 17
Source File: DerivedLawsSuite.scala    From meow-mtl   with MIT License 5 votes vote down vote up
package com.olegpy.meow.derivations

import cats.{ApplicativeError, Eq, MonadError}
import cats.data.State
import cats.instances.all._
import cats.mtl._
import minitest._
import minitest.laws.Checkers
import org.typelevel.discipline.Laws
import com.olegpy.meow.hierarchy._
import cats.mtl.instances.all._
import cats.mtl.laws.discipline._
import cats.laws.discipline._
import cats.laws.discipline.arbitrary._
import cats.laws.discipline.eq._
import cats.laws.discipline.DeprecatedEqInstances._


object DerivedLawsSuite extends SimpleTestSuite with Checkers {
  private def checkAll(name: String)(ruleSet: Laws#RuleSet) = {
    for ((id, prop) <- ruleSet.all.properties)
      test(name + "." + id) {
        check(prop)
      }
  }

  type Data = (Long, Int)

  checkAll("MonadState") {
    type M[A] = State[Data, A]
    def derive[F[_]](implicit MS: MonadState[F, Data]): MonadState[F, Int] =
      implicitly

    implicit def eqState[A: Eq]: Eq[M[A]] = Eq.by(_.run((0L, 0)))
    MonadStateTests(derive[M]).monadState[Int]
  }

  checkAll("ApplicativeLocal") {
    type M[A] = Data => A
    def derive[F[_]](implicit MS: ApplicativeLocal[F, Data]): ApplicativeLocal[F, Int] =
      implicitly

    ApplicativeLocalTests(derive[M]).applicativeLocal[Int, String]
  }

//  checkAll("ApplicativeAsk") {
//    type M[A] = Data => A
//    def derive[F[_]](implicit MS: ApplicativeAsk[F, Data]): ApplicativeAsk[F, Int] =
//      implicitly
//
//    ApplicativeAskTests(derive[M]).applicativeAsk[Int]
//  }

  type DataC = Either[String, Either[Int, Long]]

  checkAll("MonadError") {
    type M[A] = Either[DataC, A]

    def derive[F[_]](implicit MS: MonadError[F, DataC]): MonadError[F, Long] =
      implicitly

    MonadErrorTests(derive[M]).monadError[Int, Long, String]
  }

  checkAll("ApplicativeError") {
    type M[A] = Either[DataC, A]

    def derive[F[_]](implicit MS: ApplicativeError[F, DataC]): ApplicativeError[F, Long] =
      implicitly

    ApplicativeErrorTests(derive[M]).applicativeError[Int, Long, String]
  }

  checkAll("ApplicativeHandle") {
    type M[A] = Either[DataC, A]

    def derive[F[_]](implicit MS: ApplicativeHandle[F, DataC]): ApplicativeHandle[F, Long] =
      implicitly

    ApplicativeHandleTests(derive[M]).applicativeHandle[Int]
  }
} 
Example 18
Source File: BaseTestsSuite.scala    From cats-effect   with Apache License 2.0 5 votes vote down vote up
package cats.effect

import cats.effect.internals.TestUtils
import cats.effect.laws.util.{TestContext, TestInstances}
import org.scalactic.source
import org.scalatest.Tag
import org.scalatest.matchers.should.Matchers
import org.scalatest.funsuite.AnyFunSuite
import org.scalatestplus.scalacheck.Checkers
import org.typelevel.discipline.Laws
import org.typelevel.discipline.scalatest.FunSuiteDiscipline

class BaseTestsSuite
    extends AnyFunSuite
    with Matchers
    with Checkers
    with FunSuiteDiscipline
    with TestInstances
    with TestUtils {

  
  def testAsync[A](name: String, tags: Tag*)(f: TestContext => Unit)(implicit pos: source.Position): Unit =
    // Overriding System.err
    test(name, tags: _*)(silenceSystemErr(f(TestContext())))(pos)

  def checkAllAsync(name: String, f: TestContext => Laws#RuleSet): Unit = {
    val context = TestContext()
    val ruleSet = f(context)

    for ((id, prop) <- ruleSet.all.properties)
      test(name + "." + id) {
        silenceSystemErr(check(prop))
      }
  }
} 
Example 19
Source File: ExtraMonadTests.scala    From interop-cats   with Apache License 2.0 5 votes vote down vote up
package zio.interop

import cats.kernel.laws.discipline.catsLawsIsEqToProp
import cats.{ Eq, Monad }
import org.scalacheck.{ Arbitrary, Prop }
import org.typelevel.discipline.Laws

trait ExtraMonadTests[F[_]] extends Laws {
  def laws: ExtraMonadLaws[F]

  def monadExtras[A: Arbitrary: Eq](
    implicit
    EqFInt: Eq[F[Int]]
  ): RuleSet =
    new RuleSet {
      def name: String                  = "monadExtras"
      def bases: Seq[(String, RuleSet)] = Nil
      def parents: Seq[RuleSet]         = Nil
      def props: Seq[(String, Prop)] =
        Seq[(String, Prop)]("tailRecM construction stack safety" -> Prop.lzy(laws.tailRecMConstructionStackSafety))
    }
}

object ExtraMonadTests {
  def apply[F[_]: Monad]: ExtraMonadTests[F] =
    new ExtraMonadTests[F] {
      def laws: ExtraMonadLaws[F] = ExtraMonadLaws[F]
    }
} 
Example 20
Source File: catzSpecBase.scala    From interop-cats   with Apache License 2.0 5 votes vote down vote up
package zio.interop

import cats.Eq
import cats.effect.laws.util.{ TestContext, TestInstances }
import cats.implicits._
import org.scalacheck.Arbitrary
import org.scalatest.funsuite.AnyFunSuite
import org.scalatest.prop.Configuration
import org.typelevel.discipline.Laws
import org.typelevel.discipline.scalatest.FunSuiteDiscipline
import zio.clock.Clock
import zio.console.Console
import zio.internal.{ Executor, Platform, Tracing }
import zio.interop.catz.taskEffectInstance
import zio.random.Random
import zio.system.System
import zio.{ =!=, Cause, IO, Runtime, Task, UIO, ZIO, ZManaged }

private[zio] trait catzSpecBase
    extends AnyFunSuite
    with FunSuiteDiscipline
    with Configuration
    with TestInstances
    with catzSpecBaseLowPriority {

  type Env = Clock with Console with System with Random

  implicit def rts(implicit tc: TestContext): Runtime[Unit] = Runtime(
    (),
    Platform
      .fromExecutor(Executor.fromExecutionContext(Int.MaxValue)(tc))
      .withTracing(Tracing.disabled)
      .withReportFailure(_ => ())
  )

  implicit val zioEqCauseNothing: Eq[Cause[Nothing]] = Eq.fromUniversalEquals

  implicit def zioEqIO[E: Eq, A: Eq](implicit rts: Runtime[Any], tc: TestContext): Eq[IO[E, A]] =
    Eq.by(_.either)

  implicit def zioEqTask[A: Eq](implicit rts: Runtime[Any], tc: TestContext): Eq[Task[A]] =
    Eq.by(_.either)

  implicit def zioEqUIO[A: Eq](implicit rts: Runtime[Any], tc: TestContext): Eq[UIO[A]] =
    Eq.by(uio => taskEffectInstance.toIO(uio.sandbox.either))

  implicit def zioEqZManaged[E: Eq, A: Eq](implicit rts: Runtime[Any], tc: TestContext): Eq[ZManaged[Any, E, A]] =
    Eq.by(
      zm => ZManaged.ReleaseMap.make.flatMap(releaseMap => zm.zio.provideSome[Any]((_, releaseMap)).map(_._2).either)
    )

  def checkAllAsync(name: String, f: TestContext => Laws#RuleSet): Unit =
    checkAll(name, f(TestContext()))

}

private[interop] sealed trait catzSpecBaseLowPriority { this: catzSpecBase =>

  implicit def zioEq[R: Arbitrary, E: Eq, A: Eq](implicit rts: Runtime[Any], tc: TestContext): Eq[ZIO[R, E, A]] = {
    def run(r: R, zio: ZIO[R, E, A]) = taskEffectInstance.toIO(zio.provide(r).either)
    Eq.instance((io1, io2) => Arbitrary.arbitrary[R].sample.fold(false)(r => catsSyntaxEq(run(r, io1)) eqv run(r, io2)))
  }

  // 'R =!= Any' evidence fixes the 'diverging implicit expansion for type Arbitrary' error reproducible on scala 2.12 and 2.11.
  implicit def zmanagedEq[R: * =!= Any: Arbitrary, E: Eq, A: Eq](
    implicit rts: Runtime[Any],
    tc: TestContext
  ): Eq[ZManaged[R, E, A]] = {
    def run(r: R, zm: ZManaged[R, E, A]) =
      taskEffectInstance.toIO(
        ZManaged.ReleaseMap.make.flatMap(releaseMap => zm.zio.provide((r, releaseMap)).map(_._2).either)
      )
    Eq.instance((io1, io2) => Arbitrary.arbitrary[R].sample.fold(false)(r => catsSyntaxEq(run(r, io1)) eqv run(r, io2)))
  }

} 
Example 21
Source File: MTLSpecs.scala    From shims   with Apache License 2.0 5 votes vote down vote up
package shims.effect

import cats.effect.{ContextShift, IO}
import cats.effect.laws.discipline.{arbitrary, AsyncTests, ConcurrentEffectTests, ConcurrentTests}, arbitrary._
import cats.effect.laws.util.{TestContext, TestInstances}, TestInstances._

import cats.{Eq, Functor, Monad}
import cats.instances.either._
import cats.instances.int._
import cats.instances.option._
import cats.instances.tuple._
import cats.instances.unit._
import cats.syntax.functor._

import scalaz.{EitherT, Kleisli, OptionT, StateT, WriterT}

import org.scalacheck.{Arbitrary, Prop}

import org.specs2.Specification
import org.specs2.scalacheck.Parameters
import org.specs2.specification.core.Fragments

import org.typelevel.discipline.Laws
import org.typelevel.discipline.specs2.Discipline

import scala.concurrent.ExecutionContext
import scala.util.control.NonFatal

import java.io.{ByteArrayOutputStream, PrintStream}

object MTLSpecs extends Specification with Discipline {

  def is =
    br ^ checkAllAsync("OptionT[IO, ?]", implicit ctx => ConcurrentTests[OptionT[IO, ?]].concurrent[Int, Int, Int]) ^
    br ^ checkAllAsync("Kleisli[IO, Int, ?]", implicit ctx => ConcurrentTests[Kleisli[IO, Int, ?]].concurrent[Int, Int, Int]) ^
    br ^ checkAllAsync("EitherT[IO, Throwable, ?]", implicit ctx => ConcurrentEffectTests[EitherT[IO, Throwable, ?]].concurrentEffect[Int, Int, Int]) ^
    br ^ checkAllAsync("StateT[IO, Int, ?]", implicit ctx => AsyncTests[StateT[IO, Int, ?]].async[Int, Int, Int]) ^
    br ^ checkAllAsync("WriterT[IO, Int, ?]", implicit ctx => ConcurrentEffectTests[WriterT[IO, Int, ?]].concurrentEffect[Int, Int, Int])

  def checkAllAsync(name: String, f: TestContext => Laws#RuleSet)(implicit p: Parameters) = {
    val context = TestContext()
    val ruleSet = f(context)

    Fragments.foreach(ruleSet.all.properties.toList) {
      case (id, prop) =>
        s"$name.$id" ! check(Prop(p => silenceSystemErr(prop(p))), p, defaultFreqMapPretty) ^ br
    }
  }

  implicit def iocsForEC(implicit ec: ExecutionContext): ContextShift[IO] =
    IO.contextShift(ec)

  implicit def optionTArbitrary[F[_], A](implicit arbFA: Arbitrary[F[Option[A]]]): Arbitrary[OptionT[F, A]] =
    Arbitrary(arbFA.arbitrary.map(OptionT.optionT(_)))

  implicit def kleisliArbitrary[F[_], R, A](implicit arbRFA: Arbitrary[R => F[A]]): Arbitrary[Kleisli[F, R, A]] =
    Arbitrary(arbRFA.arbitrary.map(Kleisli(_)))

  implicit def eitherTArbitrary[F[_]: Functor, L, A](implicit arbEA: Arbitrary[F[Either[L, A]]]): Arbitrary[EitherT[F, L, A]] =
    Arbitrary(arbEA.arbitrary.map(fe => EitherT.eitherT(fe.map(_.asScalaz))))

  implicit def stateTArbitrary[F[_]: Monad, S, A](implicit arbSFA: Arbitrary[S => F[(S, A)]]): Arbitrary[StateT[F, S, A]] =
    Arbitrary(arbSFA.arbitrary.map(StateT(_)))

  implicit def writerTArbitrary[F[_], L, A](implicit arbFLA: Arbitrary[F[(L, A)]]): Arbitrary[WriterT[F, L, A]] =
    Arbitrary(arbFLA.arbitrary.map(WriterT(_)))

  implicit def kleisliEq[F[_], A](implicit eqv: Eq[F[A]]): Eq[Kleisli[F, Int, A]] =
    Eq.by(_(42))   // totally random and comprehensive seed

  implicit def stateTEq[F[_]: Monad, S, A](implicit eqv: Eq[F[(Int, A)]]): Eq[StateT[F, Int, A]] =
    Eq.by(_.run(42))   // totally random and comprehensive seed

  // copied from cats-effect
  private def silenceSystemErr[A](thunk: => A): A = synchronized {
    // Silencing System.err
    val oldErr = System.err
    val outStream = new ByteArrayOutputStream()
    val fakeErr = new PrintStream(outStream)
    System.setErr(fakeErr)
    try {
      val result = thunk
      System.setErr(oldErr)
      result
    } catch {
      case NonFatal(e) =>
        System.setErr(oldErr)
        // In case of errors, print whatever was caught
        fakeErr.close()
        val out = outStream.toString("utf-8")
        if (out.nonEmpty) oldErr.println(out)
        throw e
    }
  }
} 
Example 22
Source File: EnumLikeLaws.scala    From seals   with Apache License 2.0 5 votes vote down vote up
package dev.tauri.seals
package laws

import cats.Eq
import cats.kernel.laws._
import cats.kernel.laws.discipline._
import cats.implicits._

import org.typelevel.discipline.Laws
import org.scalacheck.Arbitrary
import org.scalacheck.Prop
import org.scalacheck.Prop._

import core.EnumLike

object EnumLikeLaws {
  def apply[A](implicit arb: Arbitrary[A], enu: EnumLike[A], equ: Eq[A]): EnumLikeLaws[A] = {
    new EnumLikeLaws[A] {
      def Arb = arb
      def Enu = enu
      def Equ = equ
    }
  }
}

trait EnumLikeLaws[A] extends Laws {

  implicit def Arb: Arbitrary[A]
  implicit def Enu: EnumLike[A]
  implicit def Equ: Eq[A]

  def name: this.RuleSet = new EnumLikeRuleSet(
    "name",
    parent = None,
    "name-fromName" -> forAll { a: A =>
      Enu.fromName(Enu.name(a)) <-> Right(a)
    },
    "fromName-name" -> forAll { s: String =>
      Enu.fromName(s).fold(
        _ => provedIsEq[String],
        a => Enu.name(a) <-> s
      )
    }
  )

  def index: this.RuleSet = new EnumLikeRuleSet(
    "index",
    parent = Some(name),
    "index-fromIndex" -> forAll { a: A =>
      Enu.fromIndex(Enu.index(a)) <-> Right(a)
    },
    "fromIndex-index" -> forAll { i: Int =>
      Enu.fromIndex(i).fold(
        _ => provedIsEq[Int],
        a => Enu.index(a) <-> i
      )
    }
  )

  def all: this.RuleSet = new EnumLikeRuleSet(
    "all",
    parent = Some(index)
  )

  final class EnumLikeRuleSet(
    val name: String,
    val parent: Option[this.RuleSet],
    val props: (String, Prop)*
  ) extends RuleSet with HasOneParent {
    val bases = Nil
  }
} 
Example 23
Source File: KleeneLaws.scala    From seals   with Apache License 2.0 5 votes vote down vote up
package dev.tauri.seals
package laws

import cats.Eq
import cats.kernel.laws._
import cats.kernel.laws.discipline._
import cats.instances.all._
import org.typelevel.discipline.Laws
import org.scalacheck.Arbitrary
import org.scalacheck.Prop
import org.scalacheck.Prop._

object KleeneLaws {
  def apply[F[_], A](
    implicit
    arbA: Arbitrary[A],
    arbFA: Arbitrary[F[A]],
    arbVect: Arbitrary[Vector[A]],
    kle: Kleene[F],
    equA: Eq[A],
    equFA: Eq[F[A]]
  ): KleeneLaws[F, A] = new KleeneLaws[F, A] {
    def ArbA = arbA
    def ArbFA = arbFA
    def ArbVect = arbVect
    def Kle = kle
    def EquA = equA
    def EquFA = equFA
  }
}

trait KleeneLaws[F[_], A] extends Laws {

  implicit def Kle: Kleene[F]
  implicit def ArbA: Arbitrary[A]
  implicit def ArbFA: Arbitrary[F[A]]
  implicit def ArbVect: Arbitrary[Vector[A]]
  implicit def EquA: Eq[A]
  implicit def EquFA: Eq[F[A]]

  def roundtrip: this.RuleSet = new KleeneRuleSet(
    name = "roundtrip",
    "toVector-fromVector" -> forAll { (fa: F[A]) =>
      Kle.fromVector(Kle.toVector(fa)) <-> fa
    },
    "fromVector-toVector" -> forAll { (va: Vector[A]) =>
      Kle.toVector(Kle.fromVector(va)) <-> va
    }
  )

  final class KleeneRuleSet(
    val name: String,
    val props: (String, Prop)*
  ) extends RuleSet with HasOneParent {
    val parent = None
    val bases = Nil
  }
} 
Example 24
Source File: AnyLaws.scala    From seals   with Apache License 2.0 5 votes vote down vote up
package dev.tauri.seals
package laws

import cats.kernel.laws._
import cats.kernel.laws.discipline._
import cats.kernel.instances.boolean._
import cats.kernel.Eq

import org.typelevel.discipline.Laws
import org.scalacheck.Arbitrary
import org.scalacheck.Prop
import org.scalacheck.Prop._

object AnyLaws {

  def apply[A](implicit arb: Arbitrary[A]): AnyLaws[A] = new AnyLaws[A] {
    def Arb = arb
  }

  final class Dummy()
}

trait AnyLaws[A] extends Laws {

  import AnyLaws._

  implicit def Arb: Arbitrary[A]

  def equalsHashCode: this.RuleSet = new AnyRuleSet(
    name = "equals-hashCode",
    parent = None,
    bases = List(),
    "equals-hashCode-consistent" -> forAll { (x: A, y: A) =>
      ((!(x == y)) || (x.## == y.##)) <-> true
    },
    "equals-false-for-other-types" -> forAll { (x: A) =>
      val ok = (x != new Dummy)
      Prop(Result(status = if (ok) True else False))
    }
  )

  def serializability: this.RuleSet = new AnyRuleSet(
    name = "serializability",
    parent = Some(this.equalsHashCode),
    bases = List(),
    Rules.serializable[A]
  )

  def equality(implicit Equ: Eq[A]): this.RuleSet = new AnyRuleSet(
    name = "equality",
    parent = Some(this.serializability),
    bases = List(),
    "equals-Eq-consistent" -> forAll { (x: A, y: A) =>
      Equ.eqv(x, y) <-> (x == y)
    }
  )

  def any(implicit Equ: Eq[A]): this.RuleSet = new AnyRuleSet(
    name = "any",
    parent = Some(this.equality),
    bases = List()
  )

  def referenceEquality: this.RuleSet = new AnyRuleSet(
    name = "referenceEquality",
    parent = None,
    bases = List(),
    "reference-equals" -> forAll { (x: A, y: A) =>
      (x == y) <-> (x.asInstanceOf[AnyRef] eq y.asInstanceOf[AnyRef])
    },
    "identity-hashCode" -> forAll { (x: A, y: A) =>
      // we ignore collisions here, as
      // they should be sufficiently rare
      (x.## == y.##) <-> (x.asInstanceOf[AnyRef] eq y.asInstanceOf[AnyRef])
    }
  )

  def equalitySerializability(implicit Equ: Eq[A]): this.RuleSet = new AnyRuleSet(
    name = "equalitySerializability",
    parent = None,
    bases = List(),
    Rules.equalitySerializable[A]
  )

  final class AnyRuleSet(
    val name: String,
    val parent: Option[this.RuleSet],
    val bases: List[(String, Laws#RuleSet)],
    val props: (String, Prop)*
  ) extends RuleSet with HasOneParent
} 
Example 25
Source File: ZonedDateTimeTests.scala    From dtc   with Apache License 2.0 5 votes vote down vote up
package dtc.laws

import java.time.{Duration, LocalDate, LocalTime}

import dtc.{TimeZoneId, Zoned}
import org.scalacheck.{Arbitrary, Gen}
import org.typelevel.discipline.Laws

trait ZonedDateTimeTests[A] extends Laws {

  def generalLocalDateTimeLaws: GeneralLocalDateTimeLaws[A]
  def laws: ZonedDateTimeLaws[A]

  def zonedDateTime(implicit arbA: Arbitrary[A], arbD: Arbitrary[Duration]): RuleSet = {
    new DefaultRuleSet(
      name = "ZonedDateTime",
      parent = None,
      "[within same offset] seconds addition laws" -> generalLocalDateTimeLaws.secondsAddition,
      "[within same offset] minutes addition laws" -> generalLocalDateTimeLaws.minutesAddition,
      "[within same offset] hours addition laws" -> generalLocalDateTimeLaws.hoursAddition,
      "[within same offset] withYear laws" -> generalLocalDateTimeLaws.withYear,
      "[within same offset] withMonth laws" -> generalLocalDateTimeLaws.withMonth,
      "[within same offset] withDayOfMonth laws" -> generalLocalDateTimeLaws.withDayOfMonth,
      "[within same offset] withHour laws" -> generalLocalDateTimeLaws.withHour,
      "[within same offset] withMinute laws" -> generalLocalDateTimeLaws.withMinute,
      "[within same offset] withSecond laws" -> generalLocalDateTimeLaws.withSecond,
      "[within same offset] withMillisecond laws" -> generalLocalDateTimeLaws.withMillisecond,
      "[within same offset] withTime laws" -> generalLocalDateTimeLaws.withTime,
      "[within same offset] withDate laws" -> generalLocalDateTimeLaws.withDate,
      "[within same offset] daysUntil is consistent with addition" -> generalLocalDateTimeLaws.daysUntilIsConsistentWithPlus,
      "[within same offset] monthsUntil is consistent with addition" -> generalLocalDateTimeLaws.monthsUntilIsConsistentWithPlus,
      "[within same offset] yearsUntil counts only number of full years" -> generalLocalDateTimeLaws.yearsUntilCountsOnlyFullUnits,
      "cross-offset addition" -> laws.crossOffsetAddition,
      "withZoneSameInstant gives the same instant" -> laws.withZoneSameInstantGivesSameInstant,
      "local time difference is the offset" -> laws.localTimeAndOffsetCorrelation
    )
  }
}

object ZonedDateTimeTests {
  def apply[A: Zoned](
    gDateAndDurationWithinSameDST: Gen[(A, Duration)],
    gDataSuite: Gen[ZonedDateTimeTestData[A]],
    gValidYear: Gen[Int],
    gTimeZone: Gen[TimeZoneId])(
    implicit
    arbA: Arbitrary[A],
    arbLocalTime: Arbitrary[LocalTime],
    arbLocalDate: Arbitrary[LocalDate]): ZonedDateTimeTests[A] = new ZonedDateTimeTests[A] {

    def generalLocalDateTimeLaws: GeneralLocalDateTimeLaws[A] = GeneralLocalDateTimeLaws[A](
      gDateAndDurationWithinSameDST, arbLocalTime.arbitrary, arbLocalDate.arbitrary, gValidYear
    )

    def laws: ZonedDateTimeLaws[A] = ZonedDateTimeLaws[A](
      gDateAndDurationWithinSameDST, gDataSuite,
      arbLocalTime.arbitrary, arbLocalDate.arbitrary, gValidYear, gTimeZone
    )
  }
} 
Example 26
Source File: ProviderTests.scala    From dtc   with Apache License 2.0 5 votes vote down vote up
package dtc.laws

import java.time.Duration

import cats.Order
import dtc.{Provider, TimeZoneId}
import org.scalacheck.{Arbitrary, Gen}
import org.typelevel.discipline.Laws

trait ProviderTests[A] extends Laws {

  def laws: ProviderLaws[A]

  def provider(implicit arbA: Arbitrary[A], arbD: Arbitrary[Duration]): RuleSet = {
    new DefaultRuleSet(
      name = "Provider",
      parent = None,
      "two consequent now calls preserve order" -> laws.twoConsequentNowCalls
    )
  }
}

object ProviderTests {
  def apply[A: Provider : Order](
    gTimeZone: Gen[TimeZoneId])(
    implicit arbA: Arbitrary[A]): ProviderTests[A] = new ProviderTests[A] {
    def laws: ProviderLaws[A] = ProviderLaws(gTimeZone)
  }
} 
Example 27
Source File: DateTimeTests.scala    From dtc   with Apache License 2.0 5 votes vote down vote up
package dtc.laws

import java.time.Duration

import dtc.TimePoint
import org.scalacheck.{Arbitrary, Gen}
import org.typelevel.discipline.Laws

trait DateTimeTests[A] extends Laws {
  def laws: DateTimeLaws[A]

  def dateTime(implicit arbA: Arbitrary[A]): RuleSet = {
    new DefaultRuleSet(
      name = "DateTime",
      parent = None,
      "add and substract the same duration gives original value" -> laws.additionAndSubtractionOfSameDuration,
      "add zero gives same value" -> laws.additionOfZero,
      "add non zero changes value" -> laws.additionOfNonZero,
      "millis addition laws" -> laws.millisAddition,
      "until self is always zero" -> laws.untilSelfIsAlwaysZero,
      "until methods are consistent with addition" -> laws.untilIsConsistentWithPlus,
      "date is always defined" -> laws.dateMustNotThrow,
      "time is always defined" -> laws.timeMustNotThrow,
      "date fields are consistent with toLocalDate" -> laws.dateFieldsAreConsistentWithToLocalDate,
      "time fields are consistent with toLocalTime" -> laws.timeFieldsAreConsistentWithToLocalTime
    )
  }
}

object DateTimeTests {
  def apply[A: TimePoint](
    gDateAndDuration: Gen[(A, Duration)])(
    implicit arbA: Arbitrary[A]): DateTimeTests[A] = new DateTimeTests[A] {
    def laws: DateTimeLaws[A] = DateTimeLaws[A](gDateAndDuration)
  }
} 
Example 28
Source File: LocalDateTimeTests.scala    From dtc   with Apache License 2.0 5 votes vote down vote up
package dtc.laws

import java.time.{Duration, LocalDate, LocalTime}

import dtc.Local
import org.scalacheck.{Arbitrary, Gen}
import org.typelevel.discipline.Laws

trait LocalDateTimeTests[A] extends Laws {

  def generalLaws: GeneralLocalDateTimeLaws[A]
  def laws: LocalDateTimeLaws[A]

  def localDateTime(implicit arbA: Arbitrary[A], arbD: Arbitrary[Duration]): RuleSet = {
    new DefaultRuleSet(
      name = "LocalDateTime",
      parent = None,
      "seconds addition laws" -> generalLaws.secondsAddition,
      "minutes addition laws" -> generalLaws.minutesAddition,
      "hours addition laws" -> generalLaws.hoursAddition,
      "constructor consistency" -> laws.constructorConsistency,
      "plain constructor consistency" -> laws.plainConstructorConsistency,
      "withYear laws" -> generalLaws.withYear,
      "withMonth laws" -> generalLaws.withMonth,
      "withDayOfMonth laws" -> generalLaws.withDayOfMonth,
      "withHour laws" -> generalLaws.withHour,
      "withMinute laws" -> generalLaws.withMinute,
      "withSecond laws" -> generalLaws.withSecond,
      "withMillisecond laws" -> generalLaws.withMillisecond,
      "withTime laws" -> generalLaws.withTime,
      "withDate laws" -> generalLaws.withDate,
      "daysUntil is consistent with addition" -> generalLaws.daysUntilIsConsistentWithPlus,
      "monthsUntil is consistent with addition" -> generalLaws.monthsUntilIsConsistentWithPlus,
      "yearsUntil counts only number of full years" -> generalLaws.yearsUntilCountsOnlyFullUnits
    )
  }

  // see: https://github.com/moment/moment/issues/3029
  def monthUntilFractionHandling(implicit arbA: Arbitrary[A], arbD: Arbitrary[Duration]): RuleSet = {
    new DefaultRuleSet(
      name = "LocalDateTime",
      parent = None,
      "monthsUntil counts only number of full months" -> generalLaws.monthsUntilCountsOnlyFullUnits
    )
  }
}

object LocalDateTimeTests {
  def apply[A: Local](
    gDateAndDuration: Gen[(A, Duration)],
    gValidYear: Gen[Int])(
    implicit
    arbA: Arbitrary[A],
    arbLocalTime: Arbitrary[LocalTime],
    arbLocalDate: Arbitrary[LocalDate]): LocalDateTimeTests[A] = new LocalDateTimeTests[A] {

    def laws: LocalDateTimeLaws[A] = LocalDateTimeLaws[A](
      arbLocalTime.arbitrary, arbLocalDate.arbitrary
    )

    def generalLaws: GeneralLocalDateTimeLaws[A] = GeneralLocalDateTimeLaws[A](
      gDateAndDuration, arbLocalTime.arbitrary, arbLocalDate.arbitrary, gValidYear
    )
  }
} 
Example 29
Source File: laws.scala    From discipline-scalatest   with MIT License 5 votes vote down vote up
package org.typelevel.discipline.scalatest

import org.scalacheck.Prop
import org.typelevel.discipline.Laws

object Dummy {
  def prop = Prop(_ => Prop.Result(status = Prop.True))
  def prop2 = Prop(true)
}

object DummyLaws extends Laws {
  def dummy =
    new DefaultRuleSet(
      name = "dummy",
      parent = None,
      "true" -> Dummy.prop,
      "alsoTrue" -> Dummy.prop2
    )
} 
Example 30
Source File: TaskInstancesSpecs.scala    From shims   with Apache License 2.0 5 votes vote down vote up
package shims.effect

import cats.Eq
import cats.laws.discipline.{ApplicativeTests, ParallelTests}

import cats.effect.{Async, IO}
import cats.effect.laws.discipline.{arbitrary, EffectTests}, arbitrary._
import cats.effect.laws.util.{TestContext, TestInstances}, TestInstances._

import cats.instances.either._
import cats.instances.int._
import cats.instances.tuple._
import cats.instances.unit._

import scalaz.Tag
import scalaz.concurrent.Task
import scalaz.concurrent.Task.ParallelTask

import org.specs2.Specification
import org.specs2.scalacheck.Parameters
import org.specs2.specification.core.Fragments

import org.typelevel.discipline.Laws
import org.typelevel.discipline.specs2.Discipline

import java.util.concurrent.RejectedExecutionException

import scala.concurrent.ExecutionContext

object TaskInstancesSpecs extends Specification with Discipline {
  import TaskArbitrary._
  import Task.taskParallelApplicativeInstance

  def is = br ^ taskEff ^ br ^ taskPar ^ br ^ parTaskApp ^ br ^ asyncShiftTask

  def taskEff = checkAllAsync("Effect[Task]",
    implicit ctx => EffectTests[Task].effect[Int, Int, Int])

  def taskPar = checkAllAsync("Parallel[Task]",
    implicit ctx => ParallelTests[Task].parallel[Int, Int])

  def parTaskApp = checkAllAsync("Parallel[Task]", { implicit ctx =>
    val tests = ApplicativeTests[ParallelTask]
    tests.applicative[Int, Int, Int]
  })

  def asyncShiftTask = {
    implicit val context: TestContext = TestContext()
    val boom = new RejectedExecutionException("Boom")
    val rejectingEc = new ExecutionContext {
      def execute(runnable: Runnable): Unit = throw boom
      def reportFailure(cause: Throwable): Unit = ()
    }

    "async.shift on rejecting execution context" ! {
      Eq[Task[Unit]].eqv(Async.shift[Task](rejectingEc), Task.fail(boom)) must beTrue
    }
  }

  def checkAllAsync(name: String, f: TestContext => Laws#RuleSet)(implicit p: Parameters) = {
    val context = TestContext()
    val ruleSet = f(context)

    Fragments.foreach(ruleSet.all.properties.toList) {
      case (id, prop) =>
        id ! check(prop, p, defaultFreqMapPretty) ^ br
    }
  }

  implicit def taskEq[A: Eq](implicit ctx: TestContext): Eq[Task[A]] =
    Eq.by(ta => IO.async[A](k => ta.unsafePerformAsync(e => k(e.toEither))))

  implicit def parallelTaskEq[A: Eq](implicit ctx: TestContext): Eq[ParallelTask[A]] =
    Tag.subst(taskEq[A])
} 
Example 31
Source File: SymmetricSerializationLaws.scala    From circe-yaml   with Apache License 2.0 5 votes vote down vote up
package io.circe.yaml

import cats.Eq
import cats.instances.either._
import cats.laws._
import cats.laws.discipline._
import io.circe.{ Decoder, Encoder, Json, ParsingFailure }
import org.scalacheck.{ Arbitrary, Prop, Shrink }
import org.typelevel.discipline.Laws

trait SymmetricSerializationLaws {

  def printerRoundTrip[A: Eq: Encoder: Decoder](
    parse: String => Either[ParsingFailure, Json],
    print: Json => String,
    a: A
  ): IsEq[Either[io.circe.Error, A]] =
    parse(print(Encoder[A].apply(a))).right.flatMap(_.as[A]) <-> Right(a)

}

object SymmetricSerializationLaws {

  def apply(): SymmetricSerializationLaws = new SymmetricSerializationLaws {}
}

trait SymmetricSerializationTests extends Laws {
  def laws: SymmetricSerializationLaws

  def symmetricPrinter[A: Eq: Arbitrary: Shrink: Encoder: Decoder](
    print: Json => String,
    parse: String => Either[ParsingFailure, Json]
  ): RuleSet =
    new DefaultRuleSet(
      name = "printer",
      parent = None,
      "roundTrip" -> Prop.forAll { (a: A) =>
        laws.printerRoundTrip(parse, print, a)
      }
    )
}

object SymmetricSerializationTests {
  def apply[A: Eq: Arbitrary: Decoder: Encoder](
    print: Json => String,
    parse: String => Either[ParsingFailure, Json]
  ): SymmetricSerializationTests =
    new SymmetricSerializationTests {
      val laws: SymmetricSerializationLaws = SymmetricSerializationLaws()
      symmetricPrinter[A](print, parse)
    }
} 
Example 32
Source File: CodecEquivalenceTests.scala    From circe-magnolia   with Apache License 2.0 5 votes vote down vote up
package io.circe.magnolia

import cats.instances.either._
import cats.kernel.Eq
import cats.laws._
import cats.laws.discipline._
import io.circe.magnolia.tags.{TaggedDecoder, TaggedEncoder}
import io.circe.{Decoder, Encoder, Json}
import org.scalacheck.{Arbitrary, Prop, Shrink}
import org.typelevel.discipline.Laws
import shapeless.tag.@@

trait CodecEquivalenceLaws[A] {
  def circeDecoder: Decoder[A] @@ tags.Circe
  def magnoliaDecoder: Decoder[A] @@ tags.Magnolia

  def circeEncoder: Encoder[A] @@ tags.Circe
  def magnoliaEncoder: Encoder[A] @@ tags.Magnolia

  def encoderEq(a: A): IsEq[Json] =
    circeEncoder(a) <-> magnoliaEncoder(a)

  def decoderEq(a: A): IsEq[Decoder.Result[A]] = {
    val encoded = magnoliaEncoder(a)
    encoded.as(circeDecoder) <-> encoded.as(magnoliaDecoder)
  }
}

object CodecEquivalenceLaws {

  def apply[A](
    implicit
    circeDecode: Decoder[A] @@ tags.Circe,
    magnoliaDecode: Decoder[A] @@ tags.Magnolia,
    circeEncode: Encoder[A] @@ tags.Circe,
    magnoliaEncode: Encoder[A] @@ tags.Magnolia) = new CodecEquivalenceLaws[A] {

    override val circeDecoder = circeDecode
    override val magnoliaDecoder = magnoliaDecode
    override val circeEncoder = circeEncode
    override val magnoliaEncoder = magnoliaEncode
  }
}

trait CodecEquivalenceTests[A] extends Laws {
  def laws: CodecEquivalenceLaws[A]

  def codecEquivalence(
    implicit
    arbitraryA: Arbitrary[A],
    shrinkA: Shrink[A],
    eqA: Eq[A]): RuleSet = new DefaultRuleSet(
    name = "codec equality",
    parent = None,
    "encoder equivalence" -> Prop.forAll { (a: A) =>
      laws.encoderEq(a)
    },
    "decoder equivalence" -> Prop.forAll { (a: A) =>
      laws.decoderEq(a)
    }
  )

  // Use codecEquivalence if possible. Use only when only
  // derived Encoder can be equivalent and should be documented
  def encoderEquivalence(
    implicit
    arbitraryA: Arbitrary[A],
    shrinkA: Shrink[A]
    ): RuleSet = new DefaultRuleSet(
    name = "codec equality",
    parent = None,
    "encoder equivalence" -> Prop.forAll { (a: A) =>
      laws.encoderEq(a)
    },
  )
}

object CodecEquivalenceTests {
  def apply[A](
    implicit
    circeDecode: Decoder[A] @@ tags.Circe,
    magnoliaDecode: Decoder[A] @@ tags.Magnolia,
    circeEncode: Encoder[A] @@ tags.Circe,
    magnoliaEncode: Encoder[A] @@ tags.Magnolia): CodecEquivalenceTests[A] = new CodecEquivalenceTests[A] {
    val laws: CodecEquivalenceLaws[A] = CodecEquivalenceLaws[A](
      circeDecode, magnoliaDecode, circeEncode, magnoliaEncode)
  }

  def useTagged[A](
    implicit
    circeDecode: TaggedDecoder[tags.Circe, A],
    magnoliaDecode: TaggedDecoder[tags.Magnolia, A],
    circeEncode: TaggedEncoder[tags.Circe, A],
    magnoliaEncode: TaggedEncoder[tags.Magnolia, A]): CodecEquivalenceTests[A] = new CodecEquivalenceTests[A] {
    val laws: CodecEquivalenceLaws[A] = CodecEquivalenceLaws[A](
      circeDecode.toTagged, magnoliaDecode.toTagged, circeEncode.toTagged, magnoliaEncode.toTagged)
  }
} 
Example 33
Source File: CirceSuite.scala    From circe-magnolia   with Apache License 2.0 5 votes vote down vote up
package io.circe.tests

import cats.instances.AllInstances
import cats.kernel.Eq
import cats.syntax.{AllSyntax, EitherOps}
import io.circe.testing.{ArbitraryInstances, EqInstances}
import org.scalatest.FlatSpec
import org.scalatestplus.scalacheck.{Checkers, ScalaCheckDrivenPropertyChecks}
import org.typelevel.discipline.Laws


trait CirceSuite
    extends FlatSpec
    with ScalaCheckDrivenPropertyChecks
    with AllInstances
    with AllSyntax
    with ArbitraryInstances
    with Checkers
    with EqInstances {

  override def convertToEqualizer[T](left: T): Equalizer[T] =
    sys.error("Intentionally ambiguous implicit for Equalizer")

  implicit def prioritizedCatsSyntaxEither[A, B](eab: Either[A, B]): EitherOps[A, B] = new EitherOps(eab)

  def checkLaws(name: String, ruleSet: Laws#RuleSet): Unit =
    ruleSet.all.properties.zipWithIndex.foreach {
      case ((id, prop), 0) => name should s"obey $id" in check(prop)
      case ((id, prop), _) => it should s"obey $id" in check(prop)
    }

  implicit def eqSeq[A: Eq]: Eq[Seq[A]] = Eq.by((_: Seq[A]).toVector)(
    cats.kernel.instances.vector.catsKernelStdEqForVector[A]
  )
} 
Example 34
Source File: CodecSpec.scala    From hammock   with MIT License 5 votes vote down vote up
package hammock

import cats.Eq
import cats.instances.option._
import cats.instances.int._
import cats.laws._
import cats.laws.discipline._
import cats.syntax.either._

import org.scalacheck.{Arbitrary, Prop}
import org.scalatest.matchers.should.Matchers
import org.scalatest.funsuite.AnyFunSuite
import org.typelevel.discipline.Laws
import org.typelevel.discipline.scalatest.Discipline

import scala.util._

trait CodecLaws[A] {
  implicit def F: Codec[A]

  def decodeAfterEncodeEquality(a: A): IsEq[Option[A]] =
    F.decode(F.encode(a)).right.toOption <-> Some(a)
}

object CodecLaws {
  def apply[T](implicit ev: Codec[T]): CodecLaws[T] = new CodecLaws[T] { def F = ev }
}

trait CodecTests[A] extends Laws {
  def laws: CodecLaws[A]

  def codec(implicit A: Arbitrary[A], eq: Eq[A]): RuleSet =
    new DefaultRuleSet("Codec", None, "decodeAfterEncodeEquality" -> Prop.forAll { (a: A) =>
      laws.decodeAfterEncodeEquality(a)
    })
}

object CodecTests {

  def apply[A: Codec: Arbitrary: Eq]: CodecTests[A] = new CodecTests[A] {
    def laws: CodecLaws[A] = CodecLaws[A]
  }

}

class CodecSpec extends AnyFunSuite with Discipline with Matchers {
  import Encoder.ops._

  implicit val intCodec = new Codec[Int] {
    def encode(t: Int): Entity = Entity.StringEntity(t.toString)
    def decode(s: Entity): Either[CodecException, Int] = s match {
      case Entity.StringEntity(body, _) =>
        Either
          .catchOnly[NumberFormatException](body.toInt)
          .left
          .map(ex => CodecException.withMessageAndException(ex.getMessage, ex))
      case _ => Left(CodecException.withMessage("only StringEntities accepted"))
    }
  }

  checkAll("Codec[Int]", CodecTests[Int].codec)

  test("syntax should exist for types for which a Codec exist") {
    1.encode shouldEqual Entity.StringEntity("1")
  }
} 
Example 35
Source File: SplitEpiTests.scala    From redis4cats   with Apache License 2.0 5 votes vote down vote up
package dev.profunktor.redis4cats.codecs

import cats.Eq
import cats.laws.discipline._
import dev.profunktor.redis4cats.codecs.laws.SplitEpiLaws
import dev.profunktor.redis4cats.codecs.splits.SplitEpi
import org.scalacheck.Arbitrary
import org.scalacheck.Prop._
import org.typelevel.discipline.Laws

// Credits to Rob Norris (@tpolecat) -> https://skillsmatter.com/skillscasts/11626-keynote-pushing-types-and-gazing-at-the-stars
trait SplitEpiTests[A, B] extends Laws {
  def laws: SplitEpiLaws[A, B]

  def splitEpi(implicit a: Arbitrary[A], b: Arbitrary[B], eqA: Eq[A], eqB: Eq[B]): RuleSet =
    new DefaultRuleSet(
      name = "splitEpimorphism",
      parent = None,
      "identity" -> forAll(laws.identity _),
      "idempotence" -> forAll(laws.idempotence _)
    )
}

object SplitEpiTests {
  def apply[A, B](epi: SplitEpi[A, B]): SplitEpiTests[A, B] =
    new SplitEpiTests[A, B] {
      val laws = SplitEpiLaws[A, B](epi)
    }
} 
Example 36
Source File: SplitMonoTests.scala    From redis4cats   with Apache License 2.0 5 votes vote down vote up
package dev.profunktor.redis4cats.codecs

import cats.Eq
import cats.laws.discipline._
import dev.profunktor.redis4cats.codecs.laws.SplitMonoLaws
import dev.profunktor.redis4cats.codecs.splits.SplitMono
import org.scalacheck.Arbitrary
import org.scalacheck.Prop._
import org.typelevel.discipline.Laws

// Credits to Rob Norris (@tpolecat) -> https://skillsmatter.com/skillscasts/11626-keynote-pushing-types-and-gazing-at-the-stars
trait SplitMonoTests[A, B] extends Laws {
  def laws: SplitMonoLaws[A, B]

  def splitMono(implicit a: Arbitrary[A], b: Arbitrary[B], eqA: Eq[A], eqB: Eq[B]): RuleSet =
    new DefaultRuleSet(
      name = "splitMonomorphism",
      parent = None,
      "identity" -> forAll(laws.identity _),
      "idempotence" -> forAll(laws.idempotence _)
    )
}

object SplitMonoTests {
  def apply[A, B](mono: SplitMono[A, B]): SplitMonoTests[A, B] =
    new SplitMonoTests[A, B] {
      val laws = SplitMonoLaws[A, B](mono)
    }
} 
Example 37
Source File: SemigroupalKTests.scala    From cats-tagless   with Apache License 2.0 5 votes vote down vote up
package cats.tagless
package laws
package discipline


import cats.{Eq, ~>}
import cats.data.Tuple2K
import cats.tagless.laws.discipline.SemigroupalKTests.IsomorphismsK
import org.scalacheck.Prop._
import org.scalacheck.{Arbitrary, Prop}
import org.typelevel.discipline.Laws

trait SemigroupalKTests[F[_[_]]] extends Laws {
  def laws: SemigroupalKLaws[F]

  def semigroupalK[A[_], B[_], C[_]](implicit
                                               ArbCF: Arbitrary[F[A]],
                                               ArbCG: Arbitrary[F[B]],
                                               ArbCH: Arbitrary[F[C]],
                                               iso: IsomorphismsK[F],
                                               EqFGH: Eq[F[Tuple3K[A, B, C]#λ]]
                                              ): RuleSet = {
    new DefaultRuleSet(
      name = "SemigroupalK",
      parent = None,
      "semigroupal associativity" -> forAll((af: F[A], ag: F[B], ah: F[C]) => iso.associativity(laws.semigroupalAssociativity[A, B, C](af, ag, ah))))
  }
}


object SemigroupalKTests {
  def apply[F[_[_]]: SemigroupalK]: SemigroupalKTests[F] =
    new SemigroupalKTests[F] { def laws: SemigroupalKLaws[F] = SemigroupalKLaws[F] }

  import IsomorphismsK._

  trait IsomorphismsK[F[_[_]]] {
    def associativity[A[_], B[_], C[_]](fs: (F[ProdA_BC[A, B, C]#λ], F[ProdAB_C[A, B, C]#λ]))
                                       (implicit EqFGH: Eq[F[Tuple3K[A, B, C]#λ]]): Prop
  }

  object IsomorphismsK {
    
    type ProdA_BC[A[_], B[_], C[_]]  = { type λ[T] = Tuple2K[A, Tuple2K[B, C, *], T] }
    type ProdAB_C[A[_], B[_], C[_]]  = { type λ[T] = Tuple2K[Tuple2K[A, B, *], C, T] }

    implicit def invariantK[F[_[_]]](implicit F: InvariantK[F]): IsomorphismsK[F] =
      new IsomorphismsK[F] {
        def associativity[A[_], B[_], C[_]](fs: (F[ProdA_BC[A, B, C]#λ], F[ProdAB_C[A, B, C]#λ]))
                                           (implicit EqFGH: Eq[F[Tuple3K[A, B, C]#λ]]): Prop = {

          val fkA_BC_T3 = λ[ProdA_BC[A, B, C]#λ ~> Tuple3K[A, B, C]#λ ]{ case Tuple2K(a, Tuple2K(b, c)) => (a, b, c) }
          val fkAB_C_T3 = λ[ProdAB_C[A, B, C]#λ ~> Tuple3K[A, B, C]#λ ]{ case Tuple2K(Tuple2K(a, b), c) => (a, b, c) }
          val fkT3_AB_C = λ[Tuple3K[A, B, C]#λ ~> ProdAB_C[A, B, C]#λ]{ case (a, b, c) => Tuple2K(Tuple2K(a, b), c) }
          val fkT3_A_BC = λ[Tuple3K[A, B, C]#λ ~> ProdA_BC[A, B, C]#λ]{ case (a, b, c) => Tuple2K(a, Tuple2K(b, c)) }

          EqFGH.eqv(
            F.imapK[ProdA_BC[A, B, C]#λ, Tuple3K[A, B, C]#λ](fs._1)(fkA_BC_T3)(fkT3_A_BC),
            F.imapK[ProdAB_C[A, B, C]#λ, Tuple3K[A, B, C]#λ](fs._2)(fkAB_C_T3)(fkT3_AB_C)
          )
        }

      }
  }
} 
Example 38
Source File: InvariantKTests.scala    From cats-tagless   with Apache License 2.0 5 votes vote down vote up
package cats.tagless
package laws
package discipline

import cats.{Eq, ~>}
import org.scalacheck.Prop._
import org.scalacheck.Arbitrary
import org.typelevel.discipline.Laws
import cats.laws.discipline._

trait InvariantKTests[F[_[_]]] extends Laws {
  def laws: InvariantKLaws[F]

  def invariantK[A[_], B[_], C[_]](implicit
                                                          ArbFA: Arbitrary[F[A]],
                                                          ArbAB: Arbitrary[A ~> B],
                                                          ArbBA: Arbitrary[B ~> A],
                                                          ArbBC: Arbitrary[B ~> C],
                                                          ArbCB: Arbitrary[C ~> B],
                                                          EqFA: Eq[F[A]],
                                                          EqFC: Eq[F[C]]
                                                         ): RuleSet = {
    new DefaultRuleSet(
      name = "invariantK",
      parent = None,
      "invariant identity" -> forAll(laws.invariantIdentity[A] _),
      "invariant composition" -> forAll(laws.invariantComposition[A, B, C] _))
  }
}

object InvariantKTests {
  def apply[F[_[_]]: InvariantK]: InvariantKTests[F] =
    new InvariantKTests[F] { def laws: InvariantKLaws[F] = InvariantKLaws[F] }
} 
Example 39
Source File: KnownFormatsReaderTests.scala    From kantan.csv   with Apache License 2.0 5 votes vote down vote up
package kantan.csv
package laws
package discipline

import org.scalacheck.Prop
import org.typelevel.discipline.Laws

trait KnownFormatsReaderTests extends Laws {
  def laws: KnownFormatsReaderLaws

  def knownFormats: RuleSet = new DefaultRuleSet(
    name = "knownFormats",
    parent = None,
    "excel for mac 12.0" -> Prop(laws.excelMac120),
    "numbers 1.0.3"      -> Prop(laws.numbers103),
    "google docs"        -> Prop(laws.googleDocs)
  )
} 
Example 40
Source File: SpectrumReaderTests.scala    From kantan.csv   with Apache License 2.0 5 votes vote down vote up
package kantan.csv
package laws
package discipline

import org.scalacheck.Prop
import org.typelevel.discipline.Laws

trait SpectrumReaderTests extends Laws {
  def laws: SpectrumReaderLaws

  def csvSpectrum: RuleSet = new DefaultRuleSet(
    name = "csvSpectrum",
    parent = None,
    "comma in quotes"     -> Prop(laws.commaInQuotes),
    "empty"               -> Prop(laws.empty),
    "empty crlf"          -> Prop(laws.emptyCRLF),
    "escaped quotes"      -> Prop(laws.escapedQuotes),
    "json"                -> Prop(laws.json),
    "newlines"            -> Prop(laws.newLines),
    "newlines crlf"       -> Prop(laws.newLinesCRLF),
    "quotes and newlines" -> Prop(laws.quotesAndNewLines),
    "simple"              -> Prop(laws.simple),
    "simple crlf"         -> Prop(laws.simpleCRLF),
    "utf8"                -> Prop(laws.utf8)
  )
}