[Native][tests] Refactoring: Rework @TestCaseGroupProviding

This commit is contained in:
Dmitriy Dolovov
2021-11-24 16:51:25 +03:00
parent 7e92e3c57f
commit 3c47880eba
4 changed files with 47 additions and 14 deletions
@@ -8,8 +8,7 @@ package org.jetbrains.kotlin.generators.tests
import org.jetbrains.kotlin.generators.generateTestGroupSuiteWithJUnit5
import org.jetbrains.kotlin.generators.model.annotation
import org.jetbrains.kotlin.konan.blackboxtest.AbstractNativeBlackBoxTest
import org.jetbrains.kotlin.konan.blackboxtest.support.group.NativeBlackBoxTestCaseGroupProvider
import org.jetbrains.kotlin.konan.blackboxtest.support.group.ExtTestCaseGroupProvider
import org.jetbrains.kotlin.konan.blackboxtest.support.group.UseExtTestCaseGroupProvider
import org.jetbrains.kotlin.test.TargetBackend
fun main() {
@@ -20,7 +19,7 @@ fun main() {
testGroup("native/native.tests/tests-gen", "compiler/testData") {
testClass<AbstractNativeBlackBoxTest>(
suiteTestClassName = "NativeExtBlackBoxTestGenerated",
annotations = listOf(annotation(NativeBlackBoxTestCaseGroupProvider::class.java, ExtTestCaseGroupProvider::class.java))
annotations = listOf(annotation(UseExtTestCaseGroupProvider::class.java))
) {
model("codegen/box", targetBackend = TargetBackend.NATIVE)
model("codegen/boxInline", targetBackend = TargetBackend.NATIVE)
@@ -6,9 +6,9 @@
package org.jetbrains.kotlin.konan.blackboxtest.support
import org.jetbrains.kotlin.konan.blackboxtest.AbstractNativeBlackBoxTest
import org.jetbrains.kotlin.konan.blackboxtest.support.group.NativeBlackBoxTestCaseGroupProvider
import org.jetbrains.kotlin.konan.blackboxtest.support.group.StandardTestCaseGroupProvider
import org.jetbrains.kotlin.konan.blackboxtest.support.group.TestCaseGroupProvider
import org.jetbrains.kotlin.konan.blackboxtest.support.group.TestCaseGroupProviding
import org.jetbrains.kotlin.konan.blackboxtest.support.util.*
import org.jetbrains.kotlin.test.TestMetadata
import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertEquals
@@ -20,6 +20,8 @@ import org.junit.jupiter.api.extension.ExtensionContext
import org.junit.jupiter.api.extension.TestInstancePostProcessor
import java.io.File
import kotlin.reflect.KClass
import kotlin.reflect.KParameter
import kotlin.reflect.full.findAnnotation
class NativeBlackBoxTestSupport : BeforeEachCallback {
/**
@@ -124,17 +126,39 @@ class NativeBlackBoxTestSupport : BeforeEachCallback {
}
private fun Class<*>.createTestCaseGroupProvider(environment: TestEnvironment): TestCaseGroupProvider {
val providerClass = getAnnotation(NativeBlackBoxTestCaseGroupProvider::class.java)?.value
?: return StandardTestCaseGroupProvider(environment)
val (providerAnnotation, providerAnnotationClass, providerClass) = annotations.asSequence()
.mapNotNull { annotation ->
val annotationClass = annotation.annotationClass
val providerClass = annotationClass.findAnnotation<TestCaseGroupProviding>()?.providerClass ?: return@mapNotNull null
Triple(annotation, annotationClass, providerClass)
}.firstOrNull()
?: return StandardTestCaseGroupProvider(environment) // Fallback if there is no annotation.
val constructor = providerClass.constructors.firstOrNull { constructor ->
val singleParameter = constructor.parameters.singleOrNull() ?: return@firstOrNull false
(singleParameter.type.classifier as? KClass<*>)?.qualifiedName == TestEnvironment::class.qualifiedName
} ?: fail { "No suitable constructor for $providerClass" }
// First, try to find two-argument constructor.
providerClass.constructors.asSequence()
.forEach { c ->
val (p1, p2) = c.parameters.takeIf { it.size == 2 } ?: return@forEach
val provider = when {
p1.hasTypeOf<TestEnvironment>() && p2.hasTypeOf(providerAnnotationClass) -> c.call(environment, providerAnnotation)
p1.hasTypeOf(providerAnnotationClass) && p2.hasTypeOf<TestEnvironment>() -> c.call(providerAnnotation, environment)
else -> return@forEach
}
return provider.cast()
}
return constructor.call(environment).cast()
// Next, try to find a single-argument constructor.
providerClass.constructors.asSequence()
.forEach { c ->
val p = c.parameters.singleOrNull() ?: return@forEach
if (p.hasTypeOf<TestEnvironment>()) return c.call(environment).cast()
}
fail { "No suitable constructor for $providerClass" }
}
private inline fun <reified T : Any> KParameter.hasTypeOf(): Boolean = hasTypeOf(T::class)
private fun KParameter.hasTypeOf(clazz: KClass<*>): Boolean = (type.classifier as? KClass<*>)?.qualifiedName == clazz.qualifiedName
private val TestMetadata.testRoot: File get() = getAbsoluteFile(localPath = value)
}
}
@@ -0,0 +1,11 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.konan.blackboxtest.support.group
import kotlin.reflect.KClass
@Target(AnnotationTarget.ANNOTATION_CLASS)
internal annotation class TestCaseGroupProviding(val providerClass: KClass<out TestCaseGroupProvider>)
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.konan.blackboxtest.support.group
import kotlin.reflect.KClass
@Target(AnnotationTarget.CLASS)
annotation class NativeBlackBoxTestCaseGroupProvider(val value: KClass<*>)
@TestCaseGroupProviding(ExtTestCaseGroupProvider::class)
annotation class UseExtTestCaseGroupProvider