diff --git a/build.xml b/build.xml index 3bc22fb7e..a88650ced 100644 --- a/build.xml +++ b/build.xml @@ -1416,10 +1416,11 @@ BOOTRAPING TEST AND TEST SUITE - + + diff --git a/src/partest/scala/tools/partest/PartestTask.scala b/src/partest/scala/tools/partest/PartestTask.scala index 46ca3bf1f..fc76065d6 100644 --- a/src/partest/scala/tools/partest/PartestTask.scala +++ b/src/partest/scala/tools/partest/PartestTask.scala @@ -8,13 +8,18 @@ // $Id$ -package scala.tools.partest +package scala.tools +package partest import scala.actors.Actor._ -import util.Properties.setProp +import scala.util.Properties.setProp +import nsc.Settings +import nsc.util.ClassPath +import util.PathResolver import java.io.File import java.net.URLClassLoader +import java.lang.reflect.Method import org.apache.tools.ant.Task import org.apache.tools.ant.types.{Path, Reference, FileSet} @@ -44,6 +49,10 @@ class PartestTask extends Task { def addConfiguredBuildManagerTests(input: FileSet) { buildManagerFiles = Some(input) } + + def addConfiguredScalacheckTests(input: FileSet) { + scalacheckFiles = Some(input) + } def addConfiguredScriptTests(input: FileSet) { scriptFiles = Some(input) @@ -121,6 +130,7 @@ class PartestTask extends Task { private var jvmFiles: Option[FileSet] = None private var residentFiles: Option[FileSet] = None private var buildManagerFiles: Option[FileSet] = None + private var scalacheckFiles: Option[FileSet] = None private var scriptFiles: Option[FileSet] = None private var shootoutFiles: Option[FileSet] = None private var scalapFiles: Option[FileSet] = None @@ -161,67 +171,69 @@ class PartestTask extends Task { private def getJvmFiles = getFilesAndDirs(jvmFiles) private def getResidentFiles = getFiles(residentFiles) private def getBuildManagerFiles = getFilesAndDirs(buildManagerFiles) + private def getScalacheckFiles = getFiles(scalacheckFiles) private def getScriptFiles = getFiles(scriptFiles) private def getShootoutFiles = getFiles(shootoutFiles) private def getScalapFiles = getFiles(scalapFiles) + + private def findMethod(target: AnyRef, name: String, types: Class[_]*): Method = + target.getClass.getMethod(name, Array(types: _*): _*) + + private def invokeMethod[T](target: AnyRef, m: Method, args: AnyRef*): T = + m.invoke(target, args: _*).asInstanceOf[T] + + private def invoke[T](target: AnyRef, name: String, args: Any*): T = { + val boxed = args map (_.asInstanceOf[AnyRef]) + val m = findMethod(target, name, boxed map (_.getClass): _*) + invokeMethod[T](target, m, boxed: _*) + } override def execute() { if (isPartestDebug) setProp("partest.debug", "true") - if (classpath.isEmpty) - error("Mandatory attribute 'classpath' is not set.") - - val scalaLibrary = - (classpath.get.list map { fs => new File(fs) }) find { f => + val classpath = this.classpath getOrElse error("Mandatory attribute 'classpath' is not set.") + + val scalaLibrary = { + (classpath.list map { fs => new File(fs) }) find { f => f.getName match { case "scala-library.jar" => true case "library" if (f.getParentFile.getName == "classes") => true case _ => false } } - - if (scalaLibrary.isEmpty) - error("Provided classpath does not contain a Scala library.") + } getOrElse error("Provided classpath does not contain a Scala library.") val classloader = this.getClass.getClassLoader + def load(name: String) = classloader.loadClass(name).newInstance().asInstanceOf[AnyRef] - val antRunner: AnyRef = - classloader.loadClass("scala.tools.partest.nest.AntRunner").newInstance().asInstanceOf[AnyRef] - val antFileManager: AnyRef = - antRunner.getClass.getMethod("fileManager", Array[Class[_]](): _*).invoke(antRunner, Array[Object](): _*) + val antRunner = load("scala.tools.partest.nest.AntRunner") + val antFileManager = invoke[AnyRef](antRunner, "fileManager") + val runMethod = findMethod(antRunner, "reflectiveRunTestsForFiles", classOf[Array[File]], classOf[String]) - val runMethod = - antRunner.getClass.getMethod("reflectiveRunTestsForFiles", Array(classOf[Array[File]], classOf[String]): _*) - def runTestsForFiles(kindFiles: Array[File], kind: String) = - runMethod.invoke(antRunner, kindFiles, kind).asInstanceOf[scala.collection.Map[String, Int]] + invokeMethod[Map[String, Int]](antRunner, runMethod, kindFiles, kind) def setFileManagerBooleanProperty(name: String, value: Boolean) { - val setMethod = - antFileManager.getClass.getMethod(name+"_$eq", Array(classOf[Boolean]): _*) - setMethod.invoke(antFileManager, Array(java.lang.Boolean.valueOf(value)).asInstanceOf[Array[Object]]: _*) + val setMethod = findMethod(antFileManager, name + "_$eq", classOf[Boolean]) + invokeMethod[Unit](antFileManager, setMethod, Boolean.box(value)) } def setFileManagerStringProperty(name: String, value: String) { - val setMethod = - antFileManager.getClass.getMethod(name+"_$eq", Array(classOf[String]): _*) - setMethod.invoke(antFileManager, Array(value).asInstanceOf[Array[Object]]: _*) + val setMethod = findMethod(antFileManager, name + "_$eq", classOf[String]) + invokeMethod[Unit](antFileManager, setMethod, value) } setFileManagerBooleanProperty("showDiff", showDiff) setFileManagerBooleanProperty("showLog", showLog) - setFileManagerBooleanProperty("failed", runFailed) - if (!javacmd.isEmpty) - setFileManagerStringProperty("JAVACMD", javacmd.get.getAbsolutePath) - if (!javaccmd.isEmpty) - setFileManagerStringProperty("JAVAC_CMD", javaccmd.get.getAbsolutePath) - setFileManagerStringProperty("CLASSPATH", classpath.get.list.mkString(File.pathSeparator)) - setFileManagerStringProperty("LATEST_LIB", scalaLibrary.get.getAbsolutePath) - if (!scalacOpts.isEmpty) - setFileManagerStringProperty("SCALAC_OPTS", scalacOpts.get) - if (!timeout.isEmpty) - setFileManagerStringProperty("timeout", timeout.get) + setFileManagerBooleanProperty("failed", runFailed) + setFileManagerStringProperty("CLASSPATH", ClassPath.join(classpath.list: _*)) + setFileManagerStringProperty("LATEST_LIB", scalaLibrary.getAbsolutePath) + + javacmd foreach (x => setFileManagerStringProperty("JAVACMD", x.getAbsolutePath)) + javaccmd foreach (x => setFileManagerStringProperty("JAVAC_CMD", x.getAbsolutePath)) + scalacOpts foreach (x => setFileManagerStringProperty("SCALAC_OPTS", x)) + timeout foreach (x => setFileManagerStringProperty("timeout", x)) type TFSet = (Array[File], String, String) val testFileSets = List( @@ -231,6 +243,7 @@ class PartestTask extends Task { (getJvmFiles, "jvm", "Compiling and running files"), (getResidentFiles, "res", "Running resident compiler scenarii"), (getBuildManagerFiles, "buildmanager", "Running Build Manager scenarii"), + (getScalacheckFiles, "scalacheck", "Running scalacheck tests"), (getScriptFiles, "script", "Running script files"), (getShootoutFiles, "shootout", "Running shootout tests"), (getScalapFiles, "scalap", "Running scalap tests") @@ -242,15 +255,11 @@ class PartestTask extends Task { else { log(msg) val results: Iterable[(String, Int)] = runTestsForFiles(files, name) + val (succs, fails) = resultsToStatistics(results) - val (succs, fails) = - results - .map { case (file, resultCode) => if (resultCode == 0) (1, 0) else (0, 1) } - .reduceLeft((res1, res2) => (res1._1 + res2._1, res1._2 + res2._2)) - - val failed: Iterable[String] = results flatMap { case (path, state) => - if (state == 0) List() - else List(path+" ["+(if (state == 1) "FAILED" else "TIMOUT")+"]") + val failed: Iterable[String] = results partialMap { + case (path, 1) => path + " [FAILED]" + case (path, 2) => path + " [TIMOUT]" } // create JUnit Report xml files if directory was specified diff --git a/src/partest/scala/tools/partest/nest/ConsoleRunner.scala b/src/partest/scala/tools/partest/nest/ConsoleRunner.scala index c7d7f2a34..264e47b73 100644 --- a/src/partest/scala/tools/partest/nest/ConsoleRunner.scala +++ b/src/partest/scala/tools/partest/nest/ConsoleRunner.scala @@ -59,7 +59,7 @@ class ConsoleRunner extends DirectRunner { private val unaryArgs = List( "--pack", "--all", "--verbose", "--show-diff", "--show-log", - "--failed", "--version", "--ansi" + "--failed", "--version", "--ansi", "--debug" ) ::: testSetArgs def main(argstr: String) { @@ -98,6 +98,7 @@ class ConsoleRunner extends DirectRunner { if (parsed isSet "--ansi") NestUI initialize NestUI.MANY if (parsed isSet "--timeout") fileManager.timeout = parsed("--timeout") + if (parsed isSet "--debug") setProp("partest.debug", "true") testFiles :::= args map { arg => val file = new File(arg) @@ -157,11 +158,6 @@ class ConsoleRunner extends DirectRunner { System exit ( if (failures == errors) 0 else 1 ) } - def toStatistics[A](results: Iterable[(A, Int)]): (Int, Int) = { - val (files, failures) = results map (_._2 == 0) partition (_ == true) - (files.size, failures.size) - } - def runTests(testSet: TestSet): (Int, Int) = { val TestSet(loc, filter, kind, msg) = testSet @@ -170,7 +166,7 @@ class ConsoleRunner extends DirectRunner { case files => NestUI.verbose("test files: "+files) NestUI.outline("\n"+msg+"\n") - toStatistics(runTestsForFiles(files, kind)) + resultsToStatistics(runTestsForFiles(files, kind)) } } @@ -208,7 +204,7 @@ class ConsoleRunner extends DirectRunner { Predef.exit(1) } else { NestUI.outline("\nTesting individual files\n") - toStatistics(runTestsForFiles(testFiles, fstKind)) + resultsToStatistics(runTestsForFiles(testFiles, fstKind)) } } else (0, 0) diff --git a/src/partest/scala/tools/partest/nest/NestUI.scala b/src/partest/scala/tools/partest/nest/NestUI.scala index 90827b9a3..183e539ca 100644 --- a/src/partest/scala/tools/partest/nest/NestUI.scala +++ b/src/partest/scala/tools/partest/nest/NestUI.scala @@ -77,6 +77,7 @@ object NestUI { println(" --jvm run JVM backend tests") println(" --res run resident compiler tests") println(" --buildmanager run Build Manager tests") + println(" --scalacheck run ScalaCheck tests") println(" --script run script runner tests") println(" --shootout run shootout tests") println @@ -91,6 +92,7 @@ object NestUI { println(" --classpath set (absolute) path to build classes") println(" --srcpath set (relative) path to test source files") println(" ex.: --srcpath pending") + println(" --debug enable debugging output") println println(utils.Properties.versionString) println("maintained by Philipp Haller (EPFL)") @@ -98,6 +100,7 @@ object NestUI { } var _verbose = false + var _debug = false def verbose(msg: String) { if (_verbose) { @@ -105,5 +108,10 @@ object NestUI { println(msg) } } - + def debug(msg: String) { + if (isPartestDebug) { + outline("debug: ") + println(msg) + } + } } diff --git a/src/partest/scala/tools/partest/nest/Worker.scala b/src/partest/scala/tools/partest/nest/Worker.scala index dbd0b6651..8e0a1bd41 100644 --- a/src/partest/scala/tools/partest/nest/Worker.scala +++ b/src/partest/scala/tools/partest/nest/Worker.scala @@ -449,6 +449,9 @@ class Worker(val fileManager: FileManager) extends Actor { val outURL = outDir.getCanonicalFile.toURI.toURL val classpath: List[URL] = List(outURL, scalacheckURL, latestCompFile.toURI.toURL, latestLibFile.toURI.toURL, latestPartestFile.toURI.toURL).distinct + + NestUI.debug("scalacheck urls") + classpath foreach (x => NestUI.debug(x.toString)) val logWriter = new PrintStream(new FileOutputStream(logFile)) diff --git a/src/partest/scala/tools/partest/package.scala b/src/partest/scala/tools/partest/package.scala index 61c726f96..6a555d47d 100644 --- a/src/partest/scala/tools/partest/package.scala +++ b/src/partest/scala/tools/partest/package.scala @@ -12,6 +12,10 @@ package object partest { import nest.NestUI def basename(name: String): String = Path(name).stripExtension + def resultsToStatistics(results: Iterable[(_, Int)]): (Int, Int) = { + val (files, failures) = results map (_._2 == 0) partition (_ == true) + (files.size, failures.size) + } object PartestDefaults { import nsc.Properties._ diff --git a/test/files/lib/scalacheck-1.7-SNAPSHOT.jar b/test/files/lib/scalacheck-1.7-SNAPSHOT.jar new file mode 120000 index 000000000..127d85268 --- /dev/null +++ b/test/files/lib/scalacheck-1.7-SNAPSHOT.jar @@ -0,0 +1 @@ +../../../lib/scalacheck-1.7-SNAPSHOT.jar \ No newline at end of file diff --git a/test/files/scalacheck/array.scala b/test/files/scalacheck/array.scala index 7466eddd0..4eed23bc5 100644 --- a/test/files/scalacheck/array.scala +++ b/test/files/scalacheck/array.scala @@ -4,36 +4,34 @@ import Gen._ import Arbitrary._ import util._ import Buildable._ +import scala.collection.mutable.GenericArray -object Test extends Properties("Array") { - val myGens: Seq[Gen[Array[_]]] = List( - arbArray[Int], - arbArray[Array[Int]], - arbArray[List[String]], - arbArray[String], - arbArray[Boolean], - arbArray[AnyVal](arbAnyVal) - ) map (_.arbitrary) +object Test extends Properties("Array") { + /** At this moment the authentic scalacheck Array Builder/Arb bits are commented out. + */ + implicit def arbArray[T](implicit a: Arbitrary[T], m: Manifest[T]): Arbitrary[Array[T]] = + Arbitrary(containerOf[List,T](arbitrary[T]) map (_.toArray)) + + val arrGen: Gen[Array[_]] = oneOf( + arbitrary[Array[Int]], + arbitrary[Array[Array[Int]]], + arbitrary[Array[List[String]]], + arbitrary[Array[String]], + arbitrary[Array[Boolean]], + arbitrary[Array[AnyVal]] + ) // inspired by #1857 and #2352 - property("eq/ne") = - forAll(oneOf(myGens: _*)) { c1 => - forAll(oneOf(myGens: _*)) { c2 => - (c1 eq c2) || (c1 ne c2) - } - } - - def smallInt = choose(1, 10) - // inspired by #2299 - property("ofDim") = forAll(smallInt) { i1 => - forAll(smallInt) { i2 => - forAll(smallInt) { i3 => - val arr = Array.ofDim[String](i1, i2, i3) - val flattened = arr flatMap (x => x) flatMap (x => x) - - flattened.length == i1 * i2 * i3 - } - } + property("eq/ne") = forAll(arrGen, arrGen) { (c1, c2) => + (c1 eq c2) || (c1 ne c2) } + + // inspired by #2299 + def smallInt = choose(1, 10) + property("ofDim") = forAll(smallInt, smallInt, smallInt) { (i1, i2, i3) => + val arr = Array.ofDim[String](i1, i2, i3) + val flattened = arr flatMap (x => x) flatMap (x => x) + flattened.length == i1 * i2 * i3 + } } diff --git a/test/files/scalacheck/eqeq.scala b/test/files/scalacheck/eqeq.scala new file mode 100644 index 000000000..707bbc81b --- /dev/null +++ b/test/files/scalacheck/eqeq.scala @@ -0,0 +1,17 @@ +import org.scalacheck._ +import Prop._ +import Gen._ + +object Test extends Properties("==") { + property("reflexive") = forAll { (x: AnyVal, y: AnyVal) => (x == y) == (y == x) } + // property("hashCode") = forAll { (x + + property("short/char") = forAll { (x: Short) => { + val ch: Char = x.toChar + (x == ch) == (ch == x) || + // that's the whole test once it works, but since it doesn't yet: + x < 0 + } + } +} +