Skip to content

Commit

Permalink
Handling Jest coverage reports from root directory with no package (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
craigatk committed Apr 5, 2024
1 parent 95e5540 commit e2804ea
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package projektor.parser.coverage

import projektor.parser.coverage.clover.CloverXmlReportParser
import projektor.parser.coverage.clover.model.CoverageFile
import projektor.parser.coverage.clover.model.CoveragePackage
import projektor.parser.coverage.clover.model.LineType
import projektor.parser.coverage.clover.model.Metrics
import projektor.parser.coverage.model.CoverageReport
Expand All @@ -12,21 +14,12 @@ class CloverCoverageReportParser : CoverageReportParser {
override fun parseReport(reportXml: String, baseDirectoryPath: String?): CoverageReport {
val parsedReport = CloverXmlReportParser().parseReport(reportXml)

val files = parsedReport.project.packages.flatMap { pkg ->
pkg.files.map { sourceFile ->
val directoryName = pkg.name.replace(".", "/")
val fileName = sourceFile.name
val filePath = if (baseDirectoryPath != null) "$baseDirectoryPath/$directoryName/$fileName" else "$directoryName/$fileName"

CoverageReportFile(
directoryName = directoryName,
fileName = fileName,
filePath = filePath,
missedLines = sourceFile.lines?.filter { it.lineCoverageType() == LineType.MISSED }?.map { it.number } ?: listOf(),
partialLines = listOf(), // Clover partial lines from Jest coverage reports is not accurate so don't show anything rather than inaccurate data
stats = createStats(sourceFile.metrics)
)
val files = if (parsedReport.project.packages != null) {
parsedReport.project.packages.flatMap { pkg ->
pkg.files.map { sourceFile -> createCoverageReportFile(sourceFile, pkg, baseDirectoryPath) }
}
} else {
parsedReport.project.files.map { sourceFile -> createCoverageReportFile(sourceFile, null, baseDirectoryPath) }
}

return CoverageReport(
Expand All @@ -49,5 +42,20 @@ class CloverCoverageReportParser : CoverageReportParser {
),
statementStat = CoverageReportStat(covered = 0, missed = 0)
)

private fun createCoverageReportFile(sourceFile: CoverageFile, pkg: CoveragePackage?, baseDirectoryPath: String?): CoverageReportFile {
val directoryName = pkg?.name?.replace(".", "/") ?: ""
val fileName = sourceFile.name
val filePath = if (baseDirectoryPath != null) "$baseDirectoryPath/$directoryName/$fileName" else "$directoryName/$fileName"

return CoverageReportFile(
directoryName = directoryName,
fileName = fileName,
filePath = filePath,
missedLines = sourceFile.lines?.filter { it.lineCoverageType() == LineType.MISSED }?.map { it.number } ?: listOf(),
partialLines = listOf(), // Clover partial lines from Jest coverage reports is not accurate so don't show anything rather than inaccurate data
stats = createStats(sourceFile.metrics)
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -138,4 +138,22 @@ class CoverageParserFileSpec : StringSpec({
get { partialLines }.hasSize(0)
}
}

"should parse Jest Clover report with no package" {
val reportXml = CloverXmlLoader().noPackage()

val coverageReport = CoverageParser.parseReport(reportXml, null)
assertNotNull(coverageReport)

val coverageReportFiles = coverageReport.files
assertNotNull(coverageReportFiles)
expectThat(coverageReportFiles).hasSize(1)

val actionFile = coverageReportFiles.find { it.fileName == "projektor-action.js" }
expectThat(actionFile).isNotNull().and {
get { directoryName }.isEqualTo("")
get { filePath }.isEqualTo("/projektor-action.js")
get { stats }.get { lineStat }.get { percentCovered }.isEqualTo(BigDecimal("100.00"))
}
}
})
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,9 @@ public class Project {
@JsonProperty("package")
@JacksonXmlElementWrapper(useWrapping = false)
public List<CoveragePackage> packages;

// Used if there are no packages
@JsonProperty("file")
@JacksonXmlElementWrapper(useWrapping = false)
public List<CoverageFile> files;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package projektor.parser.coverage.clover


import projektor.parser.coverage.clover.model.Coverage
import projektor.server.example.coverage.JacocoXmlLoader
import projektor.server.example.coverage.CloverXmlLoader
import spock.lang.Specification
Expand All @@ -12,7 +12,7 @@ class CloverXmlReportParserSpec extends Specification {
String reportXml = new CloverXmlLoader().uiClover()

when:
projektor.parser.coverage.clover.model.Coverage report = new CloverXmlReportParser().parseReport(reportXml)
Coverage report = new CloverXmlReportParser().parseReport(reportXml)

then:
report.project != null
Expand All @@ -29,14 +29,38 @@ class CloverXmlReportParserSpec extends Specification {
report.project.metrics.coveredConditionals == 158
}

def "should parse Jest coverage XML report without a package"() {
given:
String reportXml = new CloverXmlLoader().noPackage()

when:
Coverage report = new CloverXmlReportParser().parseReport(reportXml)

then:
report.project != null
report.project.metrics != null

report.project.packages == null

report.project.name == "All files"

// <metrics statements="44" coveredstatements="44" conditionals="24" coveredconditionals="24" methods="2" coveredmethods="2"/>

report.project.metrics.statements == 44
report.project.metrics.coveredStatements == 44

report.project.metrics.conditionals == 24
report.project.metrics.coveredConditionals == 24
}

@Unroll
def "should determine if report is Jest report #shouldBeJest"() {
expect:
CloverXmlReportParser.isCloverReport(reportXml) == shouldBeJest

where:
reportXml || shouldBeJest
new CloverXmlLoader().uiClover() || true
new CloverXmlLoader().uiClover() || true
new JacocoXmlLoader().jacocoXmlParser() || false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ class CloverXmlLoader : CoverageXmlLoader() {
fun uiClover2() = loadTextFromFile("ui-clover-2.xml")
fun uiCloverLarge() = loadTextFromFile("ui-clover-large.xml")
fun uiCloverManyMissedLines() = loadTextFromFile("ui-clover-many-missed-lines.xml")
fun noPackage() = loadTextFromFile("clover-no-package.xml")

fun coverageFilesTable() = loadTextFromFile("clover-append/CoverageFilesTable-clover.xml")
fun coverageGraph() = loadTextFromFile("clover-append/CoverageGraph-clover.xml")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<coverage generated="1712315323674" clover="3.2.0">
<project timestamp="1712315323674" name="All files">
<metrics statements="44" coveredstatements="44" conditionals="24" coveredconditionals="24" methods="2" coveredmethods="2" elements="70" coveredelements="70" complexity="0" loc="44" ncloc="44" packages="1" files="1" classes="1"/>
<file name="projektor-action.js" path="/home/runner/work/projektor-action/projektor-action/projektor-action.js">
<metrics statements="44" coveredstatements="44" conditionals="24" coveredconditionals="24" methods="2" coveredmethods="2"/>
<line num="1" count="2" type="stmt"/>
<line num="2" count="2" type="stmt"/>
<line num="4" count="2" type="stmt"/>
<line num="15" count="12" type="cond" truecount="2" falsecount="0"/>
<line num="16" count="12" type="cond" truecount="2" falsecount="0"/>
<line num="17" count="12" type="cond" truecount="2" falsecount="0"/>
<line num="18" count="12" type="cond" truecount="2" falsecount="0"/>
<line num="20" count="12" type="stmt"/>
<line num="22" count="12" type="cond" truecount="2" falsecount="0"/>
<line num="23" count="2" type="stmt"/>
<line num="26" count="12" type="cond" truecount="2" falsecount="0"/>
<line num="27" count="10" type="stmt"/>
<line num="30" count="12" type="cond" truecount="2" falsecount="0"/>
<line num="31" count="9" type="stmt"/>
<line num="34" count="12" type="cond" truecount="2" falsecount="0"/>
<line num="35" count="2" type="stmt"/>
<line num="38" count="12" type="cond" truecount="2" falsecount="0"/>
<line num="39" count="2" type="stmt"/>
<line num="42" count="12" type="cond" truecount="2" falsecount="0"/>
<line num="43" count="1" type="stmt"/>
<line num="46" count="12" type="cond" truecount="2" falsecount="0"/>
<line num="47" count="1" type="stmt"/>
<line num="50" count="12" type="stmt"/>
<line num="52" count="12" type="stmt"/>
<line num="54" count="7" type="stmt"/>
<line num="57" count="2" type="stmt"/>
<line num="58" count="8" type="stmt"/>
<line num="59" count="8" type="stmt"/>
<line num="61" count="7" type="cond" truecount="2" falsecount="0"/>
<line num="62" count="1" type="stmt"/>
<line num="63" count="1" type="stmt"/>
<line num="65" count="6" type="stmt"/>
<line num="66" count="6" type="stmt"/>
<line num="67" count="6" type="stmt"/>
<line num="68" count="6" type="stmt"/>
<line num="69" count="6" type="stmt"/>
<line num="70" count="6" type="stmt"/>
<line num="71" count="6" type="stmt"/>
<line num="73" count="6" type="stmt"/>
<line num="74" count="6" type="stmt"/>
<line num="76" count="6" type="stmt"/>
<line num="88" count="1" type="stmt"/>
<line num="91" count="6" type="stmt"/>
<line num="95" count="2" type="stmt"/>
</file>
</project>
</coverage>

0 comments on commit e2804ea

Please sign in to comment.