diff options
Diffstat (limited to 'src/scalacheck/org')
-rw-r--r-- | src/scalacheck/org/scalacheck/Arbitrary.scala | 426 | ||||
-rw-r--r-- | src/scalacheck/org/scalacheck/Arg.scala | 20 | ||||
-rw-r--r-- | src/scalacheck/org/scalacheck/Commands.scala | 148 | ||||
-rw-r--r-- | src/scalacheck/org/scalacheck/ConsoleReporter.scala | 52 | ||||
-rw-r--r-- | src/scalacheck/org/scalacheck/Gen.scala | 531 | ||||
-rw-r--r-- | src/scalacheck/org/scalacheck/Pretty.scala | 127 | ||||
-rw-r--r-- | src/scalacheck/org/scalacheck/Prop.scala | 763 | ||||
-rw-r--r-- | src/scalacheck/org/scalacheck/Properties.scala | 82 | ||||
-rw-r--r-- | src/scalacheck/org/scalacheck/Shrink.scala | 208 | ||||
-rw-r--r-- | src/scalacheck/org/scalacheck/Test.scala | 269 | ||||
-rw-r--r-- | src/scalacheck/org/scalacheck/util/Buildable.scala | 64 | ||||
-rw-r--r-- | src/scalacheck/org/scalacheck/util/CmdLineParser.scala | 101 | ||||
-rw-r--r-- | src/scalacheck/org/scalacheck/util/FreqMap.scala | 65 | ||||
-rw-r--r-- | src/scalacheck/org/scalacheck/util/StdRand.scala | 12 |
14 files changed, 0 insertions, 2868 deletions
diff --git a/src/scalacheck/org/scalacheck/Arbitrary.scala b/src/scalacheck/org/scalacheck/Arbitrary.scala deleted file mode 100644 index 8c43cdaafe..0000000000 --- a/src/scalacheck/org/scalacheck/Arbitrary.scala +++ /dev/null @@ -1,426 +0,0 @@ -/*-------------------------------------------------------------------------*\ -** ScalaCheck ** -** Copyright (c) 2007-2011 Rickard Nilsson. All rights reserved. ** -** http://www.scalacheck.org ** -** ** -** This software is released under the terms of the Revised BSD License. ** -** There is NO WARRANTY. See the file LICENSE for the full text. ** -\*------------------------------------------------------------------------ */ - -package org.scalacheck - -import util.{FreqMap,Buildable} -import scala.reflect.ClassTag - -sealed abstract class Arbitrary[T] { - val arbitrary: Gen[T] -} - -/** Defines implicit <code>Arbitrary</code> instances for common types. - * <p> - * ScalaCheck - * uses implicit <code>Arbitrary</code> instances when creating properties - * out of functions with the <code>Prop.property</code> method, and when - * the <code>Arbitrary.arbitrary</code> method is used. For example, the - * following code requires that there exists an implicit - * <code>Arbitrary[MyClass]</code> instance: - * </p> - * - * <p> - * <code> - * val myProp = Prop.forAll { myClass: MyClass =><br /> - * ...<br /> - * }<br /> - * - * val myGen = Arbitrary.arbitrary[MyClass] - * </code> - * </p> - * - * <p> - * The required implicit definition could look like this: - * </p> - * - * <p> - * <code> - * implicit val arbMyClass: Arbitrary[MyClass] = Arbitrary(...) - * </code> - * </p> - * - * <p> - * The factory method <code>Arbitrary(...)</code> takes a generator of type - * <code>Gen[T]</code> and returns an instance of <code>Arbitrary[T]</code>. - * </p> - * - * <p> - * The <code>Arbitrary</code> module defines implicit <code>Arbitrary</code> - * instances for common types, for convenient use in your properties and - * generators. - * </p> - */ -object Arbitrary { - - import Gen.{value, choose, sized, listOf, listOf1, - frequency, oneOf, containerOf, resize} - import util.StdRand - import scala.collection.{immutable, mutable} - import java.util.Date - - /** Creates an Arbitrary instance */ - def apply[T](g: => Gen[T]): Arbitrary[T] = new Arbitrary[T] { - lazy val arbitrary = g - } - - /** Returns an arbitrary generator for the type T. */ - def arbitrary[T](implicit a: Arbitrary[T]): Gen[T] = a.arbitrary - - /**** Arbitrary instances for each AnyVal ****/ - - /** Arbitrary AnyVal */ - implicit lazy val arbAnyVal: Arbitrary[AnyVal] = Arbitrary(oneOf( - arbitrary[Unit], arbitrary[Boolean], arbitrary[Char], arbitrary[Byte], - arbitrary[Short], arbitrary[Int], arbitrary[Long], arbitrary[Float], - arbitrary[Double] - )) - - /** Arbitrary instance of Boolean */ - implicit lazy val arbBool: Arbitrary[Boolean] = - Arbitrary(oneOf(true, false)) - - /** Arbitrary instance of Int */ - implicit lazy val arbInt: Arbitrary[Int] = Arbitrary( - Gen.chooseNum(Int.MinValue, Int.MaxValue) - ) - - /** Arbitrary instance of Long */ - implicit lazy val arbLong: Arbitrary[Long] = Arbitrary( - Gen.chooseNum(Long.MinValue / 2, Long.MaxValue / 2) - ) - - /** Arbitrary instance of Float */ - implicit lazy val arbFloat: Arbitrary[Float] = Arbitrary( - Gen.chooseNum( - Float.MinValue, Float.MaxValue - // I find that including these by default is a little TOO testy. - // Float.Epsilon, Float.NaN, Float.PositiveInfinity, Float.NegativeInfinity - ) - ) - - /** Arbitrary instance of Double */ - implicit lazy val arbDouble: Arbitrary[Double] = Arbitrary( - Gen.chooseNum( - Double.MinValue / 2, Double.MaxValue / 2 - // As above. Perhaps behind some option? - // Double.Epsilon, Double.NaN, Double.PositiveInfinity, Double.NegativeInfinity - ) - ) - - /** Arbitrary instance of Char */ - implicit lazy val arbChar: Arbitrary[Char] = Arbitrary( - Gen.frequency( - (0xD800-Char.MinValue, Gen.choose(Char.MinValue,0xD800-1)), - (Char.MaxValue-0xDFFF, Gen.choose(0xDFFF+1,Char.MaxValue)) - ) - ) - - /** Arbitrary instance of Byte */ - implicit lazy val arbByte: Arbitrary[Byte] = Arbitrary( - Gen.chooseNum(Byte.MinValue, Byte.MaxValue) - ) - - /** Arbitrary instance of Short */ - implicit lazy val arbShort: Arbitrary[Short] = Arbitrary( - Gen.chooseNum(Short.MinValue, Short.MaxValue) - ) - - /** Absolutely, totally, 100% arbitrarily chosen Unit. */ - implicit lazy val arbUnit: Arbitrary[Unit] = Arbitrary(value(())) - - /**** Arbitrary instances of other common types ****/ - - /** Arbitrary instance of String */ - implicit lazy val arbString: Arbitrary[String] = - Arbitrary(arbitrary[List[Char]] map (_.mkString)) - - /** Arbitrary instance of Date */ - implicit lazy val arbDate: Arbitrary[Date] = Arbitrary(for { - l <- arbitrary[Long] - d = new Date - } yield new Date(d.getTime + l)) - - /** Arbitrary instance of Throwable */ - implicit lazy val arbThrowable: Arbitrary[Throwable] = - Arbitrary(value(new Exception)) - - /** Arbitrary BigInt */ - implicit lazy val arbBigInt: Arbitrary[BigInt] = { - def chooseBigInt: Gen[BigInt] = sized((s: Int) => choose(-s, s)) map (x => BigInt(x)) - def chooseReallyBigInt = chooseBigInt.combine(choose(32, 128))((x, y) => Some(x.get << y.get)) - - Arbitrary( - frequency( - (5, chooseBigInt), - (10, chooseReallyBigInt), - (1, BigInt(0)), - (1, BigInt(1)), - (1, BigInt(-1)), - (1, BigInt(Int.MaxValue) + 1), - (1, BigInt(Int.MinValue) - 1), - (1, BigInt(Long.MaxValue)), - (1, BigInt(Long.MinValue)), - (1, BigInt(Long.MaxValue) + 1), - (1, BigInt(Long.MinValue) - 1) - ) - ) - } - - /** Arbitrary BigDecimal */ - implicit lazy val arbBigDecimal: Arbitrary[BigDecimal] = { - import java.math.MathContext._ - val mcGen = oneOf(UNLIMITED, DECIMAL32, DECIMAL64, DECIMAL128) - val bdGen = for { - x <- arbBigInt.arbitrary - mc <- mcGen - limit <- value(if(mc == UNLIMITED) 0 else math.max(x.abs.toString.length - mc.getPrecision, 0)) - scale <- Gen.chooseNum(Int.MinValue + limit , Int.MaxValue) - } yield BigDecimal(x, scale, mc) - Arbitrary(bdGen) - } - - /** Arbitrary java.lang.Number */ - implicit lazy val arbNumber: Arbitrary[Number] = { - val gen = Gen.oneOf( - arbitrary[Byte], arbitrary[Short], arbitrary[Int], arbitrary[Long], - arbitrary[Float], arbitrary[Double] - ) - Arbitrary(gen map (_.asInstanceOf[Number])) - // XXX TODO - restore BigInt and BigDecimal - // Arbitrary(oneOf(arbBigInt.arbitrary :: (arbs map (_.arbitrary) map toNumber) : _*)) - } - - /** Generates an arbitrary property */ - implicit lazy val arbProp: Arbitrary[Prop] = { - import Prop._ - val undecidedOrPassed = forAll { b: Boolean => - b ==> true - } - Arbitrary(frequency( - (4, falsified), - (4, passed), - (3, proved), - (3, undecidedOrPassed), - (2, undecided), - (1, exception(null)) - )) - } - - /** Arbitrary instance of test params */ - implicit lazy val arbTestParams: Arbitrary[Test.Params] = - Arbitrary(for { - minSuccTests <- choose(10,200) - maxDiscardRatio <- choose(0.2f,10f) - minSize <- choose(0,500) - sizeDiff <- choose(0,500) - maxSize <- choose(minSize, minSize + sizeDiff) - ws <- choose(1,4) - } yield Test.Params( - minSuccessfulTests = minSuccTests, - maxDiscardRatio = maxDiscardRatio, - minSize = minSize, - maxSize = maxSize, - workers = ws - )) - - /** Arbitrary instance of gen params */ - implicit lazy val arbGenParams: Arbitrary[Gen.Params] = - Arbitrary(for { - size <- arbitrary[Int] suchThat (_ >= 0) - } yield Gen.Params(size, StdRand)) - - /** Arbitrary instance of prop params */ - implicit lazy val arbPropParams: Arbitrary[Prop.Params] = - Arbitrary(for { - genPrms <- arbitrary[Gen.Params] - } yield Prop.Params(genPrms, FreqMap.empty[immutable.Set[Any]])) - - - // Higher-order types // - - /** Arbitrary instance of Gen */ - implicit def arbGen[T](implicit a: Arbitrary[T]): Arbitrary[Gen[T]] = - Arbitrary(frequency( - (5, arbitrary[T] map (value(_))), - (1, Gen.fail) - )) - - /** Arbitrary instance of option type */ - implicit def arbOption[T](implicit a: Arbitrary[T]): Arbitrary[Option[T]] = - Arbitrary(sized(n => if(n == 0) value(None) else resize(n - 1, arbitrary[T]).map(Some(_)))) - - implicit def arbEither[T, U](implicit at: Arbitrary[T], au: Arbitrary[U]): Arbitrary[Either[T, U]] = - Arbitrary(oneOf(arbitrary[T].map(Left(_)), arbitrary[U].map(Right(_)))) - - /** Arbitrary instance of immutable map */ - implicit def arbImmutableMap[T,U](implicit at: Arbitrary[T], au: Arbitrary[U] - ): Arbitrary[immutable.Map[T,U]] = Arbitrary( - for(seq <- arbitrary[Stream[(T,U)]]) yield immutable.Map(seq: _*) - ) - - /** Arbitrary instance of mutable map */ - implicit def arbMutableMap[T,U](implicit at: Arbitrary[T], au: Arbitrary[U] - ): Arbitrary[mutable.Map[T,U]] = Arbitrary( - for(seq <- arbitrary[Stream[(T,U)]]) yield mutable.Map(seq: _*) - ) - - /** Arbitrary instance of any buildable container (such as lists, arrays, - * streams, etc). The maximum size of the container depends on the size - * generation parameter. */ - implicit def arbContainer[C[_],T](implicit a: Arbitrary[T], b: Buildable[T,C] - ): Arbitrary[C[T]] = Arbitrary(containerOf[C,T](arbitrary[T])) - - /** Arbitrary instance of any array. */ - implicit def arbArray[T](implicit a: Arbitrary[T], c: ClassTag[T] - ): Arbitrary[Array[T]] = Arbitrary(containerOf[Array,T](arbitrary[T])) - - - // Functions // - - /** Arbitrary instance of Function1 */ - implicit def arbFunction1[T1,R](implicit a: Arbitrary[R] - ): Arbitrary[T1 => R] = Arbitrary( - for(r <- arbitrary[R]) yield (t1: T1) => r - ) - - /** Arbitrary instance of Function2 */ - implicit def arbFunction2[T1,T2,R](implicit a: Arbitrary[R] - ): Arbitrary[(T1,T2) => R] = Arbitrary( - for(r <- arbitrary[R]) yield (t1: T1, t2: T2) => r - ) - - /** Arbitrary instance of Function3 */ - implicit def arbFunction3[T1,T2,T3,R](implicit a: Arbitrary[R] - ): Arbitrary[(T1,T2,T3) => R] = Arbitrary( - for(r <- arbitrary[R]) yield (t1: T1, t2: T2, t3: T3) => r - ) - - /** Arbitrary instance of Function4 */ - implicit def arbFunction4[T1,T2,T3,T4,R](implicit a: Arbitrary[R] - ): Arbitrary[(T1,T2,T3,T4) => R] = Arbitrary( - for(r <- arbitrary[R]) yield (t1: T1, t2: T2, t3: T3, t4: T4) => r - ) - - /** Arbitrary instance of Function5 */ - implicit def arbFunction5[T1,T2,T3,T4,T5,R](implicit a: Arbitrary[R] - ): Arbitrary[(T1,T2,T3,T4,T5) => R] = Arbitrary( - for(r <- arbitrary[R]) yield (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5) => r - ) - - - // Tuples // - - /** Arbitrary instance of 2-tuple */ - implicit def arbTuple2[T1,T2](implicit - a1: Arbitrary[T1], a2: Arbitrary[T2] - ): Arbitrary[(T1,T2)] = - Arbitrary(for { - t1 <- arbitrary[T1] - t2 <- arbitrary[T2] - } yield (t1,t2)) - - /** Arbitrary instance of 3-tuple */ - implicit def arbTuple3[T1,T2,T3](implicit - a1: Arbitrary[T1], a2: Arbitrary[T2], a3: Arbitrary[T3] - ): Arbitrary[(T1,T2,T3)] = - Arbitrary(for { - t1 <- arbitrary[T1] - t2 <- arbitrary[T2] - t3 <- arbitrary[T3] - } yield (t1,t2,t3)) - - /** Arbitrary instance of 4-tuple */ - implicit def arbTuple4[T1,T2,T3,T4](implicit - a1: Arbitrary[T1], a2: Arbitrary[T2], a3: Arbitrary[T3], a4: Arbitrary[T4] - ): Arbitrary[(T1,T2,T3,T4)] = - Arbitrary(for { - t1 <- arbitrary[T1] - t2 <- arbitrary[T2] - t3 <- arbitrary[T3] - t4 <- arbitrary[T4] - } yield (t1,t2,t3,t4)) - - /** Arbitrary instance of 5-tuple */ - implicit def arbTuple5[T1,T2,T3,T4,T5](implicit - a1: Arbitrary[T1], a2: Arbitrary[T2], a3: Arbitrary[T3], a4: Arbitrary[T4], - a5: Arbitrary[T5] - ): Arbitrary[(T1,T2,T3,T4,T5)] = - Arbitrary(for { - t1 <- arbitrary[T1] - t2 <- arbitrary[T2] - t3 <- arbitrary[T3] - t4 <- arbitrary[T4] - t5 <- arbitrary[T5] - } yield (t1,t2,t3,t4,t5)) - - /** Arbitrary instance of 6-tuple */ - implicit def arbTuple6[T1,T2,T3,T4,T5,T6](implicit - a1: Arbitrary[T1], a2: Arbitrary[T2], a3: Arbitrary[T3], a4: Arbitrary[T4], - a5: Arbitrary[T5], a6: Arbitrary[T6] - ): Arbitrary[(T1,T2,T3,T4,T5,T6)] = - Arbitrary(for { - t1 <- arbitrary[T1] - t2 <- arbitrary[T2] - t3 <- arbitrary[T3] - t4 <- arbitrary[T4] - t5 <- arbitrary[T5] - t6 <- arbitrary[T6] - } yield (t1,t2,t3,t4,t5,t6)) - - /** Arbitrary instance of 7-tuple */ - implicit def arbTuple7[T1,T2,T3,T4,T5,T6,T7](implicit - a1: Arbitrary[T1], a2: Arbitrary[T2], a3: Arbitrary[T3], a4: Arbitrary[T4], - a5: Arbitrary[T5], a6: Arbitrary[T6], a7: Arbitrary[T7] - ): Arbitrary[(T1,T2,T3,T4,T5,T6,T7)] = - Arbitrary(for { - t1 <- arbitrary[T1] - t2 <- arbitrary[T2] - t3 <- arbitrary[T3] - t4 <- arbitrary[T4] - t5 <- arbitrary[T5] - t6 <- arbitrary[T6] - t7 <- arbitrary[T7] - } yield (t1,t2,t3,t4,t5,t6,t7)) - - /** Arbitrary instance of 8-tuple */ - implicit def arbTuple8[T1,T2,T3,T4,T5,T6,T7,T8](implicit - a1: Arbitrary[T1], a2: Arbitrary[T2], a3: Arbitrary[T3], a4: Arbitrary[T4], - a5: Arbitrary[T5], a6: Arbitrary[T6], a7: Arbitrary[T7], a8: Arbitrary[T8] - ): Arbitrary[(T1,T2,T3,T4,T5,T6,T7,T8)] = - Arbitrary(for { - t1 <- arbitrary[T1] - t2 <- arbitrary[T2] - t3 <- arbitrary[T3] - t4 <- arbitrary[T4] - t5 <- arbitrary[T5] - t6 <- arbitrary[T6] - t7 <- arbitrary[T7] - t8 <- arbitrary[T8] - } yield (t1,t2,t3,t4,t5,t6,t7,t8)) - - /** Arbitrary instance of 9-tuple */ - implicit def arbTuple9[T1,T2,T3,T4,T5,T6,T7,T8,T9](implicit - a1: Arbitrary[T1], a2: Arbitrary[T2], a3: Arbitrary[T3], a4: Arbitrary[T4], - a5: Arbitrary[T5], a6: Arbitrary[T6], a7: Arbitrary[T7], a8: Arbitrary[T8], - a9: Arbitrary[T9] - ): Arbitrary[(T1,T2,T3,T4,T5,T6,T7,T8,T9)] = - Arbitrary(for { - t1 <- arbitrary[T1] - t2 <- arbitrary[T2] - t3 <- arbitrary[T3] - t4 <- arbitrary[T4] - t5 <- arbitrary[T5] - t6 <- arbitrary[T6] - t7 <- arbitrary[T7] - t8 <- arbitrary[T8] - t9 <- arbitrary[T9] - } yield (t1,t2,t3,t4,t5,t6,t7,t8,t9)) - -} diff --git a/src/scalacheck/org/scalacheck/Arg.scala b/src/scalacheck/org/scalacheck/Arg.scala deleted file mode 100644 index 8959211f09..0000000000 --- a/src/scalacheck/org/scalacheck/Arg.scala +++ /dev/null @@ -1,20 +0,0 @@ -/*-------------------------------------------------------------------------*\ -** ScalaCheck ** -** Copyright (c) 2007-2011 Rickard Nilsson. All rights reserved. ** -** http://www.scalacheck.org ** -** ** -** This software is released under the terms of the Revised BSD License. ** -** There is NO WARRANTY. See the file LICENSE for the full text. ** -\*------------------------------------------------------------------------ */ - -package org.scalacheck - -case class Arg[+T]( - label: String, - arg: T, - shrinks: Int, - origArg: T -)(implicit prettyPrinter: T => Pretty) { - lazy val prettyArg: Pretty = prettyPrinter(arg) - lazy val prettyOrigArg: Pretty = prettyPrinter(origArg) -} diff --git a/src/scalacheck/org/scalacheck/Commands.scala b/src/scalacheck/org/scalacheck/Commands.scala deleted file mode 100644 index 88ef8ae2a1..0000000000 --- a/src/scalacheck/org/scalacheck/Commands.scala +++ /dev/null @@ -1,148 +0,0 @@ -/*-------------------------------------------------------------------------*\ -** ScalaCheck ** -** Copyright (c) 2007-2011 Rickard Nilsson. All rights reserved. ** -** http://www.scalacheck.org ** -** ** -** This software is released under the terms of the Revised BSD License. ** -** There is NO WARRANTY. See the file LICENSE for the full text. ** -\*------------------------------------------------------------------------ */ - -package org.scalacheck - -import Gen._ -import Prop._ -import Shrink._ - -/** See User Guide for usage examples */ -trait Commands extends Prop { - - /** The abstract state data type. This type must be immutable. - * The state type that encodes the abstract state. The abstract state - * should model all the features we need from the real state, the system - * under test. We should leave out all details that aren't needed for - * specifying our pre- and postconditions. The state type must be called - * State and be immutable. */ - type State <: AnyRef - - class Binding(private val key: State) { - def get: Any = bindings.find(_._1 eq key) match { - case None => sys.error("No value bound") - case Some(x) => x._2 - } - } - - /** Abstract commands are defined as subtypes of the traits Command or SetCommand. - * Each command must have a run method and a method that returns the new abstract - * state, as it should look after the command has been run. - * A command can also define a precondition that states how the current - * abstract state must look if the command should be allowed to run. - * Finally, we can also define a postcondition which verifies that the - * system under test is in a correct state after the command exectution. */ - trait Command { - - /** Used internally. */ - protected[Commands] def run_(s: State) = run(s) - - def run(s: State): Any - def nextState(s: State): State - - /** Returns all preconditions merged into a single function */ - def preCondition: (State => Boolean) = s => preConditions.toList.forall(_.apply(s)) - - /** A precondition is a function that - * takes the current abstract state as parameter and returns a boolean - * that says if the precondition is fulfilled or not. You can add several - * conditions to the precondition list */ - val preConditions = new scala.collection.mutable.ListBuffer[State => Boolean] - - /** Returns all postconditions merged into a single function */ - def postCondition: (State,State,Any) => Prop = (s0,s1,r) => all(postConditions.map(_.apply(s0,s1,r)): _*) - - /** A postcondition is a function that - * takes three parameters, s0, s1 and r. s0 is the abstract state before - * the command was run, s1 is the abstract state after the command was - * run, and r is the result from the command's run - * method. The postcondition function should return a Boolean (or - * a Prop instance) that says if the condition holds or not. You can add several - * conditions to the postConditions list. */ - val postConditions = new scala.collection.mutable.ListBuffer[(State,State,Any) => Prop] - } - - /** A command that binds its result for later use */ - trait SetCommand extends Command { - /** Used internally. */ - protected[Commands] final override def run_(s: State) = { - val r = run(s) - bindings += ((s,r)) - r - } - - final def nextState(s: State) = nextState(s, new Binding(s)) - def nextState(s: State, b: Binding): State - } - - private case class Cmds(cs: List[Command], ss: List[State]) { - override def toString = cs.map(_.toString).mkString(", ") - } - - private val bindings = new scala.collection.mutable.ListBuffer[(State,Any)] - - private def initState() = { - bindings.clear() - initialState() - } - - private def genCmds: Gen[Cmds] = { - def sizedCmds(s: State)(sz: Int): Gen[Cmds] = - if(sz <= 0) value(Cmds(Nil, Nil)) else for { - c <- genCommand(s) suchThat (_.preCondition(s)) - Cmds(cs,ss) <- sizedCmds(c.nextState(s))(sz-1) - } yield Cmds(c::cs, s::ss) - - for { - s0 <- wrap(value(initialState())) - cmds <- sized(sizedCmds(s0)) - } yield cmds - } - - private def validCmds(s: State, cs: List[Command]): Option[Cmds] = - cs match { - case Nil => Some(Cmds(Nil, s::Nil)) - case c::_ if !c.preCondition(s) => None - case c::cmds => for { - Cmds(_, ss) <- validCmds(c.nextState(s), cmds) - } yield Cmds(cs, s::ss) - } - - private def runCommands(cmds: Cmds): Prop = cmds match { - case Cmds(Nil, _) => proved - case Cmds(c::cs, s::ss) => - c.postCondition(s,c.nextState(s),c.run_(s)) && runCommands(Cmds(cs,ss)) - case _ => sys.error("Should not be here") - } - - private def commandsProp: Prop = { - def shrinkCmds(cmds: Cmds) = cmds match { case Cmds(cs,_) => - shrink(cs)(shrinkContainer).flatMap(cs => validCmds(initialState(), cs).toList) - } - - forAllShrink(genCmds label "COMMANDS", shrinkCmds)(runCommands _) - } - - def apply(p: Prop.Params) = commandsProp(p) - - /** initialState should reset the system under test to a well defined - * initial state, and return the abstract version of that state. */ - def initialState(): State - - /** The command generator. Given an abstract state, the generator - * should return a command that is allowed to run in that state. Note that - * it is still neccessary to define preconditions on the commands if there - * are any. The generator is just giving a hint of which commands that are - * suitable for a given state, the preconditions will still be checked before - * a command runs. Sometimes you maybe want to adjust the distribution of - * your command generator according to the state, or do other calculations - * based on the state. */ - def genCommand(s: State): Gen[Command] - -} diff --git a/src/scalacheck/org/scalacheck/ConsoleReporter.scala b/src/scalacheck/org/scalacheck/ConsoleReporter.scala deleted file mode 100644 index 93f1dc222e..0000000000 --- a/src/scalacheck/org/scalacheck/ConsoleReporter.scala +++ /dev/null @@ -1,52 +0,0 @@ -/*-------------------------------------------------------------------------*\ -** ScalaCheck ** -** Copyright (c) 2007-2011 Rickard Nilsson. All rights reserved. ** -** http://www.scalacheck.org ** -** ** -** This software is released under the terms of the Revised BSD License. ** -** There is NO WARRANTY. See the file LICENSE for the full text. ** -\*------------------------------------------------------------------------ */ - -package org.scalacheck - -import Pretty._ -import util.FreqMap - -class ConsoleReporter(val verbosity: Int) extends Test.TestCallback { - - private val prettyPrms = Params(verbosity) - - override def onTestResult(name: String, res: Test.Result) = { - if(verbosity > 0) { - if(name == "") { - val s = (if(res.passed) "+ " else "! ") + pretty(res, prettyPrms) - printf("\r%s\n", format(s, "", "", 75)) - } else { - val s = (if(res.passed) "+ " else "! ") + name + ": " + - pretty(res, prettyPrms) - printf("\r%s\n", format(s, "", "", 75)) - } - } - } - -} - -object ConsoleReporter { - - /** Factory method, creates a ConsoleReporter with the - * the given verbosity */ - def apply(verbosity: Int = 0) = new ConsoleReporter(verbosity) - - def testStatsEx(msg: String, res: Test.Result) = { - lazy val m = if(msg.length == 0) "" else msg + ": " - res.status match { - case Test.Proved(_) => {} - case Test.Passed => {} - case f @ Test.Failed(_, _) => sys.error(m + f) - case Test.Exhausted => {} - case f @ Test.GenException(_) => sys.error(m + f) - case f @ Test.PropException(_, _, _) => sys.error(m + f) - } - } - -} diff --git a/src/scalacheck/org/scalacheck/Gen.scala b/src/scalacheck/org/scalacheck/Gen.scala deleted file mode 100644 index 64bb61c2d3..0000000000 --- a/src/scalacheck/org/scalacheck/Gen.scala +++ /dev/null @@ -1,531 +0,0 @@ -/*-------------------------------------------------------------------------*\ -** ScalaCheck ** -** Copyright (c) 2007-2011 Rickard Nilsson. All rights reserved. ** -** http://www.scalacheck.org ** -** ** -** This software is released under the terms of the Revised BSD License. ** -** There is NO WARRANTY. See the file LICENSE for the full text. ** -\*------------------------------------------------------------------------ */ - -package org.scalacheck - -import scala.collection.mutable.ListBuffer -import util.Buildable -import Prop._ -import Arbitrary._ - -trait Choose[T] { - def choose(min: T, max: T): Gen[T] -} - -object Choose { - import Gen.{fail, parameterized, value} - - implicit val chooseLong: Choose[Long] = new Choose[Long] { - def choose(low: Long, high: Long) = - if(low > high || (high-low < 0)) fail - else parameterized(prms => value(prms.choose(low,high))) - } - - implicit val chooseDouble: Choose[Double] = new Choose[Double] { - def choose(low: Double, high: Double) = - if (low > high || (high-low > Double.MaxValue)) fail - else parameterized(prms => value(prms.choose(low,high))) - } - - implicit val chooseInt: Choose[Int] = new Choose[Int] { - def choose(low: Int, high: Int) = - chooseLong.choose(low, high).map(_.toInt) - } - - implicit val chooseByte: Choose[Byte] = new Choose[Byte] { - def choose(low: Byte, high: Byte) = - chooseLong.choose(low, high).map(_.toByte) - } - - implicit val chooseShort: Choose[Short] = new Choose[Short] { - def choose(low: Short, high: Short) = - chooseLong.choose(low, high).map(_.toShort) - } - - implicit val chooseChar: Choose[Char] = new Choose[Char] { - def choose(low: Char, high: Char) = - chooseLong.choose(low, high).map(_.toChar) - } - - implicit val chooseFloat: Choose[Float] = new Choose[Float] { - def choose(low: Float, high: Float) = - chooseDouble.choose(low, high).map(_.toFloat) - } -} - -case class FiniteGenRes[+T]( - r: T -) - -sealed trait FiniteGen[+T] extends Gen[FiniteGenRes[T]] - - -/** Class that represents a generator. */ -sealed trait Gen[+T] { - - import Gen.choose - - var label = "" // TODO: Ugly mutable field - - /** Put a label on the generator to make test reports clearer */ - def label(l: String): Gen[T] = { - label = l - this - } - - /** Put a label on the generator to make test reports clearer */ - def :|(l: String) = label(l) - - /** Put a label on the generator to make test reports clearer */ - def |:(l: String) = label(l) - - /** Put a label on the generator to make test reports clearer */ - def :|(l: Symbol) = label(l.toString.drop(1)) - - /** Put a label on the generator to make test reports clearer */ - def |:(l: Symbol) = label(l.toString.drop(1)) - - def apply(prms: Gen.Params): Option[T] - - def map[U](f: T => U): Gen[U] = Gen(prms => this(prms).map(f)).label(label) - - def map2[U, V](g: Gen[U])(f: (T, U) => V) = - combine(g)((t, u) => t.flatMap(t => u.flatMap(u => Some(f(t, u))))) - - def map3[U, V, W](gu: Gen[U], gv: Gen[V])(f: (T, U, V) => W) = - combine3(gu, gv)((t, u, v) => t.flatMap(t => u.flatMap(u => v.flatMap(v => Some(f(t, u, v)))))) - - def map4[U, V, W, X](gu: Gen[U], gv: Gen[V], gw: Gen[W])(f: (T, U, V, W) => X) = - combine4(gu, gv, gw)((t, u, v, w) => t.flatMap(t => u.flatMap(u => v.flatMap(v => w.flatMap(w => Some(f(t, u, v, w))))))) - - def map5[U, V, W, X, Y](gu: Gen[U], gv: Gen[V], gw: Gen[W], gx: Gen[X])(f: (T, U, V, W, X) => Y) = - combine5(gu, gv, gw, gx)((t, u, v, w, x) => t.flatMap(t => u.flatMap(u => v.flatMap(v => w.flatMap(w => x.flatMap(x => Some(f(t, u, v, w, x)))))))) - - def map6[U, V, W, X, Y, Z](gu: Gen[U], gv: Gen[V], gw: Gen[W], gx: Gen[X], gy: Gen[Y])(f: (T, U, V, W, X, Y) => Z) = - combine6(gu, gv, gw, gx, gy)((t, u, v, w, x, y) => t.flatMap(t => u.flatMap(u => v.flatMap(v => w.flatMap(w => x.flatMap(x => y.flatMap(y => Some(f(t, u, v, w, x, y))))))))) - - def flatMap[U](f: T => Gen[U]): Gen[U] = Gen(prms => for { - t <- this(prms) - u <- f(t)(prms) - } yield u) - - def filter(p: T => Boolean): Gen[T] = Gen(prms => for { - t <- this(prms) - u <- if (p(t)) Some(t) else None - } yield u).label(label) - - def withFilter(p: T => Boolean) = new GenWithFilter[T](this, p) - - final class GenWithFilter[+A](self: Gen[A], p: A => Boolean) { - def map[B](f: A => B): Gen[B] = self filter p map f - def flatMap[B](f: A => Gen[B]): Gen[B] = self filter p flatMap f - def withFilter(q: A => Boolean): GenWithFilter[A] = new GenWithFilter[A](self, x => p(x) && q(x)) - } - - def suchThat(p: T => Boolean): Gen[T] = filter(p) - - def combine[U,V](g: Gen[U])(f: (Option[T],Option[U]) => Option[V]): Gen[V] = - Gen(prms => f(this(prms), g(prms))) - - def combine3[U, V, W](gu: Gen[U], gv: Gen[V]) - (f: (Option[T], Option[U], Option[V]) => Option[W]) = - Gen(prms => f(this(prms), gu(prms), gv(prms))) - - def combine4[U, V, W, X](gu: Gen[U], gv: Gen[V], gw: Gen[W]) - (f: (Option[T], Option[U], Option[V], Option[W]) => Option[X]) = - Gen(prms => f(this(prms), gu(prms), gv(prms), gw(prms))) - - def combine5[U, V, W, X, Y](gu: Gen[U], gv: Gen[V], gw: Gen[W], gx: Gen[X]) - (f: (Option[T], Option[U], Option[V], Option[W], Option[X]) => Option[Y]) = - Gen(prms => f(this(prms), gu(prms), gv(prms), gw(prms), gx(prms))) - - def combine6[U, V, W, X, Y, Z](gu: Gen[U], gv: Gen[V], gw: Gen[W], gx: Gen[X], gy: Gen[Y]) - (f: (Option[T], Option[U], Option[V], Option[W], Option[X], Option[Y]) => Option[Z]) = - Gen(prms => f(this(prms), gu(prms), gv(prms), gw(prms), gx(prms), gy(prms))) - - def ap[U](g: Gen[T => U]) = flatMap(t => g.flatMap(u => Gen(p => Some(u(t))))) - - override def toString = - if(label.length == 0) "Gen()" else "Gen(\"" + label + "\")" - - /** Returns a new property that holds if and only if both this - * and the given generator generates the same result, or both - * generators generate no result. */ - def ==[U](g: Gen[U]) = Prop(prms => - (this(prms.genPrms), g(prms.genPrms)) match { - case (None,None) => proved(prms) - case (Some(r1),Some(r2)) if r1 == r2 => proved(prms) - case _ => falsified(prms) - } - ) - - def !=[U](g: Gen[U]) = forAll(this)(r => forAll(g)(_ != r)) - - def !==[U](g: Gen[U]) = Prop(prms => - (this(prms.genPrms), g(prms.genPrms)) match { - case (None,None) => falsified(prms) - case (Some(r1),Some(r2)) if r1 == r2 => falsified(prms) - case _ => proved(prms) - } - ) - - private var freq = 1 - def |[U >: T](g: Gen[U]): Gen[U] = { - val h = Gen.frequency((freq, this), (1, g)) - h.freq = freq+1 - h - } - - /** Generates a sample value by using default parameters */ - def sample: Option[T] = apply(Gen.Params()) - -} - - -/** Contains combinators for building generators. */ -object Gen { - - import Arbitrary._ - import Shrink._ - - /** Record that encapsulates all parameters required for data generation */ - case class Params( - size: Int = 100, - rng: java.util.Random = util.StdRand - ) { - def resize(newSize: Int) = this.copy(size = newSize) - - /** @throws IllegalArgumentException if l is greater than h, or if - * the range between l and h doesn't fit in a Long. */ - def choose(l: Long, h: Long): Long = { - val d = h-l - if (d < 0) throw new IllegalArgumentException("Invalid range") - else l + math.abs(rng.nextLong % (d+1)) - } - - /** @throws IllegalArgumentException if l is greater than h, or if - * the range between l and h doesn't fit in a Double. */ - def choose(l: Double, h: Double) = { - val d = h-l - if (d < 0 || d > Double.MaxValue) - throw new IllegalArgumentException("Invalid range") - else if (d == 0) l - else rng.nextDouble * (h-l) + l - } - } - - /* Generator factory method */ - def apply[T](g: Gen.Params => Option[T]) = new Gen[T] { - def apply(p: Gen.Params) = g(p) - } - - /* Convenience method for using the <code>frequency</code> method like this: - * <code>frequency((1, "foo"), (3, "bar"))</code> */ - implicit def freqTuple[T](t: (Int, T)): (Int, Gen[T]) = (t._1, value(t._2)) - - - //// Various Generator Combinators //// - - /** Sequences generators. If any of the given generators fails, the - * resulting generator will also fail. */ - def sequence[C[_],T](gs: Iterable[Gen[T]])(implicit b: Buildable[T,C]): Gen[C[T]] = Gen(prms => { - val builder = b.builder - var none = false - val xs = gs.iterator - while(xs.hasNext && !none) xs.next.apply(prms) match { - case None => none = true - case Some(x) => builder += x - } - if(none) None else Some(builder.result()) - }) - - /** Wraps a generator lazily. The given parameter is only evalutated once, - * and not until the wrapper generator is evaluated. */ - def lzy[T](g: => Gen[T]) = new Gen[T] { - lazy val h = g - def apply(prms: Params) = h(prms) - } - - /** Wraps a generator for later evaluation. The given parameter is - * evaluated each time the wrapper generator is evaluated. */ - def wrap[T](g: => Gen[T]) = Gen(p => g(p)) - - /** A generator that always generates the given value */ - implicit def value[T](x: T) = Gen(p => Some(x)) - - /** A generator that never generates a value */ - def fail[T]: Gen[T] = Gen(p => None) - - /** A generator that generates a random value in the given (inclusive) - * range. If the range is invalid, the generator will not generate any value. - */ - def choose[T](min: T, max: T)(implicit c: Choose[T]): Gen[T] = { - c.choose(min, max) - } - - /** Creates a generator that can access its generation parameters */ - def parameterized[T](f: Params => Gen[T]): Gen[T] = Gen(prms => f(prms)(prms)) - - /** Creates a generator that can access its generation size */ - def sized[T](f: Int => Gen[T]) = parameterized(prms => f(prms.size)) - - /** Creates a resized version of a generator */ - def resize[T](s: Int, g: Gen[T]) = Gen(prms => g(prms.resize(s))) - - /** Chooses one of the given generators with a weighted random distribution */ - def frequency[T](gs: (Int,Gen[T])*): Gen[T] = { - lazy val tot = (gs.map(_._1) :\ 0) (_+_) - - def pick(n: Int, l: List[(Int,Gen[T])]): Gen[T] = l match { - case Nil => fail - case (k,g)::gs => if(n <= k) g else pick(n-k, gs) - } - - for { - n <- choose(1,tot) - x <- pick(n,gs.toList) - } yield x - } - - /** Picks a random value from a list */ - def oneOf[T](xs: Seq[T]): Gen[T] = if(xs.isEmpty) fail else for { - i <- choose(0, xs.size-1) - } yield xs(i) - - /** Picks a random generator from a list */ - def oneOf[T](g1: Gen[T], g2: Gen[T], gs: Gen[T]*) = for { - i <- choose(0, gs.length+1) - x <- if(i == 0) g1 else if(i == 1) g2 else gs(i-2) - } yield x - - - //// List Generators //// - - /** Generates a container of any type for which there exists an implicit - * <code>Buildable</code> instance. The elements in the container will - * be generated by the given generator. The size of the generated container - * is given by <code>n</code>. */ - def containerOfN[C[_],T](n: Int, g: Gen[T])(implicit b: Buildable[T,C] - ): Gen[C[T]] = sequence[C,T](new Iterable[Gen[T]] { - def iterator = new Iterator[Gen[T]] { - var i = 0 - def hasNext = i < n - def next = { i += 1; g } - } - }) - - /** Generates a container of any type for which there exists an implicit - * <code>Buildable</code> instance. The elements in the container will - * be generated by the given generator. The size of the container is - * bounded by the size parameter used when generating values. */ - def containerOf[C[_],T](g: Gen[T])(implicit b: Buildable[T,C]): Gen[C[T]] = - sized(size => for(n <- choose(0,size); c <- containerOfN[C,T](n,g)) yield c) - - /** Generates a non-empty container of any type for which there exists an - * implicit <code>Buildable</code> instance. The elements in the container - * will be generated by the given generator. The size of the container is - * bounded by the size parameter used when generating values. */ - def containerOf1[C[_],T](g: Gen[T])(implicit b: Buildable[T,C]): Gen[C[T]] = - sized(size => for(n <- choose(1,size); c <- containerOfN[C,T](n,g)) yield c) - - /** Generates a list of random length. The maximum length depends on the - * size parameter. This method is equal to calling - * <code>containerOf[List,T](g)</code>. */ - def listOf[T](g: => Gen[T]) = containerOf[List,T](g) - - /** Generates a non-empty list of random length. The maximum length depends - * on the size parameter. This method is equal to calling - * <code>containerOf1[List,T](g)</code>. */ - def listOf1[T](g: => Gen[T]) = containerOf1[List,T](g) - - /** Generates a list of the given length. This method is equal to calling - * <code>containerOfN[List,T](n,g)</code>. */ - def listOfN[T](n: Int, g: Gen[T]) = containerOfN[List,T](n,g) - - /** A generator that picks a random number of elements from a list */ - def someOf[T](l: Iterable[T]) = choose(0,l.size) flatMap (pick(_,l)) - - /** A generator that picks a random number of elements from a list */ - def someOf[T](g1: Gen[T], g2: Gen[T], gs: Gen[T]*) = for { - n <- choose(0, gs.length+2) - x <- pick(n, g1, g2, gs: _*) - } yield x - - /** A generator that picks a given number of elements from a list, randomly */ - def pick[T](n: Int, l: Iterable[T]): Gen[Seq[T]] = - if(n > l.size || n < 0) fail - else Gen(prms => { - val buf = new ListBuffer[T] - buf ++= l - while(buf.length > n) { - val g = choose(0, buf.length-1) - buf.remove(g(prms).get) - } - Some(buf) - }) - - /** A generator that picks a given number of elements from a list, randomly */ - def pick[T](n: Int, g1: Gen[T], g2: Gen[T], gs: Gen[T]*): Gen[Seq[T]] = for { - is <- pick(n, 0 until (gs.size+2)) - allGs = gs ++ (g1::g2::Nil) - xs <- sequence[List,T](is.toList.map(allGs(_))) - } yield xs - - - //// Character Generators //// - - /* Generates a numerical character */ - def numChar: Gen[Char] = choose(48,57) map (_.toChar) - - /* Generates an upper-case alpha character */ - def alphaUpperChar: Gen[Char] = choose(65,90) map (_.toChar) - - /* Generates a lower-case alpha character */ - def alphaLowerChar: Gen[Char] = choose(97,122) map (_.toChar) - - /* Generates an alpha character */ - def alphaChar = frequency((1,alphaUpperChar), (9,alphaLowerChar)) - - /* Generates an alphanumerical character */ - def alphaNumChar = frequency((1,numChar), (9,alphaChar)) - - //// String Generators //// - - /* Generates a string that starts with a lower-case alpha character, - * and only contains alphanumerical characters */ - def identifier: Gen[String] = for { - c <- alphaLowerChar - cs <- listOf(alphaNumChar) - } yield (c::cs).mkString - - /* Generates a string of alpha characters */ - def alphaStr: Gen[String] = for(cs <- listOf(Gen.alphaChar)) yield cs.mkString - - /* Generates a string of digits */ - def numStr: Gen[String] = for(cs <- listOf(Gen.numChar)) yield cs.mkString - - //// Number Generators //// - - /** Generates positive numbers of uniform distribution, with an - * upper bound of the generation size parameter. */ - def posNum[T](implicit num: Numeric[T], c: Choose[T]): Gen[T] = { - import num._ - sized(max => c.choose(one, fromInt(max))) - } - - /** Generates negative numbers of uniform distribution, with an - * lower bound of the negated generation size parameter. */ - def negNum[T](implicit num: Numeric[T], c: Choose[T]): Gen[T] = { - import num._ - sized(max => c.choose(-fromInt(max), -one)) - } - - /** Generates numbers within the given inclusive range, with - * extra weight on zero, +/- unity, both extremities, and any special - * numbers provided. The special numbers must lie within the given range, - * otherwise they won't be included. */ - def chooseNum[T](minT: T, maxT: T, specials: T*)( - implicit num: Numeric[T], c: Choose[T] - ): Gen[T] = { - import num._ - val basics = List(minT, maxT, zero, one, -one) - val basicsAndSpecials = for { - t <- specials ++ basics if t >= minT && t <= maxT - } yield (1, value(t)) - val allGens = basicsAndSpecials ++ List( - (basicsAndSpecials.length, c.choose(minT, maxT)) - ) - frequency(allGens: _*) - } - - /** Takes a function and returns a generator that generates arbitrary - * results of that function by feeding it with arbitrarily generated input - * parameters. */ - def resultOf[T,R](f: T => R)(implicit a: Arbitrary[T]): Gen[R] = - arbitrary[T] map f - - /** Takes a function and returns a generator that generates arbitrary - * results of that function by feeding it with arbitrarily generated input - * parameters. */ - def resultOf[T1,T2,R](f: (T1,T2) => R)(implicit - a1: Arbitrary[T1], a2: Arbitrary[T2] - ): Gen[R] = arbitrary[T1] flatMap { t => resultOf(f(t, _:T2)) } - - /** Takes a function and returns a generator that generates arbitrary - * results of that function by feeding it with arbitrarily generated input - * parameters. */ - def resultOf[T1,T2,T3,R](f: (T1,T2,T3) => R)(implicit - a1: Arbitrary[T1], a2: Arbitrary[T2], a3: Arbitrary[T3] - ): Gen[R] = arbitrary[T1] flatMap { t => resultOf(f(t, _:T2, _:T3)) } - - /** Takes a function and returns a generator that generates arbitrary - * results of that function by feeding it with arbitrarily generated input - * parameters. */ - def resultOf[T1,T2,T3,T4,R](f: (T1,T2,T3,T4) => R)(implicit - a1: Arbitrary[T1], a2: Arbitrary[T2], a3: Arbitrary[T3], a4: Arbitrary[T4] - ): Gen[R] = arbitrary[T1] flatMap { - t => resultOf(f(t, _:T2, _:T3, _:T4)) - } - - /** Takes a function and returns a generator that generates arbitrary - * results of that function by feeding it with arbitrarily generated input - * parameters. */ - def resultOf[T1,T2,T3,T4,T5,R](f: (T1,T2,T3,T4,T5) => R)(implicit - a1: Arbitrary[T1], a2: Arbitrary[T2], a3: Arbitrary[T3], a4: Arbitrary[T4], - a5: Arbitrary[T5] - ): Gen[R] = arbitrary[T1] flatMap { - t => resultOf(f(t, _:T2, _:T3, _:T4, _:T5)) - } - - /** Takes a function and returns a generator that generates arbitrary - * results of that function by feeding it with arbitrarily generated input - * parameters. */ - def resultOf[T1,T2,T3,T4,T5,T6,R]( - f: (T1,T2,T3,T4,T5,T6) => R)(implicit - a1: Arbitrary[T1], a2: Arbitrary[T2], a3: Arbitrary[T3], - a4: Arbitrary[T4], a5: Arbitrary[T5], a6: Arbitrary[T6] - ): Gen[R] = arbitrary[T1] flatMap { - t => resultOf(f(t, _:T2, _:T3, _:T4, _:T5, _:T6)) - } - - /** Takes a function and returns a generator that generates arbitrary - * results of that function by feeding it with arbitrarily generated input - * parameters. */ - def resultOf[T1,T2,T3,T4,T5,T6,T7,R]( - f: (T1,T2,T3,T4,T5,T6,T7) => R)(implicit - a1: Arbitrary[T1], a2: Arbitrary[T2], a3: Arbitrary[T3], - a4: Arbitrary[T4], a5: Arbitrary[T5], a6: Arbitrary[T6], a7: Arbitrary[T7] - ): Gen[R] = arbitrary[T1] flatMap { - t => resultOf(f(t, _:T2, _:T3, _:T4, _:T5, _:T6, _:T7)) - } - - /** Takes a function and returns a generator that generates arbitrary - * results of that function by feeding it with arbitrarily generated input - * parameters. */ - def resultOf[T1,T2,T3,T4,T5,T6,T7,T8,R]( - f: (T1,T2,T3,T4,T5,T6,T7,T8) => R)(implicit - a1: Arbitrary[T1], a2: Arbitrary[T2], a3: Arbitrary[T3], a4: Arbitrary[T4], - a5: Arbitrary[T5], a6: Arbitrary[T6], a7: Arbitrary[T7], a8: Arbitrary[T8] - ): Gen[R] = arbitrary[T1] flatMap { - t => resultOf(f(t, _:T2, _:T3, _:T4, _:T5, _:T6, _:T7, _:T8)) - } - - /** Takes a function and returns a generator that generates arbitrary - * results of that function by feeding it with arbitrarily generated input - * parameters. */ - def resultOf[T1,T2,T3,T4,T5,T6,T7,T8,T9,R]( - f: (T1,T2,T3,T4,T5,T6,T7,T8,T9) => R)(implicit - a1: Arbitrary[T1], a2: Arbitrary[T2], a3: Arbitrary[T3], a4: Arbitrary[T4], - a5: Arbitrary[T5], a6: Arbitrary[T6], a7: Arbitrary[T7], a8: Arbitrary[T8], - a9: Arbitrary[T9] - ): Gen[R] = arbitrary[T1] flatMap { - t => resultOf(f(t, _:T2, _:T3, _:T4, _:T5, _:T6, _:T7, _:T8, _:T9)) - } - -} diff --git a/src/scalacheck/org/scalacheck/Pretty.scala b/src/scalacheck/org/scalacheck/Pretty.scala deleted file mode 100644 index eeb5936086..0000000000 --- a/src/scalacheck/org/scalacheck/Pretty.scala +++ /dev/null @@ -1,127 +0,0 @@ -/*-------------------------------------------------------------------------*\ -** ScalaCheck ** -** Copyright (c) 2007-2011 Rickard Nilsson. All rights reserved. ** -** http://www.scalacheck.org ** -** ** -** This software is released under the terms of the Revised BSD License. ** -** There is NO WARRANTY. See the file LICENSE for the full text. ** -\*------------------------------------------------------------------------ */ - -package org.scalacheck - -import math.round - - -sealed trait Pretty { - def apply(prms: Pretty.Params): String - - def map(f: String => String) = Pretty(prms => f(Pretty.this(prms))) - - def flatMap(f: String => Pretty) = Pretty(prms => f(Pretty.this(prms))(prms)) -} - -object Pretty { - - case class Params(verbosity: Int) - - val defaultParams = Params(0) - - def apply(f: Params => String) = new Pretty { def apply(p: Params) = f(p) } - - def pretty[T <% Pretty](t: T, prms: Params): String = t(prms) - - def pretty[T <% Pretty](t: T): String = t(defaultParams) - - implicit def strBreak(s1: String) = new { - def /(s2: String) = if(s2 == "") s1 else s1+"\n"+s2 - } - - def pad(s: String, c: Char, length: Int) = - if(s.length >= length) s - else s + List.fill(length-s.length)(c).mkString - - def break(s: String, lead: String, length: Int): String = - if(s.length <= length) s - else s.substring(0, length) / break(lead+s.substring(length), lead, length) - - def format(s: String, lead: String, trail: String, width: Int) = - s.lines.map(l => break(lead+l+trail, " ", width)).mkString("\n") - - implicit def prettyAny(t: Any) = Pretty { p => t.toString } - - implicit def prettyString(t: String) = Pretty { p => "\""++t++"\"" } - - implicit def prettyList(l: List[Any]) = Pretty { p => - l.map("\""+_+"\"").mkString("List(", ", ", ")") - } - - implicit def prettyThrowable(e: Throwable) = Pretty { prms => - val strs = e.getStackTrace.map { st => - import st._ - getClassName+"."+getMethodName + "("+getFileName+":"+getLineNumber+")" - } - - val strs2 = - if(prms.verbosity <= 0) Array[String]() - else if(prms.verbosity <= 1) strs.take(5) - else strs - - e.getClass.getName + ": " + e.getMessage / strs2.mkString("\n") - } - - implicit def prettyArgs(args: List[Arg[Any]]): Pretty = Pretty { prms => - if(args.isEmpty) "" else { - for((a,i) <- args.zipWithIndex) yield { - val l = if(a.label == "") "ARG_"+i else a.label - val s = - if(a.shrinks == 0 || prms.verbosity <= 1) "" - else " (orig arg: "+a.prettyOrigArg(prms)+")" - - "> "+l+": "+a.prettyArg(prms)+""+s - } - }.mkString("\n") - } - - implicit def prettyFreqMap(fm: Prop.FM) = Pretty { prms => - if(fm.total == 0) "" - else { - "> Collected test data: " / { - for { - (xs,r) <- fm.getRatios - ys = xs - () - if !ys.isEmpty - } yield round(r*100)+"% " + ys.mkString(", ") - }.mkString("\n") - } - } - - implicit def prettyTestRes(res: Test.Result) = Pretty { prms => - def labels(ls: scala.collection.immutable.Set[String]) = - if(ls.isEmpty) "" - else "> Labels of failing property: " / ls.mkString("\n") - val s = res.status match { - case Test.Proved(args) => "OK, proved property."/pretty(args,prms) - case Test.Passed => "OK, passed "+res.succeeded+" tests." - case Test.Failed(args, l) => - "Falsified after "+res.succeeded+" passed tests."/labels(l)/pretty(args,prms) - case Test.Exhausted => - "Gave up after only "+res.succeeded+" passed tests. " + - res.discarded+" tests were discarded." - case Test.PropException(args,e,l) => - "Exception raised on property evaluation."/labels(l)/pretty(args,prms)/ - "> Exception: "+pretty(e,prms) - case Test.GenException(e) => - "Exception raised on argument generation."/ - "> Exception: "+pretty(e,prms) - } - val t = if(prms.verbosity <= 1) "" else "Elapsed time: "+prettyTime(res.time) - s/t/pretty(res.freqMap,prms) - } - - def prettyTime(millis: Long): String = { - val min = millis/(60*1000) - val sec = (millis-(60*1000*min)) / 1000d - if(min <= 0) "%.3f sec ".format(sec) - else "%d min %.3f sec ".format(min, sec) - } -} diff --git a/src/scalacheck/org/scalacheck/Prop.scala b/src/scalacheck/org/scalacheck/Prop.scala deleted file mode 100644 index dfd85a832a..0000000000 --- a/src/scalacheck/org/scalacheck/Prop.scala +++ /dev/null @@ -1,763 +0,0 @@ -/*-------------------------------------------------------------------------*\ -** ScalaCheck ** -** Copyright (c) 2007-2011 Rickard Nilsson. All rights reserved. ** -** http://www.scalacheck.org ** -** ** -** This software is released under the terms of the Revised BSD License. ** -** There is NO WARRANTY. See the file LICENSE for the full text. ** -\*------------------------------------------------------------------------ */ - -package org.scalacheck - -import util.{FreqMap,Buildable} -import scala.collection._ -import scala.annotation.tailrec - -/** A property is a generator that generates a property result */ -trait Prop { - - import Prop.{Result,Params,Proof,True,False,Exception,Undecided,provedToTrue} - import Test.cmdLineParser.{Success, NoSuccess} - import Result.merge - - def apply(prms: Params): Result - - def map(f: Result => Result): Prop = Prop(prms => f(this(prms))) - - def flatMap(f: Result => Prop): Prop = Prop(prms => f(this(prms))(prms)) - - def combine(p: Prop)(f: (Result, Result) => Result) = - for(r1 <- this; r2 <- p) yield f(r1,r2) - - /** Convenience method that checks this property with the given parameters - * and reports the result on the console. If you need to get the results - * from the test use the <code>check</code> methods in <code>Test</code> - * instead. */ - def check(prms: Test.Params): Unit = Test.check( - prms copy (testCallback = ConsoleReporter(1) chain prms.testCallback), this - ) - - /** Convenience method that checks this property and reports the - * result on the console. If you need to get the results from the test use - * the <code>check</code> methods in <code>Test</code> instead. */ - def check: Unit = check(Test.Params()) - - /** The logic for main, separated out to make it easier to - * avoid System.exit calls. Returns exit code. - */ - def mainRunner(args: Array[String]): Int = { - Test.cmdLineParser.parseParams(args) match { - case Success(params, _) => - if (Test.check(params, this).passed) 0 - else 1 - case e: NoSuccess => - println("Incorrect options:"+"\n"+e+"\n") - Test.cmdLineParser.printHelp - -1 - } - } - - /** Whether main should call System.exit with an exit code. - * Defaults to true; override to change. - */ - def mainCallsExit = false - - /** Convenience method that makes it possible to use this property - * as an application that checks itself on execution */ - def main(args: Array[String]): Unit = { - val code = mainRunner(args) - if (mainCallsExit) - System exit code - } - - /** Returns a new property that holds if and only if both this - * and the given property hold. If one of the properties doesn't - * generate a result, the new property will generate false. */ - def &&(p: Prop) = combine(p)(_ && _) - - /** Returns a new property that holds if either this - * or the given property (or both) hold. */ - def ||(p: Prop) = combine(p)(_ || _) - - /** Returns a new property that holds if and only if both this - * and the given property hold. If one of the properties doesn't - * generate a result, the new property will generate the same result - * as the other property. */ - def ++(p: Prop): Prop = combine(p)(_ ++ _) - - /** Combines two properties through implication */ - def ==>(p: => Prop): Prop = flatMap { r1 => - if(r1.proved) p map { r2 => merge(r1,r2,r2.status) } - else if(r1.success) p map { r2 => provedToTrue(merge(r1,r2,r2.status)) } - else Prop(r1.copy(status = Undecided)) - } - - /** Returns a new property that holds if and only if both this - * and the given property generates a result with the exact - * same status. Note that this means that if one of the properties is - * proved, and the other one passed, then the resulting property - * will fail. */ - def ==(p: Prop) = this.flatMap { r1 => - p.map { r2 => - Result.merge(r1, r2, if(r1.status == r2.status) True else False) - } - } - - override def toString = "Prop" - - /** Put a label on the property to make test reports clearer */ - def label(l: String) = map(_.label(l)) - - /** Put a label on the property to make test reports clearer */ - def :|(l: String) = label(l) - - /** Put a label on the property to make test reports clearer */ - def |:(l: String) = label(l) - - /** Put a label on the property to make test reports clearer */ - def :|(l: Symbol) = label(l.toString.drop(1)) - - /** Put a label on the property to make test reports clearer */ - def |:(l: Symbol) = label(l.toString.drop(1)) - -} - -object Prop { - - import Gen.{value, fail, frequency, oneOf} - import Arbitrary._ - import Shrink._ - - - // Types - - type Args = List[Arg[Any]] - type FM = FreqMap[immutable.Set[Any]] - - /** Property parameters */ - case class Params(val genPrms: Gen.Params, val freqMap: FM) - - object Result { - def apply(st: Status) = new Result( - st, - Nil, - immutable.Set.empty[Any], - immutable.Set.empty[String] - ) - - def merge(x: Result, y: Result, status: Status) = new Result( - status, - x.args ++ y.args, - (x.collected.asInstanceOf[Set[AnyRef]] ++ y.collected).asInstanceOf[immutable.Set[Any]], - x.labels ++ y.labels - ) - } - - /** The result of evaluating a property */ - case class Result( - status: Status, - args: Args, - collected: immutable.Set[Any], - labels: immutable.Set[String] - ) { - def success = status match { - case True => true - case Proof => true - case _ => false - } - - def failure = status match { - case False => true - case Exception(_) => true - case _ => false - } - - def proved = status == Proof - - def addArg(a: Arg[Any]) = copy(args = a::args) - - def collect(x: Any) = copy(collected = collected+x) - - def label(l: String) = copy(labels = labels+l) - - import Result.merge - - def &&(r: Result) = (this.status, r.status) match { - case (Exception(_),_) => this - case (_,Exception(_)) => r - - case (False,_) => this - case (_,False) => r - - case (Undecided,_) => this - case (_,Undecided) => r - - case (_,Proof) => merge(this, r, this.status) - case (Proof,_) => merge(this, r, r.status) - - case (True,True) => merge(this, r, True) - } - - def ||(r: Result) = (this.status, r.status) match { - case (Exception(_),_) => this - case (_,Exception(_)) => r - - case (False,False) => merge(this, r, False) - case (False,_) => r - case (_,False) => this - - case (Proof,_) => this - case (_,Proof) => r - - case (True,_) => this - case (_,True) => r - - case (Undecided,Undecided) => merge(this, r, Undecided) - } - - def ++(r: Result) = (this.status, r.status) match { - case (Exception(_),_) => this - case (_,Exception(_)) => r - - case (_, Undecided) => this - case (Undecided, _) => r - - case (_, Proof) => this - case (Proof, _) => r - - case (_, True) => this - case (True, _) => r - - case (False, _) => this - case (_, False) => r - } - - def ==>(r: Result) = (this.status, r.status) match { - case (Exception(_),_) => this - case (_,Exception(_)) => r - - case (False,_) => merge(this, r, Undecided) - - case (Undecided,_) => this - - case (Proof,_) => merge(this, r, r.status) - case (True,_) => merge(this, r, r.status) - } - - } - - sealed trait Status - - /** The property was proved */ - case object Proof extends Status - - /** The property was true */ - case object True extends Status - - /** The property was false */ - case object False extends Status - - /** The property could not be falsified or proved */ - case object Undecided extends Status - - /** Evaluating the property raised an exception */ - sealed case class Exception(e: Throwable) extends Status { - override def equals(o: Any) = o match { - case Exception(_) => true - case _ => false - } - } - - def apply(f: Params => Result): Prop = new Prop { - def apply(prms: Params) = f(prms) - } - - def apply(r: Result): Prop = Prop(prms => r) - - - // Implicit defs - - class ExtendedAny[T <% Pretty](x: => T) { - def imply(f: PartialFunction[T,Prop]) = Prop.imply(x,f) - def iff(f: PartialFunction[T,Prop]) = Prop.iff(x,f) - def throws[U <: Throwable](c: Class[U]) = Prop.throws(x, c) - def ?=(y: T) = Prop.?=(x, y) - def =?(y: T) = Prop.=?(x, y) - } - - implicit def extendedAny[T <% Pretty](x: => T) = new ExtendedAny[T](x) - - implicit def propBoolean(b: Boolean): Prop = if(b) proved else falsified - - - // Private support functions - - private def provedToTrue(r: Result) = r.status match { - case Proof => new Result(True, r.args, r.collected, r.labels) - case _ => r - } - - - // Property combinators - - /** A property that never is proved or falsified */ - lazy val undecided = Prop(Result(Undecided)) - - /** A property that always is false */ - lazy val falsified = Prop(Result(False)) - - /** A property that always is proved */ - lazy val proved = Prop(Result(Proof)) - - /** A property that always is passed */ - lazy val passed = Prop(Result(True)) - - /** A property that denotes an exception */ - def exception(e: Throwable): Prop = Prop(Result(Exception(e))) - - /** A property that denotes an exception */ - lazy val exception: Prop = exception(null) - - def ?=[T](x: T, y: T)(implicit pp: T => Pretty): Prop = - if(x == y) proved else falsified :| { - val exp = Pretty.pretty[T](y, Pretty.Params(0)) - val act = Pretty.pretty[T](x, Pretty.Params(0)) - "Expected "+exp+" but got "+act - } - - def =?[T](x: T, y: T)(implicit pp: T => Pretty): Prop = ?=(y, x) - - /** A property that depends on the generator size */ - def sizedProp(f: Int => Prop): Prop = Prop { prms => - // provedToTrue since if the property is proved for - // one size, it shouldn't be regarded as proved for - // all sizes. - provedToTrue(f(prms.genPrms.size)(prms)) - } - - /** Implication with several conditions */ - def imply[T](x: T, f: PartialFunction[T,Prop]): Prop = - secure(if(f.isDefinedAt(x)) f(x) else undecided) - - /** Property holds only if the given partial function is defined at - * <code>x</code>, and returns a property that holds */ - def iff[T](x: T, f: PartialFunction[T,Prop]): Prop = - secure(if(f.isDefinedAt(x)) f(x) else falsified) - - /** Combines properties into one, which is true if and only if all the - * properties are true */ - def all(ps: Prop*) = if(ps.isEmpty) proved else Prop(prms => - ps.map(p => p(prms)).reduceLeft(_ && _) - ) - - /** Combines properties into one, which is true if at least one of the - * properties is true */ - def atLeastOne(ps: Prop*) = if(ps.isEmpty) falsified else Prop(prms => - ps.map(p => p(prms)).reduceLeft(_ || _) - ) - - /** A property that holds if at least one of the given generators - * fails generating a value */ - def someFailing[T](gs: Seq[Gen[T]]) = atLeastOne(gs.map(_ == fail):_*) - - /** A property that holds iff none of the given generators - * fails generating a value */ - def noneFailing[T](gs: Seq[Gen[T]]) = all(gs.map(_ !== fail):_*) - - /** A property that holds if the given statement throws an exception - * of the specified type */ - def throws[T <: Throwable](x: => Any, c: Class[T]) = - try { x; falsified } catch { case e if c.isInstance(e) => proved } - - /** Collect data for presentation in test report */ - def collect[T, P <% Prop](f: T => P): T => Prop = t => Prop { prms => - val prop = f(t) - prop(prms).collect(t) - } - - /** Collect data for presentation in test report */ - def collect[T](t: T)(prop: Prop) = Prop { prms => - prop(prms).collect(t) - } - - /** Collect data for presentation in test report */ - def classify(c: => Boolean, ifTrue: Any)(prop: Prop): Prop = - if(c) collect(ifTrue)(prop) else collect(())(prop) - - /** Collect data for presentation in test report */ - def classify(c: => Boolean, ifTrue: Any, ifFalse: Any)(prop: Prop): Prop = - if(c) collect(ifTrue)(prop) else collect(ifFalse)(prop) - - /** Wraps and protects a property */ - def secure[P <% Prop](p: => P): Prop = - try { p: Prop } catch { case e => exception(e) } - - /** Existential quantifier for an explicit generator. */ - def exists[A,P](f: A => P)(implicit - pv: P => Prop, - pp: A => Pretty, - aa: Arbitrary[A] - ): Prop = exists(aa.arbitrary)(f) - - /** Existential quantifier for an explicit generator. */ - def exists[A,P](g: Gen[A])(f: A => P)(implicit - pv: P => Prop, - pp: A => Pretty - ): Prop = Prop { prms => - g(prms.genPrms) match { - case None => undecided(prms) - case Some(x) => - val p = secure(f(x)) - val r = p(prms).addArg(Arg(g.label,x,0,x)) - r.status match { - case True => new Result(Proof, r.args, r.collected, r.labels) - case False => new Result(Undecided, r.args, r.collected, r.labels) - case _ => r - } - } - } - - /** Universal quantifier for an explicit generator. Does not shrink failed - * test cases. */ - def forAllNoShrink[T1,P]( - g1: Gen[T1])( - f: T1 => P)(implicit - pv: P => Prop, - pp1: T1 => Pretty - ): Prop = Prop { prms => - g1(prms.genPrms) match { - case None => undecided(prms) - case Some(x) => - val p = secure(f(x)) - provedToTrue(p(prms)).addArg(Arg(g1.label,x,0,x)) - } - } - - /** Universal quantifier for two explicit generators. - * Does not shrink failed test cases. */ - def forAllNoShrink[T1,T2,P]( - g1: Gen[T1], g2: Gen[T2])( - f: (T1,T2) => P)(implicit - p: P => Prop, - pp1: T1 => Pretty, - pp2: T2 => Pretty - ): Prop = forAllNoShrink(g1)(t => forAllNoShrink(g2)(f(t, _:T2))) - - /** Universal quantifier for three explicit generators. - * Does not shrink failed test cases. */ - def forAllNoShrink[T1,T2,T3,P]( - g1: Gen[T1], g2: Gen[T2], g3: Gen[T3])( - f: (T1,T2,T3) => P)(implicit - p: P => Prop, - pp1: T1 => Pretty, - pp2: T2 => Pretty, - pp3: T3 => Pretty - ): Prop = forAllNoShrink(g1)(t => forAllNoShrink(g2,g3)(f(t, _:T2, _:T3))) - - /** Universal quantifier for four explicit generators. - * Does not shrink failed test cases. */ - def forAllNoShrink[T1,T2,T3,T4,P]( - g1: Gen[T1], g2: Gen[T2], g3: Gen[T3], g4: Gen[T4])( - f: (T1,T2,T3,T4) => P)(implicit - p: P => Prop, - pp1: T1 => Pretty, - pp2: T2 => Pretty, - pp3: T3 => Pretty, - pp4: T4 => Pretty - ): Prop = forAllNoShrink(g1)(t => forAllNoShrink(g2,g3,g4)(f(t, _:T2, _:T3, _:T4))) - - /** Universal quantifier for five explicit generators. - * Does not shrink failed test cases. */ - def forAllNoShrink[T1,T2,T3,T4,T5,P]( - g1: Gen[T1], g2: Gen[T2], g3: Gen[T3], g4: Gen[T4], g5: Gen[T5])( - f: (T1,T2,T3,T4,T5) => P)(implicit - p: P => Prop, - pp1: T1 => Pretty, - pp2: T2 => Pretty, - pp3: T3 => Pretty, - pp4: T4 => Pretty, - pp5: T5 => Pretty - ): Prop = forAllNoShrink(g1)(t => forAllNoShrink(g2,g3,g4,g5)(f(t, _:T2, _:T3, _:T4, _:T5))) - - /** Universal quantifier for six explicit generators. - * Does not shrink failed test cases. */ - def forAllNoShrink[T1,T2,T3,T4,T5,T6,P]( - g1: Gen[T1], g2: Gen[T2], g3: Gen[T3], g4: Gen[T4], g5: Gen[T5], g6: Gen[T6])( - f: (T1,T2,T3,T4,T5,T6) => P)(implicit - p: P => Prop, - pp1: T1 => Pretty, - pp2: T2 => Pretty, - pp3: T3 => Pretty, - pp4: T4 => Pretty, - pp5: T5 => Pretty, - pp6: T6 => Pretty - ): Prop = forAllNoShrink(g1)(t => forAllNoShrink(g2,g3,g4,g5,g6)(f(t, _:T2, _:T3, _:T4, _:T5, _:T6))) - - /** Universal quantifier for seven explicit generators. - * Does not shrink failed test cases. */ - def forAllNoShrink[T1,T2,T3,T4,T5,T6,T7,P]( - g1: Gen[T1], g2: Gen[T2], g3: Gen[T3], g4: Gen[T4], g5: Gen[T5], g6: Gen[T6], g7: Gen[T7])( - f: (T1,T2,T3,T4,T5,T6,T7) => P)(implicit - p: P => Prop, - pp1: T1 => Pretty, - pp2: T2 => Pretty, - pp3: T3 => Pretty, - pp4: T4 => Pretty, - pp5: T5 => Pretty, - pp6: T6 => Pretty, - pp7: T7 => Pretty - ): Prop = forAllNoShrink(g1)(t => forAllNoShrink(g2,g3,g4,g5,g6,g7)(f(t, _:T2, _:T3, _:T4, _:T5, _:T6, _:T7))) - - /** Universal quantifier for eight explicit generators. - * Does not shrink failed test cases. */ - def forAllNoShrink[T1,T2,T3,T4,T5,T6,T7,T8,P]( - g1: Gen[T1], g2: Gen[T2], g3: Gen[T3], g4: Gen[T4], g5: Gen[T5], g6: Gen[T6], g7: Gen[T7], g8: Gen[T8])( - f: (T1,T2,T3,T4,T5,T6,T7,T8) => P)(implicit - p: P => Prop, - pp1: T1 => Pretty, - pp2: T2 => Pretty, - pp3: T3 => Pretty, - pp4: T4 => Pretty, - pp5: T5 => Pretty, - pp6: T6 => Pretty, - pp7: T7 => Pretty, - pp8: T8 => Pretty - ): Prop = forAllNoShrink(g1)(t => forAllNoShrink(g2,g3,g4,g5,g6,g7,g8)(f(t, _:T2, _:T3, _:T4, _:T5, _:T6, _:T7, _:T8))) - - /** Universal quantifier for an explicit generator. Shrinks failed arguments - * with the given shrink function */ - def forAllShrink[T <% Pretty, P <% Prop](g: Gen[T], - shrink: T => Stream[T])(f: T => P - ): Prop = Prop { prms => - - /** Returns the first failed result in Left or success in Right */ - def getFirstFailure(xs: Stream[T]): Either[(T,Result),(T,Result)] = { - assert(!xs.isEmpty, "Stream cannot be empty") - val results = xs.map { x => - val p = secure(f(x)) - (x, provedToTrue(p(prms))) - } - results.dropWhile(!_._2.failure).headOption match { - case None => Right(results.head) - case Some(xr) => Left(xr) - } - } - - def shrinker(x: T, r: Result, shrinks: Int, orig: T): Result = { - val xs = shrink(x) - val res = r.addArg(Arg(g.label,x,shrinks,orig)) - if(xs.isEmpty) res else getFirstFailure(xs) match { - case Right(_) => res - case Left((x2,r2)) => shrinker(x2, r2, shrinks+1, orig) - } - } - - g(prms.genPrms) match { - case None => undecided(prms) - case Some(x) => getFirstFailure(Stream.cons(x, Stream.empty)) match { - case Right((x,r)) => r.addArg(Arg(g.label,x,0,x)) - case Left((x,r)) => shrinker(x,r,0,x) - } - } - - } - - /** Universal quantifier for an explicit generator. Shrinks failed arguments - * with the default shrink function for the type */ - def forAll[T1,P]( - g1: Gen[T1])( - f: T1 => P)(implicit - p: P => Prop, - s1: Shrink[T1], - pp1: T1 => Pretty - ): Prop = forAllShrink(g1, shrink[T1])(f) - - /** Universal quantifier for two explicit generators. Shrinks failed arguments - * with the default shrink function for the type */ - def forAll[T1,T2,P]( - g1: Gen[T1], g2: Gen[T2])( - f: (T1,T2) => P)(implicit - p: P => Prop, - s1: Shrink[T1], pp1: T1 => Pretty, - s2: Shrink[T2], pp2: T2 => Pretty - ): Prop = forAll(g1)(t => forAll(g2)(f(t, _:T2))) - - /** Universal quantifier for three explicit generators. Shrinks failed arguments - * with the default shrink function for the type */ - def forAll[T1,T2,T3,P]( - g1: Gen[T1], g2: Gen[T2], g3: Gen[T3])( - f: (T1,T2,T3) => P)(implicit - p: P => Prop, - s1: Shrink[T1], pp1: T1 => Pretty, - s2: Shrink[T2], pp2: T2 => Pretty, - s3: Shrink[T3], pp3: T3 => Pretty - ): Prop = forAll(g1)(t => forAll(g2,g3)(f(t, _:T2, _:T3))) - - /** Universal quantifier for four explicit generators. Shrinks failed arguments - * with the default shrink function for the type */ - def forAll[T1,T2,T3,T4,P]( - g1: Gen[T1], g2: Gen[T2], g3: Gen[T3], g4: Gen[T4])( - f: (T1,T2,T3,T4) => P)(implicit - p: P => Prop, - s1: Shrink[T1], pp1: T1 => Pretty, - s2: Shrink[T2], pp2: T2 => Pretty, - s3: Shrink[T3], pp3: T3 => Pretty, - s4: Shrink[T4], pp4: T4 => Pretty - ): Prop = forAll(g1)(t => forAll(g2,g3,g4)(f(t, _:T2, _:T3, _:T4))) - - /** Universal quantifier for five explicit generators. Shrinks failed arguments - * with the default shrink function for the type */ - def forAll[T1,T2,T3,T4,T5,P]( - g1: Gen[T1], g2: Gen[T2], g3: Gen[T3], g4: Gen[T4], g5: Gen[T5])( - f: (T1,T2,T3,T4,T5) => P)(implicit - p: P => Prop, - s1: Shrink[T1], pp1: T1 => Pretty, - s2: Shrink[T2], pp2: T2 => Pretty, - s3: Shrink[T3], pp3: T3 => Pretty, - s4: Shrink[T4], pp4: T4 => Pretty, - s5: Shrink[T5], pp5: T5 => Pretty - ): Prop = forAll(g1)(t => forAll(g2,g3,g4,g5)(f(t, _:T2, _:T3, _:T4, _:T5))) - - /** Universal quantifier for six explicit generators. Shrinks failed arguments - * with the default shrink function for the type */ - def forAll[T1,T2,T3,T4,T5,T6,P]( - g1: Gen[T1], g2: Gen[T2], g3: Gen[T3], g4: Gen[T4], g5: Gen[T5], g6: Gen[T6])( - f: (T1,T2,T3,T4,T5,T6) => P)(implicit - p: P => Prop, - s1: Shrink[T1], pp1: T1 => Pretty, - s2: Shrink[T2], pp2: T2 => Pretty, - s3: Shrink[T3], pp3: T3 => Pretty, - s4: Shrink[T4], pp4: T4 => Pretty, - s5: Shrink[T5], pp5: T5 => Pretty, - s6: Shrink[T6], pp6: T6 => Pretty - ): Prop = forAll(g1)(t => forAll(g2,g3,g4,g5,g6)(f(t, _:T2, _:T3, _:T4, _:T5, _:T6))) - - /** Universal quantifier for seven explicit generators. Shrinks failed arguments - * with the default shrink function for the type */ - def forAll[T1,T2,T3,T4,T5,T6,T7,P]( - g1: Gen[T1], g2: Gen[T2], g3: Gen[T3], g4: Gen[T4], g5: Gen[T5], g6: Gen[T6], g7: Gen[T7])( - f: (T1,T2,T3,T4,T5,T6,T7) => P)(implicit - p: P => Prop, - s1: Shrink[T1], pp1: T1 => Pretty, - s2: Shrink[T2], pp2: T2 => Pretty, - s3: Shrink[T3], pp3: T3 => Pretty, - s4: Shrink[T4], pp4: T4 => Pretty, - s5: Shrink[T5], pp5: T5 => Pretty, - s6: Shrink[T6], pp6: T6 => Pretty, - s7: Shrink[T7], pp7: T7 => Pretty - ): Prop = forAll(g1)(t => forAll(g2,g3,g4,g5,g6,g7)(f(t, _:T2, _:T3, _:T4, _:T5, _:T6, _:T7))) - - /** Universal quantifier for eight explicit generators. Shrinks failed arguments - * with the default shrink function for the type */ - def forAll[T1,T2,T3,T4,T5,T6,T7,T8,P]( - g1: Gen[T1], g2: Gen[T2], g3: Gen[T3], g4: Gen[T4], g5: Gen[T5], g6: Gen[T6], g7: Gen[T7], g8: Gen[T8])( - f: (T1,T2,T3,T4,T5,T6,T7,T8) => P)(implicit - p: P => Prop, - s1: Shrink[T1], pp1: T1 => Pretty, - s2: Shrink[T2], pp2: T2 => Pretty, - s3: Shrink[T3], pp3: T3 => Pretty, - s4: Shrink[T4], pp4: T4 => Pretty, - s5: Shrink[T5], pp5: T5 => Pretty, - s6: Shrink[T6], pp6: T6 => Pretty, - s7: Shrink[T7], pp7: T7 => Pretty, - s8: Shrink[T8], pp8: T8 => Pretty - ): Prop = forAll(g1)(t => forAll(g2,g3,g4,g5,g6,g7,g8)(f(t, _:T2, _:T3, _:T4, _:T5, _:T6, _:T7, _:T8))) - - /** Converts a function into a universally quantified property */ - def forAll[A1,P] ( - f: A1 => P)(implicit - p: P => Prop, - a1: Arbitrary[A1], s1: Shrink[A1], pp1: A1 => Pretty - ): Prop = forAllShrink(arbitrary[A1],shrink[A1])(f andThen p) - - /** Converts a function into a universally quantified property */ - def forAll[A1,A2,P] ( - f: (A1,A2) => P)(implicit - p: P => Prop, - a1: Arbitrary[A1], s1: Shrink[A1], pp1: A1 => Pretty, - a2: Arbitrary[A2], s2: Shrink[A2], pp2: A2 => Pretty - ): Prop = forAll((a: A1) => forAll(f(a, _:A2))) - - /** Converts a function into a universally quantified property */ - def forAll[A1,A2,A3,P] ( - f: (A1,A2,A3) => P)(implicit - p: P => Prop, - a1: Arbitrary[A1], s1: Shrink[A1], pp1: A1 => Pretty, - a2: Arbitrary[A2], s2: Shrink[A2], pp2: A2 => Pretty, - a3: Arbitrary[A3], s3: Shrink[A3], pp3: A3 => Pretty - ): Prop = forAll((a: A1) => forAll(f(a, _:A2, _:A3))) - - /** Converts a function into a universally quantified property */ - def forAll[A1,A2,A3,A4,P] ( - f: (A1,A2,A3,A4) => P)(implicit - p: P => Prop, - a1: Arbitrary[A1], s1: Shrink[A1], pp1: A1 => Pretty, - a2: Arbitrary[A2], s2: Shrink[A2], pp2: A2 => Pretty, - a3: Arbitrary[A3], s3: Shrink[A3], pp3: A3 => Pretty, - a4: Arbitrary[A4], s4: Shrink[A4], pp4: A4 => Pretty - ): Prop = forAll((a: A1) => forAll(f(a, _:A2, _:A3, _:A4))) - - /** Converts a function into a universally quantified property */ - def forAll[A1,A2,A3,A4,A5,P] ( - f: (A1,A2,A3,A4,A5) => P)(implicit - p: P => Prop, - a1: Arbitrary[A1], s1: Shrink[A1], pp1: A1 => Pretty, - a2: Arbitrary[A2], s2: Shrink[A2], pp2: A2 => Pretty, - a3: Arbitrary[A3], s3: Shrink[A3], pp3: A3 => Pretty, - a4: Arbitrary[A4], s4: Shrink[A4], pp4: A4 => Pretty, - a5: Arbitrary[A5], s5: Shrink[A5], pp5: A5 => Pretty - ): Prop = forAll((a: A1) => forAll(f(a, _:A2, _:A3, _:A4, _:A5))) - - /** Converts a function into a universally quantified property */ - def forAll[A1,A2,A3,A4,A5,A6,P] ( - f: (A1,A2,A3,A4,A5,A6) => P)(implicit - p: P => Prop, - a1: Arbitrary[A1], s1: Shrink[A1], pp1: A1 => Pretty, - a2: Arbitrary[A2], s2: Shrink[A2], pp2: A2 => Pretty, - a3: Arbitrary[A3], s3: Shrink[A3], pp3: A3 => Pretty, - a4: Arbitrary[A4], s4: Shrink[A4], pp4: A4 => Pretty, - a5: Arbitrary[A5], s5: Shrink[A5], pp5: A5 => Pretty, - a6: Arbitrary[A6], s6: Shrink[A6], pp6: A6 => Pretty - ): Prop = forAll((a: A1) => forAll(f(a, _:A2, _:A3, _:A4, _:A5, _:A6))) - - /** Converts a function into a universally quantified property */ - def forAll[A1,A2,A3,A4,A5,A6,A7,P] ( - f: (A1,A2,A3,A4,A5,A6,A7) => P)(implicit - p: P => Prop, - a1: Arbitrary[A1], s1: Shrink[A1], pp1: A1 => Pretty, - a2: Arbitrary[A2], s2: Shrink[A2], pp2: A2 => Pretty, - a3: Arbitrary[A3], s3: Shrink[A3], pp3: A3 => Pretty, - a4: Arbitrary[A4], s4: Shrink[A4], pp4: A4 => Pretty, - a5: Arbitrary[A5], s5: Shrink[A5], pp5: A5 => Pretty, - a6: Arbitrary[A6], s6: Shrink[A6], pp6: A6 => Pretty, - a7: Arbitrary[A7], s7: Shrink[A7], pp7: A7 => Pretty - ): Prop = forAll((a: A1) => forAll(f(a, _:A2, _:A3, _:A4, _:A5, _:A6, _:A7))) - - /** Converts a function into a universally quantified property */ - def forAll[A1,A2,A3,A4,A5,A6,A7,A8,P] ( - f: (A1,A2,A3,A4,A5,A6,A7,A8) => P)(implicit - p: P => Prop, - a1: Arbitrary[A1], s1: Shrink[A1], pp1: A1 => Pretty, - a2: Arbitrary[A2], s2: Shrink[A2], pp2: A2 => Pretty, - a3: Arbitrary[A3], s3: Shrink[A3], pp3: A3 => Pretty, - a4: Arbitrary[A4], s4: Shrink[A4], pp4: A4 => Pretty, - a5: Arbitrary[A5], s5: Shrink[A5], pp5: A5 => Pretty, - a6: Arbitrary[A6], s6: Shrink[A6], pp6: A6 => Pretty, - a7: Arbitrary[A7], s7: Shrink[A7], pp7: A7 => Pretty, - a8: Arbitrary[A8], s8: Shrink[A8], pp8: A8 => Pretty - ): Prop = forAll((a: A1) => forAll(f(a, _:A2, _:A3, _:A4, _:A5, _:A6, _:A7, _:A8))) - - /** Ensures that the property expression passed in completes within the given space of time. */ - def within(maximumMs: Long)(wrappedProp: => Prop): Prop = new Prop { - @tailrec private def attempt(prms: Params, endTime: Long): Result = { - val result = wrappedProp.apply(prms) - if (System.currentTimeMillis > endTime) { - (if (result.failure) result else Result(False)).label("Timeout") - } else { - if (result.success) result - else attempt(prms, endTime) - } - } - def apply(prms: Params) = attempt(prms, System.currentTimeMillis + maximumMs) - } -} diff --git a/src/scalacheck/org/scalacheck/Properties.scala b/src/scalacheck/org/scalacheck/Properties.scala deleted file mode 100644 index 26059231d6..0000000000 --- a/src/scalacheck/org/scalacheck/Properties.scala +++ /dev/null @@ -1,82 +0,0 @@ -/*-------------------------------------------------------------------------*\ -** ScalaCheck ** -** Copyright (c) 2007-2011 Rickard Nilsson. All rights reserved. ** -** http://www.scalacheck.org ** -** ** -** This software is released under the terms of the Revised BSD License. ** -** There is NO WARRANTY. See the file LICENSE for the full text. ** -\*------------------------------------------------------------------------ */ - -package org.scalacheck - -/** Represents a collection of properties, with convenient methods - * for checking all properties at once. This class is itself a property, which - * holds if and only if all of the contained properties hold. - * <p>Properties are added in the following way:</p> - * - * <p> - * <code> - * object MyProps extends Properties("MyProps") { - * property("myProp1") = forAll { (n:Int, m:Int) => - * n+m == m+n - * } - * - * property("myProp2") = ((0/1) throws classOf[ArithmeticException]) - * } - */ -class Properties(val name: String) extends Prop { - - import Test.cmdLineParser.{Success, NoSuccess} - - private val props = new scala.collection.mutable.ListBuffer[(String,Prop)] - - /** Returns one property which holds if and only if all of the - * properties in this property collection hold */ - private def oneProperty: Prop = Prop.all((properties map (_._2)):_*) - - /** Returns all properties of this collection in a list of name/property - * pairs. */ - def properties: Seq[(String,Prop)] = props - - def apply(p: Prop.Params) = oneProperty(p) - - /** Convenience method that checks the properties with the given parameters - * and reports the result on the console. If you need to get the results - * from the test use the <code>check</code> methods in <code>Test</code> - * instead. */ - override def check(prms: Test.Params): Unit = Test.checkProperties( - prms copy (testCallback = ConsoleReporter(1) chain prms.testCallback), this - ) - - /** Convenience method that checks the properties and reports the - * result on the console. If you need to get the results from the test use - * the <code>check</code> methods in <code>Test</code> instead. */ - override def check: Unit = check(Test.Params()) - - /** The logic for main, separated out to make it easier to - * avoid System.exit calls. Returns exit code. - */ - override def mainRunner(args: Array[String]): Int = { - Test.cmdLineParser.parseParams(args) match { - case Success(params, _) => - val res = Test.checkProperties(params, this) - val failed = res.filter(!_._2.passed).size - failed - case e: NoSuccess => - println("Incorrect options:"+"\n"+e+"\n") - Test.cmdLineParser.printHelp - -1 - } - } - - /** Adds all properties from another property collection to this one. */ - def include(ps: Properties) = for((n,p) <- ps.properties) property(n) = p - - /** Used for specifying properties. Usage: - * <code>property("myProp") = ...</code> */ - class PropertySpecifier() { - def update(propName: String, p: Prop) = props += ((name+"."+propName, p)) - } - - lazy val property = new PropertySpecifier() -} diff --git a/src/scalacheck/org/scalacheck/Shrink.scala b/src/scalacheck/org/scalacheck/Shrink.scala deleted file mode 100644 index ae15bd9616..0000000000 --- a/src/scalacheck/org/scalacheck/Shrink.scala +++ /dev/null @@ -1,208 +0,0 @@ -/*-------------------------------------------------------------------------*\ -** ScalaCheck ** -** Copyright (c) 2007-2011 Rickard Nilsson. All rights reserved. ** -** http://www.scalacheck.org ** -** ** -** This software is released under the terms of the Revised BSD License. ** -** There is NO WARRANTY. See the file LICENSE for the full text. ** -\*------------------------------------------------------------------------ */ - -package org.scalacheck - -import util.Buildable -import scala.collection.{ JavaConversions => jcl } - -sealed abstract class Shrink[T] { - def shrink(x: T): Stream[T] -} - -object Shrink { - - import Stream.{cons, empty} - import scala.collection._ - import java.util.ArrayList - - /** Interleaves to streams */ - private def interleave[T](xs: Stream[T], ys: Stream[T]): Stream[T] = - if(xs.isEmpty) ys - else if(ys.isEmpty) xs - else Stream(xs.head, ys.head) append interleave(xs.tail, ys.tail) - - /** Shrink instance factory */ - def apply[T](s: T => Stream[T]): Shrink[T] = new Shrink[T] { - override def shrink(x: T) = s(x) - } - - /** Shrink a value */ - def shrink[T](x: T)(implicit s: Shrink[T]): Stream[T] = s.shrink(x) - - /** Default shrink instance */ - implicit def shrinkAny[T]: Shrink[T] = Shrink(x => empty) - - /** Shrink instance of container */ - implicit def shrinkContainer[C[_],T](implicit v: C[T] => Traversable[T], s: Shrink[T], - b: Buildable[T,C] - ): Shrink[C[T]] = Shrink { xs: C[T] => - - def removeChunks(n: Int, xs: Stream[T]): Stream[Stream[T]] = - if(xs.isEmpty) empty - else if(xs.tail.isEmpty) cons(empty, empty) - else { - val n1 = n / 2 - val n2 = n - n1 - lazy val xs1 = xs.take(n1) - lazy val xs2 = xs.drop(n1) - lazy val xs3 = - for(ys1 <- removeChunks(n1,xs1) if !ys1.isEmpty) yield ys1 append xs2 - lazy val xs4 = - for(ys2 <- removeChunks(n2,xs2) if !ys2.isEmpty) yield xs1 append ys2 - - cons(xs1, cons(xs2, interleave(xs3,xs4))) - } - - def shrinkOne(zs: Stream[T]): Stream[Stream[T]] = - if(zs.isEmpty) empty - else { - val x = zs.head - val xs = zs.tail - (for(y <- shrink(x)) yield cons(y,xs)) append - (for(ys <- shrinkOne(xs)) yield cons(x,ys)) - } - - val ys = v(xs) - val zs = ys.toStream - removeChunks(ys.size,zs).append(shrinkOne(zs)).map(b.fromIterable) - - } - - /** Shrink instance of integer */ - implicit lazy val shrinkInt: Shrink[Int] = Shrink { n => - - def halfs(n: Int): Stream[Int] = - if(n == 0) empty else cons(n, halfs(n/2)) - - if(n == 0) empty else { - val ns = halfs(n/2).map(n - _) - cons(0, interleave(ns, ns.map(-1 * _))) - } - } - - /** Shrink instance of String */ - implicit lazy val shrinkString: Shrink[String] = Shrink { s => - shrinkContainer[List,Char].shrink(s.toList).map(_.mkString) - } - - /** Shrink instance of Option */ - implicit def shrinkOption[T](implicit s: Shrink[T]): Shrink[Option[T]] = - Shrink { - case None => empty - case Some(x) => cons(None, for(y <- shrink(x)) yield Some(y)) - } - - /** Shrink instance of 2-tuple */ - implicit def shrinkTuple2[T1,T2](implicit - s1: Shrink[T1], s2: Shrink[T2] - ): Shrink[(T1,T2)] = - Shrink { case (t1,t2) => - (for(x1 <- shrink(t1)) yield (x1, t2)) append - (for(x2 <- shrink(t2)) yield (t1, x2)) - } - - /** Shrink instance of 3-tuple */ - implicit def shrinkTuple3[T1,T2,T3](implicit - s1: Shrink[T1], s2: Shrink[T2], s3: Shrink[T3] - ): Shrink[(T1,T2,T3)] = - Shrink { case (t1,t2,t3) => - (for(x1 <- shrink(t1)) yield (x1, t2, t3)) append - (for(x2 <- shrink(t2)) yield (t1, x2, t3)) append - (for(x3 <- shrink(t3)) yield (t1, t2, x3)) - } - - /** Shrink instance of 4-tuple */ - implicit def shrinkTuple4[T1,T2,T3,T4](implicit - s1: Shrink[T1], s2: Shrink[T2], s3: Shrink[T3], s4: Shrink[T4] - ): Shrink[(T1,T2,T3,T4)] = - Shrink { case (t1,t2,t3,t4) => - (for(x1 <- shrink(t1)) yield (x1, t2, t3, t4)) append - (for(x2 <- shrink(t2)) yield (t1, x2, t3, t4)) append - (for(x3 <- shrink(t3)) yield (t1, t2, x3, t4)) append - (for(x4 <- shrink(t4)) yield (t1, t2, t3, x4)) - } - - /** Shrink instance of 5-tuple */ - implicit def shrinkTuple5[T1,T2,T3,T4,T5](implicit - s1: Shrink[T1], s2: Shrink[T2], s3: Shrink[T3], s4: Shrink[T4], - s5: Shrink[T5] - ): Shrink[(T1,T2,T3,T4,T5)] = - Shrink { case (t1,t2,t3,t4,t5) => - (for(x1 <- shrink(t1)) yield (x1, t2, t3, t4, t5)) append - (for(x2 <- shrink(t2)) yield (t1, x2, t3, t4, t5)) append - (for(x3 <- shrink(t3)) yield (t1, t2, x3, t4, t5)) append - (for(x4 <- shrink(t4)) yield (t1, t2, t3, x4, t5)) append - (for(x5 <- shrink(t5)) yield (t1, t2, t3, t4, x5)) - } - - /** Shrink instance of 6-tuple */ - implicit def shrinkTuple6[T1,T2,T3,T4,T5,T6](implicit - s1: Shrink[T1], s2: Shrink[T2], s3: Shrink[T3], s4: Shrink[T4], - s5: Shrink[T5], s6: Shrink[T6] - ): Shrink[(T1,T2,T3,T4,T5,T6)] = - Shrink { case (t1,t2,t3,t4,t5,t6) => - (for(x1 <- shrink(t1)) yield (x1, t2, t3, t4, t5, t6)) append - (for(x2 <- shrink(t2)) yield (t1, x2, t3, t4, t5, t6)) append - (for(x3 <- shrink(t3)) yield (t1, t2, x3, t4, t5, t6)) append - (for(x4 <- shrink(t4)) yield (t1, t2, t3, x4, t5, t6)) append - (for(x5 <- shrink(t5)) yield (t1, t2, t3, t4, x5, t6)) append - (for(x6 <- shrink(t6)) yield (t1, t2, t3, t4, t5, x6)) - } - - /** Shrink instance of 7-tuple */ - implicit def shrinkTuple7[T1,T2,T3,T4,T5,T6,T7](implicit - s1: Shrink[T1], s2: Shrink[T2], s3: Shrink[T3], s4: Shrink[T4], - s5: Shrink[T5], s6: Shrink[T6], s7: Shrink[T7] - ): Shrink[(T1,T2,T3,T4,T5,T6,T7)] = - Shrink { case (t1,t2,t3,t4,t5,t6,t7) => - (for(x1 <- shrink(t1)) yield (x1, t2, t3, t4, t5, t6, t7)) append - (for(x2 <- shrink(t2)) yield (t1, x2, t3, t4, t5, t6, t7)) append - (for(x3 <- shrink(t3)) yield (t1, t2, x3, t4, t5, t6, t7)) append - (for(x4 <- shrink(t4)) yield (t1, t2, t3, x4, t5, t6, t7)) append - (for(x5 <- shrink(t5)) yield (t1, t2, t3, t4, x5, t6, t7)) append - (for(x6 <- shrink(t6)) yield (t1, t2, t3, t4, t5, x6, t7)) append - (for(x7 <- shrink(t7)) yield (t1, t2, t3, t4, t5, t6, x7)) - } - - /** Shrink instance of 8-tuple */ - implicit def shrinkTuple8[T1,T2,T3,T4,T5,T6,T7,T8](implicit - s1: Shrink[T1], s2: Shrink[T2], s3: Shrink[T3], s4: Shrink[T4], - s5: Shrink[T5], s6: Shrink[T6], s7: Shrink[T7], s8: Shrink[T8] - ): Shrink[(T1,T2,T3,T4,T5,T6,T7,T8)] = - Shrink { case (t1,t2,t3,t4,t5,t6,t7,t8) => - (for(x1 <- shrink(t1)) yield (x1, t2, t3, t4, t5, t6, t7, t8)) append - (for(x2 <- shrink(t2)) yield (t1, x2, t3, t4, t5, t6, t7, t8)) append - (for(x3 <- shrink(t3)) yield (t1, t2, x3, t4, t5, t6, t7, t8)) append - (for(x4 <- shrink(t4)) yield (t1, t2, t3, x4, t5, t6, t7, t8)) append - (for(x5 <- shrink(t5)) yield (t1, t2, t3, t4, x5, t6, t7, t8)) append - (for(x6 <- shrink(t6)) yield (t1, t2, t3, t4, t5, x6, t7, t8)) append - (for(x7 <- shrink(t7)) yield (t1, t2, t3, t4, t5, t6, x7, t8)) append - (for(x8 <- shrink(t8)) yield (t1, t2, t3, t4, t5, t6, t7, x8)) - } - - /** Shrink instance of 9-tuple */ - implicit def shrinkTuple9[T1,T2,T3,T4,T5,T6,T7,T8,T9](implicit - s1: Shrink[T1], s2: Shrink[T2], s3: Shrink[T3], s4: Shrink[T4], - s5: Shrink[T5], s6: Shrink[T6], s7: Shrink[T7], s8: Shrink[T8], - s9: Shrink[T9] - ): Shrink[(T1,T2,T3,T4,T5,T6,T7,T8,T9)] = - Shrink { case (t1,t2,t3,t4,t5,t6,t7,t8,t9) => - (for(x1 <- shrink(t1)) yield (x1, t2, t3, t4, t5, t6, t7, t8, t9)) append - (for(x2 <- shrink(t2)) yield (t1, x2, t3, t4, t5, t6, t7, t8, t9)) append - (for(x3 <- shrink(t3)) yield (t1, t2, x3, t4, t5, t6, t7, t8, t9)) append - (for(x4 <- shrink(t4)) yield (t1, t2, t3, x4, t5, t6, t7, t8, t9)) append - (for(x5 <- shrink(t5)) yield (t1, t2, t3, t4, x5, t6, t7, t8, t9)) append - (for(x6 <- shrink(t6)) yield (t1, t2, t3, t4, t5, x6, t7, t8, t9)) append - (for(x7 <- shrink(t7)) yield (t1, t2, t3, t4, t5, t6, x7, t8, t9)) append - (for(x8 <- shrink(t8)) yield (t1, t2, t3, t4, t5, t6, t7, x8, t9)) append - (for(x9 <- shrink(t9)) yield (t1, t2, t3, t4, t5, t6, t7, t8, x9)) - } - -} diff --git a/src/scalacheck/org/scalacheck/Test.scala b/src/scalacheck/org/scalacheck/Test.scala deleted file mode 100644 index 4368184823..0000000000 --- a/src/scalacheck/org/scalacheck/Test.scala +++ /dev/null @@ -1,269 +0,0 @@ -/*-------------------------------------------------------------------------*\ -** ScalaCheck ** -** Copyright (c) 2007-2011 Rickard Nilsson. All rights reserved. ** -** http://www.scalacheck.org ** -** ** -** This software is released under the terms of the Revised BSD License. ** -** There is NO WARRANTY. See the file LICENSE for the full text. ** -\*------------------------------------------------------------------------ */ - -package org.scalacheck - -object Test { - - import util.FreqMap - import scala.collection.immutable - import Prop.FM - import util.CmdLineParser - - /** Test parameters */ - case class Params( - minSuccessfulTests: Int = 100, - - /** @deprecated Use maxDiscardRatio instead. */ - @deprecated("Use maxDiscardRatio instead.", "1.10") - maxDiscardedTests: Int = -1, - - minSize: Int = 0, - maxSize: Int = Gen.Params().size, - rng: java.util.Random = Gen.Params().rng, - workers: Int = 1, - testCallback: TestCallback = new TestCallback {}, - maxDiscardRatio: Float = 5, - customClassLoader: Option[ClassLoader] = None - ) - - /** Test statistics */ - case class Result(status: Status, succeeded: Int, discarded: Int, freqMap: FM, time: Long = 0) { - def passed = status match { - case Passed => true - case Proved(_) => true - case _ => false - } - } - - /** Test status */ - sealed trait Status - - /** ScalaCheck found enough cases for which the property holds, so the - * property is considered correct. (It is not proved correct, though). */ - case object Passed extends Status - - /** ScalaCheck managed to prove the property correct */ - sealed case class Proved(args: Prop.Args) extends Status - - /** The property was proved wrong with the given concrete arguments. */ - sealed case class Failed(args: Prop.Args, labels: Set[String]) extends Status - - /** The property test was exhausted, it wasn't possible to generate enough - * concrete arguments satisfying the preconditions to get enough passing - * property evaluations. */ - case object Exhausted extends Status - - /** An exception was raised when trying to evaluate the property with the - * given concrete arguments. */ - sealed case class PropException(args: Prop.Args, e: Throwable, - labels: Set[String]) extends Status - - /** An exception was raised when trying to generate concrete arguments - * for evaluating the property. */ - sealed case class GenException(e: Throwable) extends Status - - trait TestCallback { self => - /** Called each time a property is evaluated */ - def onPropEval(name: String, threadIdx: Int, succeeded: Int, - discarded: Int): Unit = () - - /** Called whenever a property has finished testing */ - def onTestResult(name: String, result: Result): Unit = () - - def chain(testCallback: TestCallback) = new TestCallback { - override def onPropEval(name: String, threadIdx: Int, - succeeded: Int, discarded: Int - ): Unit = { - self.onPropEval(name,threadIdx,succeeded,discarded) - testCallback.onPropEval(name,threadIdx,succeeded,discarded) - } - - override def onTestResult(name: String, result: Result): Unit = { - self.onTestResult(name,result) - testCallback.onTestResult(name,result) - } - } - } - - private def assertParams(prms: Params) = { - import prms._ - if( - minSuccessfulTests <= 0 || - maxDiscardRatio <= 0 || - minSize < 0 || - maxSize < minSize || - workers <= 0 - ) throw new IllegalArgumentException("Invalid test parameters") - } - - private def secure[T](x: => T): Either[T,Throwable] = - try { Left(x) } catch { case e => Right(e) } - - private[scalacheck] lazy val cmdLineParser = new CmdLineParser { - object OptMinSuccess extends IntOpt { - val default = Test.Params().minSuccessfulTests - val names = Set("minSuccessfulTests", "s") - val help = "Number of tests that must succeed in order to pass a property" - } - object OptMaxDiscardRatio extends FloatOpt { - val default = Test.Params().maxDiscardRatio - val names = Set("maxDiscardRatio", "r") - val help = - "The maximum ratio between discarded and succeeded tests " + - "allowed before ScalaCheck stops testing a property. At " + - "least minSuccessfulTests will always be tested, though." - } - object OptMinSize extends IntOpt { - val default = Test.Params().minSize - val names = Set("minSize", "n") - val help = "Minimum data generation size" - } - object OptMaxSize extends IntOpt { - val default = Test.Params().maxSize - val names = Set("maxSize", "x") - val help = "Maximum data generation size" - } - object OptWorkers extends IntOpt { - val default = Test.Params().workers - val names = Set("workers", "w") - val help = "Number of threads to execute in parallel for testing" - } - object OptVerbosity extends IntOpt { - val default = 1 - val names = Set("verbosity", "v") - val help = "Verbosity level" - } - - val opts = Set[Opt[_]]( - OptMinSuccess, OptMaxDiscardRatio, OptMinSize, - OptMaxSize, OptWorkers, OptVerbosity - ) - - def parseParams(args: Array[String]) = parseArgs(args) { - optMap => Test.Params( - minSuccessfulTests = optMap(OptMinSuccess), - maxDiscardRatio = optMap(OptMaxDiscardRatio), - minSize = optMap(OptMinSize), - maxSize = optMap(OptMaxSize), - rng = Test.Params().rng, - workers = optMap(OptWorkers), - testCallback = ConsoleReporter(optMap(OptVerbosity)) - ) - } - } - - /** Tests a property with the given testing parameters, and returns - * the test results. */ - def check(params: Params, p: Prop): Result = { - - // maxDiscardedTests is deprecated, but if someone - // uses it let it override maxDiscardRatio - val mdr = - if(params.maxDiscardedTests < 0) params.maxDiscardRatio - else (params.maxDiscardedTests: Float)/(params.minSuccessfulTests: Float) - val prms = params.copy( maxDiscardRatio = mdr) - - import prms._ - import scala.actors.Futures.future - - assertParams(prms) - if(workers > 1) - assert(!p.isInstanceOf[Commands], "Commands cannot be checked multi-threaded") - - val iterations = math.ceil(minSuccessfulTests / (workers: Double)) - val sizeStep = (maxSize-minSize) / (iterations*workers) - var stop = false - - def worker(workerIdx: Int) = future { - params.customClassLoader.map(Thread.currentThread.setContextClassLoader(_)) - var n = 0 // passed tests - var d = 0 // discarded tests - var res: Result = null - var fm = FreqMap.empty[immutable.Set[Any]] - while(!stop && res == null && n < iterations) { - val size = (minSize: Double) + (sizeStep * (workerIdx + (workers*(n+d)))) - val propPrms = Prop.Params(Gen.Params(size.round.toInt, prms.rng), fm) - secure(p(propPrms)) match { - case Right(e) => res = - Result(GenException(e), n, d, FreqMap.empty[immutable.Set[Any]]) - case Left(propRes) => - fm = - if(propRes.collected.isEmpty) fm - else fm + propRes.collected - propRes.status match { - case Prop.Undecided => - d += 1 - testCallback.onPropEval("", workerIdx, n, d) - // The below condition is kind of hacky. We have to have - // some margin, otherwise workers might stop testing too - // early because they have been exhausted, but the overall - // test has not. - if (n+d > minSuccessfulTests && 1+workers*maxDiscardRatio*n < d) - res = Result(Exhausted, n, d, fm) - case Prop.True => - n += 1 - testCallback.onPropEval("", workerIdx, n, d) - case Prop.Proof => - n += 1 - res = Result(Proved(propRes.args), n, d, fm) - stop = true - case Prop.False => - res = Result(Failed(propRes.args,propRes.labels), n, d, fm) - stop = true - case Prop.Exception(e) => - res = Result(PropException(propRes.args,e,propRes.labels), n, d, fm) - stop = true - } - } - } - if (res == null) { - if (maxDiscardRatio*n > d) Result(Passed, n, d, fm) - else Result(Exhausted, n, d, fm) - } else res - } - - def mergeResults(r1: () => Result, r2: () => Result) = { - val Result(st1, s1, d1, fm1, _) = r1() - val Result(st2, s2, d2, fm2, _) = r2() - if (st1 != Passed && st1 != Exhausted) - () => Result(st1, s1+s2, d1+d2, fm1++fm2, 0) - else if (st2 != Passed && st2 != Exhausted) - () => Result(st2, s1+s2, d1+d2, fm1++fm2, 0) - else { - if (s1+s2 >= minSuccessfulTests && maxDiscardRatio*(s1+s2) >= (d1+d2)) - () => Result(Passed, s1+s2, d1+d2, fm1++fm2, 0) - else - () => Result(Exhausted, s1+s2, d1+d2, fm1++fm2, 0) - } - } - - val start = System.currentTimeMillis - val results = for(i <- 0 until workers) yield worker(i) - val r = results.reduceLeft(mergeResults)() - stop = true - results foreach (_.apply()) - val timedRes = r.copy(time = System.currentTimeMillis-start) - prms.testCallback.onTestResult("", timedRes) - timedRes - } - - def checkProperties(prms: Params, ps: Properties): Seq[(String,Result)] = - ps.properties.map { case (name,p) => - val testCallback = new TestCallback { - override def onPropEval(n: String, t: Int, s: Int, d: Int) = - prms.testCallback.onPropEval(name,t,s,d) - override def onTestResult(n: String, r: Result) = - prms.testCallback.onTestResult(name,r) - } - val res = check(prms copy (testCallback = testCallback), p) - (name,res) - } - -} diff --git a/src/scalacheck/org/scalacheck/util/Buildable.scala b/src/scalacheck/org/scalacheck/util/Buildable.scala deleted file mode 100644 index 221b8a61c3..0000000000 --- a/src/scalacheck/org/scalacheck/util/Buildable.scala +++ /dev/null @@ -1,64 +0,0 @@ -/*-------------------------------------------------------------------------*\ -** ScalaCheck ** -** Copyright (c) 2007-2011 Rickard Nilsson. All rights reserved. ** -** http://www.scalacheck.org ** -** ** -** This software is released under the terms of the Revised BSD License. ** -** There is NO WARRANTY. See the file LICENSE for the full text. ** -\*------------------------------------------------------------------------ */ - -package org.scalacheck.util - -import scala.collection._ -import scala.reflect.ClassTag - -trait Buildable[T,C[_]] { - def builder: mutable.Builder[T,C[T]] - def fromIterable(it: Traversable[T]): C[T] = { - val b = builder - b ++= it - b.result() - } -} - -object Buildable { - - implicit def buildableList[T] = new Buildable[T,List] { - def builder = new mutable.ListBuffer[T] - } - - implicit def buildableStream[T] = new Buildable[T,Stream] { - def builder = (new mutable.ListBuffer[T]).mapResult(_.toStream) - } - - implicit def buildableArray[T](implicit cm: ClassTag[T]) = - new Buildable[T,Array] { - def builder = mutable.ArrayBuilder.make[T] - } - - implicit def buildableMutableSet[T] = new Buildable[T,mutable.Set] { - def builder = new mutable.SetBuilder(mutable.Set.empty[T]) - } - - implicit def buildableImmutableSet[T] = new Buildable[T,immutable.Set] { - def builder = new mutable.SetBuilder(immutable.Set.empty[T]) - } - - implicit def buildableSet[T] = new Buildable[T,Set] { - def builder = new mutable.SetBuilder(Set.empty[T]) - } - - import java.util.ArrayList - implicit def buildableArrayList[T] = new Buildable[T,ArrayList] { - def builder = new mutable.Builder[T,ArrayList[T]] { - val al = new ArrayList[T] - def +=(x: T) = { - al.add(x) - this - } - def clear() = al.clear() - def result() = al - } - } - -} diff --git a/src/scalacheck/org/scalacheck/util/CmdLineParser.scala b/src/scalacheck/org/scalacheck/util/CmdLineParser.scala deleted file mode 100644 index 4683c34a65..0000000000 --- a/src/scalacheck/org/scalacheck/util/CmdLineParser.scala +++ /dev/null @@ -1,101 +0,0 @@ -/*-------------------------------------------------------------------------*\ -** ScalaCheck ** -** Copyright (c) 2007-2011 Rickard Nilsson. All rights reserved. ** -** http://www.scalacheck.org ** -** ** -** This software is released under the terms of the Revised BSD License. ** -** There is NO WARRANTY. See the file LICENSE for the full text. ** -\*------------------------------------------------------------------------ */ - -package org.scalacheck.util - -import scala.util.parsing.combinator.Parsers -import scala.util.parsing.input.Reader -import scala.util.parsing.input.Position -import scala.collection.Set -import org.scalacheck.Test - -trait CmdLineParser extends Parsers { - - type Elem = String - - trait Opt[+T] { - val default: T - val names: Set[String] - val help: String - } - trait Flag extends Opt[Unit] - trait IntOpt extends Opt[Int] - trait FloatOpt extends Opt[Float] - trait StrOpt extends Opt[String] - - class OptMap { - private val opts = new scala.collection.mutable.HashMap[Opt[_], Any] - def apply(flag: Flag): Boolean = opts.contains(flag) - def apply[T](opt: Opt[T]): T = opts.get(opt) match { - case None => opt.default - case Some(v) => v.asInstanceOf[T] - } - def update[T](opt: Opt[T], optVal: T) = opts.update(opt, optVal) - } - - val opts: Set[Opt[_]] - - private class ArgsReader(args: Array[String], i: Int) extends Reader[String] { - val pos = new Position { - val column = (args take i).foldLeft(1)(_ + _.length + 1) - val line = 1 - val lineContents = args.mkString(" ") - } - val atEnd = i >= args.length - def first = if(atEnd) null else args(i) - def rest = if(atEnd) this else new ArgsReader(args, i+1) - } - - private def getOpt(s: String) = { - if(s == null || s.length == 0 || s.charAt(0) != '-') None - else opts.find(_.names.contains(s.drop(1))) - } - - private val opt: Parser[Opt[Any]] = accept("option name", { - case s if getOpt(s).isDefined => getOpt(s).get - }) - - private val strVal: Parser[String] = accept("string", { - case s if s != null => s - }) - - private val intVal: Parser[Int] = accept("integer", { - case s if s != null && s.length > 0 && s.forall(_.isDigit) => s.toInt - }) - - private val floatVal: Parser[Float] = accept("float", { - case s if s != null && s.matches("[0987654321]+\\.?[0987654321]*") - => s.toFloat - }) - - private case class OptVal[T](o: Opt[T], v: T) - - private val optVal: Parser[OptVal[Any]] = opt into { - case o: Flag => success(OptVal(o, ())) - case o: IntOpt => intVal ^^ (v => OptVal(o, v)) - case o: FloatOpt => floatVal ^^ (v => OptVal(o, v)) - case o: StrOpt => strVal ^^ (v => OptVal(o, v)) - } - - val options: Parser[OptMap] = rep(optVal) ^^ { xs => - val map = new OptMap - xs.foreach { case OptVal(o,v) => map(o) = v } - map - } - - def printHelp = { - println("Available options:") - opts.foreach { opt => - println(" " + opt.names.map("-"+_).mkString(", ") + ": " + opt.help) - } - } - - def parseArgs[T](args: Array[String])(f: OptMap => T) = - phrase(options map f)(new ArgsReader(args,0)) -} diff --git a/src/scalacheck/org/scalacheck/util/FreqMap.scala b/src/scalacheck/org/scalacheck/util/FreqMap.scala deleted file mode 100644 index c7474d3b87..0000000000 --- a/src/scalacheck/org/scalacheck/util/FreqMap.scala +++ /dev/null @@ -1,65 +0,0 @@ -/*-------------------------------------------------------------------------*\ -** ScalaCheck ** -** Copyright (c) 2007-2011 Rickard Nilsson. All rights reserved. ** -** http://www.scalacheck.org ** -** ** -** This software is released under the terms of the Revised BSD License. ** -** There is NO WARRANTY. See the file LICENSE for the full text. ** -\*------------------------------------------------------------------------ */ - -package org.scalacheck.util - -trait FreqMap[T] { - protected val underlying: scala.collection.immutable.Map[T,Int] - val total: Int - - def +(t: T) = new FreqMap[T] { - private val n = FreqMap.this.underlying.get(t) match { - case None => 1 - case Some(n) => n+1 - } - val underlying = FreqMap.this.underlying + (t -> n) - val total = FreqMap.this.total + 1 - } - - def -(t: T) = new FreqMap[T] { - val underlying = FreqMap.this.underlying.get(t) match { - case None => FreqMap.this.underlying - case Some(n) => FreqMap.this.underlying + (t -> (n-1)) - } - val total = FreqMap.this.total + 1 - } - - def ++(fm: FreqMap[T]) = new FreqMap[T] { - private val keys = FreqMap.this.underlying.keySet ++ fm.underlying.keySet - private val mappings = keys.toStream.map { x => - (x, fm.getCount(x).getOrElse(0) + FreqMap.this.getCount(x).getOrElse(0)) - } - val underlying = scala.collection.immutable.Map(mappings: _*) - val total = FreqMap.this.total + fm.total - } - - def --(fm: FreqMap[T]) = new FreqMap[T] { - val underlying = FreqMap.this.underlying transform { - case (x,n) => n - fm.getCount(x).getOrElse(0) - } - lazy val total = (0 /: underlying.valuesIterator) (_ + _) - } - - def getCount(t: T) = underlying.get(t) - - def getCounts: List[(T,Int)] = underlying.toList.sortBy(-_._2) - - def getRatio(t: T) = for(c <- getCount(t)) yield (c: Float)/total - - def getRatios = for((t,c) <- getCounts) yield (t, (c: Float)/total) - - override def toString = underlying.toString -} - -object FreqMap { - def empty[T] = new FreqMap[T] { - val underlying = scala.collection.immutable.Map.empty[T,Int] - val total = 0 - } -} diff --git a/src/scalacheck/org/scalacheck/util/StdRand.scala b/src/scalacheck/org/scalacheck/util/StdRand.scala deleted file mode 100644 index 317b0ccd10..0000000000 --- a/src/scalacheck/org/scalacheck/util/StdRand.scala +++ /dev/null @@ -1,12 +0,0 @@ -/*-------------------------------------------------------------------------*\ -** ScalaCheck ** -** Copyright (c) 2007-2011 Rickard Nilsson. All rights reserved. ** -** http://www.scalacheck.org ** -** ** -** This software is released under the terms of the Revised BSD License. ** -** There is NO WARRANTY. See the file LICENSE for the full text. ** -\*------------------------------------------------------------------------ */ - -package org.scalacheck.util - -object StdRand extends java.util.Random |