Skip to content

Commit

Permalink
Merge pull request #12 from Banno/xml-dsl
Browse files Browse the repository at this point in the history
Custom xml dsl to avoid issues with xmlpull
  • Loading branch information
joshschriever authored Nov 15, 2019
2 parents c067627 + f7902ff commit 99fecb9
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 35 deletions.
5 changes: 2 additions & 3 deletions gordon-plugin/src/main/kotlin/com/banno/gordon/TestResults.kt
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ internal fun Map<PoolName, Map<TestCase, TestResult>>.summary(): String {
internal fun Map<PoolName, Map<TestCase, TestResult>>.junitReports() =
flatMap { (poolName, results) ->
results.map { (testCase, result) ->
val fileContent = xmlDocument {
element("testsuite") {
val fileContent =
xmlDocument("testsuite") {
attribute("name", poolName)
attribute("tests", "1")
attribute("skipped", if (result == TestResult.Ignored) "1" else "0")
Expand All @@ -87,7 +87,6 @@ internal fun Map<PoolName, Map<TestCase, TestResult>>.junitReports() =
}
}
}
}

ReportFile(
"$poolName-${testCase.fullyQualifiedClassName}.${testCase.methodName}.xml",
Expand Down
88 changes: 56 additions & 32 deletions gordon-plugin/src/main/kotlin/com/banno/gordon/Xml.kt
Original file line number Diff line number Diff line change
@@ -1,42 +1,66 @@
package com.banno.gordon

import org.xmlpull.v1.XmlPullParserFactory
import org.xmlpull.v1.XmlSerializer
import java.io.StringWriter

internal fun xmlDocument(block: XmlSerializer.() -> Unit) = StringWriter().also {
XmlPullParserFactory.newInstance(System.getProperty(XmlPullParserFactory.PROPERTY_NAME), null).newSerializer().run {
setOutput(it)
indentOutput()
startDocument("UTF-8", null)
block()
endDocument()
internal class XmlElement(
private val name: String,
private val indentation: Int = 0,
private val text: String? = null,
private val attributes: MutableMap<String, String> = mutableMapOf(),
private val children: MutableList<XmlElement> = mutableListOf()
) {

fun attribute(name: String, value: String) {
attributes[name] = value
}

fun element(name: String, block: XmlElement.() -> Unit = {}) {
children.add(XmlElement(name, indentation + 1).apply(block))
}

fun element(name: String, text: String, block: XmlElement.() -> Unit = {}) {
children.add(XmlElement(name, indentation + 1, text).apply(block))
}
}.toString()

private fun XmlSerializer.indentOutput() {
try {
setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true)
} catch (ignored: Throwable) {
try {
setProperty("http://xmlpull.org/v1/doc/properties.html#serializer-indentation", " ")
setProperty("http://xmlpull.org/v1/doc/properties.html#serializer-line-separator", "\n")
} catch (ignored: Throwable) {

override fun toString(): String = StringBuilder().run {
append(TAB.repeat(indentation))
append("<$name")
attributes.forEach { append(" ${it.key}=\"${it.value.escape()}\"") }
if (text == null && children.isEmpty()) {
append("/>")
} else {
if (text != null) {
append(">")
append(text.escape())
} else {
appendln(">")
children.forEach { appendln(it.toString()) }
append(TAB.repeat(indentation))
}
append("</$name>")
}
toString()
}
}

internal fun XmlSerializer.attribute(name: String, value: String) {
attribute("", name, value)
}
companion object {
private const val TAB = " "

internal fun XmlSerializer.element(name: String, block: XmlSerializer.() -> Unit = {}) {
startTag("", name)
block()
endTag("", name)
private fun String.escape() = this
.replace("<", "&lt;")
.replace(">", "&gt;")
.replace("&", "&amp;")
.replace("'", "&apos;")
.replace("\"", "&quot;")
}
}

internal fun XmlSerializer.element(name: String, text: String, block: XmlSerializer.() -> Unit = {}) = element(name) {
block()
text(text)
internal fun xmlDocument(
rootElementName: String,
rootElementText: String?,
block: XmlElement.() -> Unit = {}
): String = StringBuilder().run {
appendln("<?xml version='1.0' encoding='UTF-8'?>")
appendln(XmlElement(name = rootElementName, text = rootElementText).apply(block).toString())
toString()
}

internal fun xmlDocument(rootElementName: String, block: XmlElement.() -> Unit = {}) =
xmlDocument(rootElementName, null, block)

0 comments on commit 99fecb9

Please sign in to comment.