Skip to content
This repository was archived by the owner on Dec 3, 2020. It is now read-only.

Commit 0cef252

Browse files
authored
Merge pull request #21 from DReigada/allow-specifying-parser
Allow the coverage parser to be specified
2 parents 960e448 + fca37e3 commit 0cef252

File tree

5 files changed

+101
-22
lines changed

5 files changed

+101
-22
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package com.codacy.parsers
22

3+
import java.io.File
4+
35
import com.codacy.api.{CoverageReport, Language}
46
import com.codacy.parsers.implementation.{CoberturaParser, JacocoParser}
57
import com.codacy.parsers.util.XML
6-
import java.io.File
8+
79
import scala.util.Try
810
import scala.xml.Elem
911

@@ -25,9 +27,17 @@ trait XMLCoverageParser extends CoverageParser {
2527

2628
}
2729

30+
trait CoverageParserFactory {
31+
def apply(language: Language.Value, rootProject: File, reportFile: File): CoverageParser
32+
}
33+
2834
object CoverageParserFactory {
2935

30-
def withCoverageReport[A](language: Language.Value, rootProject: File, reportFile: File)(block: CoverageReport => A): Either[String, A] = {
36+
def withCoverageReport[A](language: Language.Value,
37+
rootProject: File,
38+
reportFile: File,
39+
parserFactory: Option[CoverageParserFactory] = None
40+
)(block: CoverageReport => A): Either[String, A] = {
3141
val isEmptyReport = {
3242
// just starting by detecting the simplest case: a single report file
3343
Try(reportFile.isFile && reportFile.length() == 0).getOrElse(false)
@@ -36,27 +46,27 @@ object CoverageParserFactory {
3646
if (isEmptyReport) {
3747
Left(s"report file is empty: ${reportFile.getAbsolutePath}")
3848
} else {
39-
create(language, rootProject, reportFile).map {
40-
parser =>
41-
val report = parser.generateReport()
42-
Right(block(report))
43-
}.getOrElse {
44-
Left(s"no parser for $language")
49+
parserFactory.fold[Either[String, A]] {
50+
val parsers = allParsers(language, rootProject, reportFile)
51+
withReport(parsers)(s"could not parse report, unrecognized report format")(block)
52+
} { parserFactory =>
53+
val parser = parserFactory(language, rootProject, reportFile)
54+
withReport(Seq(parser))("could not parse report with the provided parser")(block)
4555
}
4656
}
4757
}
4858

49-
private def create(language: Language.Value, rootProject: File, reportFile: File): Option[CoverageParser] = {
50-
val implementations =
51-
Seq(
52-
new CoberturaParser(language, rootProject, reportFile),
53-
new JacocoParser(language, rootProject, reportFile)
54-
)
59+
private def allParsers(language: Language.Value, rootProject: File, reportFile: File): Seq[CoverageParser] = {
60+
Seq(
61+
new CoberturaParser(language, rootProject, reportFile),
62+
new JacocoParser(language, rootProject, reportFile)
63+
)
64+
}
5565

56-
implementations.collectFirst {
57-
case implementation if implementation.isValidReport =>
58-
implementation
59-
}
66+
private def withReport[A](parsers: Seq[CoverageParser])(errorMessage: String)(block: CoverageReport => A): Either[String, A] = {
67+
parsers
68+
.find(_.isValidReport)
69+
.fold[Either[String, A]](Left(errorMessage))(parser => Right(block(parser.generateReport())))
6070
}
6171

6272
}

src/main/scala/com/codacy/parsers/implementation/CoberturaParser.scala

+6-1
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,17 @@ import java.text.NumberFormat
55
import java.util.Locale
66

77
import com.codacy.api.{CoverageFileReport, CoverageReport, Language}
8-
import com.codacy.parsers.XMLCoverageParser
98
import com.codacy.parsers.util.LanguageUtils
9+
import com.codacy.parsers.{CoverageParser, CoverageParserFactory, XMLCoverageParser}
1010

1111
import scala.util.Try
1212
import scala.xml.Node
1313

14+
object CoberturaParser extends CoverageParserFactory {
15+
override def apply(language: Language.Value, rootProject: File, reportFile: File): CoverageParser =
16+
new CoberturaParser(language, rootProject, reportFile)
17+
}
18+
1419
class CoberturaParser(val language: Language.Value, val rootProject: File, val coverageReport: File) extends XMLCoverageParser {
1520

1621
val rootProjectDir = sanitiseFilename(rootProject.getAbsolutePath + File.separator)

src/main/scala/com/codacy/parsers/implementation/JacocoParser.scala

+8-3
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,17 @@ package com.codacy.parsers.implementation
33
import java.io.File
44

55
import com.codacy.api._
6-
import com.codacy.parsers.XMLCoverageParser
6+
import com.codacy.parsers.{CoverageParser, CoverageParserFactory, XMLCoverageParser}
77

88
import scala.xml.Node
99

1010
private case class LineCoverage(missedInstructions: Int, coveredInstructions: Int)
1111

12+
object JacocoParser extends CoverageParserFactory {
13+
override def apply(language: Language.Value, rootProject: File, reportFile: File): CoverageParser =
14+
new JacocoParser(language, rootProject, reportFile)
15+
}
16+
1217
class JacocoParser(val language: Language.Value, val rootProject: File, val coverageReport: File) extends XMLCoverageParser {
1318

1419
val rootProjectDir = rootProject.getAbsolutePath + File.separator
@@ -52,9 +57,9 @@ class JacocoParser(val language: Language.Value, val rootProject: File, val cove
5257
line =>
5358
(line \ "@nr").text.toInt -> LineCoverage((line \ "@mi").text.toInt, (line \ "@ci").text.toInt)
5459
}.toMap.collect {
55-
case (key, lineCoverage) if lineCoverage.missedInstructions+ lineCoverage.coveredInstructions > 0 =>
60+
case (key, lineCoverage) if lineCoverage.missedInstructions + lineCoverage.coveredInstructions > 0 =>
5661

57-
key -> (if(lineCoverage.coveredInstructions > 0) 1 else 0)
62+
key -> (if (lineCoverage.coveredInstructions > 0) 1 else 0)
5863
}
5964

6065
CoverageFileReport(sourceFilename.stripPrefix(rootProjectDir), fileHit, lineHitMap)

src/test/resources/invalid_report.xml

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<coverageReport>
2+
<files>
3+
<file name="test.scala">
4+
<lines>
5+
<line id="2">3</line>
6+
</lines>
7+
</file>
8+
</files>
9+
</coverageReport>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.codacy.parsers
2+
3+
import java.io.File
4+
5+
import com.codacy.api.{CoverageFileReport, CoverageReport, Language}
6+
import com.codacy.parsers.implementation.{CoberturaParser, JacocoParser}
7+
import org.scalatest.{BeforeAndAfterAll, Matchers, WordSpec}
8+
9+
class CoverageParserFactoryTest extends WordSpec with BeforeAndAfterAll with Matchers {
10+
"CoverageParserFactory" should {
11+
"get report with unspecified parser" in {
12+
val expectedReport = CoverageReport(87, List(
13+
CoverageFileReport("src/test/resources/TestSourceFile.scala", 87,
14+
Map(5 -> 1, 10 -> 1, 6 -> 2, 9 -> 1, 3 -> 0, 4 -> 1)),
15+
CoverageFileReport("src/test/resources/TestSourceFile2.scala", 87,
16+
Map(1 -> 1, 2 -> 1, 3 -> 1))))
17+
18+
runForFile("src/test/resources/test_cobertura.xml", None) shouldEqual Right(expectedReport)
19+
}
20+
21+
"get report with jacoco parser" in {
22+
val expectedReport = CoverageReport(73, List(
23+
CoverageFileReport("org/eluder/coverage/sample/InnerClassCoverage.java", 81,
24+
Map(10 -> 1, 6 -> 1, 9 -> 1, 13 -> 1, 22 -> 1, 27 -> 0, 12 -> 1, 3 -> 1, 16 -> 1, 26 -> 0, 19 -> 1)),
25+
CoverageFileReport("org/eluder/coverage/sample/SimpleCoverage.java", 50,
26+
Map(3 -> 1, 6 -> 1, 10 -> 0, 11 -> 0))))
27+
28+
runForFile("src/test/resources/test_jacoco.xml", Some(JacocoParser)) shouldEqual Right(expectedReport)
29+
}
30+
31+
"fail to get invalid report" in {
32+
runForFile("invalid_report.xml", None) shouldEqual
33+
Left("could not parse report, unrecognized report format")
34+
}
35+
36+
"fail to get report with wrong parser" in {
37+
runForFile("src/test/resources/test_jacoco.xml", Some(CoberturaParser)) shouldEqual
38+
Left("could not parse report with the provided parser")
39+
}
40+
}
41+
42+
private def runForFile(file: String, parser: Option[CoverageParserFactory]) = {
43+
CoverageParserFactory.withCoverageReport(
44+
Language.Scala,
45+
new File("."),
46+
new File(file),
47+
parser
48+
)(identity)
49+
}
50+
}

0 commit comments

Comments
 (0)