Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow display name formatter to return null #3764

Merged
merged 6 commits into from
Nov 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import io.kotest.core.config.ProjectConfiguration
import io.kotest.core.descriptors.toDescriptor
import io.kotest.core.spec.Spec
import io.kotest.core.test.TestCase
import io.kotest.engine.test.names.getDisplayNameFormatter
import io.kotest.engine.test.names.getFallbackDisplayNameFormatter
import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.extension.ExtensionContext
import org.junit.jupiter.api.extension.TestInstances
Expand All @@ -19,7 +19,7 @@ class KotestExtensionContext(
private val testCase: TestCase?
) : ExtensionContext {

private val formatter = getDisplayNameFormatter(ProjectConfiguration().registry, ProjectConfiguration())
private val formatter = getFallbackDisplayNameFormatter(ProjectConfiguration().registry, ProjectConfiguration())

override fun getExecutionMode(): ExecutionMode = ExecutionMode.CONCURRENT

Expand Down Expand Up @@ -103,7 +103,7 @@ class ExtensionStore(private val namespace: ExtensionContext.Namespace) : Extens
key: K,
defaultCreator: Function<K, V>,
requiredType: Class<V>
): V? {
): V {
val value = map[namespace to key]
return when {
value == null -> defaultCreator.apply(key)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import io.kotest.core.test.TestCase
import io.kotest.core.test.TestResult
import io.kotest.core.test.TestType
import io.kotest.engine.test.names.formatTestPath
import io.kotest.engine.test.names.getDisplayNameFormatter
import io.kotest.engine.test.names.getFallbackDisplayNameFormatter
import org.jdom2.Document
import org.jdom2.Element
import org.jdom2.output.Format
Expand All @@ -25,7 +25,6 @@ import java.time.format.DateTimeFormatter.ISO_LOCAL_DATE_TIME
import java.util.concurrent.ConcurrentHashMap
import kotlin.io.path.absolute
import kotlin.reflect.KClass
import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.DurationUnit

Expand Down Expand Up @@ -58,7 +57,7 @@ class JunitXmlReporter(
const val AttributeName = "name"
}

private val formatter = getDisplayNameFormatter(ProjectConfiguration().registry, ProjectConfiguration())
private val formatter = getFallbackDisplayNameFormatter(ProjectConfiguration().registry, ProjectConfiguration())
private var marks = ConcurrentHashMap<KClass<out Spec>, Long>()

private fun outputDir(): Path {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package io.kotest.core.config

import io.kotest.common.KotestInternal
import io.kotest.core.extensions.Extension

@KotestInternal
interface ExtensionRegistry {
fun all(): List<Extension>
fun add(extension: Extension)
Expand All @@ -11,6 +13,7 @@ interface ExtensionRegistry {
fun isNotEmpty(): Boolean
}

@KotestInternal
class DefaultExtensionRegistry : ExtensionRegistry {

private val extensions = mutableListOf<Extension>()
Expand All @@ -33,6 +36,7 @@ class DefaultExtensionRegistry : ExtensionRegistry {
override fun isNotEmpty(): Boolean = extensions.isNotEmpty()
}

@KotestInternal
object EmptyExtensionRegistry : ExtensionRegistry {

override fun all(): List<Extension> = emptyList()
Expand All @@ -53,6 +57,7 @@ object EmptyExtensionRegistry : ExtensionRegistry {
override fun isNotEmpty(): Boolean = false
}

@KotestInternal
class FixedExtensionRegistry(private vararg val extensions: Extension) : ExtensionRegistry {

override fun all(): List<Extension> = extensions.toList()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ interface DisplayNameFormatter {
/**
* Returns a formatted name for a test.
*/
fun format(testCase: TestCase): String
fun format(testCase: TestCase): String?

/**
* Returns a formatted name for a spec class.
*/
fun format(kclass: KClass<*>): String
fun format(kclass: KClass<*>): String?
}
Original file line number Diff line number Diff line change
Expand Up @@ -826,15 +826,31 @@ public final class io/kotest/engine/test/names/DefaultDisplayNameFormatter : io/

public final class io/kotest/engine/test/names/DefaultDisplayNameFormatterKt {
public static final fun appendTagsInDisplayName (Lio/kotest/core/test/TestCase;Ljava/lang/String;)Ljava/lang/String;
public static final fun getDisplayNameFormatter (Lio/kotest/core/config/ExtensionRegistry;Lio/kotest/core/config/ProjectConfiguration;)Lio/kotest/core/names/DisplayNameFormatter;
}

public final class io/kotest/engine/test/names/DuplicateTestNameException : java/lang/RuntimeException {
public fun <init> (Ljava/lang/String;)V
}

public final class io/kotest/engine/test/names/FallbackDisplayNameFormatter {
public static final field Companion Lio/kotest/engine/test/names/FallbackDisplayNameFormatter$Companion;
public fun <init> (Lio/kotest/core/names/DisplayNameFormatter;Lio/kotest/engine/test/names/DefaultDisplayNameFormatter;)V
public fun <init> (Lio/kotest/engine/test/names/DefaultDisplayNameFormatter;)V
public final fun format (Lio/kotest/core/test/TestCase;)Ljava/lang/String;
public final fun format (Lkotlin/reflect/KClass;)Ljava/lang/String;
}

public final class io/kotest/engine/test/names/FallbackDisplayNameFormatter$Companion {
public final fun default ()Lio/kotest/engine/test/names/FallbackDisplayNameFormatter;
public final fun default (Lio/kotest/core/config/ProjectConfiguration;)Lio/kotest/engine/test/names/FallbackDisplayNameFormatter;
}

public final class io/kotest/engine/test/names/GetDisplayNameFormatterKt {
public static final fun getFallbackDisplayNameFormatter (Lio/kotest/core/config/ExtensionRegistry;Lio/kotest/core/config/ProjectConfiguration;)Lio/kotest/engine/test/names/FallbackDisplayNameFormatter;
}

public final class io/kotest/engine/test/names/PathsKt {
public static final fun formatTestPath (Lio/kotest/core/names/DisplayNameFormatter;Lio/kotest/core/test/TestCase;Ljava/lang/String;)Ljava/lang/String;
public static final fun formatTestPath (Lio/kotest/engine/test/names/FallbackDisplayNameFormatter;Lio/kotest/core/test/TestCase;Ljava/lang/String;)Ljava/lang/String;
}

public final class io/kotest/engine/test/scopes/DuplicateNameHandlingTestScope : io/kotest/core/test/TestScope {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package io.kotest.engine.listener

import io.kotest.common.KotestInternal
import io.kotest.core.config.ProjectConfiguration
import io.kotest.core.descriptors.Descriptor
import io.kotest.core.descriptors.toDescriptor
import io.kotest.core.names.DisplayNameFormatter
import io.kotest.core.test.TestCase
import io.kotest.core.test.TestResult
import io.kotest.core.test.TestType
Expand All @@ -12,23 +12,24 @@ import io.kotest.engine.extensions.MultipleExceptions
import io.kotest.engine.interceptors.EngineContext
import io.kotest.engine.teamcity.Locations
import io.kotest.engine.teamcity.TeamCityMessageBuilder
import io.kotest.engine.test.names.DefaultDisplayNameFormatter
import io.kotest.engine.test.names.getDisplayNameFormatter
import io.kotest.engine.test.names.FallbackDisplayNameFormatter
import io.kotest.engine.test.names.getFallbackDisplayNameFormatter
import io.kotest.mpp.Logger
import io.kotest.mpp.bestName
import kotlin.reflect.KClass

/**
* A [TestEngineListener] that logs events to the console using a [TeamCityMessageBuilder].
*/
@KotestInternal
class TeamCityTestEngineListener(
private val prefix: String = TeamCityMessageBuilder.TeamCityPrefix,
private val details: Boolean = true,
) : TestEngineListener {

private val logger = Logger(TeamCityTestEngineListener::class)

private var formatter: DisplayNameFormatter = DefaultDisplayNameFormatter(ProjectConfiguration())
private var formatter = FallbackDisplayNameFormatter.default(ProjectConfiguration())

// once a spec has completed, we want to be able to check whether any given test is
// a container or a leaf test, and so this map contains all test that have children
Expand Down Expand Up @@ -73,7 +74,7 @@ class TeamCityTestEngineListener(
override suspend fun engineStarted() {}

override suspend fun engineInitialized(context: EngineContext) {
formatter = getDisplayNameFormatter(context.configuration.registry, context.configuration)
formatter = getFallbackDisplayNameFormatter(context.configuration.registry, context.configuration)
}

override suspend fun engineFinished(t: List<Throwable>) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ package io.kotest.engine.test.names
import io.kotest.common.Platform
import io.kotest.common.platform
import io.kotest.core.annotation.displayname.wrapper
import io.kotest.core.config.ExtensionRegistry
import io.kotest.core.config.ProjectConfiguration
import io.kotest.core.extensions.DisplayNameFormatterExtension
import io.kotest.core.names.DisplayNameFormatter
import io.kotest.core.names.TestNameCase
import io.kotest.core.spec.DisplayName
Expand All @@ -14,13 +12,6 @@ import io.kotest.mpp.annotation
import io.kotest.mpp.bestName
import kotlin.reflect.KClass

fun getDisplayNameFormatter(registry: ExtensionRegistry, configuration: ProjectConfiguration): DisplayNameFormatter {
return registry.all()
.filterIsInstance<DisplayNameFormatterExtension>()
.firstOrNull()
?.formatter() ?: DefaultDisplayNameFormatter(configuration)
}

/**
* A default implementation of [DisplayNameFormatter].
* Used when there are no registered [io.kotest.core.extensions.DisplayNameFormatterExtension]s.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package io.kotest.engine.test.names

import io.kotest.core.config.ProjectConfiguration
import io.kotest.core.names.DisplayNameFormatter
import io.kotest.core.test.TestCase
import kotlin.reflect.KClass

class FallbackDisplayNameFormatter(
private val custom: DisplayNameFormatter?,
private val fallback: DefaultDisplayNameFormatter,
) {

companion object {
fun default() = default(ProjectConfiguration())

fun default(configuration: ProjectConfiguration) =
FallbackDisplayNameFormatter(DefaultDisplayNameFormatter(configuration))
}

constructor(fallback: DefaultDisplayNameFormatter) : this(null, fallback)

fun format(kclass: KClass<*>): String {
return custom?.format(kclass) ?: fallback.format(kclass)
}

fun format(testCase: TestCase): String {
return custom?.format(testCase) ?: fallback.format(testCase)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.kotest.engine.test.names

import io.kotest.common.KotestInternal
import io.kotest.core.config.ExtensionRegistry
import io.kotest.core.config.ProjectConfiguration
import io.kotest.core.extensions.DisplayNameFormatterExtension

@KotestInternal
fun getFallbackDisplayNameFormatter(
registry: ExtensionRegistry,
configuration: ProjectConfiguration,
): FallbackDisplayNameFormatter {
val custom = registry.all()
.filterIsInstance<DisplayNameFormatterExtension>()
.firstOrNull()?.formatter()
return FallbackDisplayNameFormatter(custom, DefaultDisplayNameFormatter(configuration))
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package io.kotest.engine.test.names

import io.kotest.core.names.DisplayNameFormatter
import io.kotest.core.test.TestCase

fun DisplayNameFormatter.formatTestPath(testCase: TestCase, separator: String): String {
fun FallbackDisplayNameFormatter.formatTestPath(testCase: TestCase, separator: String): String {
return when (val parent = testCase.parent) {
null -> format(testCase)
else -> formatTestPath(parent, separator) + separator + format(testCase)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import io.kotest.engine.interceptors.EngineContext
import io.kotest.engine.it
import io.kotest.engine.test.TestCaseExecutor
import io.kotest.engine.test.interceptors.testNameEscape
import io.kotest.engine.test.names.getDisplayNameFormatter
import io.kotest.engine.test.names.getFallbackDisplayNameFormatter
import io.kotest.engine.test.scopes.TerminalTestScope
import io.kotest.engine.test.status.isEnabledInternal
import io.kotest.engine.xit
Expand All @@ -32,7 +32,7 @@ internal actual fun createSpecExecutorDelegate(
@ExperimentalKotest
internal class JavascriptSpecExecutorDelegate(private val context: EngineContext) : SpecExecutorDelegate {

private val formatter = getDisplayNameFormatter(
private val formatter = getFallbackDisplayNameFormatter(
context.configuration.registry,
context.configuration,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@ import com.github.ajalt.mordant.TermColors
import io.kotest.core.config.ProjectConfiguration
import io.kotest.core.descriptors.Descriptor
import io.kotest.core.descriptors.toDescriptor
import io.kotest.core.names.DisplayNameFormatter
import io.kotest.core.test.TestCase
import io.kotest.core.test.TestResult
import io.kotest.core.test.TestType
import io.kotest.engine.interceptors.EngineContext
import io.kotest.engine.test.names.DefaultDisplayNameFormatter
import io.kotest.engine.test.names.FallbackDisplayNameFormatter
import io.kotest.engine.test.names.formatTestPath
import io.kotest.engine.test.names.getDisplayNameFormatter
import io.kotest.engine.test.names.getFallbackDisplayNameFormatter
import kotlin.reflect.KClass
import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds
Expand All @@ -32,7 +31,7 @@ class EnhancedConsoleTestEngineListener(private val term: TermColors) : Abstract
private var slow = 500.milliseconds
private var verySlow = 5000.milliseconds

private var formatter:DisplayNameFormatter = DefaultDisplayNameFormatter(ProjectConfiguration())
private var formatter = FallbackDisplayNameFormatter.default(ProjectConfiguration())

private fun green(str: String) = term.green(str)
private fun greenBold(str: String) = term.green.plus(term.bold).invoke(str)
Expand Down Expand Up @@ -75,7 +74,7 @@ class EnhancedConsoleTestEngineListener(private val term: TermColors) : Abstract

override suspend fun engineInitialized(context: EngineContext) {

formatter = getDisplayNameFormatter(context.configuration.registry, context.configuration)
formatter = getFallbackDisplayNameFormatter(context.configuration.registry, context.configuration)

println(bold(">> Kotest"))
println("- " + intros.shuffled().first())
Expand Down Expand Up @@ -209,6 +208,7 @@ class EnhancedConsoleTestEngineListener(private val term: TermColors) : Abstract
testsFailed = testsFailed + Pair(testCase, result)
specsFailed = specsFailed + testCase.descriptor.spec()
}

else -> Unit
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ public final class io/kotest/runner/junit/platform/DescriptorsKt {
}

public final class io/kotest/runner/junit/platform/JUnitTestEngineListener : io/kotest/engine/listener/AbstractTestEngineListener {
public fun <init> (Lorg/junit/platform/engine/EngineExecutionListener;Lorg/junit/platform/engine/support/descriptor/EngineDescriptor;Lio/kotest/core/names/DisplayNameFormatter;)V
public fun <init> (Lorg/junit/platform/engine/EngineExecutionListener;Lorg/junit/platform/engine/support/descriptor/EngineDescriptor;Lio/kotest/engine/test/names/FallbackDisplayNameFormatter;)V
public fun engineFinished (Ljava/util/List;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun engineInitialized (Lio/kotest/engine/interceptors/EngineContext;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun engineStarted (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
Expand All @@ -27,7 +27,6 @@ public final class io/kotest/runner/junit/platform/KotestEngineDescriptor : org/

public final class io/kotest/runner/junit/platform/KotestJunitPlatformTestEngine : org/junit/platform/engine/TestEngine {
public static final field Companion Lio/kotest/runner/junit/platform/KotestJunitPlatformTestEngine$Companion;
public static final field EngineId Ljava/lang/String;
public fun <init> ()V
public fun discover (Lorg/junit/platform/engine/EngineDiscoveryRequest;Lorg/junit/platform/engine/UniqueId;)Lio/kotest/runner/junit/platform/KotestEngineDescriptor;
public synthetic fun discover (Lorg/junit/platform/engine/EngineDiscoveryRequest;Lorg/junit/platform/engine/UniqueId;)Lorg/junit/platform/engine/TestDescriptor;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ import io.kotest.core.test.TestType
import io.kotest.engine.errors.ExtensionExceptionExtractor
import io.kotest.engine.interceptors.EngineContext
import io.kotest.engine.listener.AbstractTestEngineListener
import io.kotest.engine.test.names.DefaultDisplayNameFormatter
import io.kotest.engine.test.names.getDisplayNameFormatter
import io.kotest.engine.test.names.FallbackDisplayNameFormatter
import io.kotest.mpp.Logger
import io.kotest.mpp.bestName
import org.junit.platform.engine.EngineExecutionListener
Expand Down Expand Up @@ -75,7 +74,7 @@ import kotlin.time.Duration
class JUnitTestEngineListener(
private val listener: EngineExecutionListener,
val root: EngineDescriptor,
private val formatter: DisplayNameFormatter,
private val formatter: FallbackDisplayNameFormatter,
) : AbstractTestEngineListener() {

private val logger = Logger(JUnitTestEngineListener::class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import io.kotest.core.config.ProjectConfiguration
import io.kotest.core.descriptors.toDescriptor
import io.kotest.core.extensions.Extension
import io.kotest.core.filter.TestFilter
import io.kotest.core.names.DisplayNameFormatter
import io.kotest.core.spec.Spec
import io.kotest.engine.TestEngineLauncher
import io.kotest.engine.config.ConfigManager
import io.kotest.engine.config.detectAbstractProjectConfigsJVM
import io.kotest.engine.config.loadProjectConfigFromClassnameJVM
import io.kotest.engine.listener.PinnedSpecTestEngineListener
import io.kotest.engine.listener.ThreadSafeTestEngineListener
import io.kotest.engine.test.names.getDisplayNameFormatter
import io.kotest.engine.test.names.FallbackDisplayNameFormatter
import io.kotest.engine.test.names.getFallbackDisplayNameFormatter
import io.kotest.framework.discovery.Discovery
import io.kotest.framework.discovery.DiscoveryRequest
import io.kotest.mpp.Logger
Expand Down Expand Up @@ -41,7 +41,7 @@ class KotestJunitPlatformTestEngine : TestEngine {
private val logger = Logger(KotestJunitPlatformTestEngine::class)

companion object {
const val EngineId = "kotest"
internal const val EngineId = "kotest"
}

override fun getId(): String = EngineId
Expand Down Expand Up @@ -169,8 +169,8 @@ class KotestEngineDescriptor(
val error: Throwable?, // an error during discovery
) : EngineDescriptor(id, "Kotest") {

internal val formatter: DisplayNameFormatter by lazy {
getDisplayNameFormatter(configuration.registry, configuration)
internal val formatter: FallbackDisplayNameFormatter by lazy {
getFallbackDisplayNameFormatter(configuration.registry, configuration)
}

internal val classes: List<KClass<out Spec>>
Expand Down