Skip to content

Commit 34b4e38

Browse files
Merge pull request #434 from codacy/io-142-remove-total-field
IO-142-Remove total field from coverage parser implementation
2 parents 8e0d45c + 1e3d923 commit 34b4e38

21 files changed

+124
-321
lines changed

build.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ lazy val coverageParser = project
8585
.in(file("coverage-parser"))
8686
.settings(
8787
libraryDependencies ++= Seq(
88-
"com.codacy" %% "codacy-api-scala" % "7.0.7",
88+
"com.codacy" %% "codacy-api-scala" % "7.0.8",
8989
"com.codacy" %% "codacy-plugins-api" % "5.2.0",
9090
"org.scala-lang.modules" %% "scala-xml" % "1.2.0",
9191
"org.scalatest" %% "scalatest" % "3.0.8" % Test

coverage-parser/src/main/scala/com/codacy/parsers/implementation/CloverParser.scala

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import java.io.File
44
import java.nio.file.Paths
55

66
import com.codacy.api.{CoverageFileReport, CoverageReport}
7-
import com.codacy.parsers.util.{MathUtils, TextUtils}
7+
import com.codacy.parsers.util.TextUtils
88
import com.codacy.parsers.{CoverageParser, XmlReportParser}
99

1010
import scala.xml.{Elem, Node, NodeSeq}
@@ -27,10 +27,6 @@ object CloverParser extends CoverageParser with XmlReportParser {
2727
override def getRootNode(xml: Elem): NodeSeq = xml \\ CoverageTag
2828

2929
private def parseReportNode(rootProject: File, report: NodeSeq): Either[String, CoverageReport] = {
30-
val metricsNode = report \ ProjectTag \ MetricsTag
31-
val totalCoverage = getCoveragePercentage(metricsNode).left
32-
.map(errorMessage => s"Could not retrieve total coverage from metrics tag in project: $errorMessage")
33-
3430
val rootPath = TextUtils.sanitiseFilename(rootProject.getAbsolutePath)
3531

3632
val coverageFiles = (report \\ "file").foldLeft[Either[String, Seq[CoverageFileReport]]](Right(List())) {
@@ -41,17 +37,7 @@ object CloverParser extends CoverageParser with XmlReportParser {
4137
case (Left(errorMessage), _) => Left(errorMessage)
4238
}
4339

44-
for {
45-
totalCoverage <- totalCoverage
46-
coverageFiles <- coverageFiles
47-
} yield CoverageReport(totalCoverage, coverageFiles)
48-
}
49-
50-
private def getCoveragePercentage(metrics: NodeSeq): Either[String, Int] = {
51-
for {
52-
totalStatements <- getFirstNonEmptyValueAsInt(metrics, "statements")
53-
coveredStatements <- getFirstNonEmptyValueAsInt(metrics, "coveredstatements")
54-
} yield MathUtils.computePercentage(coveredStatements, totalStatements)
40+
coverageFiles.map(CoverageReport(_))
5541
}
5642

5743
private def getCoverageFileReport(rootPath: String, fileNode: Node): Either[String, CoverageFileReport] = {
@@ -72,15 +58,9 @@ object CloverParser extends CoverageParser with XmlReportParser {
7258

7359
for {
7460
relativeFilePath <- relativeFilePath
75-
metricsNode = fileNode \ MetricsTag
76-
fileCoverage <- getCoveragePercentage(metricsNode).left
77-
.map(
78-
errorMessage =>
79-
s"Could not retrieve file coverage from metrics tag for file '$relativeFilePath': $errorMessage"
80-
)
8161
linesCoverage <- getLinesCoverage(fileNode).left
8262
.map(errorMessage => s"Could not retrieve lines coverage for file '$relativeFilePath': $errorMessage")
83-
} yield CoverageFileReport(relativeFilePath, fileCoverage, linesCoverage)
63+
} yield CoverageFileReport(relativeFilePath, linesCoverage)
8464
}
8565

8666
private def getLinesCoverage(fileNode: Node): Either[String, Map[Int, Int]] = {

coverage-parser/src/main/scala/com/codacy/parsers/implementation/CoberturaParser.scala

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,31 +31,23 @@ object CoberturaParser extends CoverageParser with XmlReportParser {
3131
private def parseReportNode(projectRoot: File, report: NodeSeq) = {
3232
val projectRootStr: String = TextUtils.sanitiseFilename(projectRoot.getAbsolutePath)
3333

34-
val total = math.round(TextUtils.asFloat(report \\ CoverageTag \@ LineRateAttribute) * 100)
35-
3634
val fileReports: List[CoverageFileReport] = (for {
3735
(filename, classes) <- (report \\ "class").groupBy(c => c \@ "filename")
3836
} yield {
3937
val cleanFilename = TextUtils.sanitiseFilename(filename).stripPrefix(projectRootStr).stripPrefix("/")
4038
lineCoverage(cleanFilename, classes)
4139
})(collection.breakOut)
4240

43-
CoverageReport(total, fileReports)
41+
CoverageReport(fileReports)
4442
}
4543

4644
private def lineCoverage(sourceFilename: String, classes: NodeSeq): CoverageFileReport = {
47-
val classHit = (classes \\ s"@$LineRateAttribute").map { total =>
48-
val totalValue = TextUtils.asFloat(total.text)
49-
math.round(totalValue * 100)
50-
}
51-
val fileHit = if (classHit.nonEmpty) { classHit.sum / classHit.length } else 0
52-
5345
val lineHitMap: Map[Int, Int] =
5446
(for {
5547
xClass <- classes
5648
line <- xClass \\ "line"
5749
} yield (line \@ "number").toInt -> (line \@ "hits").toIntOrMaxValue).toMap
5850

59-
CoverageFileReport(sourceFilename, fileHit, lineHitMap)
51+
CoverageFileReport(sourceFilename, lineHitMap)
6052
}
6153
}

coverage-parser/src/main/scala/com/codacy/parsers/implementation/DotcoverParser.scala

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,11 @@ package com.codacy.parsers.implementation
33
import java.io.File
44

55
import com.codacy.api.{CoverageFileReport, CoverageReport}
6-
import com.codacy.parsers.util.{MathUtils, TextUtils}
6+
import com.codacy.parsers.util.TextUtils
77
import com.codacy.parsers.{CoverageParser, XmlReportParser}
88

99
import scala.xml.{Elem, NodeSeq}
1010

11-
case class StatementNode(fileIndex: Int, line: Int, covered: Boolean)
12-
1311
object DotcoverParser extends CoverageParser with XmlReportParser {
1412
override val name: String = "DotCover"
1513

@@ -29,8 +27,6 @@ object DotcoverParser extends CoverageParser with XmlReportParser {
2927
private def parseReportNode(rootProject: File, rootNode: NodeSeq): CoverageReport = {
3028
val projectRootStr: String = TextUtils.sanitiseFilename(rootProject.getAbsolutePath)
3129

32-
val totalCoverage = (rootNode \@ CoverageAttribute).toInt
33-
3430
val fileIndices: Map[Int, String] = (rootNode \ "FileIndices" \ "File").map { x =>
3531
(x \@ "Index").toInt -> (x \@ "Name")
3632
}.toMap
@@ -41,12 +37,9 @@ object DotcoverParser extends CoverageParser with XmlReportParser {
4137
(fileIndex, statements) <- statementsPerFile
4238
filename = TextUtils.sanitiseFilename(fileIndices(fileIndex)).stripPrefix(projectRootStr).stripPrefix("/")
4339
lineCoverage = getLineCoverage(statements)
44-
totalLines = lineCoverage.keys.size
45-
coveredLines = lineCoverage.values.count(_ > 0)
46-
total = MathUtils.computePercentage(coveredLines, totalLines)
47-
} yield CoverageFileReport(filename, total, lineCoverage)
40+
} yield CoverageFileReport(filename, lineCoverage)
4841

49-
CoverageReport(totalCoverage, fileReports.toSeq)
42+
CoverageReport(fileReports.toSeq)
5043
}
5144

5245
private def getLineCoverage(statementNodes: NodeSeq) = {

coverage-parser/src/main/scala/com/codacy/parsers/implementation/GoParser.scala

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package com.codacy.parsers.implementation
33
import com.codacy.parsers.CoverageParser
44

55
import java.io.File
6-
import com.codacy.parsers.util.MathUtils
76

87
import com.codacy.api.{CoverageFileReport, CoverageReport}
98

@@ -63,31 +62,14 @@ object GoParser extends CoverageParser {
6362
acc ++ lineHits(coverageInfo)
6463
}
6564

66-
val totalForFile = calculateTotal(statementsCountForFile)
67-
6865
accum :+ CoverageFileReportWithStatementsCount(
6966
statementsCountForFile,
70-
CoverageFileReport(filename, totalForFile, coverage)
67+
CoverageFileReport(filename, coverage)
7168
)
7269
}
7370
})
7471

75-
val (covered, total) = coverageFileReports
76-
.foldLeft[(Int, Int)]((0, 0)) {
77-
case ((covered, total), coverageFileReportWithStatementsCount) =>
78-
(
79-
covered + coverageFileReportWithStatementsCount.statementsCount.coveredStatements,
80-
total + coverageFileReportWithStatementsCount.statementsCount.numberStatements
81-
)
82-
}
83-
84-
val totalCoverage = MathUtils.computePercentage(covered, total)
85-
86-
CoverageReport(totalCoverage, coverageFileReports.map(_.coverageFileReport))
87-
}
88-
89-
private def calculateTotal(coverageFileStatements: GoCoverageStatementsCount): Int = {
90-
MathUtils.computePercentage(coverageFileStatements.coveredStatements, coverageFileStatements.numberStatements)
72+
CoverageReport(coverageFileReports.map(_.coverageFileReport))
9173
}
9274

9375
private def lineHits(coverageInfo: GoCoverageInfo): Map[Int, Int] = {
Lines changed: 18 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,47 @@
11
package com.codacy.parsers.implementation
22

33
import java.io.File
4-
54
import com.codacy.api._
65
import com.codacy.parsers.util.TextUtils
76
import com.codacy.parsers.{CoverageParser, XmlReportParser}
87

98
import scala.xml.{Elem, Node, NodeSeq}
109

11-
private case class LineCoverage(missedInstructions: Int, coveredInstructions: Int)
12-
1310
object JacocoParser extends CoverageParser with XmlReportParser {
1411

1512
override val name: String = "Jacoco"
1613

1714
private val ReportTag = "report"
1815

1916
override def parse(projectRoot: File, reportFile: File): Either[String, CoverageReport] =
20-
parseReport(reportFile, s"Could not find top level <$ReportTag> tag") {
21-
parseReportNode(projectRoot, _)
17+
parseReport(reportFile, s"Could not find top level <$ReportTag> tag") { node =>
18+
Right(parseReportNode(projectRoot, node))
2219
}
2320

2421
override def validateSchema(xml: Elem): Boolean = getRootNode(xml).nonEmpty
2522

2623
override def getRootNode(xml: Elem): NodeSeq = xml \\ ReportTag
2724

28-
private def parseReportNode(projectRoot: File, report: NodeSeq): Either[String, CoverageReport] = {
25+
private def parseReportNode(projectRoot: File, report: NodeSeq): CoverageReport = {
2926
val projectRootStr: String = TextUtils.sanitiseFilename(projectRoot.getAbsolutePath)
30-
totalPercentage(report).map { total =>
31-
val filesCoverage = for {
32-
pkg <- report \\ "package"
33-
packageName = (pkg \@ "name")
34-
sourceFile <- pkg \\ "sourcefile"
35-
} yield {
36-
val filename =
37-
TextUtils
38-
.sanitiseFilename(s"$packageName/${(sourceFile \@ "name")}")
39-
.stripPrefix(projectRootStr)
40-
.stripPrefix("/")
41-
lineCoverage(filename, sourceFile)
42-
}
43-
44-
CoverageReport(total, filesCoverage)
27+
val filesCoverage = for {
28+
pkg <- report \\ "package"
29+
packageName = (pkg \@ "name")
30+
sourceFile <- pkg \\ "sourcefile"
31+
} yield {
32+
val filename =
33+
TextUtils
34+
.sanitiseFilename(s"$packageName/${(sourceFile \@ "name")}")
35+
.stripPrefix(projectRootStr)
36+
.stripPrefix("/")
37+
calculateCoverageFileReport(filename, sourceFile)
4538
}
39+
CoverageReport(filesCoverage)
4640
}
4741

48-
private def totalPercentage(report: NodeSeq): Either[String, Int] = {
49-
(report \\ ReportTag \ "counter")
50-
.collectFirst {
51-
case counter if (counter \@ "type") == "LINE" =>
52-
val covered = TextUtils.asFloat((counter \@ "covered"))
53-
val missed = TextUtils.asFloat((counter \@ "missed"))
54-
Right(((covered / (covered + missed)) * 100).toInt)
55-
}
56-
.getOrElse {
57-
Left("Could not retrieve total percentage of coverage.")
58-
}
59-
}
60-
61-
private def lineCoverage(filename: String, fileNode: Node): CoverageFileReport = {
62-
val lineHit = (fileNode \ "counter").collect {
63-
case counter if (counter \@ "type") == "LINE" =>
64-
val covered = TextUtils.asFloat((counter \@ "covered"))
65-
val missed = TextUtils.asFloat((counter \@ "missed"))
66-
(if ((covered + missed) > 0) (covered / (covered + missed)) * 100 else 0f).toInt
67-
}
42+
private def calculateCoverageFileReport(filename: String, fileNode: Node): CoverageFileReport = {
6843

69-
val fileHit = if (lineHit.sum != 0) { lineHit.sum / lineHit.length } else 0
44+
case class LineCoverage(missedInstructions: Int, coveredInstructions: Int)
7045

7146
val lineHitMap: Map[Int, Int] = (fileNode \\ "line")
7247
.map { line =>
@@ -77,6 +52,6 @@ object JacocoParser extends CoverageParser with XmlReportParser {
7752
key -> (if (lineCoverage.coveredInstructions > 0) 1 else 0)
7853
}(collection.breakOut)
7954

80-
CoverageFileReport(filename, fileHit, lineHitMap)
55+
CoverageFileReport(filename, lineHitMap)
8156
}
8257
}

coverage-parser/src/main/scala/com/codacy/parsers/implementation/LCOVParser.scala

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import com.codacy.parsers.util.MathUtils._
55
import com.codacy.api.{CoverageFileReport, CoverageReport}
66
import java.io.File
77

8-
import com.codacy.parsers.util.{MathUtils, XMLoader}
8+
import com.codacy.parsers.util.XMLoader
99

1010
import scala.io.Source
1111
import scala.util.{Failure, Success, Try}
@@ -36,7 +36,7 @@ object LCOVParser extends CoverageParser {
3636
(accum, next) =>
3737
accum.flatMap {
3838
case reports if next startsWith SF =>
39-
Right(CoverageFileReport(next stripPrefix SF, 0, Map()) +: reports)
39+
Right(CoverageFileReport(next stripPrefix SF, Map()) +: reports)
4040
case reports if next startsWith DA =>
4141
reports.headOption match {
4242
case Some(value) =>
@@ -56,25 +56,9 @@ object LCOVParser extends CoverageParser {
5656
)
5757
coverageFileReports.map { fileReports =>
5858
val totalFileReport = fileReports.map { report =>
59-
val coveredLines = report.coverage.count { case (_, hit) => hit > 0 }
60-
val totalLines = report.coverage.size
61-
val fileCoverage =
62-
MathUtils.computePercentage(coveredLines, totalLines)
63-
64-
CoverageFileReport(report.filename, fileCoverage, report.coverage)
59+
CoverageFileReport(report.filename, report.coverage)
6560
}
66-
67-
val (covered, total) = totalFileReport
68-
.map { f =>
69-
(f.coverage.count { case (_, hit) => hit > 0 }, f.coverage.size)
70-
}
71-
.foldLeft(0 -> 0) {
72-
case ((accumCovered, accumTotal), (nextCovered, nextTotal)) =>
73-
(accumCovered + nextCovered, accumTotal + nextTotal)
74-
}
75-
76-
val totalCoverage = MathUtils.computePercentage(covered, total)
77-
CoverageReport(totalCoverage, totalFileReport)
61+
CoverageReport(totalFileReport)
7862
}
7963
}
8064
}

coverage-parser/src/main/scala/com/codacy/parsers/implementation/OpenCoverParser.scala

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package com.codacy.parsers.implementation
33
import java.io.File
44

55
import com.codacy.api.{CoverageFileReport, CoverageReport}
6-
import com.codacy.parsers.util.{MathUtils, TextUtils}
6+
import com.codacy.parsers.util.TextUtils
77
import com.codacy.parsers.{CoverageParser, XmlReportParser}
88

99
import scala.xml.{Elem, NodeSeq}
@@ -43,35 +43,18 @@ object OpenCoverParser extends CoverageParser with XmlReportParser {
4343
filename <- fileIndices.get(fileIndex)
4444

4545
sanitisedFileName = TextUtils.sanitiseFilename(filename).stripPrefix(projectRoot).stripPrefix("/")
46-
lineCoverage = getLineCoverage(methods, sanitisedFileName)
47-
totalLines = lineCoverage.size
48-
coveredLines = lineCoverage.count { case (_, visitCount) => visitCount > 0 }
49-
coverage = MathUtils.computePercentage(coveredLines, totalLines)
50-
} yield CoverageFileReport(sanitisedFileName, coverage, lineCoverage)).toSeq
46+
lineCoverage = getLineCoverage(methods)
47+
} yield CoverageFileReport(sanitisedFileName, lineCoverage)).toSeq
5148

52-
val totalCoverage = computeTotalCoverage(fileReports)
53-
54-
CoverageReport(totalCoverage, fileReports)
49+
CoverageReport(fileReports)
5550
}
5651

57-
private def getLineCoverage(methodNodes: NodeSeq, filename: String) = {
52+
private def getLineCoverage(methodNodes: NodeSeq) = {
5853
val lineCoverage = for {
5954
methodNode <- methodNodes
6055
sequencePoint <- methodNode \\ SequencePointTag
6156
} yield (sequencePoint \@ LineAttribute).toInt -> (sequencePoint \@ VisitCounterAttribute).toInt
6257

6358
lineCoverage.toMap
6459
}
65-
66-
private def computeTotalCoverage(fileReports: Seq[CoverageFileReport]) = {
67-
val (totalLines, coveredLines) = fileReports
68-
.foldLeft((0, 0)) {
69-
case ((total, covered), f) =>
70-
val totalLines = f.coverage.size
71-
val coveredLines = (f.total * totalLines) / 100
72-
(total + totalLines, covered + coveredLines)
73-
}
74-
75-
MathUtils.computePercentage(coveredLines, totalLines)
76-
}
7760
}

0 commit comments

Comments
 (0)