summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbuild.xml2
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala31
-rw-r--r--src/partest/scala/tools/partest/PartestDefaults.scala4
-rw-r--r--src/partest/scala/tools/partest/TestState.scala19
-rw-r--r--src/partest/scala/tools/partest/nest/ConsoleRunner.scala3
-rw-r--r--src/partest/scala/tools/partest/nest/DirectCompiler.scala2
-rw-r--r--src/partest/scala/tools/partest/nest/DirectRunner.scala52
-rw-r--r--src/partest/scala/tools/partest/nest/FileManager.scala1
-rw-r--r--src/partest/scala/tools/partest/nest/NestUI.scala24
-rw-r--r--src/partest/scala/tools/partest/nest/PathSettings.scala8
-rw-r--r--src/partest/scala/tools/partest/nest/ReflectiveRunner.scala2
-rw-r--r--src/partest/scala/tools/partest/nest/Runner.scala317
-rw-r--r--src/partest/scala/tools/partest/nest/RunnerManager.scala97
-rw-r--r--src/partest/scala/tools/partest/package.scala24
-rw-r--r--src/scalacheck/org/scalacheck/Arbitrary.scala83
-rw-r--r--src/scalacheck/org/scalacheck/Arg.scala2
-rw-r--r--src/scalacheck/org/scalacheck/Commands.scala11
-rw-r--r--src/scalacheck/org/scalacheck/ConsoleReporter.scala2
-rw-r--r--src/scalacheck/org/scalacheck/Gen.scala41
-rw-r--r--src/scalacheck/org/scalacheck/Pretty.scala4
-rw-r--r--src/scalacheck/org/scalacheck/Prop.scala81
-rw-r--r--src/scalacheck/org/scalacheck/Properties.scala30
-rw-r--r--src/scalacheck/org/scalacheck/ScalaCheckFramework.scala92
-rw-r--r--src/scalacheck/org/scalacheck/Shrink.scala2
-rw-r--r--src/scalacheck/org/scalacheck/Test.scala207
-rw-r--r--src/scalacheck/org/scalacheck/util/Buildable.scala5
-rw-r--r--src/scalacheck/org/scalacheck/util/CmdLineParser.scala4
-rw-r--r--src/scalacheck/org/scalacheck/util/FreqMap.scala2
-rw-r--r--src/scalacheck/org/scalacheck/util/StdRand.scala2
-rw-r--r--test/files/scalacheck/HashTrieSplit.scala47
-rw-r--r--test/files/scalacheck/parallel-collections/pc.scala14
-rwxr-xr-xtest/partest1
-rw-r--r--test/scaladoc/scalacheck/CommentFactoryTest.scala2
-rw-r--r--test/scaladoc/scalacheck/HtmlFactoryTest.scala17
-rw-r--r--test/scaladoc/scalacheck/IndexScriptTest.scala14
-rw-r--r--test/scaladoc/scalacheck/IndexTest.scala12
36 files changed, 826 insertions, 435 deletions
diff --git a/build.xml b/build.xml
index e1c19fd909..2e101f1ec3 100755
--- a/build.xml
+++ b/build.xml
@@ -224,6 +224,7 @@ TODO:
<artifact:dependencies pathId="partest.extras.classpath" filesetId="partest.extras.fileset" versionsId="partest.extras.versions">
<dependency groupId="com.googlecode.java-diff-utils" artifactId="diffutils" version="1.3.0"/>
+ <dependency groupId="org.scala-tools.testing" artifactId="test-interface" version="0.5" />
</artifact:dependencies>
<!-- BND support -->
@@ -530,6 +531,7 @@ TODO:
<pathelement location="${build-quick.dir}/classes/library"/>
<pathelement location="${build-quick.dir}/classes/actors"/>
<pathelement location="${build-quick.dir}/classes/scalacheck"/>
+ <path refid="partest.extras.classpath"/>
</path>
<path id="quick.scalap.build.path">
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
index e9f42ea5ce..74d6d061e3 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
@@ -51,6 +51,22 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM {
override def erasedTypes = true
def apply(cls: IClass) = sys.error("no implementation")
+ // An AsmPhase starts and ends within a Run, thus the caches in question will get populated and cleared within a Run, too), SI-7422
+ javaNameCache.clear()
+ javaNameCache ++= List(
+ NothingClass -> binarynme.RuntimeNothing,
+ RuntimeNothingClass -> binarynme.RuntimeNothing,
+ NullClass -> binarynme.RuntimeNull,
+ RuntimeNullClass -> binarynme.RuntimeNull
+ )
+
+ // unlike javaNameCache, reverseJavaName contains entries only for class symbols and their internal names.
+ reverseJavaName.clear()
+ reverseJavaName ++= List(
+ binarynme.RuntimeNothing.toString() -> RuntimeNothingClass, // RuntimeNothingClass is the bytecode-level return type of Scala methods with Nothing return-type.
+ binarynme.RuntimeNull.toString() -> RuntimeNullClass
+ )
+
// Lazy val; can't have eager vals in Phase constructors which may
// cause cycles before Global has finished initialization.
lazy val BeanInfoAttr = rootMirror.getRequiredClass("scala.beans.BeanInfo")
@@ -130,8 +146,6 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM {
}
bytecodeWriter.close()
- classes.clear()
- reverseJavaName.clear()
/* don't javaNameCache.clear() because that causes the following tests to fail:
* test/files/run/macro-repl-dontexpand.scala
@@ -155,19 +169,10 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM {
var pickledBytes = 0 // statistics
- // Don't put this in per run caches. Contains entries for classes as well as members.
- val javaNameCache = new mutable.WeakHashMap[Symbol, Name]() ++= List(
- NothingClass -> binarynme.RuntimeNothing,
- RuntimeNothingClass -> binarynme.RuntimeNothing,
- NullClass -> binarynme.RuntimeNull,
- RuntimeNullClass -> binarynme.RuntimeNull
- )
+ val javaNameCache = perRunCaches.newMap[Symbol, Name]()
// unlike javaNameCache, reverseJavaName contains entries only for class symbols and their internal names.
- val reverseJavaName = mutable.Map.empty[String, Symbol] ++= List(
- binarynme.RuntimeNothing.toString() -> RuntimeNothingClass, // RuntimeNothingClass is the bytecode-level return type of Scala methods with Nothing return-type.
- binarynme.RuntimeNull.toString() -> RuntimeNullClass
- )
+ val reverseJavaName = perRunCaches.newMap[String, Symbol]()
private def mkFlags(args: Int*) = args.foldLeft(0)(_ | _)
private def hasPublicBitSet(flags: Int) = (flags & asm.Opcodes.ACC_PUBLIC) != 0
diff --git a/src/partest/scala/tools/partest/PartestDefaults.scala b/src/partest/scala/tools/partest/PartestDefaults.scala
index 16f1a6933f..8478edeb4d 100644
--- a/src/partest/scala/tools/partest/PartestDefaults.scala
+++ b/src/partest/scala/tools/partest/PartestDefaults.scala
@@ -1,6 +1,7 @@
package scala.tools
package partest
+import scala.concurrent.duration.Duration
import scala.tools.nsc.Properties.{ propOrElse, propOrNone, propOrEmpty }
import java.lang.Runtime.{ getRuntime => runtime }
@@ -21,6 +22,7 @@ object PartestDefaults {
def testBuild = propOrNone("partest.build")
def errorCount = propOrElse("partest.errors", "0").toInt
def numThreads = propOrNone("partest.threads") map (_.toInt) getOrElse runtime.availableProcessors
+ def waitTime = propOrNone("partest.timeout") map (Duration.apply) getOrElse Duration("4 hours")
- def timeout = "1200000"
+ //def timeout = "1200000" // per-test timeout
}
diff --git a/src/partest/scala/tools/partest/TestState.scala b/src/partest/scala/tools/partest/TestState.scala
index ce8e72f616..dbe8a222a5 100644
--- a/src/partest/scala/tools/partest/TestState.scala
+++ b/src/partest/scala/tools/partest/TestState.scala
@@ -12,13 +12,15 @@ sealed abstract class TestState {
def isOk = false
def isSkipped = false
def testIdent = testFile.testIdent
- def transcriptString = transcript.mkString("\n")
+ def transcriptString = transcript mkString EOL
def identAndReason = testIdent + reasonString
def status = s"$what - $identAndReason"
def longStatus = status + transcriptString
def reasonString = if (reason == "") "" else s" [$reason]"
+ def shortStatus = if (isOk) "ok" else "!!"
+
override def toString = status
}
@@ -27,18 +29,27 @@ object TestState {
def what = "uninitialized"
def reason = what
def transcript = Nil
+ override def shortStatus = "??"
}
case class Pass(testFile: File) extends TestState {
- final override def isOk = true
def what = "pass"
+ override def isOk = true
def transcript: List[String] = Nil
def reason = ""
}
- case class Skip(testFile: File, reason: String) extends TestState {
+ case class Updated(testFile: File) extends TestState {
+ def what = "updated"
override def isOk = true
- final override def isSkipped = true
def transcript: List[String] = Nil
+ def reason = "updated check file"
+ override def shortStatus = "++"
+ }
+ case class Skip(testFile: File, reason: String) extends TestState {
def what = "skip"
+ override def isOk = true
+ override def isSkipped = true
+ def transcript: List[String] = Nil
+ override def shortStatus = "--"
}
case class Fail(testFile: File, reason: String, transcript: List[String]) extends TestState {
def what = "fail"
diff --git a/src/partest/scala/tools/partest/nest/ConsoleRunner.scala b/src/partest/scala/tools/partest/nest/ConsoleRunner.scala
index ddd42f5601..e5ace20062 100644
--- a/src/partest/scala/tools/partest/nest/ConsoleRunner.scala
+++ b/src/partest/scala/tools/partest/nest/ConsoleRunner.scala
@@ -86,7 +86,7 @@ class ConsoleRunner extends DirectRunner {
) ::: standardArgs
private val binaryArgs = List(
- "--grep", "--srcpath", "--buildpath", "--classpath"
+ "--grep", "--srcpath", "--buildpath", "--classpath", "--timeout"
)
def main(argstr: String) {
@@ -109,6 +109,7 @@ class ConsoleRunner extends DirectRunner {
}
parsed get "--srcpath" foreach (x => setProp("partest.srcdir", x))
+ parsed get "--timeout" foreach (x => setProp("partest.timeout", x))
fileManager =
if (parsed isSet "--buildpath") new ConsoleFileManager(parsed("--buildpath"))
diff --git a/src/partest/scala/tools/partest/nest/DirectCompiler.scala b/src/partest/scala/tools/partest/nest/DirectCompiler.scala
index 650b6c35c8..8e5ff2abc4 100644
--- a/src/partest/scala/tools/partest/nest/DirectCompiler.scala
+++ b/src/partest/scala/tools/partest/nest/DirectCompiler.scala
@@ -48,7 +48,7 @@ class DirectCompiler(val fileManager: FileManager) {
}
def compile(runner: Runner, opts0: List[String], sources: List[File]): TestState = {
- import runner._
+ import runner.{ sources => _, _ }
val testSettings = new TestSettings(ClassPath.join(fileManager.LATEST_LIB, outDir.getPath))
val logWriter = new FileWriter(logFile)
diff --git a/src/partest/scala/tools/partest/nest/DirectRunner.scala b/src/partest/scala/tools/partest/nest/DirectRunner.scala
deleted file mode 100644
index 49dd39c344..0000000000
--- a/src/partest/scala/tools/partest/nest/DirectRunner.scala
+++ /dev/null
@@ -1,52 +0,0 @@
-/* NEST (New Scala Test)
- * Copyright 2007-2013 LAMP/EPFL
- * @author Philipp Haller
- */
-
-package scala.tools.partest
-package nest
-
-import java.io.File
-import scala.util.Properties.setProp
-import scala.tools.nsc.util.{ ScalaClassLoader, Exceptional }
-import scala.tools.nsc.io.Path
-import scala.collection.{ mutable, immutable }
-import java.util.concurrent._
-
-case class TestRunParams(val scalaCheckParentClassLoader: ScalaClassLoader)
-
-trait DirectRunner {
- def fileManager: FileManager
-
- import PartestDefaults.numThreads
-
- Thread.setDefaultUncaughtExceptionHandler(
- new Thread.UncaughtExceptionHandler {
- def uncaughtException(thread: Thread, t: Throwable) {
- val t1 = Exceptional unwrap t
- System.err.println(s"Uncaught exception on thread $thread: $t1")
- t1.printStackTrace()
- }
- }
- )
- def runTestsForFiles(kindFiles: List[File], kind: String): List[TestState] = {
-
- NestUI.resetTestNumber()
-
- val allUrls = PathSettings.scalaCheck.toURL :: fileManager.latestUrls
- val parentClassLoader = ScalaClassLoader fromURLs allUrls
- val pool = Executors newFixedThreadPool numThreads
- val manager = new RunnerManager(kind, fileManager, TestRunParams(parentClassLoader))
- val futures = kindFiles map (f => pool submit callable(manager runTest f))
-
- pool.shutdown()
- try if (!pool.awaitTermination(4, TimeUnit.HOURS))
- NestUI warning "Thread pool timeout elapsed before all tests were complete!"
- catch { case t: InterruptedException =>
- NestUI warning "Thread pool was interrupted"
- t.printStackTrace()
- }
-
- futures map (_.get)
- }
-}
diff --git a/src/partest/scala/tools/partest/nest/FileManager.scala b/src/partest/scala/tools/partest/nest/FileManager.scala
index 25371b7d54..230ada4803 100644
--- a/src/partest/scala/tools/partest/nest/FileManager.scala
+++ b/src/partest/scala/tools/partest/nest/FileManager.scala
@@ -85,7 +85,6 @@ trait FileManager extends FileUtil {
var SCALAC_OPTS = PartestDefaults.scalacOpts.split(' ').toSeq
var JAVA_OPTS = PartestDefaults.javaOpts
- var timeout = PartestDefaults.timeout
/** Only when --debug is given. */
lazy val testTimings = new mutable.HashMap[String, Long]
diff --git a/src/partest/scala/tools/partest/nest/NestUI.scala b/src/partest/scala/tools/partest/nest/NestUI.scala
index 2e203bfd91..87ffb0fed2 100644
--- a/src/partest/scala/tools/partest/nest/NestUI.scala
+++ b/src/partest/scala/tools/partest/nest/NestUI.scala
@@ -27,9 +27,14 @@ class Colors(enabled: => Boolean) {
object NestUI {
private val testNum = new java.util.concurrent.atomic.AtomicInteger(1)
+ @volatile private var testNumberFmt = "%3d"
// @volatile private var testNumber = 1
- private def testNumber = "%3d" format testNum.getAndIncrement()
- def resetTestNumber() = testNum set 1
+ private def testNumber = testNumberFmt format testNum.getAndIncrement()
+ def resetTestNumber(max: Int = -1) {
+ testNum set 1
+ val width = if (max > 0) max.toString.length else 3
+ testNumberFmt = s"%${width}d"
+ }
var colorEnabled = sys.props contains "partest.colors"
val color = new Colors(colorEnabled)
@@ -57,12 +62,15 @@ object NestUI {
def statusLine(state: TestState) = {
import state._
- val word = bold(
- if (isSkipped) yellow("--")
- else if (isOk) green("ok")
- else red("!!")
- )
- word + f" $testNumber%3s - $testIdent%-40s$reasonString"
+ import TestState._
+ val colorizer = state match {
+ case _: Skip => yellow
+ case _: Updated => cyan
+ case s if s.isOk => green
+ case _ => red
+ }
+ val word = bold(colorizer(state.shortStatus))
+ f"$word $testNumber - $testIdent%-40s$reasonString"
}
def reportTest(state: TestState) = {
diff --git a/src/partest/scala/tools/partest/nest/PathSettings.scala b/src/partest/scala/tools/partest/nest/PathSettings.scala
index bae6bf819d..8e454d8de8 100644
--- a/src/partest/scala/tools/partest/nest/PathSettings.scala
+++ b/src/partest/scala/tools/partest/nest/PathSettings.scala
@@ -7,9 +7,9 @@ package nest
import scala.tools.nsc.Properties.{ setProp, propOrEmpty, propOrNone, propOrElse }
import scala.tools.nsc.util.ClassPath
-import scala.tools.nsc.io
+import scala.tools.nsc.io.{ Path, File, Directory }
import scala.util.Properties.{ envOrElse, envOrNone, javaHome, jdkHome }
-import io.{ Path, File, Directory }
+import Path._
object PathSettings {
import PartestDefaults.{ testRootDir, srcDirName }
@@ -19,6 +19,8 @@ object PathSettings {
private def findJar(d: Directory, name: String): Option[File] = findJar(d.files, name)
private def findJar(files: Iterator[File], name: String): Option[File] =
files filter (_ hasExtension "jar") find { _.name startsWith name }
+ private def findJarOrFail(name: String, ds: Directory*): File = findJar(ds flatMap (_.files) iterator, name) getOrElse
+ sys.error(s"'${name}.jar' not found in '${ds map (_.path) mkString ", "}'.")
// Directory <root>/test
lazy val testRoot: Directory = testRootDir getOrElse {
@@ -73,6 +75,8 @@ object PathSettings {
sys.error("No scalacheck jar found in '%s' or '%s'".format(buildPackLibDir, srcLibDir))
}
+ lazy val testInterface: File = findJarOrFail("test-interface", buildPackLibDir, srcLibDir)
+
lazy val diffUtils: File =
findJar(buildPackLibDir.files, "diffutils") getOrElse sys.error(s"No diffutils.jar found in '$buildPackLibDir'.")
diff --git a/src/partest/scala/tools/partest/nest/ReflectiveRunner.scala b/src/partest/scala/tools/partest/nest/ReflectiveRunner.scala
index 9780e82cd9..734affa153 100644
--- a/src/partest/scala/tools/partest/nest/ReflectiveRunner.scala
+++ b/src/partest/scala/tools/partest/nest/ReflectiveRunner.scala
@@ -55,7 +55,7 @@ class ReflectiveRunner {
// we hack into the classloader that will become parent classloader for scalac
// this way we ensure that reflective macro lookup will pick correct Code.lift
// it's also used to inject diffutils into the classpath when running partest from the test/partest script
- val srcCodeLibAndDiff = List(PathSettings.srcCodeLib, PathSettings.diffUtils)
+ val srcCodeLibAndDiff = List(PathSettings.srcCodeLib, PathSettings.diffUtils, PathSettings.testInterface)
val sepUrls = srcCodeLibAndDiff.map(_.toURI.toURL) ::: fileManager.latestUrls
// this seems to be the core classloader that determines which classes can be found when running partest from the test/partest script
val sepLoader = new URLClassLoader(sepUrls.toArray, null)
diff --git a/src/partest/scala/tools/partest/nest/Runner.scala b/src/partest/scala/tools/partest/nest/Runner.scala
index fc56818bfc..d8e1eeb9b9 100644
--- a/src/partest/scala/tools/partest/nest/Runner.scala
+++ b/src/partest/scala/tools/partest/nest/Runner.scala
@@ -7,19 +7,24 @@ package nest
import java.io.{ Console => _, _ }
import java.net.URL
-import scala.tools.nsc.Properties.{ jdkHome, javaHome, propOrElse, propOrEmpty }
-import scala.util.Properties.{ envOrElse, isWin }
+import java.nio.charset.{ Charset, CharsetDecoder, CharsetEncoder, CharacterCodingException, CodingErrorAction => Action }
+import java.util.concurrent.Executors
+import java.util.concurrent.TimeUnit.NANOSECONDS
+import scala.collection.mutable.ListBuffer
+import scala.concurrent.duration.Duration
+import scala.io.Codec
+import scala.sys.process.Process
+import scala.tools.nsc.Properties.{ envOrElse, isWin, jdkHome, javaHome, propOrElse, propOrEmpty, setProp }
import scala.tools.nsc.{ Settings, CompilerCommand, Global }
-import scala.tools.nsc.io.{ AbstractFile, PlainFile, Path, Directory, File => SFile }
+import scala.tools.nsc.io.{ AbstractFile, PlainFile }
import scala.tools.nsc.reporters.ConsoleReporter
-import scala.tools.nsc.util.{ ClassPath, FakePos, ScalaClassLoader, stackTraceString }
-import ClassPath.{ join, split }
+import scala.tools.nsc.util.{ Exceptional, ScalaClassLoader, stackTraceString }
+import scala.tools.scalap.Main.decompileScala
import scala.tools.scalap.scalax.rules.scalasig.ByteCode
-import scala.collection.{ mutable, immutable }
-import scala.sys.process.Process
-import java.util.concurrent.{ Executors, TimeUnit, TimeoutException }
+import scala.util.{ Try, Success, Failure }
+import ClassPath.{ join, split }
import PartestDefaults.{ javaCmd, javacCmd }
-import scala.tools.scalap.Main.decompileScala
+import TestState.{ Pass, Fail, Crash, Uninitialized, Updated }
trait PartestRunSettings {
def gitPath: Path
@@ -35,7 +40,7 @@ trait PartestRunSettings {
class TestTranscript {
import NestUI.color._
- private val buf = mutable.ListBuffer[String]()
+ private val buf = ListBuffer[String]()
private def pass(s: String) = bold(green("% ")) + s
private def fail(s: String) = bold(red("% ")) + s
@@ -49,7 +54,8 @@ class TestTranscript {
}
}
-class Runner(val testFile: File, fileManager: FileManager) {
+/** Run a single test. Rubber meets road. */
+class Runner(val testFile: File, fileManager: FileManager, val testRunParams: TestRunParams) {
import fileManager._
// Override to true to have the outcome of this test displayed
@@ -57,12 +63,10 @@ class Runner(val testFile: File, fileManager: FileManager) {
// except for a . per passing test to show progress.
def isEnumeratedTest = false
- def testRunParams: TestRunParams = ???
-
private var _lastState: TestState = null
private var _transcript = new TestTranscript
- def lastState = if (_lastState == null) TestState.Uninitialized(testFile) else _lastState
+ def lastState = if (_lastState == null) Uninitialized(testFile) else _lastState
def setLastState(s: TestState) = _lastState = s
def transcript: List[String] = _transcript.fail ++ logFile.fileLines
def pushTranscript(msg: String) = _transcript add msg
@@ -94,10 +98,11 @@ class Runner(val testFile: File, fileManager: FileManager) {
genCrash(t)
}
- def genPass() = TestState.Pass(testFile)
- def genFail(reason: String) = TestState.Fail(testFile, reason, _transcript.fail)
- def genTimeout() = TestState.Fail(testFile, "timed out", _transcript.fail)
- def genCrash(caught: Throwable) = TestState.Crash(testFile, caught, _transcript.fail)
+ def genPass() = Pass(testFile)
+ def genFail(reason: String) = Fail(testFile, reason, _transcript.fail)
+ def genTimeout() = Fail(testFile, "timed out", _transcript.fail)
+ def genCrash(caught: Throwable) = Crash(testFile, caught, _transcript.fail)
+ def genUpdated() = Updated(testFile)
def speclib = PathSettings.srcSpecLib.toString // specialization lib
def codelib = PathSettings.srcCodeLib.toString // reify lib
@@ -151,14 +156,18 @@ class Runner(val testFile: File, fileManager: FileManager) {
case _ => "% "
}
+ /** Evaluate an action body and update the test state.
+ * @param failFn optionally map a result to a test state.
+ */
def nextTestAction[T](body: => T)(failFn: PartialFunction[T, TestState]): T = {
val result = body
setLastState( if (failFn isDefinedAt result) failFn(result) else genPass() )
result
}
- def nextTestActionExpectTrue[T](reason: String, body: => Boolean): Boolean = {
+ def nextTestActionExpectTrue(reason: String, body: => Boolean): Boolean = (
nextTestAction(body) { case false => genFail(reason) }
- }
+ )
+ def nextTestActionFailing(reason: String): Boolean = nextTestActionExpectTrue(reason, false)
private def assembleTestCommand(outDir: File, logFile: File): List[String] = {
// check whether there is a ".javaopts" file
@@ -227,6 +236,7 @@ class Runner(val testFile: File, fileManager: FileManager) {
override def toString = s"""Test($testIdent, lastState = $lastState)"""
+ // result is unused
def newTestWriters() = {
val swr = new StringWriter
val wr = new PrintWriter(swr, true)
@@ -320,18 +330,20 @@ class Runner(val testFile: File, fileManager: FileManager) {
def diffIsOk: Boolean = {
val diff = currentDiff
- val ok: Boolean = (diff == "") || {
- fileManager.updateCheck && {
+ // if diff is not empty, is update needed?
+ val updating: Option[Boolean] = (
+ if (diff == "") None
+ else Some(fileManager.updateCheck)
+ )
+ pushTranscript(s"diff $logFile $checkFile")
+ nextTestAction(updating) {
+ case Some(true) =>
NestUI.verbose("Updating checkfile " + checkFile)
checkFile writeAll file2String(logFile)
- true
- }
- }
- pushTranscript(s"diff $logFile $checkFile")
- nextTestAction(ok) {
- case false =>
+ genUpdated()
+ case Some(false) =>
// Get a word-highlighted diff from git if we can find it
- val bestDiff = if (ok) "" else {
+ val bestDiff = if (updating.isEmpty) "" else {
if (checkFile.canRead)
gitDiff(logFile, checkFile) getOrElse {
s"diff $logFile $checkFile\n$diff"
@@ -343,11 +355,13 @@ class Runner(val testFile: File, fileManager: FileManager) {
// TestState.fail("output differs", "output differs",
// genFail("output differs")
// TestState.Fail("output differs", bestDiff)
- }
+ case None => genPass() // redundant default case
+ } getOrElse true
}
/** 1. Creates log file and output directory.
* 2. Runs script function, providing log file and output directory as arguments.
+ * 2b. or, just run the script without context and return a new context
*/
def runInContext(body: => Boolean): (Boolean, LogContext) = {
val (swr, wr) = newTestWriters()
@@ -356,11 +370,16 @@ class Runner(val testFile: File, fileManager: FileManager) {
}
/** Grouped files in group order, and lex order within each group. */
- def groupedFiles(dir: File): List[List[File]] = {
- val testFiles = dir.listFiles.toList filter (_.isJavaOrScala)
- val grouped = testFiles groupBy (_.group)
- grouped.keys.toList.sorted map (k => grouped(k) sortBy (_.getName))
- }
+ def groupedFiles(files: List[File]): List[List[File]] = (
+ if (files.tail.nonEmpty) {
+ val grouped = files filter (_.isJavaOrScala) groupBy (_.group)
+ grouped.keys.toList.sorted map (k => grouped(k) sortBy (_.getName))
+ }
+ else List(files)
+ )
+
+ /** Source files for the given test file. */
+ def sources(file: File): List[File] = if (file.isDirectory) file.listFiles.toList else List(file)
def newCompiler = new DirectCompiler(fileManager)
@@ -411,11 +430,9 @@ class Runner(val testFile: File, fileManager: FileManager) {
lazy val result = { pushTranscript(description) ; attemptCompile(fs) }
}
- def compilationRounds(file: File): List[CompileRound] = {
- val grouped = if (file.isDirectory) groupedFiles(file) else List(List(file))
-
- (grouped map mixedCompileGroup).flatten
- }
+ def compilationRounds(file: File): List[CompileRound] = (
+ (groupedFiles(sources(file)) map mixedCompileGroup).flatten
+ )
def mixedCompileGroup(allFiles: List[File]): List[CompileRound] = {
val (scalaFiles, javaFiles) = allFiles partition (_.isScala)
val isMixed = javaFiles.nonEmpty && scalaFiles.nonEmpty
@@ -429,12 +446,16 @@ class Runner(val testFile: File, fileManager: FileManager) {
def runNegTest() = runInContext {
val rounds = compilationRounds(testFile)
- if (rounds forall (x => nextTestActionExpectTrue("compilation failed", x.isOk)))
- nextTestActionExpectTrue("expected compilation failure", false)
- else {
- normalizeLog // put errors in a normal form
- diffIsOk
+ // failing means Does Not Compile
+ val failing = rounds find (x => nextTestActionExpectTrue("compilation failed", x.isOk) == false)
+
+ // which means passing if it checks and didn't crash the compiler
+ def checked(r: CompileRound) = r.result match {
+ case f: Crash => false
+ case f => normalizeLog(); diffIsOk
}
+
+ failing map (checked) getOrElse nextTestActionFailing("expected compilation failure")
}
def runTestCommon(andAlso: => Boolean): (Boolean, LogContext) = runInContext {
@@ -495,24 +516,68 @@ class Runner(val testFile: File, fileManager: FileManager) {
}
def runScalacheckTest() = runTestCommon {
- NestUI.verbose("compilation of "+testFile+" succeeded\n")
+ NestUI verbose f"compilation of $testFile succeeded%n"
- val outURL = outDir.getAbsoluteFile.toURI.toURL
+ // this classloader is test specific: its parent contains library classes and others
+ val loader = {
+ import PathSettings.scalaCheck
+ val locations = List(outDir, scalaCheck.jfile) map (_.getAbsoluteFile.toURI.toURL)
+ ScalaClassLoader.fromURLs(locations, getClass.getClassLoader)
+ }
val logWriter = new PrintStream(new FileOutputStream(logFile), true)
- Output.withRedirected(logWriter) {
- // this classloader is test specific: its parent contains library classes and others
- ScalaClassLoader.fromURLs(List(outURL), testRunParams.scalaCheckParentClassLoader).run("Test", Nil)
+ def toolArgs(tool: String): List[String] = {
+ def argsplitter(s: String) = words(s) filter (_.nonEmpty)
+ def argsFor(f: File): List[String] = {
+ import scala.util.matching.Regex
+ val p = new Regex(s"(?:.*\\s)?${tool}:(.*)?", "args")
+ val max = 10
+ val src = Path(f).toFile.chars(codec)
+ val args = try {
+ src.getLines take max collectFirst {
+ case s if (p findFirstIn s).nonEmpty => for (m <- p findFirstMatchIn s) yield m group "args"
+ }
+ } finally src.close()
+ args.flatten map argsplitter getOrElse Nil
+ }
+ sources(testFile) flatMap argsFor
}
-
- NestUI.verbose(file2String(logFile))
- // obviously this must be improved upon
- val lines = SFile(logFile).lines map (_.trim) filterNot (_ == "") toBuffer;
- lines.forall(x => !x.startsWith("!")) || {
- NestUI.normal("ScalaCheck test failed. Output:\n")
- lines foreach (x => NestUI.normal(x + "\n"))
- false
+ def runInFramework(): Boolean = {
+ import org.scalatools.testing._
+ val f: Framework = loader.instantiate[Framework]("org.scalacheck.ScalaCheckFramework")
+ val logger = new Logger {
+ def ansiCodesSupported = false //params.env.isSet("colors")
+ def error(msg: String) = logWriter println msg
+ def warn(msg: String) = logWriter println msg
+ def info(msg: String) = logWriter println msg
+ def debug(msg: String) = logWriter println msg
+ def trace(t: Throwable) = t printStackTrace logWriter
+ }
+ var bad = 0
+ val handler = new EventHandler {
+ // testName, description, result, error
+ // Result = Success, Failure, Error, Skipped
+ def handle(event: Event): Unit = event.result match {
+ case Result.Success =>
+ //case Result.Skipped => // an exhausted test is skipped, therefore bad
+ case _ => bad += 1
+ }
+ }
+ val loggers = Array(logger)
+ val r = f.testRunner(loader, loggers).asInstanceOf[Runner2] // why?
+ val claas = "Test"
+ val fingerprint = f.tests collectFirst { case x: SubclassFingerprint if x.isModule => x }
+ val args = toolArgs("scalacheck")
+ vlog(s"Run $testFile with args $args")
+ // set the context class loader for scaladoc/scalacheck tests (FIX ME)
+ ScalaClassLoader(testRunParams.scalaCheckParentClassLoader).asContext {
+ r.run(claas, fingerprint.get, handler, args.toArray) // synchronous?
+ }
+ val ok = (bad == 0)
+ if (!ok) _transcript append logFile.fileContents
+ ok
}
+ try nextTestActionExpectTrue("ScalaCheck test failed", runInFramework()) finally logWriter.close()
}
def runResidentTest() = {
@@ -626,3 +691,139 @@ class Runner(val testFile: File, fileManager: FileManager) {
Directory(outDir).deleteRecursively()
}
}
+
+case class TestRunParams(val scalaCheckParentClassLoader: ScalaClassLoader)
+
+/** Extended by Ant- and ConsoleRunner for running a set of tests. */
+trait DirectRunner {
+ def fileManager: FileManager
+
+ import PartestDefaults.{ numThreads, waitTime }
+
+ Thread.setDefaultUncaughtExceptionHandler(
+ new Thread.UncaughtExceptionHandler {
+ def uncaughtException(thread: Thread, t: Throwable) {
+ val t1 = Exceptional unwrap t
+ System.err.println(s"Uncaught exception on thread $thread: $t1")
+ t1.printStackTrace()
+ }
+ }
+ )
+ def runTestsForFiles(kindFiles: List[File], kind: String): List[TestState] = {
+
+ NestUI.resetTestNumber(kindFiles.size)
+
+ // this special class loader is for the benefit of scaladoc tests, which need a class path
+ import PathSettings.{ testInterface, scalaCheck }
+ val allUrls = scalaCheck.toURL :: testInterface.toURL :: fileManager.latestUrls
+ val parentClassLoader = ScalaClassLoader fromURLs allUrls
+ // add scalacheck.jar to a special classloader, but use our loader as parent with test-interface
+ //val parentClassLoader = ScalaClassLoader fromURLs (List(scalaCheck.toURL), getClass().getClassLoader)
+ val pool = Executors newFixedThreadPool numThreads
+ val manager = new RunnerManager(kind, fileManager, TestRunParams(parentClassLoader))
+ val futures = kindFiles map (f => pool submit callable(manager runTest f))
+
+ pool.shutdown()
+ Try (pool.awaitTermination(waitTime) {
+ throw TimeoutException(waitTime)
+ }) match {
+ case Success(_) => futures map (_.get)
+ case Failure(e) =>
+ e match {
+ case TimeoutException(d) =>
+ NestUI warning "Thread pool timeout elapsed before all tests were complete!"
+ case ie: InterruptedException =>
+ NestUI warning "Thread pool was interrupted"
+ ie.printStackTrace()
+ }
+ pool.shutdownNow() // little point in continuing
+ // try to get as many completions as possible, in case someone cares
+ val results = for (f <- futures) yield {
+ try {
+ Some(f.get(0, NANOSECONDS))
+ } catch {
+ case _: Throwable => None
+ }
+ }
+ results.flatten
+ }
+ }
+}
+
+case class TimeoutException(duration: Duration) extends RuntimeException
+
+class LogContext(val file: File, val writers: Option[(StringWriter, PrintWriter)])
+
+object LogContext {
+ def apply(file: File, swr: StringWriter, wr: PrintWriter): LogContext = {
+ require (file != null)
+ new LogContext(file, Some((swr, wr)))
+ }
+ def apply(file: File): LogContext = new LogContext(file, None)
+}
+
+object Output {
+ object outRedirect extends Redirecter(out)
+ object errRedirect extends Redirecter(err)
+
+ System.setOut(outRedirect)
+ System.setErr(errRedirect)
+
+ import scala.util.DynamicVariable
+ private def out = java.lang.System.out
+ private def err = java.lang.System.err
+ private val redirVar = new DynamicVariable[Option[PrintStream]](None)
+
+ class Redirecter(stream: PrintStream) extends PrintStream(new OutputStream {
+ def write(b: Int) = withStream(_ write b)
+
+ private def withStream(f: PrintStream => Unit) = f(redirVar.value getOrElse stream)
+
+ override def write(b: Array[Byte]) = withStream(_ write b)
+ override def write(b: Array[Byte], off: Int, len: Int) = withStream(_.write(b, off, len))
+ override def flush = withStream(_.flush)
+ override def close = withStream(_.close)
+ })
+
+ // this supports thread-safe nested output redirects
+ def withRedirected[T](newstream: PrintStream)(func: => T): T = {
+ // note down old redirect destination
+ // this may be None in which case outRedirect and errRedirect print to stdout and stderr
+ val saved = redirVar.value
+ // set new redirecter
+ // this one will redirect both out and err to newstream
+ redirVar.value = Some(newstream)
+
+ try func
+ finally {
+ newstream.flush()
+ redirVar.value = saved
+ }
+ }
+}
+
+/** Use a Runner to run a test. */
+class RunnerManager(kind: String, fileManager: FileManager, params: TestRunParams) {
+ import fileManager._
+ fileManager.CLASSPATH += File.pathSeparator + PathSettings.scalaCheck
+ fileManager.CLASSPATH += File.pathSeparator + PathSettings.diffUtils // needed to put diffutils on test/partest's classpath
+
+ def runTest(testFile: File): TestState = {
+ val runner = new Runner(testFile, fileManager, params)
+
+ // when option "--failed" is provided execute test only if log
+ // is present (which means it failed before)
+ if (fileManager.failed && !runner.logFile.canRead)
+ runner.genPass()
+ else {
+ val (state, elapsed) =
+ try timed(runner.run())
+ catch {
+ case t: Throwable => throw new RuntimeException(s"Error running $testFile", t)
+ }
+ NestUI.reportTest(state)
+ runner.cleanup()
+ state
+ }
+ }
+}
diff --git a/src/partest/scala/tools/partest/nest/RunnerManager.scala b/src/partest/scala/tools/partest/nest/RunnerManager.scala
deleted file mode 100644
index fa2b5ea74b..0000000000
--- a/src/partest/scala/tools/partest/nest/RunnerManager.scala
+++ /dev/null
@@ -1,97 +0,0 @@
-/* NEST (New Scala Test)
- * Copyright 2007-2013 LAMP/EPFL
- * @author Philipp Haller
- */
-
-package scala.tools.partest
-package nest
-
-import java.io._
-import java.net.URL
-import scala.tools.nsc.Properties.{ jdkHome, javaHome, propOrElse }
-import scala.util.Properties.{ envOrElse, isWin }
-import scala.tools.nsc.{ Settings, CompilerCommand, Global }
-import scala.tools.nsc.io.{ AbstractFile, PlainFile, Path, Directory, File => SFile }
-import scala.tools.nsc.reporters.ConsoleReporter
-import scala.tools.nsc.util.{ ClassPath, FakePos, ScalaClassLoader, stackTraceString }
-import ClassPath.{ join, split }
-import scala.tools.scalap.scalax.rules.scalasig.ByteCode
-import scala.collection.{ mutable, immutable }
-import scala.sys.process._
-import java.util.concurrent.{ Executors, TimeUnit, TimeoutException }
-import PartestDefaults.{ javaCmd, javacCmd }
-import scala.tools.scalap.Main.decompileScala
-
-class LogContext(val file: File, val writers: Option[(StringWriter, PrintWriter)])
-
-object LogContext {
- def apply(file: File, swr: StringWriter, wr: PrintWriter): LogContext = {
- require (file != null)
- new LogContext(file, Some((swr, wr)))
- }
- def apply(file: File): LogContext = new LogContext(file, None)
-}
-
-object Output {
- object outRedirect extends Redirecter(out)
- object errRedirect extends Redirecter(err)
-
- System.setOut(outRedirect)
- System.setErr(errRedirect)
-
- import scala.util.DynamicVariable
- private def out = java.lang.System.out
- private def err = java.lang.System.err
- private val redirVar = new DynamicVariable[Option[PrintStream]](None)
-
- class Redirecter(stream: PrintStream) extends PrintStream(new OutputStream {
- def write(b: Int) = withStream(_ write b)
-
- private def withStream(f: PrintStream => Unit) = f(redirVar.value getOrElse stream)
-
- override def write(b: Array[Byte]) = withStream(_ write b)
- override def write(b: Array[Byte], off: Int, len: Int) = withStream(_.write(b, off, len))
- override def flush = withStream(_.flush)
- override def close = withStream(_.close)
- })
-
- // this supports thread-safe nested output redirects
- def withRedirected[T](newstream: PrintStream)(func: => T): T = {
- // note down old redirect destination
- // this may be None in which case outRedirect and errRedirect print to stdout and stderr
- val saved = redirVar.value
- // set new redirecter
- // this one will redirect both out and err to newstream
- redirVar.value = Some(newstream)
-
- try func
- finally {
- newstream.flush()
- redirVar.value = saved
- }
- }
-}
-
-class RunnerManager(kind: String, val fileManager: FileManager, params: TestRunParams) {
- import fileManager._
-
- fileManager.CLASSPATH += File.pathSeparator + PathSettings.scalaCheck
- fileManager.CLASSPATH += File.pathSeparator + PathSettings.diffUtils // needed to put diffutils on test/partest's classpath
- PathSettings.platformTools foreach (fileManager.CLASSPATH += File.pathSeparator + _)
-
- def runTest(testFile: File): TestState = {
- val runner = new Runner(testFile, fileManager) {
- override def testRunParams = params
- }
- // when option "--failed" is provided execute test only if log
- // is present (which means it failed before)
- if (fileManager.failed && !runner.logFile.canRead)
- runner.genPass()
- else {
- val (state, elapsed) = timed(runner.run())
- NestUI.reportTest(state)
- runner.cleanup()
- state
- }
- }
-}
diff --git a/src/partest/scala/tools/partest/package.scala b/src/partest/scala/tools/partest/package.scala
index 9e21b0f6ba..4a516d620b 100644
--- a/src/partest/scala/tools/partest/package.scala
+++ b/src/partest/scala/tools/partest/package.scala
@@ -4,8 +4,9 @@
package scala.tools
+import java.util.concurrent.{ Callable, ExecutorService }
+import scala.concurrent.duration.Duration
import scala.sys.process.javaVmArguments
-import java.util.concurrent.Callable
import scala.tools.partest.nest.NestUI
import scala.tools.nsc.util.{ ScalaClassLoader, Exceptional }
@@ -31,6 +32,8 @@ package object partest {
def ojoin(xs: String*): String = oempty(xs: _*) mkString space
def nljoin(xs: String*): String = oempty(xs: _*) mkString EOL
+ implicit val codec = scala.io.Codec.UTF8
+
def setUncaughtHandler() = {
Thread.setDefaultUncaughtExceptionHandler(
new Thread.UncaughtExceptionHandler {
@@ -85,6 +88,25 @@ package object partest {
def copyTo(dest: Path): Unit = dest.toFile writeAll f.slurp(scala.io.Codec.UTF8)
}
+ implicit class LoaderOps(val loader: ClassLoader) extends AnyVal {
+ import scala.util.control.Exception.catching
+ /** Like ScalaClassLoader.create for the case where the result type is
+ * available to the current class loader, implying that the current
+ * loader is a parent of `loader`.
+ */
+ def instantiate[A >: Null](name: String): A = (
+ catching(classOf[ClassNotFoundException], classOf[SecurityException]) opt
+ (loader loadClass name).newInstance.asInstanceOf[A] orNull
+ )
+ }
+
+ implicit class ExecutorOps(val executor: ExecutorService) {
+ def awaitTermination[A](wait: Duration)(failing: => A = ()): Option[A] = (
+ if (executor awaitTermination (wait.length, wait.unit)) None
+ else Some(failing)
+ )
+ }
+
implicit def temporaryPath2File(x: Path): File = x.jfile
implicit def stringPathToJavaFile(path: String): File = new File(path)
diff --git a/src/scalacheck/org/scalacheck/Arbitrary.scala b/src/scalacheck/org/scalacheck/Arbitrary.scala
index 8c43cdaafe..db4163c8af 100644
--- a/src/scalacheck/org/scalacheck/Arbitrary.scala
+++ b/src/scalacheck/org/scalacheck/Arbitrary.scala
@@ -1,6 +1,6 @@
/*-------------------------------------------------------------------------*\
** ScalaCheck **
-** Copyright (c) 2007-2011 Rickard Nilsson. All rights reserved. **
+** Copyright (c) 2007-2013 Rickard Nilsson. All rights reserved. **
** http://www.scalacheck.org **
** **
** This software is released under the terms of the Revised BSD License. **
@@ -10,49 +10,44 @@
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.
+/** Defines implicit [[org.scalacheck.Arbitrary]] 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
+ * uses implicit [[org.scalacheck.Arbitrary]] instances when creating properties
+ * out of functions with the `Prop.property` method, and when
+ * the `Arbitrary.arbitrary` method is used. For example, the
* following code requires that there exists an implicit
- * <code>Arbitrary[MyClass]</code> instance:
+ * `Arbitrary[MyClass]` instance:
* </p>
*
- * <p>
- * <code>
- * val myProp = Prop.forAll { myClass: MyClass =&gt;<br />
- * ...<br />
- * }<br />
+ * {{{
+ * val myProp = Prop.forAll { myClass: MyClass =>
+ * ...
+ * }
*
* 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>.
+ * The factory method `Arbitrary(...)` takes a generator of type
+ * `Gen[T]` and returns an instance of `Arbitrary[T]`.
* </p>
*
* <p>
- * The <code>Arbitrary</code> module defines implicit <code>Arbitrary</code>
+ * The `Arbitrary` module defines implicit [[org.scalacheck.Arbitrary]]
* instances for common types, for convenient use in your properties and
* generators.
* </p>
@@ -93,7 +88,7 @@ object Arbitrary {
/** Arbitrary instance of Long */
implicit lazy val arbLong: Arbitrary[Long] = Arbitrary(
- Gen.chooseNum(Long.MinValue / 2, Long.MaxValue / 2)
+ Gen.chooseNum(Long.MinValue, Long.MaxValue)
)
/** Arbitrary instance of Float */
@@ -182,7 +177,13 @@ object 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)
+ } yield {
+ try {
+ BigDecimal(x, scale, mc)
+ } catch {
+ case ae: java.lang.ArithmeticException => BigDecimal(x, scale, UNLIMITED) // Handle the case where scale/precision conflict
+ }
+ }
Arbitrary(bdGen)
}
@@ -213,23 +214,43 @@ object Arbitrary {
))
}
- /** Arbitrary instance of test params */
+ /** Arbitrary instance of test params
+ * @deprecated (in 1.10.0) Use `arbTestParameters` instead.
+ */
+ @deprecated("Use 'arbTestParameters' instead", "1.10.0")
implicit lazy val arbTestParams: Arbitrary[Test.Params] =
Arbitrary(for {
minSuccTests <- choose(10,200)
- maxDiscardRatio <- choose(0.2f,10f)
- minSize <- choose(0,500)
+ maxDiscTests <- choose(100,500)
+ mnSize <- choose(0,500)
sizeDiff <- choose(0,500)
- maxSize <- choose(minSize, minSize + sizeDiff)
+ mxSize <- choose(mnSize, mnSize + sizeDiff)
ws <- choose(1,4)
} yield Test.Params(
minSuccessfulTests = minSuccTests,
- maxDiscardRatio = maxDiscardRatio,
- minSize = minSize,
- maxSize = maxSize,
+ maxDiscardedTests = maxDiscTests,
+ minSize = mnSize,
+ maxSize = mxSize,
workers = ws
))
+ /** Arbitrary instance of test parameters */
+ implicit lazy val arbTestParameters: Arbitrary[Test.Parameters] =
+ Arbitrary(for {
+ _minSuccTests <- choose(10,200)
+ _maxDiscardRatio <- choose(0.2f,10f)
+ _minSize <- choose(0,500)
+ sizeDiff <- choose(0,500)
+ _maxSize <- choose(_minSize, _minSize + sizeDiff)
+ _workers <- choose(1,4)
+ } yield new Test.Parameters.Default {
+ override val minSuccessfulTests = _minSuccTests
+ override val maxDiscardRatio = _maxDiscardRatio
+ override val minSize = _minSize
+ override val maxSize = _maxSize
+ override val workers = _workers
+ })
+
/** Arbitrary instance of gen params */
implicit lazy val arbGenParams: Arbitrary[Gen.Params] =
Arbitrary(for {
@@ -278,7 +299,7 @@ object Arbitrary {
): 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]
+ implicit def arbArray[T](implicit a: Arbitrary[T], c: ClassManifest[T]
): Arbitrary[Array[T]] = Arbitrary(containerOf[Array,T](arbitrary[T]))
diff --git a/src/scalacheck/org/scalacheck/Arg.scala b/src/scalacheck/org/scalacheck/Arg.scala
index 8959211f09..4961c78a26 100644
--- a/src/scalacheck/org/scalacheck/Arg.scala
+++ b/src/scalacheck/org/scalacheck/Arg.scala
@@ -1,6 +1,6 @@
/*-------------------------------------------------------------------------*\
** ScalaCheck **
-** Copyright (c) 2007-2011 Rickard Nilsson. All rights reserved. **
+** Copyright (c) 2007-2013 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 2acc460b5e..604b68cb36 100644
--- a/src/scalacheck/org/scalacheck/Commands.scala
+++ b/src/scalacheck/org/scalacheck/Commands.scala
@@ -1,6 +1,6 @@
/*-------------------------------------------------------------------------*\
** ScalaCheck **
-** Copyright (c) 2007-2011 Rickard Nilsson. All rights reserved. **
+** Copyright (c) 2007-2013 Rickard Nilsson. All rights reserved. **
** http://www.scalacheck.org **
** **
** This software is released under the terms of the Revised BSD License. **
@@ -53,7 +53,7 @@ trait Commands extends Prop {
* 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]
+ val preConditions = new 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)): _*)
@@ -65,7 +65,7 @@ trait Commands extends Prop {
* 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]
+ val postConditions = new collection.mutable.ListBuffer[(State,State,Any) => Prop]
}
/** A command that binds its result for later use */
@@ -87,6 +87,11 @@ trait Commands extends Prop {
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 {
diff --git a/src/scalacheck/org/scalacheck/ConsoleReporter.scala b/src/scalacheck/org/scalacheck/ConsoleReporter.scala
index 93f1dc222e..d565322d99 100644
--- a/src/scalacheck/org/scalacheck/ConsoleReporter.scala
+++ b/src/scalacheck/org/scalacheck/ConsoleReporter.scala
@@ -1,6 +1,6 @@
/*-------------------------------------------------------------------------*\
** ScalaCheck **
-** Copyright (c) 2007-2011 Rickard Nilsson. All rights reserved. **
+** Copyright (c) 2007-2013 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/Gen.scala b/src/scalacheck/org/scalacheck/Gen.scala
index 64bb61c2d3..aec67159f1 100644
--- a/src/scalacheck/org/scalacheck/Gen.scala
+++ b/src/scalacheck/org/scalacheck/Gen.scala
@@ -1,6 +1,6 @@
/*-------------------------------------------------------------------------*\
** ScalaCheck **
-** Copyright (c) 2007-2011 Rickard Nilsson. All rights reserved. **
+** Copyright (c) 2007-2013 Rickard Nilsson. All rights reserved. **
** http://www.scalacheck.org **
** **
** This software is released under the terms of the Revised BSD License. **
@@ -23,7 +23,7 @@ object Choose {
implicit val chooseLong: Choose[Long] = new Choose[Long] {
def choose(low: Long, high: Long) =
- if(low > high || (high-low < 0)) fail
+ if (low > high) fail
else parameterized(prms => value(prms.choose(low,high)))
}
@@ -204,9 +204,17 @@ object Gen {
/** @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))
+ if (h < l) throw new IllegalArgumentException("Invalid range")
+ val d = h - l + 1
+ if (d <= 0) {
+ var n = rng.nextLong
+ while (n < l || n > h) {
+ n = rng.nextLong
+ }
+ n
+ } else {
+ l + math.abs(rng.nextLong % d)
+ }
}
/** @throws IllegalArgumentException if l is greater than h, or if
@@ -225,8 +233,11 @@ object Gen {
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> */
+ /* Convenience method for using the `frequency` method like this:
+ * {{{
+ * frequency((1, "foo"), (3, "bar"))
+ * }}}
+ */
implicit def freqTuple[T](t: (Int, T)): (Int, Gen[T]) = (t._1, value(t._2))
@@ -308,9 +319,9 @@ object Gen {
//// List Generators ////
/** Generates a container of any type for which there exists an implicit
- * <code>Buildable</code> instance. The elements in the container will
+ * [[org.scalacheck.util.Buildable]] 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>. */
+ * is given by `n`. */
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]] {
@@ -321,14 +332,14 @@ object Gen {
})
/** 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
+ * [[org.scalacheck.util.Buildable]] 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
+ * implicit [[org.scalacheck.util.Buildable]] 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]] =
@@ -336,16 +347,16 @@ object Gen {
/** 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>. */
+ * `containerOf[List,T](g)`. */
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>. */
+ * `containerOf1[List,T](g)`. */
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>. */
+ * `containerOfN[List,T](n,g)`. */
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 */
diff --git a/src/scalacheck/org/scalacheck/Pretty.scala b/src/scalacheck/org/scalacheck/Pretty.scala
index eeb5936086..3e8f6de5f6 100644
--- a/src/scalacheck/org/scalacheck/Pretty.scala
+++ b/src/scalacheck/org/scalacheck/Pretty.scala
@@ -1,6 +1,6 @@
/*-------------------------------------------------------------------------*\
** ScalaCheck **
-** Copyright (c) 2007-2011 Rickard Nilsson. All rights reserved. **
+** Copyright (c) 2007-2013 Rickard Nilsson. All rights reserved. **
** http://www.scalacheck.org **
** **
** This software is released under the terms of the Revised BSD License. **
@@ -96,7 +96,7 @@ object Pretty {
}
implicit def prettyTestRes(res: Test.Result) = Pretty { prms =>
- def labels(ls: scala.collection.immutable.Set[String]) =
+ def labels(ls: collection.immutable.Set[String]) =
if(ls.isEmpty) ""
else "> Labels of failing property: " / ls.mkString("\n")
val s = res.status match {
diff --git a/src/scalacheck/org/scalacheck/Prop.scala b/src/scalacheck/org/scalacheck/Prop.scala
index dfd85a832a..38e00f260f 100644
--- a/src/scalacheck/org/scalacheck/Prop.scala
+++ b/src/scalacheck/org/scalacheck/Prop.scala
@@ -1,6 +1,6 @@
/*-------------------------------------------------------------------------*\
** ScalaCheck **
-** Copyright (c) 2007-2011 Rickard Nilsson. All rights reserved. **
+** Copyright (c) 2007-2013 Rickard Nilsson. All rights reserved. **
** http://www.scalacheck.org **
** **
** This software is released under the terms of the Revised BSD License. **
@@ -31,16 +31,27 @@ trait Prop {
/** 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. */
+ * from the test use the `check` methods in [[org.scalacheck.Test]]
+ * instead.
+ * @deprecated (in 1.10.0) Use `check(Test.Parameters)` instead.
+ */
+ @deprecated("Use 'check(Test.Parameters)' instead", "1.10.0")
def check(prms: Test.Params): Unit = Test.check(
prms copy (testCallback = ConsoleReporter(1) chain prms.testCallback), this
)
+ /** 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 `check` methods in [[org.scalacheck.Test]]
+ * instead. */
+ def check(prms: Test.Parameters): 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 `check` methods in [[org.scalacheck.Test]] instead. */
+ def check: Unit = check(Test.Parameters.default)
/** The logic for main, separated out to make it easier to
* avoid System.exit calls. Returns exit code.
@@ -60,7 +71,7 @@ trait Prop {
/** Whether main should call System.exit with an exit code.
* Defaults to true; override to change.
*/
- def mainCallsExit = false
+ def mainCallsExit = true
/** Convenience method that makes it possible to use this property
* as an application that checks itself on execution */
@@ -274,20 +285,51 @@ object Prop {
def apply(r: Result): Prop = Prop(prms => r)
+ def apply(b: Boolean): Prop = if(b) proved else falsified
- // Implicit defs
+ // Implicits
+
+ /** A collection of property operators on [[Any]] values.
+ * Import [[Prop.AnyOperators]] to make the operators available. */
class ExtendedAny[T <% Pretty](x: => T) {
+ /** See [[Prop.imply]] */
def imply(f: PartialFunction[T,Prop]) = Prop.imply(x,f)
+ /** See [[Prop.iff]] */
def iff(f: PartialFunction[T,Prop]) = Prop.iff(x,f)
- def throws[U <: Throwable](c: Class[U]) = Prop.throws(x, c)
+ @deprecated("Use 'Prop.throws' instead", "1.10.1")
+ def throws[U <: Throwable](c: Class[U]): Prop = Prop.throws(c)(x)
+ /** See [[Prop.?=]] */
def ?=(y: T) = Prop.?=(x, y)
+ /** See [[Prop.=?]] */
def =?(y: T) = Prop.=?(x, y)
}
+ /** A collection of property operators on [[Boolean]] values.
+ * Import [[Prop.BooleanOperators]] to make the operators available. */
+ class ExtendedBoolean(b: => Boolean) {
+ /** See [[Prop.==>]] */
+ def ==>(p: => Prop) = Prop(b) ==> p
+ }
+
+ /** Implicit method that makes a number of property operators on values of
+ * type [[Any]] available in the current scope. See [[Prop.ExtendedAny]] for
+ * documentation on the operators. */
+ @deprecated("Use 'Prop.AnyOperators' instead", "1.10.1")
implicit def extendedAny[T <% Pretty](x: => T) = new ExtendedAny[T](x)
- implicit def propBoolean(b: Boolean): Prop = if(b) proved else falsified
+ /** Implicit method that makes a number of property operators on values of
+ * type [[Any]] available in the current scope. See [[Prop.ExtendedAny]] for
+ * documentation on the operators. */
+ implicit def AnyOperators[T <% Pretty](x: => T) = new ExtendedAny[T](x)
+
+ /** Implicit method that makes a number of property operators on boolean
+ * values available in the current scope. See [[Prop.ExtendedBoolean]] for
+ * documentation on the operators. */
+ implicit def BooleanOperators(b: => Boolean) = new ExtendedBoolean(b)
+
+ /** Implicit conversion of Boolean values to Prop values. */
+ implicit def propBoolean(b: Boolean): Prop = Prop(b)
// Private support functions
@@ -318,6 +360,9 @@ object Prop {
/** A property that denotes an exception */
lazy val exception: Prop = exception(null)
+ /** Create a property that compares to values. If the values aren't equal,
+ * the property will fail and report that first value doesn't match the
+ * expected (second) value. */
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))
@@ -325,6 +370,9 @@ object Prop {
"Expected "+exp+" but got "+act
}
+ /** Create a property that compares to values. If the values aren't equal,
+ * the property will fail and report that second value doesn't match the
+ * expected (first) value. */
def =?[T](x: T, y: T)(implicit pp: T => Pretty): Prop = ?=(y, x)
/** A property that depends on the generator size */
@@ -340,7 +388,7 @@ object 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 */
+ * `x`, 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)
@@ -365,9 +413,16 @@ object Prop {
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
+ * @deprecated (in 1.10.1) Use `throws(...): Boolean` instead.
+ */
+ @deprecated("Use 'throws(...): Boolean' instead", "1.10.1")
+ def throws[T <: Throwable](x: => Any, c: Class[T]): Prop = throws(c)(x)
+
+ /** Returns true 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 }
+ def throws[T <: Throwable](c: Class[T])(x: => Any): Boolean =
+ try { x; false } catch { case e if c.isInstance(e) => true }
/** Collect data for presentation in test report */
def collect[T, P <% Prop](f: T => P): T => Prop = t => Prop { prms =>
@@ -390,7 +445,7 @@ object Prop {
/** Wraps and protects a property */
def secure[P <% Prop](p: => P): Prop =
- try { p: Prop } catch { case e => exception(e) }
+ try { p: Prop } catch { case e: Throwable => exception(e) }
/** Existential quantifier for an explicit generator. */
def exists[A,P](f: A => P)(implicit
diff --git a/src/scalacheck/org/scalacheck/Properties.scala b/src/scalacheck/org/scalacheck/Properties.scala
index 26059231d6..d4836d7420 100644
--- a/src/scalacheck/org/scalacheck/Properties.scala
+++ b/src/scalacheck/org/scalacheck/Properties.scala
@@ -1,6 +1,6 @@
/*-------------------------------------------------------------------------*\
** ScalaCheck **
-** Copyright (c) 2007-2011 Rickard Nilsson. All rights reserved. **
+** Copyright (c) 2007-2013 Rickard Nilsson. All rights reserved. **
** http://www.scalacheck.org **
** **
** This software is released under the terms of the Revised BSD License. **
@@ -14,15 +14,15 @@ package org.scalacheck
* 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) =&gt;
+ * 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 {
@@ -42,16 +42,27 @@ class Properties(val name: String) extends Prop {
/** 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>
+ * from the test use the `check` methods in [[org.scalacheck.Test]]
* instead. */
+ override def check(prms: Test.Parameters): Unit = Test.checkProperties(
+ prms copy (_testCallback = ConsoleReporter(1) chain prms.testCallback), this
+ )
+
+ /** 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 `check` methods in [[org.scalacheck.Test]]
+ * instead.
+ * @deprecated (in 1.10.0) Use `check(Test.Parameters)` instead.
+ */
+ @deprecated("Use 'check(Test.Parameters)' instead", "1.10.0")
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 `check` methods in [[org.scalacheck.Test]] instead. */
+ override def check: Unit = check(Test.Parameters.default)
/** The logic for main, separated out to make it easier to
* avoid System.exit calls. Returns exit code.
@@ -73,7 +84,10 @@ class Properties(val name: String) extends Prop {
def include(ps: Properties) = for((n,p) <- ps.properties) property(n) = p
/** Used for specifying properties. Usage:
- * <code>property("myProp") = ...</code> */
+ * {{{
+ * property("myProp") = ...
+ * }}}
+ */
class PropertySpecifier() {
def update(propName: String, p: Prop) = props += ((name+"."+propName, p))
}
diff --git a/src/scalacheck/org/scalacheck/ScalaCheckFramework.scala b/src/scalacheck/org/scalacheck/ScalaCheckFramework.scala
new file mode 100644
index 0000000000..7764101844
--- /dev/null
+++ b/src/scalacheck/org/scalacheck/ScalaCheckFramework.scala
@@ -0,0 +1,92 @@
+/*-------------------------------------------------------------------------*\
+** ScalaCheck **
+** Copyright (c) 2007-2013 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. **
+\*------------------------------------------------------------------------ */
+
+// vim: set ts=2 sw=2 et:
+
+package org.scalacheck
+
+import org.scalatools.testing._
+
+class ScalaCheckFramework extends Framework {
+
+ private case object PropFingerprint extends TestFingerprint {
+ val superClassName = "org.scalacheck.Prop"
+ val isModule = false
+ }
+
+ private case object PropsFingerprint extends TestFingerprint {
+ val superClassName = "org.scalacheck.Properties"
+ val isModule = true
+ }
+
+ val name = "ScalaCheck"
+
+ val tests = Array[Fingerprint](PropsFingerprint, PropsFingerprint)
+
+ def testRunner(loader: ClassLoader, loggers: Array[Logger]) = new Runner2 {
+
+ private def asEvent(nr: (String, Test.Result)) = nr match {
+ case (n: String, r: Test.Result) => new Event {
+ val testName = n
+ val description = n
+ val result = r.status match {
+ case Test.Passed => Result.Success
+ case _:Test.Proved => Result.Success
+ case _:Test.Failed => Result.Failure
+ case Test.Exhausted => Result.Skipped
+ case _:Test.PropException | _:Test.GenException => Result.Error
+ }
+ val error = r.status match {
+ case Test.PropException(_, e, _) => e
+ case _:Test.Failed => new Exception(Pretty.pretty(r,Pretty.Params(0)))
+ case _ => null
+ }
+ }
+ }
+
+ def run(testClassName: String, fingerprint: Fingerprint, handler: EventHandler, args: Array[String]) {
+
+ val testCallback = new Test.TestCallback {
+ override def onPropEval(n: String, w: Int, s: Int, d: Int) = {}
+
+ override def onTestResult(n: String, r: Test.Result) = {
+ for (l <- loggers) {
+ import Pretty._
+ l.info(
+ (if (r.passed) "+ " else "! ") + n + ": " + pretty(r, Params(0))
+ )
+ }
+ handler.handle(asEvent((n,r)))
+ }
+ }
+
+ import Test.cmdLineParser.{Success, NoSuccess}
+ val prms = Test.cmdLineParser.parseParams(args) match {
+ case Success(params, _) =>
+ params.copy(_testCallback = testCallback, _customClassLoader = Some(loader))
+ // TODO: Maybe handle this a bit better than throwing exception?
+ case e: NoSuccess => throw new Exception(e.toString)
+ }
+
+ fingerprint match {
+ case fp: SubclassFingerprint =>
+ if(fp.isModule) {
+ val obj = Class.forName(testClassName + "$", true, loader)
+ val ps = obj.getField("MODULE$").get(null).asInstanceOf[Properties]
+ Test.checkProperties(prms, ps)
+ } else {
+ val p = Class.forName(testClassName, true, loader).newInstance.asInstanceOf[Prop]
+ handler.handle(asEvent((testClassName, Test.check(prms, p))))
+ }
+ }
+ }
+
+ }
+
+}
diff --git a/src/scalacheck/org/scalacheck/Shrink.scala b/src/scalacheck/org/scalacheck/Shrink.scala
index ae15bd9616..4895171a35 100644
--- a/src/scalacheck/org/scalacheck/Shrink.scala
+++ b/src/scalacheck/org/scalacheck/Shrink.scala
@@ -1,6 +1,6 @@
/*-------------------------------------------------------------------------*\
** ScalaCheck **
-** Copyright (c) 2007-2011 Rickard Nilsson. All rights reserved. **
+** Copyright (c) 2007-2013 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 4368184823..6e9b6b88fd 100644
--- a/src/scalacheck/org/scalacheck/Test.scala
+++ b/src/scalacheck/org/scalacheck/Test.scala
@@ -1,6 +1,6 @@
/*-------------------------------------------------------------------------*\
** ScalaCheck **
-** Copyright (c) 2007-2011 Rickard Nilsson. All rights reserved. **
+** Copyright (c) 2007-2013 Rickard Nilsson. All rights reserved. **
** http://www.scalacheck.org **
** **
** This software is released under the terms of the Revised BSD License. **
@@ -16,23 +16,120 @@ object Test {
import Prop.FM
import util.CmdLineParser
- /** Test parameters */
+ /** Test parameters used by the `Test.check` method.
+ */
+ trait Parameters {
+ /** The minimum number of tests that must succeed for ScalaCheck to
+ * consider a property passed. */
+ def minSuccessfulTests: Int
+
+ /** The starting size given as parameter to the generators. */
+ def minSize: Int
+
+ /** The maximum size given as parameter to the generators. */
+ def maxSize: Int
+
+ /** The random numbe generator used. */
+ def rng: java.util.Random
+
+ /** The number of tests run in parallell. */
+ def workers: Int
+
+ /** A callback that ScalaCheck calls each time a test is executed. */
+ def testCallback: TestCallback
+
+ /** The maximum ratio between discarded and passed tests allowed before
+ * ScalaCheck gives up and discards the property. At least
+ * `minSuccesfulTests` will always be run, though. */
+ def maxDiscardRatio: Float
+
+ /** A custom class loader that should be used during test execution. */
+ def customClassLoader: Option[ClassLoader]
+
+ // private since we can't guarantee binary compatibility for this one
+ private[scalacheck] def copy(
+ _minSuccessfulTests: Int = Parameters.this.minSuccessfulTests,
+ _minSize: Int = Parameters.this.minSize,
+ _maxSize: Int = Parameters.this.maxSize,
+ _rng: java.util.Random = Parameters.this.rng,
+ _workers: Int = Parameters.this.workers,
+ _testCallback: TestCallback = Parameters.this.testCallback,
+ _maxDiscardRatio: Float = Parameters.this.maxDiscardRatio,
+ _customClassLoader: Option[ClassLoader] = Parameters.this.customClassLoader
+ ): Parameters = new Parameters {
+ val minSuccessfulTests: Int = _minSuccessfulTests
+ val minSize: Int = _minSize
+ val maxSize: Int = _maxSize
+ val rng: java.util.Random = _rng
+ val workers: Int = _workers
+ val testCallback: TestCallback = _testCallback
+ val maxDiscardRatio: Float = _maxDiscardRatio
+ val customClassLoader: Option[ClassLoader] = _customClassLoader
+ }
+ }
+
+ /** Test parameters used by the `Test.check` method.
+ *
+ * To override default values, extend the
+ * [[org.scalacheck.Test.Parameters.Default]] trait:
+ *
+ * {{{
+ * val myParams = new Parameters.Default {
+ * override val minSuccesfulTests = 600
+ * override val maxDiscardRatio = 8
+ * }
+ * }}}
+ */
+ object Parameters {
+ /** Default test parameters trait. This can be overriden if you need to
+ * tweak the parameters. */
+ trait Default extends Parameters {
+ val minSuccessfulTests: Int = 100
+ val minSize: Int = 0
+ val maxSize: Int = Gen.Params().size
+ val rng: java.util.Random = Gen.Params().rng
+ val workers: Int = 1
+ val testCallback: TestCallback = new TestCallback {}
+ val maxDiscardRatio: Float = 5
+ val customClassLoader: Option[ClassLoader] = None
+ }
+
+ /** Default test parameters instance. */
+ val default: Parameters = new Default {}
+ }
+
+ /** Test parameters
+ * @deprecated (in 1.10.0) Use [[org.scalacheck.Test.Parameters]] instead.
+ */
+ @deprecated("Use [[org.scalacheck.Test.Parameters]] instead", "1.10.0")
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
+ testCallback: TestCallback = new TestCallback {}
)
+ @deprecated("Use [[org.scalacheck.Test.Parameters]] instead", "1.10.0")
+ private def paramsToParameters(params: Params) = new Parameters {
+ val minSuccessfulTests = params.minSuccessfulTests
+ val minSize = params.minSize
+ val maxSize = params.maxSize
+ val rng = params.rng
+ val workers = params.workers
+ val testCallback = params.testCallback
+
+ // maxDiscardedTests is deprecated, but if someone
+ // uses it let it override maxDiscardRatio
+ val maxDiscardRatio =
+ if(params.maxDiscardedTests < 0) Parameters.default.maxDiscardRatio
+ else (params.maxDiscardedTests: Float)/(params.minSuccessfulTests: Float)
+
+ val customClassLoader = Parameters.default.customClassLoader
+ }
+
/** Test statistics */
case class Result(status: Status, succeeded: Int, discarded: Int, freqMap: FM, time: Long = 0) {
def passed = status match {
@@ -92,7 +189,7 @@ object Test {
}
}
- private def assertParams(prms: Params) = {
+ private def assertParams(prms: Parameters) = {
import prms._
if(
minSuccessfulTests <= 0 ||
@@ -104,16 +201,24 @@ object Test {
}
private def secure[T](x: => T): Either[T,Throwable] =
- try { Left(x) } catch { case e => Right(e) }
+ try { Left(x) } catch { case e: Throwable => Right(e) }
private[scalacheck] lazy val cmdLineParser = new CmdLineParser {
object OptMinSuccess extends IntOpt {
- val default = Test.Params().minSuccessfulTests
+ val default = Parameters.default.minSuccessfulTests
val names = Set("minSuccessfulTests", "s")
val help = "Number of tests that must succeed in order to pass a property"
}
+ object OptMaxDiscarded extends IntOpt {
+ val default = -1
+ val names = Set("maxDiscardedTests", "d")
+ val help =
+ "Number of tests that can be discarded before ScalaCheck stops " +
+ "testing a property. NOTE: this option is deprecated, please use " +
+ "the option maxDiscardRatio (-r) instead."
+ }
object OptMaxDiscardRatio extends FloatOpt {
- val default = Test.Params().maxDiscardRatio
+ val default = Parameters.default.maxDiscardRatio
val names = Set("maxDiscardRatio", "r")
val help =
"The maximum ratio between discarded and succeeded tests " +
@@ -121,17 +226,17 @@ object Test {
"least minSuccessfulTests will always be tested, though."
}
object OptMinSize extends IntOpt {
- val default = Test.Params().minSize
+ val default = Parameters.default.minSize
val names = Set("minSize", "n")
val help = "Minimum data generation size"
}
object OptMaxSize extends IntOpt {
- val default = Test.Params().maxSize
+ val default = Parameters.default.maxSize
val names = Set("maxSize", "x")
val help = "Maximum data generation size"
}
object OptWorkers extends IntOpt {
- val default = Test.Params().workers
+ val default = Parameters.default.workers
val names = Set("workers", "w")
val help = "Number of threads to execute in parallel for testing"
}
@@ -142,54 +247,63 @@ object Test {
}
val opts = Set[Opt[_]](
- OptMinSuccess, OptMaxDiscardRatio, OptMinSize,
+ OptMinSuccess, OptMaxDiscarded, 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))
+ optMap => Parameters.default.copy(
+ _minSuccessfulTests = optMap(OptMinSuccess),
+ _maxDiscardRatio =
+ if (optMap(OptMaxDiscarded) < 0) optMap(OptMaxDiscardRatio)
+ else optMap(OptMaxDiscarded).toFloat / optMap(OptMinSuccess),
+ _minSize = optMap(OptMinSize),
+ _maxSize = optMap(OptMaxSize),
+ _workers = optMap(OptWorkers),
+ _testCallback = ConsoleReporter(optMap(OptVerbosity))
)
}
}
/** Tests a property with the given testing parameters, and returns
- * the test results. */
+ * the test results.
+ * @deprecated (in 1.10.0) Use
+ * `check(Parameters, Properties)` instead.
+ */
+ @deprecated("Use 'checkProperties(Parameters, Properties)' instead", "1.10.0")
def check(params: Params, p: Prop): Result = {
+ check(paramsToParameters(params), p)
+ }
- // 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
+ /** Tests a property with the given testing parameters, and returns
+ * the test results. */
+ def check(params: Parameters, p: Prop): Result = {
+ import params._
- assertParams(prms)
- if(workers > 1)
+ assertParams(params)
+ 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(_))
+ def worker(workerIdx: Int) =
+ if (workers < 2) () => workerFun(workerIdx)
+ else actors.Futures.future {
+ params.customClassLoader.map(Thread.currentThread.setContextClassLoader(_))
+ workerFun(workerIdx)
+ }
+
+ def workerFun(workerIdx: Int) = {
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)
+ val propPrms = Prop.Params(Gen.Params(size.round.toInt, params.rng), fm)
secure(p(propPrms)) match {
case Right(e) => res =
Result(GenException(e), n, d, FreqMap.empty[immutable.Set[Any]])
@@ -250,11 +364,20 @@ object Test {
stop = true
results foreach (_.apply())
val timedRes = r.copy(time = System.currentTimeMillis-start)
- prms.testCallback.onTestResult("", timedRes)
+ params.testCallback.onTestResult("", timedRes)
timedRes
}
+ /** Check a set of properties.
+ * @deprecated (in 1.10.0) Use
+ * `checkProperties(Parameters, Properties)` instead.
+ */
+ @deprecated("Use 'checkProperties(Parameters, Properties)' instead", "1.10.0")
def checkProperties(prms: Params, ps: Properties): Seq[(String,Result)] =
+ checkProperties(paramsToParameters(prms), ps)
+
+ /** Check a set of properties. */
+ def checkProperties(prms: Parameters, 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) =
@@ -262,7 +385,7 @@ object Test {
override def onTestResult(n: String, r: Result) =
prms.testCallback.onTestResult(name,r)
}
- val res = check(prms copy (testCallback = testCallback), p)
+ 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
index 221b8a61c3..140c541a95 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-2011 Rickard Nilsson. All rights reserved. **
+** Copyright (c) 2007-2013 Rickard Nilsson. All rights reserved. **
** http://www.scalacheck.org **
** **
** This software is released under the terms of the Revised BSD License. **
@@ -10,7 +10,6 @@
package org.scalacheck.util
import scala.collection._
-import scala.reflect.ClassTag
trait Buildable[T,C[_]] {
def builder: mutable.Builder[T,C[T]]
@@ -31,7 +30,7 @@ object Buildable {
def builder = (new mutable.ListBuffer[T]).mapResult(_.toStream)
}
- implicit def buildableArray[T](implicit cm: ClassTag[T]) =
+ implicit def buildableArray[T](implicit cm: ClassManifest[T]) =
new Buildable[T,Array] {
def builder = mutable.ArrayBuilder.make[T]
}
diff --git a/src/scalacheck/org/scalacheck/util/CmdLineParser.scala b/src/scalacheck/org/scalacheck/util/CmdLineParser.scala
index 4683c34a65..eb3a91fe59 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-2011 Rickard Nilsson. All rights reserved. **
+** Copyright (c) 2007-2013 Rickard Nilsson. All rights reserved. **
** http://www.scalacheck.org **
** **
** This software is released under the terms of the Revised BSD License. **
@@ -30,7 +30,7 @@ trait CmdLineParser extends Parsers {
trait StrOpt extends Opt[String]
class OptMap {
- private val opts = new scala.collection.mutable.HashMap[Opt[_], Any]
+ private val opts = new 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
diff --git a/src/scalacheck/org/scalacheck/util/FreqMap.scala b/src/scalacheck/org/scalacheck/util/FreqMap.scala
index c7474d3b87..d0686aec72 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-2011 Rickard Nilsson. All rights reserved. **
+** Copyright (c) 2007-2013 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 317b0ccd10..7c1dc8dcc4 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-2011 Rickard Nilsson. All rights reserved. **
+** Copyright (c) 2007-2013 Rickard Nilsson. All rights reserved. **
** http://www.scalacheck.org **
** **
** This software is released under the terms of the Revised BSD License. **
diff --git a/test/files/scalacheck/HashTrieSplit.scala b/test/files/scalacheck/HashTrieSplit.scala
deleted file mode 100644
index 908c878f54..0000000000
--- a/test/files/scalacheck/HashTrieSplit.scala
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
-
-
-
-import collection._
-
-
-
-
-// checks whether hash tries split their iterators correctly
-// even after some elements have been traversed
-object Test {
- def main(args: Array[String]) {
- doesSplitOk
- }
-
- def doesSplitOk = {
- val sz = 2000
- var ht = new parallel.immutable.ParHashMap[Int, Int]
- // println("creating trie")
- for (i <- 0 until sz) ht += ((i + sz, i))
- // println("created trie")
- for (n <- 0 until (sz - 1)) {
- // println("---------> n = " + n)
- val pit = ht.splitter
- val pit2 = ht.splitter
- var i = 0
- while (i < n) {
- pit.next
- pit2.next
- i += 1
- }
- // println("splitting")
- val pits = pit.split
- val fst = pits(0).toSet
- val snd = pits(1).toSet
- val orig = pit2.toSet
- if (orig.size != (fst.size + snd.size) || orig != (fst ++ snd)) {
- println("Original: " + orig)
- println("First: " + fst)
- println("Second: " + snd)
- assert(false)
- }
- }
- }
-}
diff --git a/test/files/scalacheck/parallel-collections/pc.scala b/test/files/scalacheck/parallel-collections/pc.scala
index 0a91977da0..e6b6b4856d 100644
--- a/test/files/scalacheck/parallel-collections/pc.scala
+++ b/test/files/scalacheck/parallel-collections/pc.scala
@@ -1,12 +1,11 @@
-
-
-
+/*
+ * scalac: -deprecation
+ * scalacheck: -workers 1 -minSize 0 -maxSize 4000 -minSuccessfulTests 5
+ */
import org.scalacheck._
-
import scala.collection.parallel._
-
class ParCollProperties extends Properties("Parallel collections") {
/* Collections */
@@ -35,8 +34,8 @@ class ParCollProperties extends Properties("Parallel collections") {
include(immutable.IntParallelVectorCheck)
}
-
-object Test {
+object Test extends ParCollProperties {
+ /*
def main(args: Array[String]) {
val pc = new ParCollProperties
org.scalacheck.Test.checkProperties(
@@ -51,4 +50,5 @@ object Test {
pc
)
}
+ */
}
diff --git a/test/partest b/test/partest
index e3270f8eaa..99a731a49b 100755
--- a/test/partest
+++ b/test/partest
@@ -129,6 +129,7 @@ fi
$JAVA_OPTS -cp "$EXT_CLASSPATH" \
${partestDebugStr} \
"$color_opts" \
+ -Dfile.encoding=UTF-8 \
-Dscala.home="${SCALA_HOME}" \
-Dpartest.javacmd="${JAVACMD}" \
-Dpartest.java_opts="${JAVA_OPTS}" \
diff --git a/test/scaladoc/scalacheck/CommentFactoryTest.scala b/test/scaladoc/scalacheck/CommentFactoryTest.scala
index 96174d29d1..28043e5a06 100644
--- a/test/scaladoc/scalacheck/CommentFactoryTest.scala
+++ b/test/scaladoc/scalacheck/CommentFactoryTest.scala
@@ -45,7 +45,7 @@ object Test extends Properties("CommentFactory") {
with MemberLookup)
}
- def parse(src: String, dst: Inline) = {
+ def parse(src: String, dst: Inline): Boolean = {
factory.parseComment(src) match {
case Some(inline) =>
inline == dst
diff --git a/test/scaladoc/scalacheck/HtmlFactoryTest.scala b/test/scaladoc/scalacheck/HtmlFactoryTest.scala
index d7b5e48288..03348b81d2 100644
--- a/test/scaladoc/scalacheck/HtmlFactoryTest.scala
+++ b/test/scaladoc/scalacheck/HtmlFactoryTest.scala
@@ -2,6 +2,8 @@ import org.scalacheck._
import org.scalacheck.Prop._
import java.net.{URLClassLoader, URLDecoder}
+import scala.collection.mutable
+import scala.xml.NodeSeq
object XMLUtil {
import scala.xml._
@@ -34,21 +36,24 @@ object Test extends Properties("HtmlFactory") {
// this test previously relied on the assumption that the current thread's classloader is an url classloader and contains all the classpaths
// does partest actually guarantee this? to quote Leonard Nimoy: The answer, of course, is no.
// this test _will_ fail again some time in the future.
- val paths = Thread.currentThread.getContextClassLoader.asInstanceOf[URLClassLoader].getURLs.map(u => URLDecoder.decode(u.getPath))
- val morepaths = Thread.currentThread.getContextClassLoader.getParent.asInstanceOf[URLClassLoader].getURLs.map(u => URLDecoder.decode(u.getPath))
- (paths ++ morepaths).mkString(java.io.File.pathSeparator)
+ // Footnote: java.lang.ClassCastException: org.apache.tools.ant.loader.AntClassLoader5 cannot be cast to java.net.URLClassLoader
+ val loader = Thread.currentThread.getContextClassLoader.asInstanceOf[URLClassLoader]
+ val paths = loader.getURLs.map(u => URLDecoder.decode(u.getPath))
+ paths mkString java.io.File.pathSeparator
}
def createFactory = {
val settings = new Settings({Console.err.println(_)})
+ settings.scaladocQuietRun = true
+ settings.nowarn.value = true
settings.classpath.value = getClasspath
val reporter = new scala.tools.nsc.reporters.ConsoleReporter(settings)
new DocFactory(reporter, settings)
}
- def createTemplates(basename: String) = {
- val result = scala.collection.mutable.Map[String, scala.xml.NodeSeq]()
+ def createTemplates(basename: String): collection.Map[String, NodeSeq] = {
+ val result = mutable.Map[String, NodeSeq]()
createFactory.makeUniverse(Left(List(RESOURCES+basename))) match {
case Some(universe) => {
@@ -57,7 +62,7 @@ object Test extends Properties("HtmlFactory") {
result += (page.absoluteLinkTo(page.path) -> page.body)
})
}
- case _ => ;
+ case _ =>
}
result
diff --git a/test/scaladoc/scalacheck/IndexScriptTest.scala b/test/scaladoc/scalacheck/IndexScriptTest.scala
index 37f6947aaa..b8b9f92965 100644
--- a/test/scaladoc/scalacheck/IndexScriptTest.scala
+++ b/test/scaladoc/scalacheck/IndexScriptTest.scala
@@ -8,14 +8,20 @@ import java.net.{URLClassLoader, URLDecoder}
object Test extends Properties("IndexScript") {
def getClasspath = {
- val loader = Thread.currentThread.getContextClassLoader
- val paths = loader.asInstanceOf[URLClassLoader].getURLs
- val morepaths = loader.getParent.asInstanceOf[URLClassLoader].getURLs
- (paths ++ morepaths).map(u => URLDecoder.decode(u.getPath)).mkString(java.io.File.pathSeparator)
+ // these things can be tricky
+ // this test previously relied on the assumption that the current thread's classloader is an url classloader and contains all the classpaths
+ // does partest actually guarantee this? to quote Leonard Nimoy: The answer, of course, is no.
+ // this test _will_ fail again some time in the future.
+ // Footnote: java.lang.ClassCastException: org.apache.tools.ant.loader.AntClassLoader5 cannot be cast to java.net.URLClassLoader
+ val loader = Thread.currentThread.getContextClassLoader.asInstanceOf[URLClassLoader]
+ val paths = loader.getURLs.map(u => URLDecoder.decode(u.getPath))
+ paths mkString java.io.File.pathSeparator
}
val docFactory = {
val settings = new doc.Settings({Console.err.println(_)})
+ settings.scaladocQuietRun = true
+ settings.nowarn.value = true
settings.classpath.value = getClasspath
val reporter = new scala.tools.nsc.reporters.ConsoleReporter(settings)
new doc.DocFactory(reporter, settings)
diff --git a/test/scaladoc/scalacheck/IndexTest.scala b/test/scaladoc/scalacheck/IndexTest.scala
index dc4ab126d4..abc0e5da01 100644
--- a/test/scaladoc/scalacheck/IndexTest.scala
+++ b/test/scaladoc/scalacheck/IndexTest.scala
@@ -12,19 +12,19 @@ object Test extends Properties("Index") {
// this test previously relied on the assumption that the current thread's classloader is an url classloader and contains all the classpaths
// does partest actually guarantee this? to quote Leonard Nimoy: The answer, of course, is no.
// this test _will_ fail again some time in the future.
- val paths = Thread.currentThread.getContextClassLoader.asInstanceOf[URLClassLoader].getURLs.map(u => URLDecoder.decode(u.getPath))
- val morepaths = Thread.currentThread.getContextClassLoader.getParent.asInstanceOf[URLClassLoader].getURLs.map(u => URLDecoder.decode(u.getPath))
- (paths ++ morepaths).mkString(java.io.File.pathSeparator)
+ // Footnote: java.lang.ClassCastException: org.apache.tools.ant.loader.AntClassLoader5 cannot be cast to java.net.URLClassLoader
+ val loader = Thread.currentThread.getContextClassLoader.asInstanceOf[URLClassLoader]
+ val paths = loader.getURLs.map(u => URLDecoder.decode(u.getPath))
+ paths mkString java.io.File.pathSeparator
}
val docFactory = {
val settings = new doc.Settings({Console.err.println(_)})
-
+ settings.scaladocQuietRun = true
+ settings.nowarn.value = true
settings.classpath.value = getClasspath
- println(settings.classpath.value)
val reporter = new scala.tools.nsc.reporters.ConsoleReporter(settings)
-
new doc.DocFactory(reporter, settings)
}