Skip to content

Commit

Permalink
Implemented aggregate reports
Browse files Browse the repository at this point in the history
Resolves #20, #43
  • Loading branch information
shanshin committed Dec 9, 2021
1 parent 1475b5d commit 96ead04
Show file tree
Hide file tree
Showing 40 changed files with 1,142 additions and 475 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,15 @@ import kotlin.test.*

internal class DefaultConfigTests : BaseGradleScriptTest() {
@Test
fun testImplicitConfigsJvm() {
builder()
.case("Test default setting for Kotlin/JVM")
fun testImplicitConfigs() {
builder("Test implicit default settings")
.languages(GradleScriptLanguage.GROOVY, GradleScriptLanguage.KOTLIN)
.types(ProjectType.KOTLIN_JVM)
.types(ProjectType.KOTLIN_JVM, ProjectType.KOTLIN_MULTIPLATFORM)
.sources("simple")
.build()
.run("build") {
checkIntellijBinaryReport(DEFAULT_INTELLIJ_KJVM_BINARY, DEFAULT_INTELLIJ_KJVM_SMAP)
checkReports(DEFAULT_XML, DEFAULT_HTML)
}
}

@Test
fun testImplicitConfigsKmp() {
builder()
.case("Test default setting for Kotlin Multi-Platform")
.languages(GradleScriptLanguage.GROOVY, GradleScriptLanguage.KOTLIN)
.types(ProjectType.KOTLIN_MULTIPLATFORM)
.sources("simple")
.build()
.run("build") {
checkIntellijBinaryReport(DEFAULT_INTELLIJ_KMP_BINARY, DEFAULT_INTELLIJ_KMP_SMAP)
checkReports(DEFAULT_XML, DEFAULT_HTML)
checkDefaultBinaryReport()
checkDefaultReports()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ internal class InstrumentationFilteringTests : BaseGradleScriptTest() {

@Test
fun testExclude() {
builder()
.case("Test exclusion of classes from instrumentation")
builder("Test exclusion of classes from instrumentation")
.languages(GradleScriptLanguage.KOTLIN, GradleScriptLanguage.GROOVY)
.types(ProjectType.KOTLIN_JVM, ProjectType.KOTLIN_MULTIPLATFORM)
.engines(CoverageEngine.INTELLIJ, CoverageEngine.JACOCO)
Expand All @@ -22,17 +21,16 @@ internal class InstrumentationFilteringTests : BaseGradleScriptTest() {
)
.build()
.run("build") {
xml(DEFAULT_XML) {
xml(defaultXmlReport()) {
assertCounterExcluded(classCounter("org.jetbrains.ExampleClass"), this@run.engine)
assertCounterCoveredAndIncluded(classCounter("org.jetbrains.SecondClass"))
assertCounterCovered(classCounter("org.jetbrains.SecondClass"))
}
}
}

@Test
fun testExcludeInclude() {
builder()
.case("Test inclusion and exclusion of classes in instrumentation")
builder("Test inclusion and exclusion of classes in instrumentation")
.languages(GradleScriptLanguage.KOTLIN, GradleScriptLanguage.GROOVY)
.types(ProjectType.KOTLIN_JVM, ProjectType.KOTLIN_MULTIPLATFORM)
.engines(CoverageEngine.INTELLIJ, CoverageEngine.JACOCO)
Expand All @@ -47,10 +45,10 @@ internal class InstrumentationFilteringTests : BaseGradleScriptTest() {
)
.build()
.run("build") {
xml(DEFAULT_XML) {
xml(defaultXmlReport()) {
assertCounterExcluded(classCounter("org.jetbrains.ExampleClass"), this@run.engine)
assertCounterExcluded(classCounter("org.jetbrains.Unused"), this@run.engine)
assertCounterCoveredAndIncluded(classCounter("org.jetbrains.SecondClass"))
assertCounterCovered(classCounter("org.jetbrains.SecondClass"))
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package kotlinx.kover.test.functional.cases

import kotlinx.kover.api.*
import kotlinx.kover.test.functional.cases.utils.*
import kotlinx.kover.test.functional.cases.utils.defaultXmlReport
import kotlinx.kover.test.functional.core.BaseGradleScriptTest
import kotlinx.kover.test.functional.core.ProjectType
import kotlin.test.*

private const val SUBMODULE_NAME = "common"

internal class MultiModulesTest : BaseGradleScriptTest() {
@Test
fun testAggregateReports() {
builder("Testing the generation of aggregating reports")
.types(ProjectType.KOTLIN_JVM, ProjectType.KOTLIN_MULTIPLATFORM)
.engines(CoverageEngine.INTELLIJ, CoverageEngine.JACOCO)
.sources("multimodule-user")
.submodule(SUBMODULE_NAME) {
sources("multimodule-common")
}
.dependency(
"implementation(project(\":$SUBMODULE_NAME\"))",
"implementation project(':$SUBMODULE_NAME')"
)
.build()
.run("build") {
xml(defaultXmlReport()) {
assertCounterFullyCovered(classCounter("org.jetbrains.CommonClass"))
assertCounterFullyCovered(classCounter("org.jetbrains.CommonInternalClass"))
assertCounterFullyCovered(classCounter("org.jetbrains.UserClass"))
}
}
}

@Test
fun testModuleReports() {
builder("Testing the generation of module reports")
.types(ProjectType.KOTLIN_JVM, ProjectType.KOTLIN_MULTIPLATFORM)
.engines(CoverageEngine.INTELLIJ, CoverageEngine.JACOCO)
.sources("multimodule-user")
.submodule(SUBMODULE_NAME) {
sources("multimodule-common")
}
.dependency(
"implementation(project(\":$SUBMODULE_NAME\"))",
"implementation project(':$SUBMODULE_NAME')"
)
.build()
.run("koverModuleReport") {
xml(defaultXmlModuleReport()) {
assertCounterAbsent(classCounter("org.jetbrains.CommonClass"))
assertCounterAbsent(classCounter("org.jetbrains.CommonInternalClass"))
assertCounterFullyCovered(classCounter("org.jetbrains.UserClass"))
}

submodule(SUBMODULE_NAME) {
xml(defaultXmlModuleReport()) {
assertCounterFullyCovered(classCounter("org.jetbrains.CommonClass"))
assertCounterFullyCovered(classCounter("org.jetbrains.CommonInternalClass"))
assertCounterAbsent(classCounter("org.jetbrains.UserClass"))
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,51 +8,48 @@ import kotlin.test.*

internal class ReportsCachingTests : BaseGradleScriptTest() {
@Test
fun testCachingForIntellij() {
builder()
.case("Test caching reports for IntelliJ Coverage Engine")
.engines(CoverageEngine.INTELLIJ)
fun testCaching() {
builder("Test caching aggregate reports")
.engines(CoverageEngine.INTELLIJ, CoverageEngine.JACOCO)
.sources("simple")
.build()
.run("build", "--build-cache") {
checkIntellijBinaryReport(DEFAULT_INTELLIJ_KJVM_BINARY, DEFAULT_INTELLIJ_KJVM_SMAP)
checkReports(DEFAULT_XML, DEFAULT_HTML)
checkDefaultBinaryReport()
checkDefaultReports()
}
.run("clean", "--build-cache") {
checkIntellijBinaryReport(DEFAULT_INTELLIJ_KJVM_BINARY, DEFAULT_INTELLIJ_KJVM_SMAP, false)
checkReports(DEFAULT_XML, DEFAULT_HTML, false)
checkDefaultBinaryReport(false)
checkDefaultReports(false)
}
.run("build", "--build-cache") {
checkIntellijBinaryReport(DEFAULT_INTELLIJ_KJVM_BINARY, DEFAULT_INTELLIJ_KJVM_SMAP)
checkReports(DEFAULT_XML, DEFAULT_HTML)
outcome(":test") { assertEquals(TaskOutcome.FROM_CACHE, this)}
outcome(":koverXmlReport") { assertEquals(TaskOutcome.FROM_CACHE, this)}
outcome(":koverHtmlReport") { assertEquals(TaskOutcome.FROM_CACHE, this)}
checkDefaultBinaryReport()
checkDefaultReports()
outcome(":test") { assertEquals(TaskOutcome.FROM_CACHE, this) }
outcome(":koverXmlReport") { assertEquals(TaskOutcome.FROM_CACHE, this) }
outcome(":koverHtmlReport") { assertEquals(TaskOutcome.FROM_CACHE, this) }
}
}

@Test
fun testCachingForJacoco() {
builder()
.case("Test caching reports for JaCoCo Coverage Engine")
.engines(CoverageEngine.JACOCO)
fun testModuleCaching() {
builder("Test caching module reports")
.engines(CoverageEngine.INTELLIJ, CoverageEngine.JACOCO)
.sources("simple")
.build()
.run("build", "--build-cache") {
checkJacocoBinaryReport(DEFAULT_JACOCO_KJVM_BINARY)
checkReports(DEFAULT_XML, DEFAULT_HTML)
.run("koverModuleReport", "--build-cache") {
checkDefaultBinaryReport()
checkDefaultModuleReports()
}
.run("clean", "--build-cache") {
checkJacocoBinaryReport(DEFAULT_JACOCO_KJVM_BINARY, false)
checkReports(DEFAULT_XML, DEFAULT_HTML, false)
checkDefaultBinaryReport(false)
checkDefaultModuleReports(false)
}
.run("build", "--build-cache") {
checkJacocoBinaryReport(DEFAULT_JACOCO_KJVM_BINARY)
checkReports(DEFAULT_XML, DEFAULT_HTML)

outcome(":test") { assertEquals(TaskOutcome.FROM_CACHE, this)}
outcome(":koverXmlReport") { assertEquals(TaskOutcome.FROM_CACHE, this)}
outcome(":koverHtmlReport") { assertEquals(TaskOutcome.FROM_CACHE, this)}
.run("koverModuleReport", "--build-cache") {
checkDefaultBinaryReport()
checkDefaultModuleReports()
outcome(":test") { assertEquals(TaskOutcome.FROM_CACHE, this) }
outcome(":koverXmlModuleReport") { assertEquals(TaskOutcome.FROM_CACHE, this) }
outcome(":koverHtmlModuleReport") { assertEquals(TaskOutcome.FROM_CACHE, this) }
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,43 +5,48 @@ import kotlinx.kover.test.functional.core.*
import kotlinx.kover.test.functional.core.RunResult
import kotlin.test.*

internal fun RunResult.checkIntellijBinaryReport(binary: String, smap: String, mustExists: Boolean = true) {
internal fun RunResult.checkDefaultBinaryReport(mustExists: Boolean = true) {
val binary: String = defaultBinaryReport(engine, projectType)

if (mustExists) {
file(binary) {
assertTrue { exists() }
assertTrue { length() > 0 }
}
file(smap) {
assertTrue { exists() }
assertTrue { length() > 0 }
}
} else {
file(binary) {
assertFalse { exists() }
}
file(smap) {
assertFalse { exists() }
}
}
}

internal fun RunResult.checkJacocoBinaryReport(binary: String, mustExists: Boolean = true) {
if (mustExists) {
file(binary) {
assertTrue { exists() }
assertTrue { length() > 0 }
}
} else {
file(binary) {
assertFalse { exists() }
if (engine == CoverageEngine.INTELLIJ) {
val smap = defaultSmapFile(projectType)

if (mustExists) {
file(smap) {
assertTrue { exists() }
assertTrue { length() > 0 }
}
} else {
file(smap) {
assertFalse { exists() }
}
}
}
}

internal fun RunResult.checkReports(xmlPath: String, htmlPath: String, mustExists: Boolean = true) {
internal fun RunResult.checkDefaultReports(mustExists: Boolean = true) {
checkReports(defaultXmlReport(), defaultHtmlReport(), mustExists)
}

internal fun RunResult.checkDefaultModuleReports(mustExists: Boolean = true) {
checkReports(defaultXmlModuleReport(), defaultHtmlModuleReport(), mustExists)
}

internal fun RunResult.checkReports(xmlPath: String, htmlPath: String, mustExists: Boolean) {
if (mustExists) {
file(xmlPath) {
assertTrue { exists() }
assertTrue("XML file must exist '$xmlPath'") { exists() }
assertTrue { length() > 0 }
}
file(htmlPath) {
Expand All @@ -58,6 +63,10 @@ internal fun RunResult.checkReports(xmlPath: String, htmlPath: String, mustExist
}
}

internal fun assertCounterAbsent(counter: Counter?) {
assertNull(counter)
}

internal fun assertCounterExcluded(counter: Counter?, engine: CoverageEngine) {
if (engine == CoverageEngine.INTELLIJ) {
assertNull(counter)
Expand All @@ -67,7 +76,15 @@ internal fun assertCounterExcluded(counter: Counter?, engine: CoverageEngine) {
}
}

internal fun assertCounterCoveredAndIncluded(counter: Counter?) {
internal fun assertCounterCovered(counter: Counter?) {
assertNotNull(counter)
assertTrue { counter.covered > 0 }
}

internal fun assertCounterFullyCovered(counter: Counter?) {
assertNotNull(counter)
assertTrue { counter.covered > 0 }
assertEquals(0, counter.missed)
}


Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
package kotlinx.kover.test.functional.cases.utils

import kotlinx.kover.api.*
import kotlinx.kover.test.functional.core.ProjectType

internal const val DEFAULT_INTELLIJ_KJVM_BINARY = "kover/test.ic"
internal const val DEFAULT_INTELLIJ_KJVM_SMAP = "kover/test.ic.smap"

internal const val DEFAULT_INTELLIJ_KMP_BINARY = "kover/jvmTest.ic"
internal const val DEFAULT_INTELLIJ_KMP_SMAP = "kover/jvmTest.ic.smap"
internal fun defaultBinaryReport(engine: CoverageEngine, projectType: ProjectType): String {
val extension = if (engine == CoverageEngine.INTELLIJ) "ic" else "exec"
return when (projectType) {
ProjectType.KOTLIN_JVM -> "kover/test.$extension"
ProjectType.KOTLIN_MULTIPLATFORM -> "kover/jvmTest.$extension"
ProjectType.ANDROID -> "kover/jvmTest.$extension"
}
}

internal const val DEFAULT_JACOCO_KJVM_BINARY = "kover/test.exec"
internal const val DEFAULT_JACOCO_KMP_BINARY = "kover/jvmTest.exec"
internal fun defaultSmapFile(projectType: ProjectType): String {
return defaultBinaryReport(CoverageEngine.INTELLIJ, projectType) + ".smap"
}

internal const val DEFAULT_XML = "reports/kover/report.xml"
internal const val DEFAULT_HTML = "reports/kover/html"
internal fun defaultXmlReport() = "reports/kover/report.xml"
internal fun defaultHtmlReport() = "reports/kover/html"

internal fun defaultXmlModuleReport() = "reports/kover/module-xml/report.xml"
internal fun defaultHtmlModuleReport() = "reports/kover/module-html"
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ internal open class BaseGradleScriptTest {
@JvmField
internal val rootFolder: TemporaryFolder = TemporaryFolder()

fun builder(): ProjectBuilder {
return createBuilder(rootFolder.root)
fun builder(description: String): ProjectBuilder {
return createBuilder(rootFolder.root, description)
}
}
Loading

0 comments on commit 96ead04

Please sign in to comment.