import org.scalacheck.Prop val propStringLength = Prop.forAll { s: String => val len = s.length (s+s).length == len+len } val propDivByZero = Prop.throws(classOf[ArithmeticException]) { 1/0 } val propListIdxOutOfBounds = Prop.forAll { xs: List[Int] => Prop.throws(classOf[IndexOutOfBoundsException]) { xs(xs.length+1) } }
import org.scalacheck.Properties import org.scalacheck.Prop.{forAll, throws} object MySpec extends Properties("MySpec") { property("list tail") = forAll { (x: Int, xs: List[Int]) => (x::xs).tail == xs } property("list head") = forAll { xs: List[Int] => if (xs.isEmpty) throws(classOf[NoSuchElementException]) { xs.head } else xs.head == xs(0) } }
scala> MySpec.check + MySpec.list tail: OK, passed 100 tests. + MySpec.list head: OK, passed 100 tests.
class Gen[+T] { def apply(prms: Gen.Params): Option[T] }
scala> import org.scalacheck.Gen import org.scalacheck.Gen scala> val myGen = Gen.choose(1,10) myGen: org.scalacheck.Gen[Int] = Gen() scala> myGen(Gen.Params()) res0: Option[Int] = Some(7) scala> myGen.sample res1: Option[Int] = Some(5)
import org.scalacheck.Gen.choose val myGen = for { n <- choose(1, 50) m <- choose(n, 2*n) } yield (n, m)
scala> myGen.sample res0: Option[(Int, Int)] = Some((45,60)) scala> myGen.sample res1: Option[(Int, Int)] = Some((29,37))
trait Color case object Red extends Color case object Green extends Color trait Shape { def color: Color } case class Line(val color: Color) extends Shape case class Circle(val color: Color) extends Shape case class Box(val color: Color, val boxed: Shape) extends Shape
import org.scalacheck.Gen val genColor = Gen.oneOf(Red, Green) val genLine = for { color <- genColor } yield Line(color) val genCircle = for { color <- genColor } yield Circle(color) val genBox = for { color <- genColor shape <- genShape } yield Box(color, shape) val genShape: Gen[Shape] = Gen.oneOf(genLine, genCircle, genBox)
scala> genShape.sample res0: Option[Shape] = Some(Line(Green)) scala> genShape.sample res1: Option[Shape] = Some(Box(Blue,Box(Red,Circle(Green))))
import org.scalacheck.{Gen, Prop} val evenInt = for { n <- Gen.choose(-1000, 1000) } yield 2*n val propDivide = Prop.forAll(evenInt) { n: Int => val half = n/2 n == 2*half }
import org.scalacheck.Prop.forAll import org.scalacheck.Gen.{posNum, negNum} val p = forAll(posNum[Int], negNum[Int]) { (n,m) => n*m <= 0 }
import org.scalacheck.Prop.forAll import org.scalacheck.Gen.choose val propPrefix = forAll { s: String => forAll(choose(0, s.length)) { n => val prefix = s.substring(0, n) s.startsWith(s) } }
import org.scalacheck.Arbitrary.arbitrary import org.scalacheck.Gen.choose val genStringWithN = for { s <- arbitrary[String] n <- choose(0, s.length) } yield (s,n)
import org.scalacheck.Prop.forAll val propPrefix = forAll(genStringWithN) { case (s,n) => val prefix = s.substring(0, n) s.startsWith(s) }
import org.scalacheck.Gen.{choose, oneOf} case class Person ( firstName: String, lastName: String, age: Int ) { def isTeenager = age >= 13 && age <= 19 } val genPerson = for { firstName <- oneOf("Alan", "Ada", "Alonzo") lastName <- oneOf("Lovelace", "Turing", "Church") age <- choose(1,100) } yield Person(firstName, lastName, age)
scala> import org.scalacheck.Arbitrary import org.scalacheck.Arbitrary scala> implicit val arbPerson = Arbitrary(genPerson) arbPerson: org.scalacheck.Arbitrary[Person] = org.scalacheck.Arbitrary$$anon$1@1391f61c
scala> import org.scalacheck.Prop.forAll import org.scalacheck.Prop.forAll scala> val propPerson = forAll { p: Person => | p.isTeenager == (p.age >= 13 && p.age <= 19) | }
import org.scalacheck.Prop.forAll import org.scalacheck.Gen.choose val propNoPairs = forAll { xs: List[Byte] => forAll(choose(0, xs.length-2)) { i => xs(i) != xs(i+1) } }
scala> propNoPairs.check ! Falsified after 11 passed tests. > ARG_0: List("127", "127") > ARG_0_ORIGINAL: List("-104", "127", "127", "-1", "89") > ARG_1: 0
For more information about ScalaCheck: The Definitive Guide, please visit: http://www.artima.com/shop/scalacheck and: |
Copyright © 2013-2014 Artima, Inc. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. |