[Native][tests] Extract all external source-transformation logic into AbstractExternalNativeBlackBoxTest
This abstract class is used only for generated external codegen box tests that may have custom source transformers.
This commit is contained in:
+2
-1
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.generators.tests
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.generators.generateTestGroupSuiteWithJUnit5
|
import org.jetbrains.kotlin.generators.generateTestGroupSuiteWithJUnit5
|
||||||
import org.jetbrains.kotlin.generators.model.annotation
|
import org.jetbrains.kotlin.generators.model.annotation
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.AbstractExternalNativeBlackBoxTest
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.AbstractNativeBlackBoxTest
|
import org.jetbrains.kotlin.konan.blackboxtest.AbstractNativeBlackBoxTest
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.group.UseExtTestCaseGroupProvider
|
import org.jetbrains.kotlin.konan.blackboxtest.support.group.UseExtTestCaseGroupProvider
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.group.UseStandardTestCaseGroupProvider
|
import org.jetbrains.kotlin.konan.blackboxtest.support.group.UseStandardTestCaseGroupProvider
|
||||||
@@ -19,7 +20,7 @@ fun main() {
|
|||||||
generateTestGroupSuiteWithJUnit5 {
|
generateTestGroupSuiteWithJUnit5 {
|
||||||
// External box tests.
|
// External box tests.
|
||||||
testGroup("native/native.tests/tests-gen", "compiler/testData") {
|
testGroup("native/native.tests/tests-gen", "compiler/testData") {
|
||||||
testClass<AbstractNativeBlackBoxTest>(
|
testClass<AbstractExternalNativeBlackBoxTest>(
|
||||||
suiteTestClassName = "ExternalTestGenerated",
|
suiteTestClassName = "ExternalTestGenerated",
|
||||||
annotations = listOf(external(), provider<UseExtTestCaseGroupProvider>())
|
annotations = listOf(external(), provider<UseExtTestCaseGroupProvider>())
|
||||||
) {
|
) {
|
||||||
|
|||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
import com.intellij.testFramework.TestDataFile
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.util.ExternalSourceTransformer
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.util.ExternalSourceTransformers
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.util.ExternalSourceTransformersProvider
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.util.ThreadSafeCache
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.util.getAbsoluteFile
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
abstract class AbstractExternalNativeBlackBoxTest : ExternalSourceTransformersProvider, AbstractNativeBlackBoxTest() {
|
||||||
|
private val registeredSourceTransformers: ThreadSafeCache<File, MutableList<ExternalSourceTransformer>> = ThreadSafeCache()
|
||||||
|
|
||||||
|
override fun getSourceTransformers(testDataFile: File): ExternalSourceTransformers? = registeredSourceTransformers[testDataFile]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called directly from test class constructor.
|
||||||
|
*/
|
||||||
|
fun register(@TestDataFile testDataFilePath: String, sourceTransformer: ExternalSourceTransformer) {
|
||||||
|
registeredSourceTransformers.computeIfAbsent(getAbsoluteFile(testDataFilePath)) { mutableListOf() } += sourceTransformer
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
-18
@@ -7,31 +7,17 @@ package org.jetbrains.kotlin.konan.blackboxtest
|
|||||||
|
|
||||||
import com.intellij.testFramework.TestDataFile
|
import com.intellij.testFramework.TestDataFile
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.*
|
import org.jetbrains.kotlin.konan.blackboxtest.support.*
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.PackageName
|
import org.jetbrains.kotlin.konan.blackboxtest.support.util.TreeNode
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.TestCaseId
|
import org.jetbrains.kotlin.konan.blackboxtest.support.util.getAbsoluteFile
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.TestRun
|
import org.jetbrains.kotlin.konan.blackboxtest.support.util.joinPackageNames
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.TestRunProvider
|
import org.jetbrains.kotlin.konan.blackboxtest.support.util.prependPackageName
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.util.*
|
|
||||||
import org.junit.jupiter.api.DynamicNode
|
import org.junit.jupiter.api.DynamicNode
|
||||||
import org.junit.jupiter.api.DynamicTest.dynamicTest
|
import org.junit.jupiter.api.DynamicTest.dynamicTest
|
||||||
import org.junit.jupiter.api.extension.ExtendWith
|
import org.junit.jupiter.api.extension.ExtendWith
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
@ExtendWith(NativeBlackBoxTestSupport::class)
|
@ExtendWith(NativeBlackBoxTestSupport::class)
|
||||||
abstract class AbstractNativeBlackBoxTest {
|
abstract class AbstractNativeBlackBoxTest {
|
||||||
internal lateinit var testRunProvider: TestRunProvider
|
internal lateinit var testRunProvider: TestRunProvider
|
||||||
private val toBeRegistered = mutableListOf<Pair<File, List<(String) -> String>>>()
|
|
||||||
internal fun onRunProviderSet() {
|
|
||||||
for ((file, transformer) in toBeRegistered) {
|
|
||||||
testRunProvider.setProcessors(file, transformer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun register(@TestDataFile testDataFilePath: String, sourceTransformers: List<(String) -> String>) =
|
|
||||||
toBeRegistered.add(File(testDataFilePath) to sourceTransformers)
|
|
||||||
|
|
||||||
fun register(@TestDataFile testDataFilePath: String, sourceTransformer: (String) -> String) =
|
|
||||||
register(testDataFilePath, listOf(sourceTransformer))
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run JUnit test.
|
* Run JUnit test.
|
||||||
|
|||||||
+36
-28
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.test.TestMetadata
|
|||||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertEquals
|
import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertEquals
|
||||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions.fail
|
import org.jetbrains.kotlin.test.services.JUnit5Assertions.fail
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
import org.junit.jupiter.api.extension.BeforeAllCallback
|
import org.junit.jupiter.api.extension.BeforeAllCallback
|
||||||
import org.junit.jupiter.api.extension.BeforeEachCallback
|
import org.junit.jupiter.api.extension.BeforeEachCallback
|
||||||
import org.junit.jupiter.api.extension.ExtensionContext
|
import org.junit.jupiter.api.extension.ExtensionContext
|
||||||
@@ -32,7 +33,6 @@ class NativeBlackBoxTestSupport : BeforeEachCallback {
|
|||||||
*/
|
*/
|
||||||
override fun beforeEach(extensionContext: ExtensionContext): Unit = with(extensionContext) {
|
override fun beforeEach(extensionContext: ExtensionContext): Unit = with(extensionContext) {
|
||||||
enclosingTestInstance.testRunProvider = getOrCreateTestRunProvider()
|
enclosingTestInstance.testRunProvider = getOrCreateTestRunProvider()
|
||||||
enclosingTestInstance.onRunProviderSet()
|
|
||||||
|
|
||||||
// Set the essential compiler property.
|
// Set the essential compiler property.
|
||||||
System.setProperty("kotlin.native.home", getOrCreateGlobalSettings().kotlinNativeHome.path)
|
System.setProperty("kotlin.native.home", getOrCreateGlobalSettings().kotlinNativeHome.path)
|
||||||
@@ -46,9 +46,15 @@ class NativeBlackBoxTestSupport : BeforeEachCallback {
|
|||||||
val enclosingTestClass = enclosingTestClass
|
val enclosingTestClass = enclosingTestClass
|
||||||
|
|
||||||
return root.getStore(NAMESPACE).getOrComputeIfAbsent(enclosingTestClass.sanitizedName) {
|
return root.getStore(NAMESPACE).getOrComputeIfAbsent(enclosingTestClass.sanitizedName) {
|
||||||
val (testSettings, testSettingsAnnotation) = computeTestSettings(enclosingTestClass)
|
val computedTestSettings = computeTestSettings(enclosingTestClass)
|
||||||
val requiredSettings: Set<KClass<*>> =
|
val requiredSettings: Set<KClass<*>> = buildSet {
|
||||||
/* Always required */ setOf(GlobalSettings::class, Binaries::class) +/* Custom */ testSettings.requiredSettings
|
// Always required:
|
||||||
|
this += GlobalSettings::class
|
||||||
|
this += Binaries::class
|
||||||
|
|
||||||
|
// Custom:
|
||||||
|
addAll(computedTestSettings.testSettings.requiredSettings)
|
||||||
|
}
|
||||||
|
|
||||||
val globalSettings = getOrCreateGlobalSettings()
|
val globalSettings = getOrCreateGlobalSettings()
|
||||||
|
|
||||||
@@ -62,7 +68,7 @@ class NativeBlackBoxTestSupport : BeforeEachCallback {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
val testCaseGroupProvider = createTestCaseGroupProvider(settings, testSettings, testSettingsAnnotation)
|
val testCaseGroupProvider = createTestCaseGroupProvider(settings, computedTestSettings, enclosingTestInstance)
|
||||||
|
|
||||||
TestRunProvider(settings, testCaseGroupProvider)
|
TestRunProvider(settings, testCaseGroupProvider)
|
||||||
}.cast()
|
}.cast()
|
||||||
@@ -80,11 +86,11 @@ class NativeBlackBoxTestSupport : BeforeEachCallback {
|
|||||||
GlobalSettings()
|
GlobalSettings()
|
||||||
}.cast()
|
}.cast()
|
||||||
|
|
||||||
private fun computeTestSettings(enclosingTestClass: Class<*>): Pair<TestSettings, Annotation?> {
|
private fun computeTestSettings(enclosingTestClass: Class<*>): ComputedTestSettings {
|
||||||
val findTestSettings: Class<*>.() -> Pair<TestSettings, Annotation>? = {
|
val findTestSettings: Class<*>.() -> ComputedTestSettings? = {
|
||||||
annotations.asSequence().mapNotNull { annotation ->
|
annotations.asSequence().mapNotNull { annotation ->
|
||||||
val testSettings = annotation.annotationClass.findAnnotation<TestSettings>() ?: return@mapNotNull null
|
val testSettings = annotation.annotationClass.findAnnotation<TestSettings>() ?: return@mapNotNull null
|
||||||
testSettings to annotation
|
ComputedTestSettings(testSettings, annotation)
|
||||||
}.firstOrNull()
|
}.firstOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,29 +153,29 @@ class NativeBlackBoxTestSupport : BeforeEachCallback {
|
|||||||
|
|
||||||
private fun createTestCaseGroupProvider(
|
private fun createTestCaseGroupProvider(
|
||||||
settings: Settings,
|
settings: Settings,
|
||||||
testSettings: TestSettings,
|
computedTestSettings: ComputedTestSettings,
|
||||||
testSettingsAnnotation: Annotation?
|
enclosingTestInstance: AbstractNativeBlackBoxTest
|
||||||
): TestCaseGroupProvider {
|
): TestCaseGroupProvider {
|
||||||
// Try to find a constructor that accepts the setting and the annotation.
|
val (testSettings: TestSettings, testSettingsAnnotation: Annotation?) = computedTestSettings
|
||||||
if (testSettingsAnnotation != null) {
|
val providerClass: KClass<out TestCaseGroupProvider> = testSettings.providerClass
|
||||||
val testSettingsAnnotationClass = testSettingsAnnotation.annotationClass
|
|
||||||
testSettings.providerClass.constructors.asSequence()
|
// Assumption: For simplicity’s sake TestCaseGroupProvider has just one constructor.
|
||||||
.forEach { c ->
|
val constructor = providerClass.constructors.singleOrNull()
|
||||||
val (p1, p2) = c.parameters.takeIf { it.size == 2 } ?: return@forEach
|
?: fail { "No or multiple constructors found for $providerClass" }
|
||||||
if (p1.hasTypeOf<Settings>() && p2.hasTypeOf(testSettingsAnnotationClass))
|
|
||||||
return c.call(settings, testSettingsAnnotation).cast()
|
val testSettingsAnnotationClass: KClass<out Annotation>? = testSettingsAnnotation?.annotationClass
|
||||||
}
|
val sourceTransformersProvider = enclosingTestInstance.safeAs<ExternalSourceTransformersProvider>()
|
||||||
|
|
||||||
|
val arguments = constructor.parameters.map { parameter ->
|
||||||
|
when {
|
||||||
|
parameter.hasTypeOf<Settings>() -> settings
|
||||||
|
sourceTransformersProvider != null && parameter.hasTypeOf<ExternalSourceTransformersProvider>() -> sourceTransformersProvider
|
||||||
|
testSettingsAnnotationClass != null && parameter.hasTypeOf(testSettingsAnnotationClass) -> testSettingsAnnotation
|
||||||
|
else -> fail { "Can't provide all arguments for $constructor" }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ... or the settings at least.
|
return constructor.call(*arguments.toTypedArray()).cast()
|
||||||
testSettings.providerClass.constructors.asSequence()
|
|
||||||
.forEach { c ->
|
|
||||||
val p = c.parameters.singleOrNull() ?: return@forEach
|
|
||||||
if (p.hasTypeOf<Settings>())
|
|
||||||
return c.call(settings).cast()
|
|
||||||
}
|
|
||||||
|
|
||||||
fail { "No suitable constructor for ${testSettings.providerClass}" }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private inline fun <reified T : Any> KParameter.hasTypeOf(): Boolean = hasTypeOf(T::class)
|
private inline fun <reified T : Any> KParameter.hasTypeOf(): Boolean = hasTypeOf(T::class)
|
||||||
@@ -178,3 +184,5 @@ class NativeBlackBoxTestSupport : BeforeEachCallback {
|
|||||||
private val TestMetadata.testRoot: File get() = getAbsoluteFile(localPath = value)
|
private val TestMetadata.testRoot: File get() = getAbsoluteFile(localPath = value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private data class ComputedTestSettings(val testSettings: TestSettings, val annotation: Annotation?)
|
||||||
|
|||||||
+1
-6
@@ -17,15 +17,14 @@ import org.jetbrains.kotlin.konan.blackboxtest.support.runner.LocalTestNameExtra
|
|||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.runner.LocalTestRunner
|
import org.jetbrains.kotlin.konan.blackboxtest.support.runner.LocalTestRunner
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.GlobalSettings
|
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.GlobalSettings
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.Settings
|
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.Settings
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.util.*
|
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.util.ThreadSafeCache
|
import org.jetbrains.kotlin.konan.blackboxtest.support.util.ThreadSafeCache
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.util.TreeNode
|
import org.jetbrains.kotlin.konan.blackboxtest.support.util.TreeNode
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.util.buildTree
|
import org.jetbrains.kotlin.konan.blackboxtest.support.util.buildTree
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.util.startsWith
|
||||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertTrue
|
import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertTrue
|
||||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions.fail
|
import org.jetbrains.kotlin.test.services.JUnit5Assertions.fail
|
||||||
import org.junit.jupiter.api.Assumptions.assumeTrue
|
import org.junit.jupiter.api.Assumptions.assumeTrue
|
||||||
import org.junit.jupiter.api.extension.ExtensionContext
|
import org.junit.jupiter.api.extension.ExtensionContext
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
internal class TestRunProvider(
|
internal class TestRunProvider(
|
||||||
private val settings: Settings,
|
private val settings: Settings,
|
||||||
@@ -35,10 +34,6 @@ internal class TestRunProvider(
|
|||||||
private val cachedCompilations = ThreadSafeCache<TestCompilationCacheKey, TestCompilation>()
|
private val cachedCompilations = ThreadSafeCache<TestCompilationCacheKey, TestCompilation>()
|
||||||
private val cachedTestNames = ThreadSafeCache<TestCompilationCacheKey, Collection<TestName>>()
|
private val cachedTestNames = ThreadSafeCache<TestCompilationCacheKey, Collection<TestName>>()
|
||||||
|
|
||||||
fun setProcessors(testDataFile: File, sourceTransformers: List<(String) -> String>) {
|
|
||||||
testCaseGroupProvider.setPreprocessors(testDataFile, sourceTransformers)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Produces a single [TestRun] per [TestCase]. So-called "one test case/one test run" mode.
|
* Produces a single [TestRun] per [TestCase]. So-called "one test case/one test run" mode.
|
||||||
*
|
*
|
||||||
|
|||||||
+19
-34
@@ -41,9 +41,9 @@ import org.jetbrains.kotlin.utils.addToStdlib.cast
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
internal class ExtTestCaseGroupProvider(
|
internal class ExtTestCaseGroupProvider(
|
||||||
private val settings: Settings
|
private val settings: Settings,
|
||||||
|
private val sourceTransformersProvider: ExternalSourceTransformersProvider
|
||||||
) : TestCaseGroupProvider, TestDisposable(parentDisposable = settings) {
|
) : TestCaseGroupProvider, TestDisposable(parentDisposable = settings) {
|
||||||
private val sourceTransformers: MutableMap<String, List<(String) -> String>> = mutableMapOf()
|
|
||||||
private val structureFactory = ExtTestDataFileStructureFactory(parentDisposable = this)
|
private val structureFactory = ExtTestDataFileStructureFactory(parentDisposable = this)
|
||||||
private val sharedModules = ThreadSafeCache<String, TestModule.Shared?>()
|
private val sharedModules = ThreadSafeCache<String, TestModule.Shared?>()
|
||||||
|
|
||||||
@@ -61,9 +61,7 @@ internal class ExtTestCaseGroupProvider(
|
|||||||
val testCases = mutableListOf<TestCase>()
|
val testCases = mutableListOf<TestCase>()
|
||||||
|
|
||||||
testDataFiles.forEach { testDataFile ->
|
testDataFiles.forEach { testDataFile ->
|
||||||
val extTestDataFile = ExtTestDataFile(
|
val extTestDataFile = ExtTestDataFile(settings, structureFactory, sourceTransformersProvider, testDataFile)
|
||||||
settings, structureFactory, testDataFile, sourceTransformers[testDataFile.canonicalPath] ?: listOf()
|
|
||||||
)
|
|
||||||
|
|
||||||
if (extTestDataFile.isRelevant)
|
if (extTestDataFile.isRelevant)
|
||||||
testCases += extTestDataFile.createTestCase(
|
testCases += extTestDataFile.createTestCase(
|
||||||
@@ -77,13 +75,6 @@ internal class ExtTestCaseGroupProvider(
|
|||||||
TestCaseGroup.Default(disabledTestCaseIds, testCases)
|
TestCaseGroup.Default(disabledTestCaseIds, testCases)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setPreprocessors(testDataDir: File, preprocessors: List<(String) -> String>) {
|
|
||||||
if (preprocessors.isNotEmpty())
|
|
||||||
sourceTransformers[testDataDir.canonicalPath] = preprocessors
|
|
||||||
else
|
|
||||||
sourceTransformers.remove(testDataDir.canonicalPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getTestCaseGroup(testCaseGroupId: TestCaseGroupId): TestCaseGroup? {
|
override fun getTestCaseGroup(testCaseGroupId: TestCaseGroupId): TestCaseGroup? {
|
||||||
assertNotDisposed()
|
assertNotDisposed()
|
||||||
assertTrue(testCaseGroupId is TestCaseGroupId.TestDataDir)
|
assertTrue(testCaseGroupId is TestCaseGroupId.TestDataDir)
|
||||||
@@ -133,15 +124,17 @@ internal class ExtTestCaseGroupProvider(
|
|||||||
private class ExtTestDataFile(
|
private class ExtTestDataFile(
|
||||||
private val settings: Settings,
|
private val settings: Settings,
|
||||||
structureFactory: ExtTestDataFileStructureFactory,
|
structureFactory: ExtTestDataFileStructureFactory,
|
||||||
private val testDataFile: File,
|
sourceTransformersProvider: ExternalSourceTransformersProvider,
|
||||||
sourceTransformers: List<(String) -> String>
|
private val testDataFile: File
|
||||||
) {
|
) {
|
||||||
private val structure by lazy {
|
private val structure by lazy {
|
||||||
structureFactory.ExtTestDataFileStructure(testDataFile, sourceTransformers) { line ->
|
val customTransformers: ExternalSourceTransformers? = sourceTransformersProvider.getSourceTransformers(testDataFile)
|
||||||
// Remove all diagnostic parameters from the text. Examples:
|
val allTransformers: ExternalSourceTransformers = if (customTransformers.isNullOrEmpty())
|
||||||
// <!NO_TAIL_CALLS_FOUND!>, <!NON_TAIL_RECURSIVE_CALL!>, <!>.
|
MANDATORY_SOURCE_TRANSFORMERS
|
||||||
line.replace(DIAGNOSTIC_REGEX) { match -> match.groupValues[1] }
|
else
|
||||||
}
|
MANDATORY_SOURCE_TRANSFORMERS + customTransformers
|
||||||
|
|
||||||
|
structureFactory.ExtTestDataFileStructure(testDataFile, allTransformers)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val testDataFileSettings by lazy {
|
private val testDataFileSettings by lazy {
|
||||||
@@ -633,14 +626,14 @@ private class ExtTestDataFile(
|
|||||||
private fun Directives.multiValues(key: String, predicate: (String) -> Boolean = { true }): Set<String> =
|
private fun Directives.multiValues(key: String, predicate: (String) -> Boolean = { true }): Set<String> =
|
||||||
listValues(key)?.flatMap { it.split(' ') }?.filter(predicate)?.toSet().orEmpty()
|
listValues(key)?.flatMap { it.split(' ') }?.filter(predicate)?.toSet().orEmpty()
|
||||||
|
|
||||||
private val DIAGNOSTIC_REGEX = Regex("<!.*?!>(.*?)<!>")
|
|
||||||
|
|
||||||
private const val THREAD_LOCAL_ANNOTATION = "@kotlin.native.ThreadLocal"
|
private const val THREAD_LOCAL_ANNOTATION = "@kotlin.native.ThreadLocal"
|
||||||
|
|
||||||
private val BOX_FUNCTION_NAME = Name.identifier("box")
|
private val BOX_FUNCTION_NAME = Name.identifier("box")
|
||||||
private val OPT_IN_ANNOTATION_NAME = Name.identifier("OptIn")
|
private val OPT_IN_ANNOTATION_NAME = Name.identifier("OptIn")
|
||||||
private val HELPERS_PACKAGE_NAME = Name.identifier("helpers")
|
private val HELPERS_PACKAGE_NAME = Name.identifier("helpers")
|
||||||
private val TYPE_OF_NAME = Name.identifier("typeOf")
|
private val TYPE_OF_NAME = Name.identifier("typeOf")
|
||||||
|
|
||||||
|
private val MANDATORY_SOURCE_TRANSFORMERS: ExternalSourceTransformers = listOf(DiagnosticsRemovingSourceTransformer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -659,16 +652,12 @@ private typealias SharedModuleCache = (moduleName: String, generator: SharedModu
|
|||||||
private class ExtTestDataFileStructureFactory(parentDisposable: Disposable) : TestDisposable(parentDisposable) {
|
private class ExtTestDataFileStructureFactory(parentDisposable: Disposable) : TestDisposable(parentDisposable) {
|
||||||
private val psiFactory = createPsiFactory(parentDisposable = this)
|
private val psiFactory = createPsiFactory(parentDisposable = this)
|
||||||
|
|
||||||
inner class ExtTestDataFileStructure(
|
inner class ExtTestDataFileStructure(originalTestDataFile: File, sourceTransformers: ExternalSourceTransformers) {
|
||||||
originalTestDataFile: File,
|
|
||||||
sourceTransformers: List<(String) -> String>,
|
|
||||||
initialCleanUpTransformation: (String) -> String
|
|
||||||
) {
|
|
||||||
init {
|
init {
|
||||||
assertNotDisposed()
|
assertNotDisposed()
|
||||||
}
|
}
|
||||||
|
|
||||||
private val filesAndModules = FilesAndModules(originalTestDataFile, initialCleanUpTransformation, sourceTransformers)
|
private val filesAndModules = FilesAndModules(originalTestDataFile, sourceTransformers)
|
||||||
|
|
||||||
val directives: Directives get() = filesAndModules.directives
|
val directives: Directives get() = filesAndModules.directives
|
||||||
|
|
||||||
@@ -824,16 +813,12 @@ private class ExtTestDataFileStructureFactory(parentDisposable: Disposable) : Te
|
|||||||
ExtTestModule(name, dependencies, friends)
|
ExtTestModule(name, dependencies, friends)
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class FilesAndModules(
|
private inner class FilesAndModules(originalTestDataFile: File, sourceTransformers: ExternalSourceTransformers) {
|
||||||
originalTestDataFile: File,
|
|
||||||
initialCleanUpTransformation: (String) -> String,
|
|
||||||
sourceTransformers: List<(String) -> String>
|
|
||||||
) {
|
|
||||||
private val testFileFactory = ExtTestFileFactory()
|
private val testFileFactory = ExtTestFileFactory()
|
||||||
|
|
||||||
private val generatedFiles = TestFiles.createTestFiles(
|
private val generatedFiles = TestFiles.createTestFiles(
|
||||||
/* testFileName = */ DEFAULT_FILE_NAME,
|
/* testFileName = */ DEFAULT_FILE_NAME,
|
||||||
/* expectedText = */ originalTestDataFile.applySourceTransformers(sourceTransformers),
|
/* expectedText = */ originalTestDataFile.readText(),
|
||||||
/* factory = */ testFileFactory,
|
/* factory = */ testFileFactory,
|
||||||
/* preserveLocations = */ true
|
/* preserveLocations = */ true
|
||||||
)
|
)
|
||||||
@@ -842,7 +827,7 @@ private class ExtTestDataFileStructureFactory(parentDisposable: Disposable) : Te
|
|||||||
// Clean up contents of every individual test file. Important: This should be done only after parsing testData file,
|
// Clean up contents of every individual test file. Important: This should be done only after parsing testData file,
|
||||||
// because parsing of testData file relies on certain directives which could be removed by the transformation.
|
// because parsing of testData file relies on certain directives which could be removed by the transformation.
|
||||||
generatedFiles.forEach { file ->
|
generatedFiles.forEach { file ->
|
||||||
file.text = file.text.lineSequence().joinToString("\n", transform = initialCleanUpTransformation)
|
file.text = sourceTransformers.fold(file.text) { source, transformer -> transformer(source) }
|
||||||
}
|
}
|
||||||
|
|
||||||
val modules = generatedFiles.map { it.module }.associateBy { it.name }
|
val modules = generatedFiles.map { it.module }.associateBy { it.name }
|
||||||
|
|||||||
-4
@@ -65,10 +65,6 @@ internal class PredefinedTestCaseGroupProvider(private val settings: Settings, a
|
|||||||
TestCaseGroup.Default(disabledTestCaseIds = emptySet(), testCases = listOf(testCase))
|
TestCaseGroup.Default(disabledTestCaseIds = emptySet(), testCases = listOf(testCase))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setPreprocessors(testDataDir: File, preprocessors: List<(String) -> String>) {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getTestCaseGroup(testCaseGroupId: TestCaseGroupId): TestCaseGroup? {
|
override fun getTestCaseGroup(testCaseGroupId: TestCaseGroupId): TestCaseGroup? {
|
||||||
assertTrue(testCaseGroupId is TestCaseGroupId.Named)
|
assertTrue(testCaseGroupId is TestCaseGroupId.Named)
|
||||||
return lazyTestCaseGroups[testCaseGroupId.cast()]
|
return lazyTestCaseGroups[testCaseGroupId.cast()]
|
||||||
|
|||||||
+2
-14
@@ -12,10 +12,6 @@ import org.jetbrains.kotlin.konan.blackboxtest.support.settings.GeneratedSources
|
|||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.Settings
|
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.Settings
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.TestRoots
|
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.TestRoots
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.util.*
|
import org.jetbrains.kotlin.konan.blackboxtest.support.util.*
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.util.DEFAULT_FILE_NAME
|
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.util.ThreadSafeFactory
|
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.util.computeGeneratedSourcesDir
|
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.util.computePackageName
|
|
||||||
import org.jetbrains.kotlin.test.directives.model.Directive
|
import org.jetbrains.kotlin.test.directives.model.Directive
|
||||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions
|
import org.jetbrains.kotlin.test.services.JUnit5Assertions
|
||||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertEquals
|
import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertEquals
|
||||||
@@ -45,13 +41,6 @@ internal class StandardTestCaseGroupProvider(private val settings: Settings) : T
|
|||||||
TestCaseGroup.Default(disabledTestCaseIds = emptySet(), testCases = testCases)
|
TestCaseGroup.Default(disabledTestCaseIds = emptySet(), testCases = testCases)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setPreprocessors(testDataDir: File, preprocessors: List<(String) -> String>) {
|
|
||||||
if (preprocessors.isNotEmpty())
|
|
||||||
sourceTransformers[testDataDir.canonicalPath] = preprocessors
|
|
||||||
else
|
|
||||||
sourceTransformers.remove(testDataDir.canonicalPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getTestCaseGroup(testCaseGroupId: TestCaseGroupId): TestCaseGroup? {
|
override fun getTestCaseGroup(testCaseGroupId: TestCaseGroupId): TestCaseGroup? {
|
||||||
assertTrue(testCaseGroupId is TestCaseGroupId.TestDataDir)
|
assertTrue(testCaseGroupId is TestCaseGroupId.TestDataDir)
|
||||||
return lazyTestCaseGroups[testCaseGroupId.cast()]
|
return lazyTestCaseGroups[testCaseGroupId.cast()]
|
||||||
@@ -101,7 +90,7 @@ internal class StandardTestCaseGroupProvider(private val settings: Settings) : T
|
|||||||
fun finishTestFile(forceFinish: Boolean, location: Location) {
|
fun finishTestFile(forceFinish: Boolean, location: Location) {
|
||||||
val needToFinish = forceFinish
|
val needToFinish = forceFinish
|
||||||
|| currentTestFileName != null
|
|| currentTestFileName != null
|
||||||
|| (currentTestFileName == null /*&& testFiles.isEmpty()*/ && currentTestFileText.hasAnythingButComments())
|
|| (/*currentTestFileName == null && testFiles.isEmpty() &&*/ currentTestFileText.hasAnythingButComments())
|
||||||
|
|
||||||
if (needToFinish) {
|
if (needToFinish) {
|
||||||
val fileName = currentTestFileName ?: DEFAULT_FILE_NAME
|
val fileName = currentTestFileName ?: DEFAULT_FILE_NAME
|
||||||
@@ -119,8 +108,7 @@ internal class StandardTestCaseGroupProvider(private val settings: Settings) : T
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val text = testDataFile.applySourceTransformers(sourceTransformers[testDataFile.canonicalPath] ?: listOf())
|
testDataFile.readLines().forEachIndexed { lineNumber, line ->
|
||||||
text.lines().forEachIndexed { lineNumber, line ->
|
|
||||||
val location = Location(testDataFile, lineNumber)
|
val location = Location(testDataFile, lineNumber)
|
||||||
val expectFileDirectiveAfterModuleDirective =
|
val expectFileDirectiveAfterModuleDirective =
|
||||||
lastParsedDirective == TestDirectives.MODULE // Only FILE directive may follow MODULE directive.
|
lastParsedDirective == TestDirectives.MODULE // Only FILE directive may follow MODULE directive.
|
||||||
|
|||||||
-8
@@ -7,15 +7,7 @@ package org.jetbrains.kotlin.konan.blackboxtest.support.group
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.TestCaseGroup
|
import org.jetbrains.kotlin.konan.blackboxtest.support.TestCaseGroup
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.TestCaseGroupId
|
import org.jetbrains.kotlin.konan.blackboxtest.support.TestCaseGroupId
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
internal interface TestCaseGroupProvider {
|
internal interface TestCaseGroupProvider {
|
||||||
fun setPreprocessors(testDataDir: File, preprocessors: List<(String) -> String>)
|
|
||||||
fun getTestCaseGroup(testCaseGroupId: TestCaseGroupId): TestCaseGroup?
|
fun getTestCaseGroup(testCaseGroupId: TestCaseGroupId): TestCaseGroup?
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun String.applySourceTransformers(sourceTransformers: List<(String) -> String>) =
|
|
||||||
sourceTransformers.fold(this) { source, transformer -> transformer(source) }
|
|
||||||
|
|
||||||
internal fun File.applySourceTransformers(sourceTransformers: List<(String) -> String>) =
|
|
||||||
readText().applySourceTransformers(sourceTransformers)
|
|
||||||
|
|||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* 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.util
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.AbstractExternalNativeBlackBoxTest
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This relates only to external codegen tests (see [AbstractExternalNativeBlackBoxTest]) that may have their own source transformers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
internal typealias ExternalSourceTransformer = (/* file contents */ String) -> /* patched file contents */ String
|
||||||
|
internal typealias ExternalSourceTransformers = List<ExternalSourceTransformer>
|
||||||
|
|
||||||
|
internal interface ExternalSourceTransformersProvider {
|
||||||
|
fun getSourceTransformers(testDataFile: File): ExternalSourceTransformers?
|
||||||
|
}
|
||||||
|
|
||||||
|
internal object DiagnosticsRemovingSourceTransformer : ExternalSourceTransformer {
|
||||||
|
override fun invoke(source: String) = source.lineSequence().joinToString("\n") { line ->
|
||||||
|
// Remove all diagnostic parameters from the text. Examples:
|
||||||
|
// <!NO_TAIL_CALLS_FOUND!>, <!NON_TAIL_RECURSIVE_CALL!>, <!>.
|
||||||
|
line.replace(DIAGNOSTIC_REGEX) { match -> match.groupValues[1] }
|
||||||
|
}
|
||||||
|
|
||||||
|
private val DIAGNOSTIC_REGEX = Regex("<!.*?!>(.*?)<!>")
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user