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

Commit c50e7a4

Browse files
committed
Clean up the outer layers of partest
- Refactored for less mutability - Narrowed scopes - Removed obsolete code
1 parent a7419b1 commit c50e7a4

File tree

11 files changed

+208
-235
lines changed

11 files changed

+208
-235
lines changed

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,7 @@ class PartestTask extends Task with CompilationPathProperty with ScalaTask {
118118
}
119119

120120
override def execute() {
121-
if (debug || propOrFalse("partest.debug")) {
122-
NestUI.setDebug()
123-
}
121+
val nestUI: NestUI = new NestUI(debug = debug || propOrFalse("partest.debug"))
124122

125123
if (compilationPath.isEmpty) sys.error("Mandatory attribute 'compilationPath' is not set.")
126124

@@ -130,7 +128,7 @@ class PartestTask extends Task with CompilationPathProperty with ScalaTask {
130128
})
131129

132130
var failureCount = 0
133-
val summary = new scala.tools.partest.nest.AntRunner(srcDir.getOrElse(null), new URLClassLoader(compilationPath.get.list.map(Path(_).toURL)), javacmd.getOrElse(null), javaccmd.getOrElse(null), scalacArgsFlat, javaOpts) {
131+
val summary = new scala.tools.partest.nest.AntRunner(srcDir.getOrElse(null), new URLClassLoader(compilationPath.get.list.map(Path(_).toURL)), javacmd.getOrElse(null), javaccmd.getOrElse(null), scalacArgsFlat, javaOpts, nestUI) {
134132
def echo(msg: String): Unit = PartestTask.this.log(msg)
135133
def log(msg: String): Unit = PartestTask.this.log(msg)
136134

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

Lines changed: 105 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -12,31 +12,45 @@ import scala.tools.nsc.Properties.{ versionMsg, propOrFalse, setProp }
1212
import scala.collection.{ mutable, immutable }
1313
import TestKinds._
1414
import scala.reflect.internal.util.Collections.distinctBy
15-
import scala.tools.cmd.{ CommandLine, CommandLineParser, Instance }
1615

17-
abstract class AbstractRunner(argstr: String) extends {
18-
val parsed = RunnerSpec.creator(CommandLineParser tokenize argstr)
19-
} with RunnerSpec with Instance {
16+
abstract class AbstractRunner {
17+
18+
val config: RunnerSpec.Config
19+
20+
val nestUI: NestUI = new NestUI(
21+
verbose = config.optVerbose,
22+
debug = config.optDebug || propOrFalse("partest.debug"),
23+
terse = config.optTerse,
24+
diffOnFail = config.optShowDiff,
25+
colorEnabled = sys.props contains "partest.colors"
26+
)
2027

2128
val suiteRunner: SuiteRunner
2229

23-
import suiteRunner._
24-
import NestUI._
25-
import NestUI.color._
30+
protected val printSummary = true
31+
protected val partestCmd = "test/partest"
32+
33+
private[this] var totalTests = 0
34+
private[this] val passedTests = mutable.ListBuffer[TestState]()
35+
private[this] val failedTests = mutable.ListBuffer[TestState]()
36+
37+
private[this] var summarizing = false
38+
private[this] var elapsedMillis = 0L
39+
private[this] var expectedFailures = 0
2640

27-
private var totalTests = 0
28-
private val passedTests = mutable.ListBuffer[TestState]()
29-
private val failedTests = mutable.ListBuffer[TestState]()
41+
import nestUI._
42+
import nestUI.color._
3043

31-
def comment(s: String) = echo(magenta("# " + s))
32-
def levyJudgment() = {
44+
private[this] def comment(s: String) = echo(magenta("# " + s))
45+
46+
private[this] def levyJudgment() = {
3347
if (totalTests == 0) echoMixed("No tests to run.")
3448
else if (elapsedMillis == 0) echoMixed("Test Run ABORTED")
3549
else if (isSuccess) echoPassed("Test Run PASSED")
3650
else echoFailed("Test Run FAILED")
3751
}
3852

39-
def passFailString(passed: Int, failed: Int, skipped: Int): String = {
53+
private[this] def passFailString(passed: Int, failed: Int, skipped: Int): String = {
4054
val total = passed + failed + skipped
4155
val isSuccess = failed == 0
4256
def p0 = s"$passed/$total"
@@ -47,12 +61,7 @@ abstract class AbstractRunner(argstr: String) extends {
4761
oempty(p, f, s) mkString ", "
4862
}
4963

50-
protected var partestCmd = "test/partest"
51-
protected var summarizing = false
52-
protected var printSummary = true
53-
private var elapsedMillis = 0L
54-
private var expectedFailures = 0
55-
protected def isSuccess = failedTests.size == expectedFailures
64+
private[this] def isSuccess = failedTests.size == expectedFailures
5665

5766
def issueSummaryReport() {
5867
// Don't run twice
@@ -69,7 +78,7 @@ abstract class AbstractRunner(argstr: String) extends {
6978
val message = passFail + elapsed
7079

7180
if (failed0.nonEmpty) {
72-
if (isPartestVerbose) {
81+
if (nestUI.verbose) {
7382
echo(bold(cyan("##### Transcripts from failed tests #####\n")))
7483
failed0 foreach { state =>
7584
comment(partestCmd + " " + state.testFile)
@@ -89,96 +98,93 @@ abstract class AbstractRunner(argstr: String) extends {
8998
}
9099
}
91100

92-
def run(): Unit = {
93-
if (optDebug || propOrFalse("partest.debug")) NestUI.setDebug()
94-
if (optVerbose) NestUI.setVerbose()
95-
if (optTerse) NestUI.setTerse()
96-
if (optShowDiff) NestUI.setDiffOnFail()
97-
98-
// Early return on no args, version, or invalid args
99-
if (optVersion) return echo(versionMsg)
100-
if (optHelp) return NestUI.usage()
101-
102-
val (individualTests, invalid) = parsed.residualArgs map (p => Path(p)) partition denotesTestPath
103-
if (invalid.nonEmpty) {
104-
if (isPartestVerbose)
105-
invalid foreach (p => echoWarning(s"Discarding invalid test path " + p))
106-
else if (!isPartestTerse)
107-
echoWarning(s"Discarding ${invalid.size} invalid test paths")
108-
}
101+
/** Run the tests and return the success status */
102+
def run(): Boolean = {
103+
if (config.optVersion) echo(versionMsg)
104+
else if (config.optHelp) nestUI.usage()
105+
else {
106+
val (individualTests, invalid) = config.parsed.residualArgs map (p => Path(p)) partition denotesTestPath
107+
if (invalid.nonEmpty) {
108+
if (nestUI.verbose)
109+
invalid foreach (p => echoWarning(s"Discarding invalid test path " + p))
110+
else if (!nestUI.terse)
111+
echoWarning(s"Discarding ${invalid.size} invalid test paths")
112+
}
109113

110-
optTimeout foreach (x => setProp("partest.timeout", x))
114+
config.optTimeout foreach (x => setProp("partest.timeout", x))
111115

112-
if (!isPartestTerse)
113-
NestUI echo banner
116+
if (!nestUI.terse)
117+
nestUI.echo(suiteRunner.banner)
114118

115-
val partestTests = (
116-
if (optSelfTest) TestKinds.testsForPartest
117-
else Nil
118-
)
119+
val partestTests = (
120+
if (config.optSelfTest) TestKinds.testsForPartest
121+
else Nil
122+
)
119123

120-
val grepExpr = optGrep getOrElse ""
124+
val grepExpr = config.optGrep getOrElse ""
121125

122-
// If --grep is given we suck in every file it matches.
123-
// TODO: intersect results of grep with specified kinds, if any
124-
val greppedTests = if (grepExpr == "") Nil else {
125-
val paths = grepFor(grepExpr)
126-
if (paths.isEmpty)
127-
echoWarning(s"grep string '$grepExpr' matched no tests.\n")
126+
// If --grep is given we suck in every file it matches.
127+
// TODO: intersect results of grep with specified kinds, if any
128+
val greppedTests = if (grepExpr == "") Nil else {
129+
val paths = grepFor(grepExpr)
130+
if (paths.isEmpty)
131+
echoWarning(s"grep string '$grepExpr' matched no tests.\n")
128132

129-
paths.sortBy(_.toString)
130-
}
133+
paths.sortBy(_.toString)
134+
}
131135

132-
val isRerun = optFailed
133-
val rerunTests = if (isRerun) TestKinds.failedTests else Nil
134-
def miscTests = partestTests ++ individualTests ++ greppedTests ++ rerunTests
135-
136-
val givenKinds = standardKinds filter parsed.isSet
137-
val kinds = (
138-
if (givenKinds.nonEmpty) givenKinds
139-
else if (miscTests.isEmpty) standardKinds // If no kinds, --grep, or individual tests were given, assume --all
140-
else Nil
141-
)
142-
val kindsTests = kinds flatMap testsFor
143-
144-
def testContributors = {
145-
List(
146-
if (partestTests.isEmpty) "" else "partest self-tests",
147-
if (rerunTests.isEmpty) "" else "previously failed tests",
148-
if (kindsTests.isEmpty) "" else s"${kinds.size} named test categories",
149-
if (greppedTests.isEmpty) "" else s"${greppedTests.size} tests matching '$grepExpr'",
150-
if (individualTests.isEmpty) "" else "specified tests"
151-
) filterNot (_ == "") mkString ", "
152-
}
136+
val isRerun = config.optFailed
137+
val rerunTests = if (isRerun) TestKinds.failedTests else Nil
138+
def miscTests = partestTests ++ individualTests ++ greppedTests ++ rerunTests
139+
140+
val givenKinds = standardKinds filter config.parsed.isSet
141+
val kinds = (
142+
if (givenKinds.nonEmpty) givenKinds
143+
else if (miscTests.isEmpty) standardKinds // If no kinds, --grep, or individual tests were given, assume --all
144+
else Nil
145+
)
146+
val kindsTests = kinds flatMap testsFor
147+
148+
def testContributors = {
149+
List(
150+
if (partestTests.isEmpty) "" else "partest self-tests",
151+
if (rerunTests.isEmpty) "" else "previously failed tests",
152+
if (kindsTests.isEmpty) "" else s"${kinds.size} named test categories",
153+
if (greppedTests.isEmpty) "" else s"${greppedTests.size} tests matching '$grepExpr'",
154+
if (individualTests.isEmpty) "" else "specified tests"
155+
) filterNot (_ == "") mkString ", "
156+
}
153157

154-
val allTests: Array[Path] = distinctBy(miscTests ++ kindsTests)(_.toCanonical) sortBy (_.toString) toArray
155-
val grouped = (allTests groupBy kindOf).toArray sortBy (x => standardKinds indexOf x._1)
158+
val allTests: Array[Path] = distinctBy(miscTests ++ kindsTests)(_.toCanonical) sortBy (_.toString) toArray
159+
val grouped = (allTests groupBy kindOf).toArray sortBy (x => standardKinds indexOf x._1)
156160

157-
totalTests = allTests.size
158-
expectedFailures = propOrNone("partest.errors") match {
159-
case Some(num) => num.toInt
160-
case _ => 0
161-
}
162-
val expectedFailureMessage = if (expectedFailures == 0) "" else s" (expecting $expectedFailures to fail)"
163-
echo(s"Selected $totalTests tests drawn from $testContributors$expectedFailureMessage\n")
164-
165-
val (_, millis) = timed {
166-
for ((kind, paths) <- grouped) {
167-
val num = paths.size
168-
val ss = if (num == 1) "" else "s"
169-
comment(s"starting $num test$ss in $kind")
170-
val results = runTestsForFiles(paths map (_.jfile.getAbsoluteFile), kind)
171-
val (passed, failed) = results partition (_.isOk)
172-
173-
passedTests ++= passed
174-
failedTests ++= failed
175-
if (failed.nonEmpty) {
176-
comment(passFailString(passed.size, failed.size, 0) + " in " + kind)
161+
totalTests = allTests.size
162+
expectedFailures = propOrNone("partest.errors") match {
163+
case Some(num) => num.toInt
164+
case _ => 0
165+
}
166+
val expectedFailureMessage = if (expectedFailures == 0) "" else s" (expecting $expectedFailures to fail)"
167+
echo(s"Selected $totalTests tests drawn from $testContributors$expectedFailureMessage\n")
168+
169+
val (_, millis) = timed {
170+
for ((kind, paths) <- grouped) {
171+
val num = paths.size
172+
val ss = if (num == 1) "" else "s"
173+
comment(s"starting $num test$ss in $kind")
174+
val results = suiteRunner.runTestsForFiles(paths map (_.jfile.getAbsoluteFile), kind)
175+
val (passed, failed) = results partition (_.isOk)
176+
177+
passedTests ++= passed
178+
failedTests ++= failed
179+
if (failed.nonEmpty) {
180+
comment(passFailString(passed.size, failed.size, 0) + " in " + kind)
181+
}
182+
echo("")
177183
}
178-
echo("")
179184
}
185+
this.elapsedMillis = millis
186+
issueSummaryReport()
180187
}
181-
this.elapsedMillis = millis
182-
issueSummaryReport()
188+
isSuccess
183189
}
184190
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,12 @@ package nest
1212
import java.net.URLClassLoader
1313

1414
// not using any Scala types to ease calling across different scala versions
15-
abstract class AntRunner(srcDir: String, testClassLoader: URLClassLoader, javaCmd: File, javacCmd: File, scalacArgs: Array[String], javaOpts: Option[Seq[String]]) extends SuiteRunner(
15+
abstract class AntRunner(srcDir: String, testClassLoader: URLClassLoader, javaCmd: File, javacCmd: File, scalacArgs: Array[String], javaOpts: Option[Seq[String]], nestUI: NestUI) extends SuiteRunner(
1616
testSourcePath = Option(srcDir) getOrElse PartestDefaults.sourcePath,
1717
new FileManager(testClassLoader = testClassLoader),
1818
updateCheck = false,
1919
failed = false,
20+
nestUI = nestUI,
2021
javaCmdPath = Option(javaCmd).map(_.getAbsolutePath) getOrElse PartestDefaults.javaCmd,
2122
javacCmdPath = Option(javacCmd).map(_.getAbsolutePath) getOrElse PartestDefaults.javacCmd,
2223
scalacExtraArgs = scalacArgs,

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

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,24 @@
33
* @author Philipp Haller
44
*/
55

6-
package scala.tools
7-
package partest
6+
package scala.tools.partest
87
package nest
98

10-
class ConsoleRunner(argstr: String) extends AbstractRunner(argstr) {
11-
12-
override val suiteRunner = new SuiteRunner (
13-
testSourcePath = optSourcePath getOrElse PartestDefaults.sourcePath,
9+
class ConsoleRunner(val config: RunnerSpec.Config) extends AbstractRunner {
10+
val suiteRunner = new SuiteRunner (
11+
testSourcePath = config.optSourcePath getOrElse PartestDefaults.sourcePath,
1412
fileManager = new FileManager(ClassPath split PathResolver.Environment.javaUserClassPath map (Path(_))), // the script sets up our classpath for us via ant
15-
updateCheck = optUpdateCheck,
16-
failed = optFailed)
17-
18-
// So we can ctrl-C a test run and still hear all
19-
// the buffered failure info.
20-
scala.sys addShutdownHook issueSummaryReport()
21-
22-
override def run(): Unit = {
23-
super.run()
24-
System exit ( if (isSuccess) 0 else 1 )
25-
}
26-
27-
run()
13+
updateCheck = config.optUpdateCheck,
14+
failed = config.optFailed,
15+
nestUI = nestUI)
2816
}
2917

3018
object ConsoleRunner {
3119
def main(args: Array[String]): Unit = {
32-
new ConsoleRunner(args mkString " ")
20+
val r = new ConsoleRunner(RunnerSpec.forArgs(args))
21+
// So we can ctrl-C a test run and still hear all
22+
// the buffered failure info.
23+
scala.sys addShutdownHook r.issueSummaryReport()
24+
System.exit( if (r.run) 0 else 1 )
3325
}
3426
}
35-

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ class DirectCompiler(val runner: Runner) {
107107
}
108108

109109
def ids = sources.map(_.testIdent) mkString space
110-
vlog(s"% scalac $ids")
110+
nestUI.vlog(s"% scalac $ids")
111111

112112
def execCompile() =
113113
if (command.shouldStopWithInfo) {

0 commit comments

Comments
 (0)