embracing-nondeterminism-code/src/test/scala/green/thisfieldwas/embracingnondeterminism/data/OptionSpec.scala

111 lines
2.6 KiB
Scala

package green.thisfieldwas.embracingnondeterminism.data
import green.thisfieldwas.embracingnondeterminism.util._
import org.scalacheck.Gen
import org.scalatest.Inside
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
class OptionSpec extends AnyWordSpec with Matchers with Inside {
"Option" can {
"get" which {
"returns the value" when {
"the option is defined" in {
val option = Option(1)
option.get shouldBe 1
}
}
"faults" when {
"the option is not defined" in {
val option = Option[Int]()
inside(the[NoSuchElementException].thrownBy(option.get)) { case e =>
e.getMessage shouldBe "None.get"
}
}
}
}
"isSome" which {
"is true" when {
"the option is defined" in {
val option = Option(1)
option.isSome shouldBe true
}
}
"is false" when {
"the option is not defined" in {
val option = Option[Int]()
option.isSome shouldBe false
}
}
}
"isNone" when {
"is true" when {
"the option is not defined" in {
val option = Option[Int]()
option.isNone shouldBe true
}
}
"is false" when {
"the option is defined" in {
val option = Option(1)
option.isNone shouldBe false
}
}
}
}
"Option object" can {
"apply" which {
"creates a Some" when {
"given a value" in {
Option(1) shouldBe Some(1)
}
}
"creates a None" when {
"given no argument" in {
Option() shouldBe None
}
}
}
"unapply" which {
"matches Some" in {
Some(1) match {
case Option(x) => x shouldBe 1
case _ => fail("unapply didn't match")
}
}
"doesn't match None" in {
None match {
case Option(_) => fail("unapply matched")
case _ =>
}
}
}
}
}
/** Check that `Option` conforms to typeclass laws.
*/
class OptionLaws extends Laws with FunctorLaws {
/** From a generator for some type `A`, generate in roughly equal proportions
* a `None` of an absence of `A` or a `Some` of a presence of `A`.
*/
implicit val optionLiftedGen: LiftedGen[Option] = new LiftedGen[Option] {
override def lift[A](gen: Gen[A]): Gen[Option[A]] =
Gen.lzy(
Gen.oneOf(
Gen.const(None),
gen.map(Some(_)),
)
)
}
checkFunctorLaws[Option]()
}