package starter.templates import org.assertj.core.api.Assertions.assertThat import org.intellij.lang.annotations.Language import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance import org.koin.dsl.koinApplication import org.w3c.dom.Node import org.w3c.dom.NodeList import starter.Project import starter.config.StarterConfig import starter.modules.configModule import starter.modules.pebbleModule import starter.modules.templateModule import javax.xml.parsers.DocumentBuilderFactory import javax.xml.xpath.XPathConstants import javax.xml.xpath.XPathFactory @TestInstance(TestInstance.Lifecycle.PER_CLASS) internal class PomTemplateTest { private val koin = koinApplication { modules(configModule, pebbleModule, templateModule) }.koin private val pomTemplate = koin.get() private val conf = koin.get() private val project = Project( name = "Test", basePackage = "org.test", inputs = conf.inputs, features = emptyList(), dependencies = conf.dependencies, repositories = conf.dependencies.mapNotNull { it.repository }.toSet() ) private val docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder() private val xPath = XPathFactory.newInstance().newXPath() // region xml utils private fun String.extract(expression: String): String { val doc = docBuilder.parse(this.byteInputStream()) xPath.compile(expression).evaluate(doc, XPathConstants.NODESET) return xPath.compile(expression).evaluate(doc) } private fun String.extractAll(expression: String, mapper: (Node) -> T): List { val doc = docBuilder.parse(this.byteInputStream()) val res = xPath.compile(expression).evaluate(doc, XPathConstants.NODESET) as NodeList return res.asList().map(mapper) } private fun NodeList.asList(): List = (0 until length).map { item(it) } // endregion @Test fun javaVersion() { val xml = pomTemplate.render(project) assertThat(xml.extract("/project/properties/java.version")) .isEqualTo(project.inputs.find { it.name == "javaVersion" }?.value) println(xml) } @Test fun dependencies() { val xml = pomTemplate.render(project) val deps = xml.extractAll("/project/dependencies/dependency") { val map = it.childNodes.asList() .filter { it.nodeType == Node.ELEMENT_NODE } .associate { it.nodeName to it.firstChild.nodeValue } Triple(map["groupId"]!!, map["artifactId"]!!, map["version"] ?: "") }.filterNot { it.second == "kotlin-stdlib-jdk8" } println(deps.joinToString("\n")) val expectedDependencies = project.dependencies .map { Triple(it.groupId, it.artifactId, "\${" + it.version.name + ".version}") } assertThat(expectedDependencies).containsExactlyInAnyOrderElementsOf(deps) } @Test fun versions() { val xml = pomTemplate.render(project) val versions = xml.extractAll("/project/properties") { it.childNodes.asList() .filter { it.nodeType == Node.ELEMENT_NODE } .filter { it.nodeName.endsWith(".version") } .filterNot { it.nodeName in listOf("java.version", "kotlin.version") } .associate { it.nodeName.substringBefore(".version") to it.firstChild.nodeValue } }.first() val expected = project.dependencies.associate { it.version.name to it.version.value } assertThat(versions).containsExactlyInAnyOrderEntriesOf(expected) println(versions) } @Test fun kotlinxSerialization() { val xml = pomTemplate.render(project) @Language("XPath") val kotlinMavenPlugin = "/project/build/plugins/plugin[artifactId='kotlin-maven-plugin']" val kotlinxPlugin = "$kotlinMavenPlugin/configuration/compilerPlugins/plugin" assertThat(xml.extract(kotlinxPlugin)) .isEqualTo("kotlinx-serialization") val kotlinxPluginDep = "$kotlinMavenPlugin/dependencies/dependency/artifactId" assertThat(xml.extract(kotlinxPluginDep)) .isEqualTo("kotlin-maven-serialization") } }