Skip to content

Commit 138f652

Browse files
authored
Merge pull request #282 from vincentdehaan/feature/report-test-names
Reporting test names
2 parents 868f3d8 + dc99882 commit 138f652

File tree

6 files changed

+43
-19
lines changed

6 files changed

+43
-19
lines changed

scalac-scoverage-plugin/src/main/scala/scoverage/IOUtils.scala

+6-3
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,16 @@ object IOUtils {
7171
val isDebugReportFile = (file: File) => file.getName == Constants.XMLReportFilenameWithDebug
7272

7373
// loads all the invoked statement ids from the given files
74-
def invoked(files: Seq[File]): Set[Int] = {
75-
val acc = mutable.Set[Int]()
74+
def invoked(files: Seq[File]): Set[(Int, String)] = {
75+
val acc = mutable.Set[(Int, String)]()
7676
files.foreach { file =>
7777
val reader = Source.fromFile(file)
7878
for ( line <- reader.getLines() ) {
7979
if (!line.isEmpty) {
80-
acc += line.toInt
80+
acc += (line.split(" ").toList match {
81+
case List(idx, clazz) => (idx.toInt, clazz)
82+
case List(idx) => (idx.toInt, "")
83+
})
8184
}
8285
}
8386
reader.close()

scalac-scoverage-plugin/src/main/scala/scoverage/coverage.scala

+8-4
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ case class Coverage()
3838
// returns the classes by least coverage
3939
def risks(limit: Int) = classes.toSeq.sortBy(_.statementCount).reverse.sortBy(_.statementCoverage).take(limit)
4040

41-
def apply(ids: Iterable[Int]): Unit = ids foreach invoked
42-
def invoked(id: Int): Unit = statementsById.get(id).foreach(_.invoked())
41+
def apply(ids: Iterable[(Int, String)]): Unit = ids foreach invoked
42+
def invoked(id: (Int, String)): Unit = statementsById.get(id._1).foreach(_.invoked(id._2))
4343
}
4444

4545
trait MethodBuilders {
@@ -119,9 +119,13 @@ case class Statement(location: Location,
119119
treeName: String,
120120
branch: Boolean,
121121
var count: Int = 0,
122-
ignored: Boolean = false) extends java.io.Serializable {
122+
ignored: Boolean = false,
123+
tests: mutable.Set[String] = mutable.Set[String]()) extends java.io.Serializable {
123124
def source = location.sourcePath
124-
def invoked(): Unit = count = count + 1
125+
def invoked(test: String): Unit = {
126+
count = count + 1
127+
if(test != "") tests += test
128+
}
125129
def isInvoked = count > 0
126130
}
127131

scalac-scoverage-plugin/src/main/scala/scoverage/plugin.scala

+14-8
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ class ScoveragePlugin(val global: Global) extends Plugin {
3535
options.dataDir = opt.substring("dataDir:".length)
3636
} else if (opt.startsWith("extraAfterPhase:") || opt.startsWith("extraBeforePhase:")) {
3737
// skip here, these flags are processed elsewhere
38+
} else if (opt == "reportTestName") {
39+
options.reportTestName = true
3840
} else {
3941
error("Unknown option: " + opt)
4042
}
@@ -82,6 +84,7 @@ class ScoverageOptions {
8284
var excludedFiles: Seq[String] = Nil
8385
var excludedSymbols: Seq[String] = Seq("scala.reflect.api.Exprs.Expr", "scala.reflect.api.Trees.Tree", "scala.reflect.macros.Universe.Tree")
8486
var dataDir: String = IOUtils.getTempPath
87+
var reportTestName: Boolean = false
8588
}
8689

8790
class ScoverageInstrumentationComponent(val global: Global, extraAfterPhase: Option[String], extraBeforePhase: Option[String])
@@ -169,14 +172,17 @@ class ScoverageInstrumentationComponent(val global: Global, extraAfterPhase: Opt
169172
),
170173
newTermName("invoked")
171174
),
172-
List(
173-
Literal(
174-
Constant(id)
175-
),
176-
Literal(
177-
Constant(options.dataDir)
178-
)
179-
)
175+
Literal(
176+
Constant(id)
177+
) ::
178+
Literal(
179+
Constant(options.dataDir)
180+
) ::
181+
(if(options.reportTestName)
182+
List(Literal(
183+
Constant(true)
184+
))
185+
else Nil)
180186
)
181187
}
182188

scalac-scoverage-plugin/src/main/scala/scoverage/report/StatementWriter.scala

+4
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class StatementWriter(mFile: MeasuredFile) {
2424
<th>Pos</th>
2525
<th>Tree</th>
2626
<th>Symbol</th>
27+
<th>Tests</th>
2728
<th>Code</th>
2829
</tr>{mFile.statements.toSeq.sortBy(_.line).map(stmt => {
2930
<tr>
@@ -44,6 +45,9 @@ class StatementWriter(mFile: MeasuredFile) {
4445
<td>
4546
{stmt.symbolName}
4647
</td>
48+
<td>
49+
{stmt.tests.mkString(",")}
50+
</td>
4751
<td style={cellStyle(stmt.isInvoked)}>
4852
{stmt.desc}
4953
</td>

scalac-scoverage-plugin/src/test/scala/scoverage/IOUtilsTest.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class IOUtilsTest extends AnyFreeSpec with OneInstancePerTest with Matchers {
1717
writer.write("1\n5\n9\n\n10\n")
1818
writer.close()
1919
val invoked = IOUtils.invoked(Seq(file))
20-
assert(invoked === Set(1, 5, 9, 10))
20+
assert(invoked === Set((1, ""), (5, ""), (9, ""), (10, "")))
2121

2222
file.delete()
2323
}
@@ -38,7 +38,7 @@ class IOUtilsTest extends AnyFreeSpec with OneInstancePerTest with Matchers {
3838

3939
val files = IOUtils.findMeasurementFiles(file1.getParent)
4040
val invoked = IOUtils.invoked(files.toIndexedSeq)
41-
assert(invoked === Set(1, 2, 5, 7, 9, 10, 14))
41+
assert(invoked === Set((1, ""), (2, ""), (5, ""), (7, ""), (9, ""), (10, ""), (14, "")))
4242

4343
file1.delete()
4444
file2.delete()

scalac-scoverage-runtime/shared/src/main/scala/scoverage/Invoker.scala

+9-2
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ object Invoker {
3131
* @param id the id of the statement that was invoked
3232
* @param dataDir the directory where the measurement data is held
3333
*/
34-
def invoked(id: Int, dataDir: String): Unit = {
34+
def invoked(id: Int, dataDir: String, reportTestName: Boolean = false): Unit = {
3535
// [sam] we can do this simple check to save writing out to a file.
3636
// This won't work across JVMs but since there's no harm in writing out the same id multiple
3737
// times since for coverage we only care about 1 or more, (it just slows things down to
@@ -55,12 +55,19 @@ object Invoker {
5555
threadFiles.set(files)
5656
}
5757
val writer = files.getOrElseUpdate(dataDir, new FileWriter(measurementFile(dataDir), true))
58-
writer.append(Integer.toString(id)).append("\n").flush()
5958

59+
if(reportTestName) writer.append(Integer.toString(id)).append(" ").append(getCallingScalaTest).append("\n").flush()
60+
else writer.append(Integer.toString(id)).append("\n").flush()
6061
ids.put(id, ())
6162
}
6263
}
6364

65+
def getCallingScalaTest: String =
66+
Thread.currentThread.getStackTrace
67+
.map(_.getClassName.toLowerCase)
68+
.find(name => name.endsWith("suite") || name.endsWith("spec") || name.endsWith("test"))
69+
.getOrElse("")
70+
6471
def measurementFile(dataDir: File): File = measurementFile(dataDir.getAbsolutePath)
6572
def measurementFile(dataDir: String): File = new File(dataDir, MeasurementsPrefix + runtimeUUID + "." + Thread.currentThread.getId)
6673

0 commit comments

Comments
 (0)