[Tests] Native tests runTest applies source transformers
This commit is contained in:
+16
@@ -208,6 +208,17 @@ object NewTestGeneratorImpl : TestGenerator(METHOD_GENERATORS) {
|
||||
|
||||
var first = true
|
||||
|
||||
val transformers = testClassModel.predefinedTransformers(false)
|
||||
|
||||
if (transformers.isNotEmpty()) {
|
||||
p.println("public ${testClassModel.name}() {")
|
||||
p.pushIndent()
|
||||
transformers.forEach { (path, transformer) -> p.println("register(\"$path\", $transformer);") }
|
||||
p.popIndent()
|
||||
p.println("}")
|
||||
first = false
|
||||
}
|
||||
|
||||
for (methodModel in testMethods) {
|
||||
if (methodModel is RunTestMethodModel) continue // should also skip its imports
|
||||
if (!methodModel.shouldBeGenerated()) continue // should also skip its imports
|
||||
@@ -274,4 +285,9 @@ object NewTestGeneratorImpl : TestGenerator(METHOD_GENERATORS) {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun TestClassModel.predefinedTransformers(recursive: Boolean): List<Pair<String, String>> =
|
||||
methods.mapNotNull { method ->
|
||||
(method as? TransformingTestMethodModel)?.takeIf { it.isNative }?.let { it.source.file.path to it.transformer }
|
||||
} + if (recursive) innerTestClasses.flatMap { it.predefinedTransformers(recursive) } else listOf()
|
||||
}
|
||||
|
||||
+1
-2
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.generators.util.TestGeneratorUtil
|
||||
import org.jetbrains.kotlin.generators.util.extractTagsFromDirectory
|
||||
import org.jetbrains.kotlin.test.TargetBackend
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
import java.util.regex.Pattern
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
@@ -96,7 +95,7 @@ class TestGroup(
|
||||
pattern: String = if (extension == null) """^([^\.]+)$""" else "^(.+)\\.$extension\$",
|
||||
excludedPattern: String? = null,
|
||||
testMethod: String = "doTest",
|
||||
singleClass: Boolean = false, // if true then tests from subdirectories will be flatten to single class
|
||||
singleClass: Boolean = false, // if true then tests from subdirectories will be flattened to single class
|
||||
testClassName: String? = null, // specific name for generated test class
|
||||
// which backend will be used in test. Specifying value may affect some test with
|
||||
// directives TARGET_BACKEND/DONT_TARGET_EXACT_BACKEND won't be generated
|
||||
|
||||
+7
-1
@@ -24,7 +24,13 @@ object TransformingTestMethodGenerator : MethodGenerator<TransformingTestMethodM
|
||||
override fun generateBody(method: TransformingTestMethodModel, p: Printer) {
|
||||
with(method) {
|
||||
val filePath = KtTestUtil.getFilePath(source.file) + if (source.file.isDirectory) "/" else ""
|
||||
p.println("${RunTestMethodModel.METHOD_NAME}(\"$filePath\", ${method.transformer});")
|
||||
p.println("${RunTestMethodModel.METHOD_NAME}(\"$filePath\"${if (isNative) "" else ", $transformer"});")
|
||||
if (isNative) {
|
||||
p.println("/*")
|
||||
p.println(" There is a registered source transformer for the testcase:")
|
||||
transformer.lines().forEach { p.println(" $it") }
|
||||
p.println("*/")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ open class SimpleTestMethodModel(
|
||||
val file: File,
|
||||
private val filenamePattern: Pattern,
|
||||
checkFilenameStartsLowerCase: Boolean?,
|
||||
protected val targetBackend: TargetBackend,
|
||||
internal val targetBackend: TargetBackend,
|
||||
private val skipIgnored: Boolean,
|
||||
override val tags: List<String>
|
||||
) : MethodModel {
|
||||
|
||||
+7
@@ -5,6 +5,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.generators.model
|
||||
|
||||
import org.jetbrains.kotlin.test.TargetBackend
|
||||
|
||||
abstract class TransformingTestMethodModel(val source: SimpleTestMethodModel, val transformer: String) : MethodModel {
|
||||
override val kind: MethodModel.Kind
|
||||
get() = Kind
|
||||
@@ -15,4 +17,9 @@ abstract class TransformingTestMethodModel(val source: SimpleTestMethodModel, va
|
||||
get() = source.tags
|
||||
|
||||
object Kind : MethodModel.Kind()
|
||||
|
||||
internal val isNative
|
||||
get() = source.targetBackend in listOf(TargetBackend.NATIVE, TargetBackend.ANY)
|
||||
// Native tests load sources before runTest call if more than 1 test is called, so we need to register it before.
|
||||
// Existing native tests specify target backend as ANY, setting it to NATIVE removes some previously generated tests.
|
||||
}
|
||||
+9
-1
@@ -15644,6 +15644,10 @@ public class NativeExtBlackBoxTestGenerated extends AbstractNativeBlackBoxTest {
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@NativeBlackBoxTestCaseGroupProvider(ExtTestCaseGroupProvider.class)
|
||||
public class InlineClasses {
|
||||
public InlineClasses() {
|
||||
register("compiler/testData/codegen/box/inlineClasses/boxResultInlineClassOfConstructorCall.kt", s -> s.replaceAll("OPTIONAL_JVM_INLINE_ANNOTATION", ""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllFilesPresentInInlineClasses() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/inlineClasses"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.NATIVE, true);
|
||||
@@ -15700,7 +15704,11 @@ public class NativeExtBlackBoxTestGenerated extends AbstractNativeBlackBoxTest {
|
||||
@Test
|
||||
@TestMetadata("boxResultInlineClassOfConstructorCall.kt")
|
||||
public void testBoxResultInlineClassOfConstructorCall_valueClasses() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxResultInlineClassOfConstructorCall.kt", s -> s.replaceAll("OPTIONAL_JVM_INLINE_ANNOTATION", ""));
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxResultInlineClassOfConstructorCall.kt");
|
||||
/*
|
||||
There is a registered source transformer for the testcase:
|
||||
s -> s.replaceAll("OPTIONAL_JVM_INLINE_ANNOTATION", "")
|
||||
*/
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+14
-3
@@ -10,14 +10,25 @@ import org.jetbrains.kotlin.konan.blackboxtest.support.NativeBlackBoxTestSupport
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.TestRunProvider
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.util.getAbsoluteFile
|
||||
import org.junit.jupiter.api.extension.ExtendWith
|
||||
import java.io.File
|
||||
|
||||
@ExtendWith(NativeBlackBoxTestSupport::class)
|
||||
abstract class AbstractNativeBlackBoxTest {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
@JvmOverloads
|
||||
fun runTest(@TestDataFile testDataFilePath: String, sourceTransformer: (String) -> String = { it }): Unit = with(testRunProvider) {
|
||||
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))
|
||||
|
||||
fun runTest(@TestDataFile testDataFilePath: String): Unit = with(testRunProvider) {
|
||||
val testDataFile = getAbsoluteFile(testDataFilePath)
|
||||
val testRun = getSingleTestRun(testDataFile)
|
||||
val testRunner = createRunner(testRun)
|
||||
|
||||
+1
@@ -30,6 +30,7 @@ class NativeBlackBoxTestSupport : BeforeEachCallback {
|
||||
*/
|
||||
override fun beforeEach(extensionContext: ExtensionContext): Unit = with(extensionContext) {
|
||||
enclosingTestInstance.testRunProvider = getOrCreateTestRunProvider()
|
||||
enclosingTestInstance.onRunProviderSet()
|
||||
|
||||
// Set the essential compiler property.
|
||||
System.setProperty("kotlin.native.home", getOrCreateGlobalEnvironment().kotlinNativeHome.path)
|
||||
|
||||
+4
@@ -24,6 +24,10 @@ internal class TestRunProvider(
|
||||
private val compilationFactory = TestCompilationFactory(environment)
|
||||
private val cachedCompilations = ThreadSafeCache<TestCompilationCacheKey, TestCompilation>()
|
||||
|
||||
fun setProcessors(testDataFile: File, sourceTransformers: List<(String) -> String>) {
|
||||
testCaseGroupProvider.setPreprocessors(testDataFile, sourceTransformers)
|
||||
}
|
||||
|
||||
fun getSingleTestRun(testDataFile: File): TestRun {
|
||||
environment.assertNotDisposed()
|
||||
|
||||
|
||||
+26
-7
@@ -38,6 +38,7 @@ import java.io.File
|
||||
internal class ExtTestCaseGroupProvider(
|
||||
private val environment: TestEnvironment
|
||||
) : TestCaseGroupProvider, TestDisposable(parentDisposable = environment) {
|
||||
private val sourceTransformers: MutableMap<String, List<(String) -> String>> = mutableMapOf()
|
||||
private val structureFactory = ExtTestDataFileStructureFactory(parentDisposable = this)
|
||||
private val sharedModules = ThreadSafeCache<String, TestModule.Shared?>()
|
||||
|
||||
@@ -55,7 +56,9 @@ internal class ExtTestCaseGroupProvider(
|
||||
val testCases = mutableListOf<TestCase>()
|
||||
|
||||
testDataFiles.forEach { testDataFile ->
|
||||
val extTestDataFile = ExtTestDataFile(environment, structureFactory, testDataFile)
|
||||
val extTestDataFile = ExtTestDataFile(
|
||||
environment, structureFactory, testDataFile, sourceTransformers[testDataFile.canonicalPath] ?: listOf()
|
||||
)
|
||||
|
||||
if (extTestDataFile.isRelevant)
|
||||
testCases += extTestDataFile.createTestCase(
|
||||
@@ -69,6 +72,13 @@ internal class ExtTestCaseGroupProvider(
|
||||
TestCaseGroup.Default(disabledTestDataFileNames, 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(testDataDir: File): TestCaseGroup? {
|
||||
assertNotDisposed()
|
||||
return lazyTestCaseGroups[testDataDir]
|
||||
@@ -117,10 +127,11 @@ internal class ExtTestCaseGroupProvider(
|
||||
private class ExtTestDataFile(
|
||||
private val environment: TestEnvironment,
|
||||
structureFactory: ExtTestDataFileStructureFactory,
|
||||
private val testDataFile: File
|
||||
private val testDataFile: File,
|
||||
sourceTransformers: List<(String) -> String>
|
||||
) {
|
||||
private val structure by lazy {
|
||||
structureFactory.ExtTestDataFileStructure(testDataFile) { line ->
|
||||
structureFactory.ExtTestDataFileStructure(testDataFile, sourceTransformers) { 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] }
|
||||
@@ -642,12 +653,16 @@ private typealias SharedModuleCache = (moduleName: String, generator: SharedModu
|
||||
private class ExtTestDataFileStructureFactory(parentDisposable: Disposable) : TestDisposable(parentDisposable) {
|
||||
private val psiFactory = createPsiFactory(parentDisposable = this)
|
||||
|
||||
inner class ExtTestDataFileStructure(originalTestDataFile: File, initialCleanUpTransformation: (String) -> String) {
|
||||
inner class ExtTestDataFileStructure(
|
||||
originalTestDataFile: File,
|
||||
sourceTransformers: List<(String) -> String>,
|
||||
initialCleanUpTransformation: (String) -> String
|
||||
) {
|
||||
init {
|
||||
assertNotDisposed()
|
||||
}
|
||||
|
||||
private val filesAndModules = FilesAndModules(originalTestDataFile, initialCleanUpTransformation)
|
||||
private val filesAndModules = FilesAndModules(originalTestDataFile, initialCleanUpTransformation, sourceTransformers)
|
||||
|
||||
val directives: Directives get() = filesAndModules.directives
|
||||
|
||||
@@ -803,12 +818,16 @@ private class ExtTestDataFileStructureFactory(parentDisposable: Disposable) : Te
|
||||
ExtTestModule(name, dependencies, friends)
|
||||
}
|
||||
|
||||
private inner class FilesAndModules(originalTestDataFile: File, initialCleanUpTransformation: (String) -> String) {
|
||||
private inner class FilesAndModules(
|
||||
originalTestDataFile: File,
|
||||
initialCleanUpTransformation: (String) -> String,
|
||||
sourceTransformers: List<(String) -> String>
|
||||
) {
|
||||
private val testFileFactory = ExtTestFileFactory()
|
||||
|
||||
private val generatedFiles = TestFiles.createTestFiles(
|
||||
/* testFileName = */ DEFAULT_FILE_NAME,
|
||||
/* expectedText = */ originalTestDataFile.readText(),
|
||||
/* expectedText = */ originalTestDataFile.applySourceTransformers(sourceTransformers),
|
||||
/* factory = */ testFileFactory,
|
||||
/* preserveLocations = */ true
|
||||
)
|
||||
|
||||
+11
-1
@@ -21,6 +21,8 @@ import org.jetbrains.kotlin.test.services.impl.RegisteredDirectivesParser
|
||||
import java.io.File
|
||||
|
||||
internal class StandardTestCaseGroupProvider(private val environment: TestEnvironment) : TestCaseGroupProvider {
|
||||
val sourceTransformers: MutableMap<String, List<(String) -> String>> = mutableMapOf()
|
||||
|
||||
// Load test cases in groups on demand.
|
||||
private val lazyTestCaseGroups = ThreadSafeFactory<File, TestCaseGroup?> { testDataDir ->
|
||||
val testDataFiles = testDataDir.listFiles()
|
||||
@@ -36,6 +38,13 @@ internal class StandardTestCaseGroupProvider(private val environment: TestEnviro
|
||||
TestCaseGroup.Default(disabledTestDataFileNames = 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(testDataDir: File) = lazyTestCaseGroups[testDataDir]
|
||||
|
||||
private fun createTestCase(testDataFile: File): TestCase {
|
||||
@@ -100,7 +109,8 @@ internal class StandardTestCaseGroupProvider(private val environment: TestEnviro
|
||||
}
|
||||
}
|
||||
|
||||
testDataFile.readLines().forEachIndexed { lineNumber, line ->
|
||||
val text = testDataFile.applySourceTransformers(sourceTransformers[testDataFile.canonicalPath] ?: listOf())
|
||||
text.lines().forEachIndexed { lineNumber, line ->
|
||||
val location = Location(testDataFile, lineNumber)
|
||||
val expectFileDirectiveAfterModuleDirective =
|
||||
lastParsedDirective == TestDirectives.MODULE // Only FILE directive may follow MODULE directive.
|
||||
|
||||
+7
@@ -9,5 +9,12 @@ import org.jetbrains.kotlin.konan.blackboxtest.support.TestCaseGroup
|
||||
import java.io.File
|
||||
|
||||
internal interface TestCaseGroupProvider {
|
||||
fun setPreprocessors(testDataDir: File, preprocessors: List<(String) -> String>)
|
||||
fun getTestCaseGroup(testDataDir: File): 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)
|
||||
|
||||
Reference in New Issue
Block a user