Created
March 29, 2012 00:55
-
-
Save etorreborre/2231981 to your computer and use it in GitHub Desktop.
Using Scalaz to get the applicative syntax for ScalaCheck generators
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import scalaz.Apply | |
import org.scalacheck.Gen | |
import org.scalacheck.Arbitrary._ | |
/** | |
* Use this trait to get applicative syntax when building generators. This | |
* is especially useful when building generators for case classes. | |
* | |
*/ | |
trait Data { | |
/** | |
* import scalaz.Scalaz._ | |
* case class MyClass(a: A, b: B, c: C) | |
* | |
* val MyCaseClassGenerator: Gen[MyCaseClass] = (genA |@| genB |@| genC)(MyCaseClass) | |
* | |
*/ | |
implicit def genIsApply: Apply[Gen] = new Apply[Gen] { | |
def ap[A, B](fa: => Gen[A])(f: => Gen[(A) => B]) = fa.map2(f)((v, function) => function(v)) | |
def map[A, B](fa: Gen[A])(f: (A) => B) = fa map f | |
} | |
} |
That was supposed to be clear from the comment :-). Something like that:
import org.scalacheck.Gen
import org.scalacheck.Gen._
case class Person(name: String, age: Int)
val names: Gen[String] = alphaStr suchThat (!_.isEmpty)
val ages: Gen[Int] = choose(1, 120)
val persons: Gen[Person] = (names |@| ages)(Person)
Then, in specs2 you can write properties like:
import org.scalacheck._
import org.scalacheck.Prop._
implicit def arbitraryPerson = Arbitrary(genPerson)
// using an implicit Arbitrary
"a person must always have a positive age" >> check { person: Person =>
person.age must be_>=(0)
}
// using an explicit Generator
"a person must always have a non-empty name" >> forAll(persons) { person: Person =>
person.name must not be empty
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
A simple usage example would be appreciated!