Skip to content

Commit

Permalink
Add a default successful testcase when no lint issues are detected (#170
Browse files Browse the repository at this point in the history
)

Fixes #170
  • Loading branch information
arunkumar9t2 committed Apr 23, 2024
1 parent 80b321b commit 013103d
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 48 deletions.
2 changes: 2 additions & 0 deletions project_views/default.bazelproject
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ directories:
-bazel-cache
-bazel-testlogs
-bazel-genfiles
-.aswb
-.ijwb

# Automatically includes all relevant targets under the 'directories' above
derive_targets_from_directories: true
Expand Down
2 changes: 1 addition & 1 deletion rules/android/lint/lint_aspect.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ def _lint_common_args(
args.set_param_file_format("multiline")
args.use_param_file("--flagfile=%s", use_always = True)

args.add("--name", ctx.label.name)
args.add("--name", str(ctx.label).lstrip("@"))
if android:
args.add("--android")
if library:
Expand Down
106 changes: 62 additions & 44 deletions tools/lint/src/main/java/com/grab/lint/LintResults.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.grab.lint

import org.w3c.dom.Document
import org.w3c.dom.Element
import java.io.File
import java.io.FileWriter
Expand All @@ -9,7 +10,6 @@ import java.util.concurrent.TimeUnit
import javax.xml.parsers.DocumentBuilder
import javax.xml.parsers.DocumentBuilderFactory
import javax.xml.transform.OutputKeys
import javax.xml.transform.Transformer
import javax.xml.transform.TransformerFactory
import javax.xml.transform.dom.DOMSource
import javax.xml.transform.stream.StreamResult
Expand Down Expand Up @@ -57,62 +57,80 @@ class LintResults(

private fun buildJunitReport(documentBuilder: DocumentBuilder, errorIssues: List<Element>) {
val junitDoc = documentBuilder.newDocument()
val testSuites = junitDoc.createElement("testsuites").also {
it["name"] = name
it["tests"] = errorIssues.size.toString()
it["time"] = TimeUnit.MILLISECONDS.toSeconds(elapsed).toString()
}
junitDoc.appendChild(testSuites)

errorIssues.groupBy { it["id"] }.forEach { (id, issues) ->
val failures = issues.size.toString()
val testSuite = junitDoc.createElement("testsuite").also {
it["name"] = id
it["tests"] = failures
it["failures"] = failures
}
testSuites.appendChild(testSuite)
val rootTestSuites = junitDoc.createElement("testsuites").also(junitDoc::appendChild)

issues.forEach { issue ->
val message = issue["message"]
val summary = issue["summary"]
val location = issue.getElementsByTagName("location").elements().first()
val file = location["file"].replace("../", "")
val line = location["line"]
val explanation = listOf(
issue["explanation"],
"\nFile: $file:$line",
"Error line:",
issue["errorLine1"],
issue["errorLine2"]
).joinToString(separator = "\n")

val testCase = junitDoc.createElement("testcase").also {
it["name"] = message
it["classname"] = summary
it["file"] = file
it["line"] = line
}
val failure = junitDoc.createElement("failure").also {
it["message"] = explanation
when {
errorIssues.isEmpty() -> addSuccessfulTestCase(junitDoc, rootTestSuites)
else -> errorIssues.groupBy { it["id"] }.forEach { (id, issues) ->
val failures = issues.size.toString()
val testSuite = junitDoc.createElement("testsuite").also {
it["name"] = id
it["tests"] = failures
it["failures"] = failures
it["time"] = TimeUnit.MILLISECONDS.toSeconds(elapsed).toString()
}
testCase.appendChild(failure)
testSuite.appendChild(testCase)
rootTestSuites.appendChild(testSuite)
issues.forEach { issue -> mapIssueToTestCase(issue, junitDoc, testSuite) }
}
}

try {
FileWriter(outputJunitXml).use { fileWriter ->
val transformer: Transformer = TransformerFactory.newInstance().newTransformer()
transformer.setOutputProperty(OutputKeys.INDENT, "yes")
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2")
transformer.transform(DOMSource(junitDoc), StreamResult(fileWriter))
with(TransformerFactory.newInstance().newTransformer()) {
setOutputProperty(OutputKeys.INDENT, "yes")
setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2")
transform(DOMSource(junitDoc), StreamResult(fileWriter))
}
}
} catch (e: Exception) {
throw RuntimeException(e)
}
}

private fun addSuccessfulTestCase(junitDoc: Document, rootTestSuites: Element) {
val testSuite = junitDoc.createElement("testsuite").also {
it["name"] = name
it["tests"] = "1"
it["time"] = TimeUnit.MILLISECONDS.toSeconds(elapsed).toString()
it.appendChild(junitDoc.createElement("testcase").also { testcase ->
testcase["name"] = "Android lint on $name"
testcase["classname"] = name
})
}
rootTestSuites.appendChild(testSuite)
}

private fun mapIssueToTestCase(
issue: Element,
junitDoc: Document,
testSuite: Element
) {
val message = issue["message"]
val summary = issue["summary"]
val location = issue.getElementsByTagName("location").elements().first()
val file = location["file"].replace("../", "")
val line = location["line"]
val explanation = listOf(
issue["explanation"],
"\nFile: $file:$line",
"Error line:",
issue["errorLine1"],
issue["errorLine2"]
).joinToString(separator = "\n")

val testCase = junitDoc.createElement("testcase").also {
it["name"] = message
it["classname"] = summary
it["file"] = file
it["line"] = line
}
val failure = junitDoc.createElement("failure").also {
it["message"] = explanation
}
testCase.appendChild(failure)
testSuite.appendChild(testCase)
}

companion object {
/**
* Map of Android Lint Issue id to message text that is recognized as success.
Expand Down
3 changes: 0 additions & 3 deletions tools/lint/src/test/java/com/grab/lint/LintResultsTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,6 @@ class LintResultsTest {
DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(outputJunitXml).apply {
assertNode(
"testsuites",
"name" to "Test",
"tests" to "1",
"time" to "0"
)
assertNode(
"testsuite",
Expand Down

0 comments on commit 013103d

Please sign in to comment.