Skip to content
This repository was archived by the owner on Sep 8, 2022. It is now read-only.

Commit ee99827

Browse files
committed
sbt test-interface for partest
It reflectively calls `SBTRunner`. Enable it in your `build.sbt` as follows (from the scala-xml build): ``` // for testing with partest (the binary version must be SBT's scala version): libraryDependencies += "com.typesafe" % "scala-partest-interface_2.10" % "0.1" % "test" testFrameworks += new TestFramework("com.typesafe.testing.partest.Framework") // the actual partest the interface calls into -- must be binary version close enough to ours // so that it can link to the compiler/lib we're using (testing) libraryDependencies += "org.scala-lang" %% "scala-partest" % "1.0" % "test" definedTests in Test += ( new sbt.TestDefinition( "partest", // marker fingerprint since there are no test classes // to be discovered by sbt: new sbt.testing.AnnotatedFingerprint { def isModule = true def annotationName = "partest" }, true, Array()) ) ``` You can now invoke partest in SBT using the `test` command.
1 parent 189f4cd commit ee99827

File tree

4 files changed

+69
-29
lines changed

4 files changed

+69
-29
lines changed

build.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,5 @@ libraryDependencies += "org.scala-lang" % "scalap" % "2.
2525

2626
libraryDependencies += "org.scalacheck" %% "scalacheck" % "1.10.2-SNAPSHOT"
2727

28-
// libraryDependencies += "org.scala-sbt" % "test-interface" % "1.0"
28+
libraryDependencies += "org.scala-sbt" % "test-interface" % "1.0"
2929

src/main/scala/scala/tools/partest/PartestTask.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ import nest.NestUI
3939
class PartestTask extends Task with CompilationPathProperty with ScalaTask {
4040
type Path = org.apache.tools.ant.types.Path
4141

42-
private var kinds: List[String] = Nil
42+
private var kinds: Array[String] = Array.empty
4343
private var classpath: Option[Path] = None
4444
private var debug = false
4545
private var errorOnFailed: Boolean = true
@@ -84,7 +84,7 @@ class PartestTask extends Task with CompilationPathProperty with ScalaTask {
8484
}
8585

8686
def setKinds(input: String) {
87-
kinds = words(input)
87+
kinds = words(input).toArray
8888
}
8989

9090
def setJavacCmd(input: File) {

src/main/scala/scala/tools/partest/nest/AntRunner.scala

Lines changed: 63 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,42 +6,53 @@
66
** |/ **
77
\* */
88

9-
109
package scala.tools.partest
1110
package nest
1211

12+
import sbt.testing.EventHandler
13+
import sbt.testing.Logger
14+
import sbt.testing.Event
15+
import sbt.testing.Fingerprint
16+
import sbt.testing.Selector
17+
import sbt.testing.Status
18+
import sbt.testing.OptionalThrowable
19+
import sbt.testing.SuiteSelector
20+
import sbt.testing.TestSelector
21+
1322
// not using any Scala types to ease calling across different scala versions
1423
abstract class AntRunner(compilationPaths: Array[String], javaCmd: File, javacCmd: File, scalacArgs: Array[String]) extends DirectRunner {
24+
def error(msg: String): Nothing = sys.error(msg)
25+
def echo(msg: String): Unit
26+
def log(msg: String): Unit
27+
def onFinishKind(kind: String, passed: Array[TestState], failed: Array[TestState]): Unit
28+
def onFinishTest(testFile: File, result: TestState): TestState = result
29+
1530
private val cpfiles = compilationPaths map { fs => new File(fs) } toList
1631
private def findCp(name: String) = cpfiles find (f =>
17-
(f.getName == s"scala-$name.jar")
18-
|| (f.absolutePathSegments endsWith Seq("classes", name))
32+
(f.getName == s"scala-$name.jar")
33+
|| (f.absolutePathSegments endsWith Seq("classes", name))
1934
) map (_.getAbsolutePath) getOrElse error(s"Provided compilationPath does not contain a Scala $name element.\nLooked in: ${compilationPaths.mkString(":")}")
2035

21-
22-
val fileManager = new FileManager {
23-
val COMPILATION_CLASSPATH: String = ClassPath.join(compilationPaths: _*)
24-
val LATEST_LIB: String = findCp("library")
25-
val LATEST_REFLECT: String = findCp("reflect")
26-
val LATEST_COMP: String = findCp("compiler")
27-
val testRootPath: String = "test"
28-
val testRootDir: Directory = Directory(testRootPath)
36+
final val fileManager = new FileManager {
37+
val COMPILATION_CLASSPATH: String = ClassPath.join(compilationPaths: _*)
38+
val LATEST_LIB: String = findCp("library")
39+
val LATEST_REFLECT: String = findCp("reflect")
40+
val LATEST_COMP: String = findCp("compiler")
41+
val testRootPath: String = "test"
42+
val testRootDir: Directory = Directory(testRootPath)
2943

3044
def failed = false
3145
def updateCheck = false
3246

33-
override val JAVACMD: String = Option(javaCmd) map (_.getAbsolutePath) getOrElse "java"
34-
override val JAVAC_CMD: String = Option(javacCmd) map (_.getAbsolutePath) getOrElse "javac"
47+
override val JAVACMD: String = Option(javaCmd) map (_.getAbsolutePath) getOrElse "java"
48+
override val JAVAC_CMD: String = Option(javacCmd) map (_.getAbsolutePath) getOrElse "javac"
3549
override def SCALAC_OPTS: Seq[String] = super.SCALAC_OPTS ++ scalacArgs
3650
}
3751

52+
final override def runTest(manager: RunnerManager, testFile: File): TestState =
53+
onFinishTest(testFile, manager runTest testFile)
3854

39-
def error(msg: String): Nothing = sys.error(msg)
40-
def echo(msg: String): Unit
41-
def log(msg: String): Unit
42-
def onFinishKind(kind: String, passed: Array[TestState], failed: Array[TestState])
43-
44-
def runSet(kind: String, files: Array[File]): (Int, Int, Array[String]) = {
55+
final def runSet(kind: String, files: Array[File]): (Int, Int, Array[String]) = {
4556
if (files.isEmpty) (0, 0, Array.empty[String])
4657
else {
4758
log(s"Running ${files.length} tests in '$kind' at $now")
@@ -58,19 +69,46 @@ abstract class AntRunner(compilationPaths: Array[String], javaCmd: File, javacCm
5869
}
5970
}
6071

61-
def execute(kinds: List[String]): String = {
72+
final def execute(kinds: Array[String]): String = {
6273
echo(banner)
6374

64-
val _results = kinds map (k => runSet(k, TestKinds testsFor k map (_.jfile) toArray))
75+
val _results = kinds map (k => runSet(k, TestKinds testsFor k map (_.jfile) toArray))
6576

66-
val allSuccesses = _results map (_._1) sum
67-
val allFailures = _results map (_._2) sum
77+
val allSuccesses = _results map (_._1) sum
78+
val allFailures = _results map (_._2) sum
6879
val allFailedPaths = _results flatMap (_._3)
6980

7081
if (allFailures > 0)
71-
s"Test suite finished with $allFailures case${if (allFailures > 1) "s" else ""} failing:\n"+
72-
allFailedPaths.mkString("\n")
82+
s"Test suite finished with $allFailures case${if (allFailures > 1) "s" else ""} failing:\n" +
83+
allFailedPaths.mkString("\n")
7384
else if (allSuccesses == 0) "There were no tests to run."
7485
else "Test suite finished with no failures."
7586
}
7687
}
88+
89+
class SBTRunner(partestFingerprint: Fingerprint, eventHandler: EventHandler, loggers: Array[Logger], compilationPaths: Array[String], javaCmd: File, javacCmd: File, scalacArgs: Array[String]) extends AntRunner(compilationPaths, javaCmd, javacCmd, scalacArgs) {
90+
override def error(msg: String): Nothing = sys.error(msg)
91+
def echo(msg: String): Unit = loggers foreach { l => l.info(msg) }
92+
def log(msg: String): Unit = loggers foreach { l => l.debug(msg) }
93+
def onFinishKind(kind: String, passed: Array[TestState], failed: Array[TestState]): Unit =
94+
eventHandler.handle(new Event {
95+
def fullyQualifiedName: String = kind
96+
def fingerprint: Fingerprint = partestFingerprint
97+
def selector: Selector = new SuiteSelector
98+
def status: Status = if (failed.isEmpty) Status.Success else Status.Failure
99+
def throwable: OptionalThrowable = new OptionalThrowable
100+
def duration: Long = -1
101+
})
102+
103+
override def onFinishTest(testFile: File, result: TestState): TestState = {
104+
eventHandler.handle(new Event {
105+
def fullyQualifiedName: String = testFile.testIdent
106+
def fingerprint: Fingerprint = partestFingerprint
107+
def selector: Selector = new TestSelector(testFile.testIdent)
108+
def status: Status = if (result.isOk) Status.Success else Status.Failure
109+
def throwable: OptionalThrowable = new OptionalThrowable
110+
def duration: Long = -1
111+
})
112+
result
113+
}
114+
}

src/main/scala/scala/tools/partest/nest/Runner.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -794,13 +794,15 @@ trait DirectRunner {
794794
// |Java Classpath: ${sys.props("java.class.path")}
795795
}
796796

797+
def runTest(manager: RunnerManager, testFile: File): TestState = manager runTest testFile
798+
797799
def runTestsForFiles(kindFiles: Array[File], kind: String): Array[TestState] = {
798800
NestUI.resetTestNumber(kindFiles.size)
799801

800802
val parentClassLoader = ScalaClassLoader fromURLs fileManager.testClassPathUrls
801803
val pool = Executors newFixedThreadPool numThreads
802804
val manager = new RunnerManager(kind, fileManager, TestRunParams(parentClassLoader))
803-
val futures = kindFiles map (f => pool submit callable(manager runTest f))
805+
val futures = kindFiles map (f => pool submit callable(runTest(manager, f)))
804806

805807
pool.shutdown()
806808
Try (pool.awaitTermination(waitTime) {

0 commit comments

Comments
 (0)