@@ -12,31 +12,46 @@ import scala.tools.nsc.Properties.{ versionMsg, propOrFalse, setProp }
1212import scala .collection .{ mutable , immutable }
1313import TestKinds ._
1414import 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+ logOnFail = config.optShowLog,
26+ colorEnabled = sys.props contains " partest.colors"
27+ )
2028
2129 val suiteRunner : SuiteRunner
2230
23- import suiteRunner ._
24- import NestUI ._
25- import NestUI .color ._
31+ protected val printSummary = true
32+ protected val partestCmd = " test/partest"
33+
34+ private [this ] var totalTests = 0
35+ private [this ] val passedTests = mutable.ListBuffer [TestState ]()
36+ private [this ] val failedTests = mutable.ListBuffer [TestState ]()
37+
38+ private [this ] var summarizing = false
39+ private [this ] var elapsedMillis = 0L
40+ private [this ] var expectedFailures = 0
2641
27- private var totalTests = 0
28- private val passedTests = mutable.ListBuffer [TestState ]()
29- private val failedTests = mutable.ListBuffer [TestState ]()
42+ import nestUI ._
43+ import nestUI .color ._
3044
31- def comment (s : String ) = echo(magenta(" # " + s))
32- def levyJudgment () = {
45+ private [this ] def comment (s : String ) = echo(magenta(" # " + s))
46+
47+ private [this ] def levyJudgment () = {
3348 if (totalTests == 0 ) echoMixed(" No tests to run." )
3449 else if (elapsedMillis == 0 ) echoMixed(" Test Run ABORTED" )
3550 else if (isSuccess) echoPassed(" Test Run PASSED" )
3651 else echoFailed(" Test Run FAILED" )
3752 }
3853
39- def passFailString (passed : Int , failed : Int , skipped : Int ): String = {
54+ private [ this ] def passFailString (passed : Int , failed : Int , skipped : Int ): String = {
4055 val total = passed + failed + skipped
4156 val isSuccess = failed == 0
4257 def p0 = s " $passed/ $total"
@@ -47,12 +62,7 @@ abstract class AbstractRunner(argstr: String) extends {
4762 oempty(p, f, s) mkString " , "
4863 }
4964
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
65+ private [this ] def isSuccess = failedTests.size == expectedFailures
5666
5767 def issueSummaryReport () {
5868 // Don't run twice
@@ -69,7 +79,7 @@ abstract class AbstractRunner(argstr: String) extends {
6979 val message = passFail + elapsed
7080
7181 if (failed0.nonEmpty) {
72- if (isPartestVerbose ) {
82+ if (nestUI.verbose ) {
7383 echo(bold(cyan(" ##### Transcripts from failed tests #####\n " )))
7484 failed0 foreach { state =>
7585 comment(partestCmd + " " + state.testFile)
@@ -89,97 +99,93 @@ abstract class AbstractRunner(argstr: String) extends {
8999 }
90100 }
91101
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- if (optShowLog) NestUI .setLogOnFail()
98-
99- // Early return on no args, version, or invalid args
100- if (optVersion) return echo(versionMsg)
101- if (optHelp) return NestUI .usage()
102-
103- val (individualTests, invalid) = parsed.residualArgs map (p => Path (p)) partition denotesTestPath
104- if (invalid.nonEmpty) {
105- if (isPartestVerbose)
106- invalid foreach (p => echoWarning(s " Discarding invalid test path " + p))
107- else if (! isPartestTerse)
108- echoWarning(s " Discarding ${invalid.size} invalid test paths " )
109- }
102+ /** Run the tests and return the success status */
103+ def run (): Boolean = {
104+ if (config.optVersion) echo(versionMsg)
105+ else if (config.optHelp) nestUI.usage()
106+ else {
107+ val (individualTests, invalid) = config.parsed.residualArgs map (p => Path (p)) partition denotesTestPath
108+ if (invalid.nonEmpty) {
109+ if (nestUI.verbose)
110+ invalid foreach (p => echoWarning(s " Discarding invalid test path " + p))
111+ else if (! nestUI.terse)
112+ echoWarning(s " Discarding ${invalid.size} invalid test paths " )
113+ }
110114
111- optTimeout foreach (x => setProp(" partest.timeout" , x))
115+ config. optTimeout foreach (x => setProp(" partest.timeout" , x))
112116
113- if (! isPartestTerse )
114- NestUI echo banner
117+ if (! nestUI.terse )
118+ nestUI.echo(suiteRunner. banner)
115119
116- val partestTests = (
117- if (optSelfTest) TestKinds .testsForPartest
118- else Nil
119- )
120+ val partestTests = (
121+ if (config. optSelfTest) TestKinds .testsForPartest
122+ else Nil
123+ )
120124
121- val grepExpr = optGrep getOrElse " "
125+ val grepExpr = config. optGrep getOrElse " "
122126
123- // If --grep is given we suck in every file it matches.
124- // TODO: intersect results of grep with specified kinds, if any
125- val greppedTests = if (grepExpr == " " ) Nil else {
126- val paths = grepFor(grepExpr)
127- if (paths.isEmpty)
128- echoWarning(s " grep string ' $grepExpr' matched no tests. \n " )
127+ // If --grep is given we suck in every file it matches.
128+ // TODO: intersect results of grep with specified kinds, if any
129+ val greppedTests = if (grepExpr == " " ) Nil else {
130+ val paths = grepFor(grepExpr)
131+ if (paths.isEmpty)
132+ echoWarning(s " grep string ' $grepExpr' matched no tests. \n " )
129133
130- paths.sortBy(_.toString)
131- }
134+ paths.sortBy(_.toString)
135+ }
132136
133- val isRerun = optFailed
134- val rerunTests = if (isRerun) TestKinds .failedTests else Nil
135- def miscTests = partestTests ++ individualTests ++ greppedTests ++ rerunTests
136-
137- val givenKinds = standardKinds filter parsed.isSet
138- val kinds = (
139- if (givenKinds.nonEmpty) givenKinds
140- else if (miscTests.isEmpty) standardKinds // If no kinds, --grep, or individual tests were given, assume --all
141- else Nil
142- )
143- val kindsTests = kinds flatMap testsFor
144-
145- def testContributors = {
146- List (
147- if (partestTests.isEmpty) " " else " partest self-tests" ,
148- if (rerunTests.isEmpty) " " else " previously failed tests" ,
149- if (kindsTests.isEmpty) " " else s " ${kinds.size} named test categories " ,
150- if (greppedTests.isEmpty) " " else s " ${greppedTests.size} tests matching ' $grepExpr' " ,
151- if (individualTests.isEmpty) " " else " specified tests"
152- ) filterNot (_ == " " ) mkString " , "
153- }
137+ val isRerun = config. optFailed
138+ val rerunTests = if (isRerun) TestKinds .failedTests else Nil
139+ def miscTests = partestTests ++ individualTests ++ greppedTests ++ rerunTests
140+
141+ val givenKinds = standardKinds filter config. parsed.isSet
142+ val kinds = (
143+ if (givenKinds.nonEmpty) givenKinds
144+ else if (miscTests.isEmpty) standardKinds // If no kinds, --grep, or individual tests were given, assume --all
145+ else Nil
146+ )
147+ val kindsTests = kinds flatMap testsFor
148+
149+ def testContributors = {
150+ List (
151+ if (partestTests.isEmpty) " " else " partest self-tests" ,
152+ if (rerunTests.isEmpty) " " else " previously failed tests" ,
153+ if (kindsTests.isEmpty) " " else s " ${kinds.size} named test categories " ,
154+ if (greppedTests.isEmpty) " " else s " ${greppedTests.size} tests matching ' $grepExpr' " ,
155+ if (individualTests.isEmpty) " " else " specified tests"
156+ ) filterNot (_ == " " ) mkString " , "
157+ }
154158
155- val allTests : Array [Path ] = distinctBy(miscTests ++ kindsTests)(_.toCanonical) sortBy (_.toString) toArray
156- val grouped = (allTests groupBy kindOf).toArray sortBy (x => standardKinds indexOf x._1)
159+ val allTests : Array [Path ] = distinctBy(miscTests ++ kindsTests)(_.toCanonical) sortBy (_.toString) toArray
160+ val grouped = (allTests groupBy kindOf).toArray sortBy (x => standardKinds indexOf x._1)
157161
158- totalTests = allTests.size
159- expectedFailures = propOrNone(" partest.errors" ) match {
160- case Some (num) => num.toInt
161- case _ => 0
162- }
163- val expectedFailureMessage = if (expectedFailures == 0 ) " " else s " (expecting $expectedFailures to fail) "
164- echo(s " Selected $totalTests tests drawn from $testContributors$expectedFailureMessage\n " )
165-
166- val (_, millis) = timed {
167- for ((kind, paths) <- grouped) {
168- val num = paths.size
169- val ss = if (num == 1 ) " " else " s"
170- comment(s " starting $num test $ss in $kind" )
171- val results = runTestsForFiles(paths map (_.jfile.getAbsoluteFile), kind)
172- val (passed, failed) = results partition (_.isOk)
173-
174- passedTests ++= passed
175- failedTests ++= failed
176- if (failed.nonEmpty) {
177- comment(passFailString(passed.size, failed.size, 0 ) + " in " + kind)
162+ totalTests = allTests.size
163+ expectedFailures = propOrNone(" partest.errors" ) match {
164+ case Some (num) => num.toInt
165+ case _ => 0
166+ }
167+ val expectedFailureMessage = if (expectedFailures == 0 ) " " else s " (expecting $expectedFailures to fail) "
168+ echo(s " Selected $totalTests tests drawn from $testContributors$expectedFailureMessage\n " )
169+
170+ val (_, millis) = timed {
171+ for ((kind, paths) <- grouped) {
172+ val num = paths.size
173+ val ss = if (num == 1 ) " " else " s"
174+ comment(s " starting $num test $ss in $kind" )
175+ val results = suiteRunner.runTestsForFiles(paths map (_.jfile.getAbsoluteFile), kind)
176+ val (passed, failed) = results partition (_.isOk)
177+
178+ passedTests ++= passed
179+ failedTests ++= failed
180+ if (failed.nonEmpty) {
181+ comment(passFailString(passed.size, failed.size, 0 ) + " in " + kind)
182+ }
183+ echo(" " )
178184 }
179- echo(" " )
180185 }
186+ this .elapsedMillis = millis
187+ issueSummaryReport()
181188 }
182- this .elapsedMillis = millis
183- issueSummaryReport()
189+ isSuccess
184190 }
185191}
0 commit comments