From 88710b419a192fd0c22c834e191eb5012b58638b Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sat, 16 Jul 2011 20:44:05 +0000 Subject: Brought scalacheck up to date with scalacheck t... Brought scalacheck up to date with scalacheck trunk (rev 06612e965d) and rebuilt jar against r25318, no review. --- src/scalacheck/org/scalacheck/Arbitrary.scala | 10 +- src/scalacheck/org/scalacheck/Arg.scala | 2 +- src/scalacheck/org/scalacheck/Commands.scala | 14 ++- .../org/scalacheck/ConsoleReporter.scala | 34 +++---- src/scalacheck/org/scalacheck/Gen.scala | 108 ++++++++++++++++++--- src/scalacheck/org/scalacheck/Pretty.scala | 21 +++- src/scalacheck/org/scalacheck/Prop.scala | 38 ++++++-- src/scalacheck/org/scalacheck/Properties.scala | 18 ++-- src/scalacheck/org/scalacheck/Shrink.scala | 2 +- src/scalacheck/org/scalacheck/Test.scala | 31 +++--- src/scalacheck/org/scalacheck/util/Buildable.scala | 2 +- .../org/scalacheck/util/CmdLineParser.scala | 2 +- src/scalacheck/org/scalacheck/util/FreqMap.scala | 2 +- src/scalacheck/org/scalacheck/util/StdRand.scala | 2 +- 14 files changed, 197 insertions(+), 89 deletions(-) (limited to 'src/scalacheck') diff --git a/src/scalacheck/org/scalacheck/Arbitrary.scala b/src/scalacheck/org/scalacheck/Arbitrary.scala index 14d2b9b924..91d56b0aec 100644 --- a/src/scalacheck/org/scalacheck/Arbitrary.scala +++ b/src/scalacheck/org/scalacheck/Arbitrary.scala @@ -1,6 +1,6 @@ /*-------------------------------------------------------------------------*\ ** ScalaCheck ** -** Copyright (c) 2007-2010 Rickard Nilsson. All rights reserved. ** +** 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. ** @@ -115,7 +115,10 @@ object Arbitrary { /** Arbitrary instance of Char */ implicit lazy val arbChar: Arbitrary[Char] = Arbitrary( - Gen.choose(Char.MinValue, Char.MaxValue) + Gen.frequency( + (0xD800-Char.MinValue, Gen.choose(Char.MinValue,0xD800-1)), + (Char.MaxValue-0xDFFF, Gen.choose(0xDFFF+1,Char.MaxValue)) + ) ) /** Arbitrary instance of Byte */ @@ -209,7 +212,8 @@ object Arbitrary { minSize <- choose(0,500) sizeDiff <- choose(0,500) maxSize <- choose(minSize, minSize + sizeDiff) - } yield Test.Params(minSuccTests,maxDiscTests,minSize,maxSize)) + ws <- choose(1,4) + } yield Test.Params(minSuccTests,maxDiscTests,minSize,maxSize,workers = ws)) /** Arbitrary instance of gen params */ implicit lazy val arbGenParams: Arbitrary[Gen.Params] = diff --git a/src/scalacheck/org/scalacheck/Arg.scala b/src/scalacheck/org/scalacheck/Arg.scala index 99657db29b..908bce2a81 100644 --- a/src/scalacheck/org/scalacheck/Arg.scala +++ b/src/scalacheck/org/scalacheck/Arg.scala @@ -1,6 +1,6 @@ /*-------------------------------------------------------------------------*\ ** ScalaCheck ** -** Copyright (c) 2007-2010 Rickard Nilsson. All rights reserved. ** +** 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. ** diff --git a/src/scalacheck/org/scalacheck/Commands.scala b/src/scalacheck/org/scalacheck/Commands.scala index 952dd15953..112dda28a7 100644 --- a/src/scalacheck/org/scalacheck/Commands.scala +++ b/src/scalacheck/org/scalacheck/Commands.scala @@ -1,6 +1,6 @@ /*-------------------------------------------------------------------------*\ ** ScalaCheck ** -** Copyright (c) 2007-2010 Rickard Nilsson. All rights reserved. ** +** 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. ** @@ -27,7 +27,7 @@ trait Commands extends Prop { 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 + case Some(x) => x._2 } } @@ -47,7 +47,7 @@ trait Commands extends Prop { def nextState(s: State): State /** @deprecated Use preConditions += ... instead. */ - @deprecated("Use 'preConditions += ...' instead.") + @deprecated("Use 'preConditions += ...' instead.", "1.6") def preCondition_=(f: State => Boolean) = { preConditions.clear preConditions += f @@ -63,14 +63,14 @@ trait Commands extends Prop { val preConditions = new collection.mutable.ListBuffer[State => Boolean] /** @deprecated Use postConditions += ... instead. */ - @deprecated("Use 'postConditions += ...' instead.") + @deprecated("Use 'postConditions += ...' instead.", "1.6") def postCondition_=(f: (State,Any) => Prop) = { postConditions.clear postConditions += ((s0,s1,r) => f(s0,r)) } /** @deprecated Use postConditions += ... instead. */ - @deprecated("Use 'postConditions += ...' instead.") + @deprecated("Use 'postConditions += ...' instead.", "1.6") def postCondition_=(f: (State,State,Any) => Prop) = { postConditions.clear postConditions += f @@ -138,18 +138,16 @@ trait Commands extends Prop { 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)) + 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) diff --git a/src/scalacheck/org/scalacheck/ConsoleReporter.scala b/src/scalacheck/org/scalacheck/ConsoleReporter.scala index a94d32797f..c3af6c83a3 100644 --- a/src/scalacheck/org/scalacheck/ConsoleReporter.scala +++ b/src/scalacheck/org/scalacheck/ConsoleReporter.scala @@ -1,6 +1,6 @@ /*-------------------------------------------------------------------------*\ ** ScalaCheck ** -** Copyright (c) 2007-2010 Rickard Nilsson. All rights reserved. ** +** 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. ** @@ -16,28 +16,16 @@ class ConsoleReporter(val verbosity: Int) extends Test.TestCallback { private val prettyPrms = Params(verbosity) - override def onPropEval(name: String, w: Int, s: Int, d: Int) = + override def onTestResult(name: String, res: Test.Result) = { if(verbosity > 0) { if(name == "") { - if(d == 0) printf("\rPassed %s tests\r", s) - else printf("\rPassed %s tests; %s discarded\r", s, d) + val s = (if(res.passed) "+ " else "! ") + pretty(res, prettyPrms) + printf("\r%s\n", format(s, "", "", 75)) } else { - if(d == 0) printf("\r %s: Passed %s tests\r", name, s) - else printf("\r %s: Passed %s tests; %s discarded\r", name, s, d) + val s = (if(res.passed) "+ " else "! ") + name + ": " + + pretty(res, prettyPrms) + printf("\r%s\n", format(s, "", "", 75)) } - Console.flush - } - - override def onTestResult(name: String, res: Test.Result) = { - if(name == "") { - print(List.fill(78)(' ').mkString) - val s = (if(res.passed) "+ " else "! ") + pretty(res, prettyPrms) - printf("\r%s\n", format(s, "", "", 75)) - } else { - print(List.fill(78)(' ').mkString) - val s = (if(res.passed) "+ " else "! ") + name + ": " + - pretty(res, prettyPrms) - printf("\r%s\n", format(s, "", "", 75)) } } @@ -49,21 +37,21 @@ object ConsoleReporter { * the given verbosity */ def apply(verbosity: Int = 0) = new ConsoleReporter(verbosity) - @deprecated("(v1.8)") + @deprecated("(v1.8)", "1.8") def propReport(s: Int, d: Int) = { if(d == 0) printf("\rPassed %s tests\r", s) else printf("\rPassed %s tests; %s discarded\r", s, d) Console.flush } - @deprecated("(v1.8)") + @deprecated("(v1.8)", "1.8") def propReport(pName: String, s: Int, d: Int) = { if(d == 0) printf("\r %s: Passed %s tests\r", pName, s) else printf("\r %s: Passed %s tests; %s discarded\r", pName, s, d) Console.flush } - @deprecated("(v1.8)") + @deprecated("(v1.8)", "1.8") def testReport(res: Test.Result) = { print(List.fill(78)(' ').mkString) val s = (if(res.passed) "+ " else "! ") + pretty(res, Params(0)) @@ -71,7 +59,7 @@ object ConsoleReporter { res } - @deprecated("(v1.8)") + @deprecated("(v1.8)", "1.8") def testStatsEx(res: Test.Result): Unit = testStatsEx("", res) def testStatsEx(msg: String, res: Test.Result) = { diff --git a/src/scalacheck/org/scalacheck/Gen.scala b/src/scalacheck/org/scalacheck/Gen.scala index ca1dae0d3c..a253b040cd 100644 --- a/src/scalacheck/org/scalacheck/Gen.scala +++ b/src/scalacheck/org/scalacheck/Gen.scala @@ -1,6 +1,6 @@ /*-------------------------------------------------------------------------*\ ** ScalaCheck ** -** Copyright (c) 2007-2010 Rickard Nilsson. All rights reserved. ** +** 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. ** @@ -152,7 +152,7 @@ sealed trait Gen[+T] { * and the given generator generates the same result, or both * generators generate no result. * @deprecated Use == instead */ - @deprecated("Use == instead") + @deprecated("Use == instead", "1.7") def ===[U](g: Gen[U]): Prop = this == g /** Returns a new property that holds if and only if both this @@ -207,12 +207,7 @@ object Gen { def choose(l: Long, h: Long): Long = { val d = h-l if (d < 0) throw new IllegalArgumentException("Invalid range") - else if (d == 0) l - else { - val r = math.abs(rng.nextLong) - val a = if(r == Long.MinValue) 1 else 0 - l + (math.abs(r+a) % d) + a - } + else l + math.abs(rng.nextLong % (d+1)) } /** @throws IllegalArgumentException if l is greater than h, or if @@ -228,7 +223,7 @@ object Gen { /* Default generator parameters * @deprecated Use Gen.Params() instead */ - @deprecated("Use Gen.Params() instead") + @deprecated("Use Gen.Params() instead", "1.8") val defaultParams = Params() /* Generator factory method */ @@ -318,13 +313,13 @@ object Gen { /** Chooses one of the given values, with a weighted random distribution. * @deprecated Use frequency with constant generators * instead. */ - @deprecated("Use 'frequency' with constant generators instead.") + @deprecated("Use 'frequency' with constant generators instead.", "1.6") def elementsFreq[T](vs: (Int, T)*): Gen[T] = frequency(vs.map { case (w,v) => (w, value(v)) } : _*) /** A generator that returns a random element from a list * @deprecated Use oneOf with constant generators instead. */ - @deprecated("Use 'oneOf' with constant generators instead.") + @deprecated("Use 'oneOf' with constant generators instead.", "1.6") def elements[T](xs: T*): Gen[T] = if(xs.isEmpty) fail else for { i <- choose(0,xs.length-1) } yield xs(i) @@ -376,7 +371,7 @@ object Gen { /** Generates a list of the given length. This method is equal to calling * containerOfN[List,T](n,g). * @deprecated Use the method listOfN instead. */ - @deprecated("Use 'listOfN' instead.") + @deprecated("Use 'listOfN' instead.", "1.6") def vectorOf[T](n: Int, g: Gen[T]) = containerOfN[List,T](n,g) /** A generator that picks a random number of elements from a list */ @@ -445,12 +440,12 @@ object Gen { /* Generates positive integers * @deprecated Use posNum[Int]code> instead */ - @deprecated("Use posNum[Int] instead") + @deprecated("Use posNum[Int] instead", "1.7") def posInt: Gen[Int] = sized(max => choose(1, max)) /* Generates negative integers * @deprecated Use negNum[Int]code> instead */ - @deprecated("Use negNum[Int] instead") + @deprecated("Use negNum[Int] instead", "1.7") def negInt: Gen[Int] = sized(max => choose(-max, -1)) /** Generates positive numbers of uniform distribution, with an @@ -484,4 +479,89 @@ object Gen { ) 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 index d3945a1985..f59ac315c7 100644 --- a/src/scalacheck/org/scalacheck/Pretty.scala +++ b/src/scalacheck/org/scalacheck/Pretty.scala @@ -1,6 +1,6 @@ /*-------------------------------------------------------------------------*\ ** ScalaCheck ** -** Copyright (c) 2007-2010 Rickard Nilsson. All rights reserved. ** +** 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. ** @@ -59,7 +59,10 @@ object Pretty { getClassName+"."+getMethodName + "("+getFileName+":"+getLineNumber+")" } - val strs2 = if(prms.verbosity > 0) strs else strs.take(5) + 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") } @@ -69,7 +72,7 @@ object Pretty { for((a,i) <- args.zipWithIndex) yield { val l = if(a.label == "") "ARG_"+i else a.label val s = - if(a.shrinks == 0) "" + if(a.shrinks == 0 || prms.verbosity <= 1) "" else " (orig arg: "+a.prettyOrigArg(prms)+")" "> "+l+": "+a.prettyArg(prms)+""+s @@ -106,9 +109,17 @@ object Pretty { "Exception raised on property evaluation."/labels(l)/pretty(args,prms)/ "> Exception: "+pretty(e,prms) case Test.GenException(e) => - "Exception raised on argument generation."/"> Stack trace: "/pretty(e,prms) + "Exception raised on argument generation."/ + "> Exception: "+pretty(e,prms) } - s/pretty(res.freqMap,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 index 199a668914..c8b19097d2 100644 --- a/src/scalacheck/org/scalacheck/Prop.scala +++ b/src/scalacheck/org/scalacheck/Prop.scala @@ -1,6 +1,6 @@ /*-------------------------------------------------------------------------*\ ** ScalaCheck ** -** Copyright (c) 2007-2010 Rickard Nilsson. All rights reserved. ** +** 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. ** @@ -39,17 +39,35 @@ trait Prop { /** 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 check methods in Test instead. */ - def check(): Unit = check(Test.Params()) + def check: Unit = check(Test.Params()) - /** Convenience method that makes it possible to use a this property - * as an application that checks itself on execution */ - def main(args: Array[String]): Unit = + /** 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, _) => Test.check(params, this) + 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 = true + + /** 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 @@ -90,7 +108,7 @@ trait Prop { * proved, and the other one passed, then the resulting property * will fail. * @deprecated Use == instead */ - @deprecated("Use == instead.") + @deprecated("Use == instead.", "1.7") def ===(p: Prop): Prop = this == p override def toString = "Prop" @@ -318,12 +336,14 @@ object Prop { 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 => f(prms.genPrms.size)(prms)) + def sizedProp(f: Int => Prop): Prop = Prop { prms => + provedToTrue(f(prms.genPrms.size)(prms)) + } /** Implication * @deprecated Use the implication operator of the Prop class instead */ - @deprecated("Use the implication operator of the Prop class instead") + @deprecated("Use the implication operator of the Prop class instead", "1.7") def ==>(b: => Boolean, p: => Prop): Prop = (b: Prop) ==> p /** Implication with several conditions */ diff --git a/src/scalacheck/org/scalacheck/Properties.scala b/src/scalacheck/org/scalacheck/Properties.scala index 7fceb4bd35..8a5b3febc9 100644 --- a/src/scalacheck/org/scalacheck/Properties.scala +++ b/src/scalacheck/org/scalacheck/Properties.scala @@ -1,6 +1,6 @@ /*-------------------------------------------------------------------------*\ ** ScalaCheck ** -** Copyright (c) 2007-2010 Rickard Nilsson. All rights reserved. ** +** 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. ** @@ -51,17 +51,23 @@ class Properties(val name: String) extends Prop { /** 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 check methods in Test instead. */ - override def check(): Unit = check(Test.Params()) + override def check: Unit = check(Test.Params()) - /** Convenience method that makes it possible to use a this instance - * as an application that checks itself on execution */ - override def main(args: Array[String]): Unit = + /** 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, _) => Test.checkProperties(params, this) + 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 diff --git a/src/scalacheck/org/scalacheck/Shrink.scala b/src/scalacheck/org/scalacheck/Shrink.scala index 70ab5f6d23..a077f21573 100644 --- a/src/scalacheck/org/scalacheck/Shrink.scala +++ b/src/scalacheck/org/scalacheck/Shrink.scala @@ -1,6 +1,6 @@ /*-------------------------------------------------------------------------*\ ** ScalaCheck ** -** Copyright (c) 2007-2010 Rickard Nilsson. All rights reserved. ** +** 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. ** diff --git a/src/scalacheck/org/scalacheck/Test.scala b/src/scalacheck/org/scalacheck/Test.scala index 0a39707ce0..48b0a151a1 100644 --- a/src/scalacheck/org/scalacheck/Test.scala +++ b/src/scalacheck/org/scalacheck/Test.scala @@ -1,6 +1,6 @@ /*-------------------------------------------------------------------------*\ ** ScalaCheck ** -** Copyright (c) 2007-2010 Rickard Nilsson. All rights reserved. ** +** 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. ** @@ -28,7 +28,7 @@ object Test { ) /** Test statistics */ - case class Result(status: Status, succeeded: Int, discarded: Int, freqMap: FM) { + case class Result(status: Status, succeeded: Int, discarded: Int, freqMap: FM, time: Long = 0) { def passed = status match { case Passed => true case Proved(_) => true @@ -157,7 +157,6 @@ object Test { def check(prms: Params, p: Prop): Result = { import prms._ import actors.Futures.future - //import scala.concurrent.ops.future assertParams(prms) if(workers > 1) @@ -170,7 +169,7 @@ object Test { def worker(workerdIdx: Int) = future { var n = 0 var d = 0 - var size = workerdIdx*sizeStep + var size = minSize + (workerdIdx*sizeStep*iterations) var res: Result = null var fm = FreqMap.empty[immutable.Set[Any]] while(!stop && res == null && n < iterations) { @@ -207,21 +206,23 @@ object Test { } def mergeResults(r1: () => Result, r2: () => Result) = r1() match { - case Result(Passed, s1, d1, fm1) => r2() match { - case Result(Passed, s2, d2, fm2) if d1+d2 >= maxDiscardedTests => - () => Result(Exhausted, s1+s2, d1+d2, fm1++fm2) - case Result(st, s2, d2, fm2) => - () => Result(st, s1+s2, d1+d2, fm1++fm2) + case Result(Passed, s1, d1, fm1, t) => r2() match { + case Result(Passed, s2, d2, fm2, t) if d1+d2 >= maxDiscardedTests => + () => Result(Exhausted, s1+s2, d1+d2, fm1++fm2, t) + case Result(st, s2, d2, fm2, t) => + () => Result(st, s1+s2, d1+d2, fm1++fm2, t) } case r => () => r } + val start = System.currentTimeMillis val results = for(i <- 0 until workers) yield worker(i) val r = results.reduceLeft(mergeResults)() stop = true results foreach (_.apply()) - prms.testCallback.onTestResult("", r) - r + val timedRes = r.copy(time = System.currentTimeMillis-start) + prms.testCallback.onTestResult("", timedRes) + timedRes } def checkProperties(prms: Params, ps: Properties): Seq[(String,Result)] = @@ -241,21 +242,21 @@ object Test { /** Default testing parameters * @deprecated Use Test.Params() instead */ - @deprecated("Use Test.Params() instead") + @deprecated("Use Test.Params() instead", "1.8") val defaultParams = Params() /** Property evaluation callback. Takes number of passed and * discarded tests, respectively */ - @deprecated("(v1.8)") + @deprecated("(v1.8)", "1.8") type PropEvalCallback = (Int,Int) => Unit /** Property evaluation callback. Takes property name, and number of passed * and discarded tests, respectively */ - @deprecated("(v1.8)") + @deprecated("(v1.8)", "1.8") type NamedPropEvalCallback = (String,Int,Int) => Unit /** Test callback. Takes property name, and test results. */ - @deprecated("(v1.8)") + @deprecated("(v1.8)", "1.8") type TestResCallback = (String,Result) => Unit /** @deprecated (v1.8) Use check(prms.copy(testCallback = myCallback), p) instead. */ diff --git a/src/scalacheck/org/scalacheck/util/Buildable.scala b/src/scalacheck/org/scalacheck/util/Buildable.scala index a41448ee94..6378e72d4f 100644 --- a/src/scalacheck/org/scalacheck/util/Buildable.scala +++ b/src/scalacheck/org/scalacheck/util/Buildable.scala @@ -1,6 +1,6 @@ /*-------------------------------------------------------------------------*\ ** ScalaCheck ** -** Copyright (c) 2007-2010 Rickard Nilsson. All rights reserved. ** +** 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. ** diff --git a/src/scalacheck/org/scalacheck/util/CmdLineParser.scala b/src/scalacheck/org/scalacheck/util/CmdLineParser.scala index 5fb572ac2d..a63e4ba10e 100644 --- a/src/scalacheck/org/scalacheck/util/CmdLineParser.scala +++ b/src/scalacheck/org/scalacheck/util/CmdLineParser.scala @@ -1,6 +1,6 @@ /*-------------------------------------------------------------------------*\ ** ScalaCheck ** -** Copyright (c) 2007-2010 Rickard Nilsson. All rights reserved. ** +** 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. ** diff --git a/src/scalacheck/org/scalacheck/util/FreqMap.scala b/src/scalacheck/org/scalacheck/util/FreqMap.scala index 11cdb3ec28..902c148d67 100644 --- a/src/scalacheck/org/scalacheck/util/FreqMap.scala +++ b/src/scalacheck/org/scalacheck/util/FreqMap.scala @@ -1,6 +1,6 @@ /*-------------------------------------------------------------------------*\ ** ScalaCheck ** -** Copyright (c) 2007-2010 Rickard Nilsson. All rights reserved. ** +** 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. ** diff --git a/src/scalacheck/org/scalacheck/util/StdRand.scala b/src/scalacheck/org/scalacheck/util/StdRand.scala index ccdbbea301..4cc83a4172 100644 --- a/src/scalacheck/org/scalacheck/util/StdRand.scala +++ b/src/scalacheck/org/scalacheck/util/StdRand.scala @@ -1,6 +1,6 @@ /*-------------------------------------------------------------------------*\ ** ScalaCheck ** -** Copyright (c) 2007-2010 Rickard Nilsson. All rights reserved. ** +** 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. ** -- cgit v1.2.3