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

Commit e3499d0

Browse files
committed
Merge pull request #40 from szeiger/wip/sbt-partest
Updated SBTRunner improvements for passing arguments to partest
2 parents ee3ae8a + 7c4659e commit e3499d0

File tree

7 files changed

+241
-206
lines changed

7 files changed

+241
-206
lines changed
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
/* NEST (New Scala Test)
2+
* Copyright 2007-2013 LAMP/EPFL
3+
* @author Philipp Haller
4+
*/
5+
6+
package scala.tools
7+
package partest
8+
package nest
9+
10+
import utils.Properties._
11+
import scala.tools.nsc.Properties.{ versionMsg, propOrFalse, setProp }
12+
import scala.collection.{ mutable, immutable }
13+
import TestKinds._
14+
import scala.reflect.internal.util.Collections.distinctBy
15+
import scala.tools.cmd.{ CommandLine, CommandLineParser, Instance }
16+
17+
abstract class AbstractRunner(argstr: String) extends {
18+
val parsed = RunnerSpec.creator(CommandLineParser tokenize argstr)
19+
} with RunnerSpec with Instance {
20+
21+
val suiteRunner: SuiteRunner
22+
23+
import suiteRunner._
24+
import NestUI._
25+
import NestUI.color._
26+
27+
private var totalTests = 0
28+
private val passedTests = mutable.ListBuffer[TestState]()
29+
private val failedTests = mutable.ListBuffer[TestState]()
30+
31+
def comment(s: String) = echo(magenta("# " + s))
32+
def levyJudgment() = {
33+
if (totalTests == 0) echoMixed("No tests to run.")
34+
else if (elapsedMillis == 0) echoMixed("Test Run ABORTED")
35+
else if (isSuccess) echoPassed("Test Run PASSED")
36+
else echoFailed("Test Run FAILED")
37+
}
38+
39+
def passFailString(passed: Int, failed: Int, skipped: Int): String = {
40+
val total = passed + failed + skipped
41+
val isSuccess = failed == 0
42+
def p0 = s"$passed/$total"
43+
def p = ( if (isSuccess) bold(green(p0)) else p0 ) + " passed"
44+
def f = if (failed == 0) "" else bold(red("" + failed)) + " failed"
45+
def s = if (skipped == 0) "" else bold(yellow("" + skipped)) + " skipped"
46+
47+
oempty(p, f, s) mkString ", "
48+
}
49+
50+
protected var summarizing = false
51+
private var elapsedMillis = 0L
52+
private var expectedFailures = 0
53+
protected def isSuccess = failedTests.size == expectedFailures
54+
55+
def issueSummaryReport() {
56+
// Don't run twice
57+
if (!summarizing) {
58+
summarizing = true
59+
60+
val passed0 = passedTests.toList
61+
val failed0 = failedTests.toList
62+
val passed = passed0.size
63+
val failed = failed0.size
64+
val skipped = totalTests - (passed + failed)
65+
val passFail = passFailString(passed, failed, skipped)
66+
val elapsed = if (elapsedMillis > 0) " (elapsed time: " + elapsedString(elapsedMillis) + ")" else ""
67+
val message = passFail + elapsed
68+
69+
if (failed0.nonEmpty) {
70+
if (isPartestVerbose) {
71+
echo(bold(cyan("##### Transcripts from failed tests #####\n")))
72+
failed0 foreach { state =>
73+
comment("partest " + state.testFile)
74+
echo(state.transcriptString + "\n")
75+
}
76+
}
77+
78+
def files_s = failed0.map(_.testFile).mkString(""" \""" + "\n ")
79+
echo("# Failed test paths (this command will update checkfiles)")
80+
echo("test/partest --update-check \\\n " + files_s + "\n")
81+
}
82+
83+
echo(message)
84+
levyJudgment()
85+
}
86+
}
87+
88+
def run(): Unit = {
89+
if (optDebug || propOrFalse("partest.debug")) NestUI.setDebug()
90+
if (optVerbose) NestUI.setVerbose()
91+
if (optTerse) NestUI.setTerse()
92+
if (optShowDiff) NestUI.setDiffOnFail()
93+
94+
// Early return on no args, version, or invalid args
95+
if (optVersion) return echo(versionMsg)
96+
if (optHelp) return NestUI.usage()
97+
98+
val (individualTests, invalid) = parsed.residualArgs map (p => Path(p)) partition denotesTestPath
99+
if (invalid.nonEmpty) {
100+
if (isPartestVerbose)
101+
invalid foreach (p => echoWarning(s"Discarding invalid test path " + p))
102+
else if (!isPartestTerse)
103+
echoWarning(s"Discarding ${invalid.size} invalid test paths")
104+
}
105+
106+
optTimeout foreach (x => setProp("partest.timeout", x))
107+
108+
if (!isPartestTerse)
109+
NestUI echo banner
110+
111+
val partestTests = (
112+
if (optSelfTest) TestKinds.testsForPartest
113+
else Nil
114+
)
115+
116+
val grepExpr = optGrep getOrElse ""
117+
118+
// If --grep is given we suck in every file it matches.
119+
// TODO: intersect results of grep with specified kinds, if any
120+
val greppedTests = if (grepExpr == "") Nil else {
121+
val paths = grepFor(grepExpr)
122+
if (paths.isEmpty)
123+
echoWarning(s"grep string '$grepExpr' matched no tests.\n")
124+
125+
paths.sortBy(_.toString)
126+
}
127+
128+
val isRerun = optFailed
129+
val rerunTests = if (isRerun) TestKinds.failedTests else Nil
130+
def miscTests = partestTests ++ individualTests ++ greppedTests ++ rerunTests
131+
132+
val givenKinds = standardKinds filter parsed.isSet
133+
val kinds = (
134+
if (givenKinds.nonEmpty) givenKinds
135+
else if (miscTests.isEmpty) standardKinds // If no kinds, --grep, or individual tests were given, assume --all
136+
else Nil
137+
)
138+
val kindsTests = kinds flatMap testsFor
139+
140+
def testContributors = {
141+
List(
142+
if (partestTests.isEmpty) "" else "partest self-tests",
143+
if (rerunTests.isEmpty) "" else "previously failed tests",
144+
if (kindsTests.isEmpty) "" else s"${kinds.size} named test categories",
145+
if (greppedTests.isEmpty) "" else s"${greppedTests.size} tests matching '$grepExpr'",
146+
if (individualTests.isEmpty) "" else "specified tests"
147+
) filterNot (_ == "") mkString ", "
148+
}
149+
150+
val allTests: Array[Path] = distinctBy(miscTests ++ kindsTests)(_.toCanonical) sortBy (_.toString) toArray
151+
val grouped = (allTests groupBy kindOf).toArray sortBy (x => standardKinds indexOf x._1)
152+
153+
totalTests = allTests.size
154+
expectedFailures = propOrNone("partest.errors") match {
155+
case Some(num) => num.toInt
156+
case _ => 0
157+
}
158+
val expectedFailureMessage = if (expectedFailures == 0) "" else s" (expecting $expectedFailures to fail)"
159+
echo(s"Selected $totalTests tests drawn from $testContributors$expectedFailureMessage\n")
160+
161+
val (_, millis) = timed {
162+
for ((kind, paths) <- grouped) {
163+
val num = paths.size
164+
val ss = if (num == 1) "" else "s"
165+
comment(s"starting $num test$ss in $kind")
166+
val results = runTestsForFiles(paths map (_.jfile.getAbsoluteFile), kind)
167+
val (passed, failed) = results partition (_.isOk)
168+
169+
passedTests ++= passed
170+
failedTests ++= failed
171+
if (failed.nonEmpty) {
172+
comment(passFailString(passed.size, failed.size, 0) + " in " + kind)
173+
}
174+
echo("")
175+
}
176+
}
177+
this.elapsedMillis = millis
178+
issueSummaryReport()
179+
}
180+
}

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,8 @@ abstract class AntRunner(srcDir: String, testClassLoader: URLClassLoader, javaCm
1919
failed = false,
2020
javaCmdPath = Option(javaCmd).map(_.getAbsolutePath) getOrElse PartestDefaults.javaCmd,
2121
javacCmdPath = Option(javacCmd).map(_.getAbsolutePath) getOrElse PartestDefaults.javacCmd,
22-
scalacExtraArgs = scalacArgs) {
23-
24-
for (jOpts <- javaOpts) System.setProperty("partest.java_opts", jOpts mkString " ")
22+
scalacExtraArgs = scalacArgs,
23+
javaOpts = javaOpts.map(_.mkString(" ")).getOrElse(PartestDefaults.javaOpts)) {
2524

2625
def error(msg: String): Nothing = sys.error(msg)
2726
def echo(msg: String): Unit

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

Lines changed: 5 additions & 167 deletions
Original file line numberDiff line numberDiff line change
@@ -7,185 +7,23 @@ package scala.tools
77
package partest
88
package nest
99

10-
import utils.Properties._
11-
import scala.tools.nsc.Properties.{ versionMsg, propOrFalse, setProp }
12-
import scala.collection.{ mutable, immutable }
13-
import TestKinds._
14-
import scala.reflect.internal.util.Collections.distinctBy
15-
import scala.tools.cmd.{ CommandLine, CommandLineParser, Instance }
10+
class ConsoleRunner(argstr: String) extends AbstractRunner(argstr) {
1611

17-
class ConsoleRunner(argstr: String) extends {
18-
val parsed = ConsoleRunnerSpec.creator(CommandLineParser tokenize argstr)
19-
} with ConsoleRunnerSpec with Instance {
20-
21-
val suiteRunner = new SuiteRunner (
12+
override val suiteRunner = new SuiteRunner (
2213
testSourcePath = optSourcePath getOrElse PartestDefaults.sourcePath,
2314
fileManager = new FileManager(ClassPath split PathResolver.Environment.javaUserClassPath map (Path(_))), // the script sets up our classpath for us via ant
2415
updateCheck = optUpdateCheck,
2516
failed = optFailed)
26-
import suiteRunner._
27-
import NestUI._
28-
import NestUI.color._
2917

3018
// So we can ctrl-C a test run and still hear all
3119
// the buffered failure info.
3220
scala.sys addShutdownHook issueSummaryReport()
3321

34-
private var totalTests = 0
35-
private val passedTests = mutable.ListBuffer[TestState]()
36-
private val failedTests = mutable.ListBuffer[TestState]()
37-
38-
def comment(s: String) = echo(magenta("# " + s))
39-
def levyJudgment() = {
40-
if (totalTests == 0) echoMixed("No tests to run.")
41-
else if (elapsedMillis == 0) echoMixed("Test Run ABORTED")
42-
else if (isSuccess) echoPassed("Test Run PASSED")
43-
else echoFailed("Test Run FAILED")
44-
}
45-
46-
def passFailString(passed: Int, failed: Int, skipped: Int): String = {
47-
val total = passed + failed + skipped
48-
val isSuccess = failed == 0
49-
def p0 = s"$passed/$total"
50-
def p = ( if (isSuccess) bold(green(p0)) else p0 ) + " passed"
51-
def f = if (failed == 0) "" else bold(red("" + failed)) + " failed"
52-
def s = if (skipped == 0) "" else bold(yellow("" + skipped)) + " skipped"
53-
54-
oempty(p, f, s) mkString ", "
55-
}
56-
57-
private var summarizing = false
58-
private var elapsedMillis = 0L
59-
private var expectedFailures = 0
60-
private def isSuccess = failedTests.size == expectedFailures
61-
62-
def issueSummaryReport() {
63-
// Don't run twice
64-
if (!summarizing) {
65-
summarizing = true
66-
67-
val passed0 = passedTests.toList
68-
val failed0 = failedTests.toList
69-
val passed = passed0.size
70-
val failed = failed0.size
71-
val skipped = totalTests - (passed + failed)
72-
val passFail = passFailString(passed, failed, skipped)
73-
val elapsed = if (elapsedMillis > 0) " (elapsed time: " + elapsedString(elapsedMillis) + ")" else ""
74-
val message = passFail + elapsed
75-
76-
if (failed0.nonEmpty) {
77-
if (isPartestVerbose) {
78-
echo(bold(cyan("##### Transcripts from failed tests #####\n")))
79-
failed0 foreach { state =>
80-
comment("partest " + state.testFile)
81-
echo(state.transcriptString + "\n")
82-
}
83-
}
84-
85-
def files_s = failed0.map(_.testFile).mkString(""" \""" + "\n ")
86-
echo("# Failed test paths (this command will update checkfiles)")
87-
echo("test/partest --update-check \\\n " + files_s + "\n")
88-
}
89-
90-
echo(message)
91-
levyJudgment()
92-
}
93-
}
94-
95-
def run(): Unit = {
96-
if (optDebug || propOrFalse("partest.debug")) NestUI.setDebug()
97-
if (optVerbose) NestUI.setVerbose()
98-
if (optTerse) NestUI.setTerse()
99-
if (optShowDiff) NestUI.setDiffOnFail()
100-
101-
// Early return on no args, version, or invalid args
102-
if (optVersion) return echo(versionMsg)
103-
if (optHelp) return NestUI.usage()
104-
105-
val (individualTests, invalid) = parsed.residualArgs map (p => Path(p)) partition denotesTestPath
106-
if (invalid.nonEmpty) {
107-
if (isPartestVerbose)
108-
invalid foreach (p => echoWarning(s"Discarding invalid test path " + p))
109-
else if (!isPartestTerse)
110-
echoWarning(s"Discarding ${invalid.size} invalid test paths")
111-
}
112-
113-
optTimeout foreach (x => setProp("partest.timeout", x))
114-
115-
if (!isPartestTerse)
116-
NestUI echo banner
117-
118-
val partestTests = (
119-
if (optSelfTest) TestKinds.testsForPartest
120-
else Nil
121-
)
122-
123-
val grepExpr = optGrep getOrElse ""
124-
125-
// If --grep is given we suck in every file it matches.
126-
// TODO: intersect results of grep with specified kinds, if any
127-
val greppedTests = if (grepExpr == "") Nil else {
128-
val paths = grepFor(grepExpr)
129-
if (paths.isEmpty)
130-
echoWarning(s"grep string '$grepExpr' matched no tests.\n")
131-
132-
paths.sortBy(_.toString)
133-
}
134-
135-
val isRerun = optFailed
136-
val rerunTests = if (isRerun) TestKinds.failedTests else Nil
137-
def miscTests = partestTests ++ individualTests ++ greppedTests ++ rerunTests
138-
139-
val givenKinds = standardKinds filter parsed.isSet
140-
val kinds = (
141-
if (givenKinds.nonEmpty) givenKinds
142-
else if (miscTests.isEmpty) standardKinds // If no kinds, --grep, or individual tests were given, assume --all
143-
else Nil
144-
)
145-
val kindsTests = kinds flatMap testsFor
146-
147-
def testContributors = {
148-
List(
149-
if (partestTests.isEmpty) "" else "partest self-tests",
150-
if (rerunTests.isEmpty) "" else "previously failed tests",
151-
if (kindsTests.isEmpty) "" else s"${kinds.size} named test categories",
152-
if (greppedTests.isEmpty) "" else s"${greppedTests.size} tests matching '$grepExpr'",
153-
if (individualTests.isEmpty) "" else "specified tests"
154-
) filterNot (_ == "") mkString ", "
155-
}
156-
157-
val allTests: Array[Path] = distinctBy(miscTests ++ kindsTests)(_.toCanonical) sortBy (_.toString) toArray
158-
val grouped = (allTests groupBy kindOf).toArray sortBy (x => standardKinds indexOf x._1)
159-
160-
totalTests = allTests.size
161-
expectedFailures = propOrNone("partest.errors") match {
162-
case Some(num) => num.toInt
163-
case _ => 0
164-
}
165-
val expectedFailureMessage = if (expectedFailures == 0) "" else s" (expecting $expectedFailures to fail)"
166-
echo(s"Selected $totalTests tests drawn from $testContributors$expectedFailureMessage\n")
167-
168-
val (_, millis) = timed {
169-
for ((kind, paths) <- grouped) {
170-
val num = paths.size
171-
val ss = if (num == 1) "" else "s"
172-
comment(s"starting $num test$ss in $kind")
173-
val results = runTestsForFiles(paths map (_.jfile.getAbsoluteFile), kind)
174-
val (passed, failed) = results partition (_.isOk)
175-
176-
passedTests ++= passed
177-
failedTests ++= failed
178-
if (failed.nonEmpty) {
179-
comment(passFailString(passed.size, failed.size, 0) + " in " + kind)
180-
}
181-
echo("")
182-
}
183-
}
184-
this.elapsedMillis = millis
185-
issueSummaryReport()
22+
override def run(): Unit = {
23+
super.run()
18624
System exit ( if (isSuccess) 0 else 1 )
18725
}
188-
26+
18927
run()
19028
}
19129

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,8 @@ object NestUI {
144144
}
145145

146146
def usage() {
147-
println(ConsoleRunnerSpec.programInfo.usage)
148-
println(ConsoleRunnerSpec.helpMsg)
147+
println(RunnerSpec.programInfo.usage)
148+
println(RunnerSpec.helpMsg)
149149
sys.exit(1)
150150
}
151151

0 commit comments

Comments
 (0)