111 lines
2.6 KiB
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]()
|
|
}
|