All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jvmTest.com.bkahlert.kommons.test.junit.launcher.TestExecutionReporterTest.kt Maven / Gradle / Ivy

There is a newer version: 2.8.0
Show newest version
package com.bkahlert.kommons.test.junit.launcher

import com.bkahlert.kommons.test.com.bkahlert.kommons.ansiRemoved
import com.bkahlert.kommons.test.test
import io.kotest.matchers.string.shouldMatch
import org.junit.jupiter.api.Test
import org.junit.platform.engine.ConfigurationParameters
import org.junit.platform.engine.TestDescriptor
import org.junit.platform.engine.TestDescriptor.Type
import org.junit.platform.engine.TestExecutionResult
import org.junit.platform.engine.TestSource
import org.junit.platform.engine.TestTag
import org.junit.platform.engine.UniqueId
import org.junit.platform.launcher.TestIdentifier
import org.junit.platform.launcher.TestPlan
import java.util.Optional

class TestExecutionReporterTest {

    @Test fun no_tests() = test {
        testExecutionReporterOutput(0, 0, 0, 0) shouldMatch """
            ⁉︎ no tests executed
        """.trimIndent()
    }

    @Test fun successful_tests() = test {
        testExecutionReporterOutput(1, 0, 0, 0) shouldMatch """
            1 test within \d+m?s: ✔︎ all passed
        """.trimIndent()
        testExecutionReporterOutput(2, 0, 0, 0) shouldMatch """
            2 tests within \d+m?s: ✔︎ all passed
        """.trimIndent()
    }

    @Test fun aborted_tests() = test {
        testExecutionReporterOutput(0, 0, 1, 0) shouldMatch """
            1 test within \d+m?s: ϟ all crashed
        """.trimIndent()
        testExecutionReporterOutput(0, 0, 2, 0) shouldMatch """
            2 tests within \d+m?s: ϟ all crashed
        """.trimIndent()
        testExecutionReporterOutput(1, 0, 2, 0) shouldMatch """
            3 tests within \d+m?s: ϟ 2 crashed, ✔︎ 1 passed
        """.trimIndent()
    }

    @Test fun failed_tests() = test {
        testExecutionReporterOutput(0, 1, 0, 0) shouldMatch """
            1 test within \d+m?s: ✘︎ all failed
        """.trimIndent()
        testExecutionReporterOutput(0, 2, 0, 0) shouldMatch """
            2 tests within \d+m?s: ✘︎ all failed
        """.trimIndent()
        testExecutionReporterOutput(1, 2, 0, 0) shouldMatch """
            3 tests within \d+m?s: ✘︎ 2 failed, ✔︎ 1 passed
        """.trimIndent()
    }

    @Test fun failed_and_failed_tests() = test {
        testExecutionReporterOutput(1, 2, 1, 0) shouldMatch """
            4 tests within \d+m?s: ✘︎ 2 failed, ϟ 1 crashed, ✔︎ 1 passed
        """.trimIndent()
        testExecutionReporterOutput(1, 1, 2, 0) shouldMatch """
            4 tests within \d+m?s: ✘︎ 1 failed, ϟ 2 crashed, ✔︎ 1 passed
        """.trimIndent()
    }

    @Test fun skipped_tests() = test {
        testExecutionReporterOutput(1, 1, 1, 2) shouldMatch """
            3 tests within \d+m?s: ✘︎ 1 failed, ϟ 1 crashed, ✔︎ 1 passed, ◍ 2 ignored
        """.trimIndent()
        testExecutionReporterOutput(2, 2, 2, 2) shouldMatch """
            6 tests within \d+m?s: ✘︎ 2 failed, ϟ 2 crashed, ✔︎ 2 passed, ◍ 2 ignored
        """.trimIndent()
        testExecutionReporterOutput(2, 0, 0, 2) shouldMatch """
            2 tests within \d+m?s: ✔︎ all passed, ◍ all ignored
        """.trimIndent()
    }
}

private fun testExecutionReporterOutput(
    passed: Int,
    failed: Int,
    aborted: Int,
    skipped: Int,
    sanitize: Boolean = true,
): String {
    val testPlan = TestPlan.from(emptyList(), configurationParameters())
    val lines = mutableListOf()
    TestExecutionReporter { lines.add(it) }.apply {
        testPlanExecutionStarted(testPlan)
        repeat(passed) {
            executionStarted(testIdentifier())
            executionFinished(testIdentifier(), TestExecutionResult.successful())
        }
        repeat(failed) {
            executionStarted(testIdentifier())
            executionFinished(testIdentifier(), TestExecutionResult.failed(RuntimeException()))
        }
        repeat(aborted) {
            executionStarted(testIdentifier())
            executionFinished(testIdentifier(), TestExecutionResult.aborted(RuntimeException()))
        }
        repeat(skipped) {
            executionSkipped(testIdentifier(), null)
        }
        testPlanExecutionFinished(testPlan)
    }
    return lines.joinToString("\n").let { if (sanitize) it.ansiRemoved.trim() else it }
}

private fun configurationParameters(vararg entries: Pair) =
    object : ConfigurationParameters {
        override fun get(key: String?): Optional =
            Optional.ofNullable(entries.firstOrNull { it.first == key }?.second)

        override fun getBoolean(key: String?): Optional =
            get(key).flatMap { Optional.ofNullable(it.toBoolean()) }

        @Deprecated("use keySet", ReplaceWith("keySet.size()"))
        override fun size(): Int = entries.size
        override fun keySet(): MutableSet = entries.mapNotNull { it.first }.toMutableSet()
    }

private fun testIdentifier(testDescriptor: TestDescriptor = testDescriptor()): TestIdentifier =
    TestIdentifier.from(testDescriptor)

private fun testDescriptor(): TestDescriptor =
    object : TestDescriptor {
        override fun getUniqueId(): UniqueId =
            UniqueId.parse("[class:foo.FooTest]/[method:bar(baz.Baz)]")

        override fun getDisplayName(): String = "bar(Baz)"
        override fun getTags(): MutableSet = mutableSetOf()
        override fun getSource(): Optional = Optional.empty()
        override fun getParent(): Optional = Optional.empty()
        override fun setParent(parent: TestDescriptor?) = throw RuntimeException("not implemented")
        override fun getChildren(): MutableSet = mutableSetOf()
        override fun addChild(descriptor: TestDescriptor?) = throw RuntimeException("not implemented")
        override fun removeChild(descriptor: TestDescriptor?) = throw RuntimeException("not implemented")
        override fun removeFromHierarchy() = throw RuntimeException("not implemented")
        override fun getType(): Type = Type.TEST
        override fun findByUniqueId(uniqueId: UniqueId?): Optional = throw RuntimeException("not implemented")
    }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy