[Test] Compute target backend in test generator automatically using reflection

This commit is contained in:
Dmitriy Novozhilov
2020-12-25 12:14:03 +03:00
committed by TeamCityServer
parent 9378d1ff31
commit 3c2079c926
7 changed files with 100 additions and 10 deletions
@@ -0,0 +1,21 @@
/*
* Copyright 2010-2020 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.test.runners
import org.jetbrains.kotlin.test.TargetBackend
/**
* If your test runner has specific target backend then you can add this interface
* to your runner and after that you should not declare targetBackend
* parameter in DSL in addition to defining it in test runner
*
* Please make sure that all abstract runners which are used in test generator
* have `open` modality, not `abstract`. This is required because test generator
* instantiates runner to get value of targetBackend and generate tests properly
*/
interface RunnerWithTargetBackendForTestGeneratorMarker {
val targetBackend: TargetBackend
}
@@ -20,7 +20,7 @@ fun generateTestGroupSuiteWithJUnit5(
dryRun: Boolean = false,
init: TestGroupSuite.() -> Unit
) {
val suite = testGroupSuite(init)
val suite = TestGroupSuite(ReflectionBasedTargetBackendComputer).apply(init)
for (testGroup in suite.testGroups) {
for (testClass in testGroup.testClasses) {
val (changed, testSourceFilePath) = NewTestGeneratorImpl.generateAndSave(testClass, dryRun)
@@ -0,0 +1,40 @@
/*
* Copyright 2010-2020 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.test.generators
import org.jetbrains.kotlin.generators.model.DefaultTargetBackendComputer
import org.jetbrains.kotlin.generators.model.TargetBackendComputer
import org.jetbrains.kotlin.test.TargetBackend
import org.jetbrains.kotlin.test.runners.RunnerWithTargetBackendForTestGeneratorMarker
import kotlin.reflect.KClass
import kotlin.reflect.full.createInstance
import kotlin.reflect.full.declaredMemberProperties
import kotlin.reflect.full.isSubclassOf
object ReflectionBasedTargetBackendComputer : TargetBackendComputer {
private val runnerMarkerKClass = RunnerWithTargetBackendForTestGeneratorMarker::class
private const val TARGET_BACKEND_PROPERTY_NAME = "targetBackend"
override fun compute(definedTargetBackend: TargetBackend?, testKClass: KClass<*>): TargetBackend {
if (!testKClass.isSubclassOf(runnerMarkerKClass)) return DefaultTargetBackendComputer.compute(definedTargetBackend, testKClass)
require(definedTargetBackend == null) {
"""
Test ${testKClass.simpleName} is inheritor of ${runnerMarkerKClass.simpleName} which means that
target you should not specify targetBackend in test generation DSL, because it will be
read from test runner class itself
""".trimIndent()
}
require(testKClass.isOpen) {
"""
Test runner which inherits from ${runnerMarkerKClass.simpleName} and used as base class
for real test should have `open` modality
""".trimIndent()
}
val instance = testKClass.createInstance() as RunnerWithTargetBackendForTestGeneratorMarker
val kProperty = runnerMarkerKClass.declaredMemberProperties.single { it.name == TARGET_BACKEND_PROPERTY_NAME }
return kProperty.get(instance) as TargetBackend
}
}
@@ -10,8 +10,8 @@ dependencies {
testImplementation(platform("org.junit:junit-bom:5.7.0"))
testImplementation("org.junit.jupiter:junit-jupiter")
testImplementation(projectTests(":compiler:tests-common"))
testImplementation(projectTests(":compiler:test-infrastructure"))
testImplementation(projectTests(":compiler:tests-common-new"))
testImplementation(projectTests(":compiler:tests-common"))
testImplementation(projectTests(":compiler"))
testImplementation(projectTests(":compiler:fir:raw-fir:psi2fir"))
testImplementation(projectTests(":compiler:fir:raw-fir:light-tree2fir"))