Skip to content

Commit

Permalink
Migrate MinutesSpec to use ScalaCheckDrivenPropertyChecks
Browse files Browse the repository at this point in the history
  • Loading branch information
mlopes committed May 3, 2019
1 parent 6c0d05a commit 9d87116
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 38 deletions.
5 changes: 4 additions & 1 deletion src/main/scala/wen/types/types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,12 @@ final object Hour {
final case class Minute(minute: NumericMinute)

final object Minute {
private[wen] val min: Int = 0
private[wen] val max: Int = 59

def apply(minute: Int): Option[Minute] =
// See comment on Year for the reasoning behind running unsafeFrom
if (minute >= 0 && minute <= 59)
if (minute >= min && minute <= max)
Some(new Minute(refineV[Interval.Closed[W.`0`.T, W.`59`.T]].unsafeFrom(minute)))
else
None
Expand Down
6 changes: 5 additions & 1 deletion src/test/scala/wen/test/Arbitraries.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package wen.test
import java.time._

import org.scalacheck.{Arbitrary, Gen}
import wen.types.{Day, Hour, Millisecond}
import wen.types.{Day, Hour, Millisecond, Minute}

object Arbitraries {
implicit val optionDayArb: Arbitrary[Option[Day]] = Arbitrary {
Expand All @@ -14,6 +14,10 @@ object Arbitraries {
Gen.choose(Hour.min, Hour.max).map(Hour(_))
}

implicit val optionMinuteArb: Arbitrary[Option[Minute]] = Arbitrary {
Gen.choose(Minute.min, Minute.max).map(Minute(_))
}

implicit val optionMillisecondArb: Arbitrary[Option[Millisecond]] = Arbitrary {
Gen.choose(Millisecond.min, Millisecond.max).map(Millisecond(_))
}
Expand Down
8 changes: 7 additions & 1 deletion src/test/scala/wen/test/Generators.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package wen.test

import org.scalacheck.{Arbitrary, Gen}
import wen.types.{Day, Hour, Millisecond}
import wen.types.{Day, Hour, Millisecond, Minute}

object Generators {

Expand All @@ -11,6 +11,9 @@ object Generators {
val failedHourGen: Gen[Option[Hour]] =
(Arbitrary.arbitrary[Int] suchThat (x => x < Hour.min || x > Hour.max)).map(Hour(_))

val failedMinuteGen: Gen[Option[Minute]] =
(Arbitrary.arbitrary[Int] suchThat (x => x < Minute.min || x > Minute.max)).map(Minute(_))

val failedMillisecondGen: Gen[Option[Millisecond]] =
(Arbitrary.arbitrary[Int] suchThat (x => x < Millisecond.min || x > Millisecond.max)).map(Millisecond(_))

Expand All @@ -20,6 +23,9 @@ object Generators {
val hourAsIntGen: Gen[Int] =
Gen.choose(Hour.min, Hour.max)

val minuteAsIntGen: Gen[Int] =
Gen.choose(Minute.min, Minute.max)

val millisecondAsIntGen: Gen[Int] =
Gen.choose(Millisecond.min, Millisecond.max)
}
51 changes: 16 additions & 35 deletions src/test/scala/wen/types/MinuteSpec.scala
Original file line number Diff line number Diff line change
@@ -1,52 +1,33 @@
package wen.types

import eu.timepit.refined.{W, refineV}
import eu.timepit.refined.numeric.Interval
import org.scalacheck.{Arbitrary, Gen}
import org.scalacheck.Prop.forAll
import org.scalactic.TypeCheckedTripleEquals
import org.scalatestplus.scalacheck.Checkers
import org.scalatest.{Matchers, WordSpec}
import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks
import wen.test.Arbitraries._
import wen.test.Generators._
import wen.refine.refineMinute
import wen.types.NumericTypes.NumericMinute

class MinuteSpec extends WordSpec with Matchers with TypeCheckedTripleEquals with Checkers {
class MinuteSpec extends WordSpec with Matchers with TypeCheckedTripleEquals with ScalaCheckDrivenPropertyChecks {

"Minute" should {

"be created with a value between 0 and 59" in {

val minute = for {
m <- Gen.choose(0, 59)
} yield Minute(m)

val prop = forAll(minute) { m =>
m !==(None)
}
check(prop)
"be created with a value between 0 and 59" in forAll { minute: Option[Minute] =>
minute should !==(None)
}

"fail to be created with an Minute not between 0 and 59" in {
val minute = for {
m <- Arbitrary.arbitrary[Int] suchThat (x => x < 0 || x > 59)
} yield Minute(m)

val prop = forAll(minute) { m =>
m ===(None)
}
check(prop)
"fail to be created with an Minute not between 0 and 59" in forAll(failedMinuteGen) { failedMinute: Option[Minute] =>
failedMinute ===(None)
}

"creates a minute from a numeric minute" in {
val numericMinute = Gen.choose(0, 59)
"creates a minute from a numeric minute" in forAll(minuteAsIntGen) { minuteAsInt: Int =>

val prop = forAll[Int, Boolean](numericMinute) { m: Int =>
refineV[Interval.Closed[W.`0`.T, W.`59`.T]](m)
.fold(_ => false, { x =>
val numericMinute = Minute(x)
val optionMinute = Minute(m).get
numericMinute ===(optionMinute)})
refineMinute(minuteAsInt) match {
case Right(m: NumericMinute) =>
Minute(m) shouldBe a[Minute]
Minute(m) should ===(Minute(minuteAsInt).get)
case _ => fail
}

check(prop)
}
}
}

0 comments on commit 9d87116

Please sign in to comment.