[Tests] Introduce replacing source transformer
This commit is contained in:
+1
-1
@@ -29,7 +29,7 @@ import org.jetbrains.kotlin.test.model.FrontendKinds
|
||||
import org.jetbrains.kotlin.test.model.ResultingArtifact
|
||||
import org.jetbrains.kotlin.test.model.TestFile
|
||||
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerTest
|
||||
import org.jetbrains.kotlin.test.runners.TransformersFunctions.Android
|
||||
import org.jetbrains.kotlin.test.utils.TransformersFunctions.Android
|
||||
import org.jetbrains.kotlin.test.services.*
|
||||
import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator
|
||||
import org.jetbrains.kotlin.test.services.configuration.JvmEnvironmentConfigurator
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.test.runners.codegen;
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
import org.jetbrains.kotlin.test.TargetBackend;
|
||||
import org.jetbrains.kotlin.test.runners.TransformersFunctions;
|
||||
import org.jetbrains.kotlin.test.utils.TransformersFunctions;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
+7
-10
@@ -51,7 +51,7 @@ class GlobalMetadataInfoHandler(
|
||||
infos += codeMetaInfos
|
||||
}
|
||||
|
||||
fun compareAllMetaDataInfos(expectedTransformer: ((String) -> String)?) {
|
||||
fun compareAllMetaDataInfos() {
|
||||
// TODO: adapt to multiple testdata files
|
||||
val moduleStructure = testServices.moduleStructure
|
||||
val builder = StringBuilder()
|
||||
@@ -66,18 +66,15 @@ class GlobalMetadataInfoHandler(
|
||||
codeMetaInfos,
|
||||
testServices.sourceFileProvider.getContentOfSourceFile(file)
|
||||
)
|
||||
builder.append(fileBuilder.stripAdditionalEmptyLines(file))
|
||||
val reverseTransformers = testServices.sourceFileProvider.preprocessors.filterIsInstance<ReversibleSourceFilePreprocessor>()
|
||||
val initialFileContent = fileBuilder.stripAdditionalEmptyLines(file).toString()
|
||||
val actualFileContent =
|
||||
reverseTransformers.foldRight(initialFileContent) { transformer, source -> transformer.revert(file, source) }
|
||||
builder.append(actualFileContent)
|
||||
}
|
||||
}
|
||||
val actualText = builder.toString()
|
||||
val expectedFile = moduleStructure.originalTestDataFiles.single()
|
||||
if (expectedTransformer != null) {
|
||||
val expectedContent = expectedFile.readText().let(expectedTransformer)
|
||||
val message = "Actual data differs from transformed content of file $expectedFile"
|
||||
testServices.assertions.assertEquals(expectedContent, actualText) { message }
|
||||
} else {
|
||||
testServices.assertions.assertEqualsToFile(expectedFile, actualText)
|
||||
}
|
||||
testServices.assertions.assertEqualsToFile(moduleStructure.originalTestDataFiles.single(), actualText)
|
||||
}
|
||||
|
||||
private fun StringBuilder.stripAdditionalEmptyLines(file: TestFile): CharSequence {
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
// WITH_STDLIB
|
||||
// WORKS_WHEN_VALUE_CLASS
|
||||
// !LANGUAGE: +ValueClasses
|
||||
// LANGUAGE: +ValueClasses
|
||||
|
||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
value class Result<T>(val a: Any?)
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.test.runners.codegen;
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
import org.jetbrains.kotlin.test.TargetBackend;
|
||||
import org.jetbrains.kotlin.test.runners.TransformersFunctions;
|
||||
import org.jetbrains.kotlin.test.utils.TransformersFunctions;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.test.runners.codegen;
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
import org.jetbrains.kotlin.test.TargetBackend;
|
||||
import org.jetbrains.kotlin.test.runners.TransformersFunctions;
|
||||
import org.jetbrains.kotlin.test.utils.TransformersFunctions;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
+8
-8
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.test.model.TestFile
|
||||
import org.jetbrains.kotlin.test.preprocessors.MetaInfosCleanupPreprocessor
|
||||
import org.jetbrains.kotlin.test.services.*
|
||||
import org.jetbrains.kotlin.test.services.impl.TemporaryDirectoryManagerImpl
|
||||
import org.jetbrains.kotlin.test.utils.ReplacingSourceTransformer
|
||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||
import org.jetbrains.kotlin.types.FlexibleTypeImpl
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
@@ -81,18 +82,17 @@ abstract class AbstractKotlinCompilerTest {
|
||||
testRunner(filePath, configuration).runTest(filePath)
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
open fun runTest(
|
||||
@TestDataFile filePath: String,
|
||||
actualContentModifier: (String) -> String,
|
||||
expectedContentModifier: ((String) -> String)? = actualContentModifier
|
||||
contentModifier: ReplacingSourceTransformer,
|
||||
) {
|
||||
class SourceTransformer(testServices: TestServices) : SourceFilePreprocessor(testServices) {
|
||||
override fun process(file: TestFile, content: String): String = content.let(actualContentModifier)
|
||||
class SourceTransformer(testServices: TestServices) : ReversibleSourceFilePreprocessor(testServices) {
|
||||
override fun process(file: TestFile, content: String): String = contentModifier.invokeForTestFile(file, content)
|
||||
override fun revert(file: TestFile, actualContent: String): String = contentModifier.revertForFile(file, actualContent)
|
||||
}
|
||||
testRunner(filePath) {
|
||||
configuration.let { it() } // property configuration, not method
|
||||
useSourcePreprocessor({ SourceTransformer(it) })
|
||||
}.runTest(filePath, expectedFileTransformer = expectedContentModifier)
|
||||
configuration.invoke(this)
|
||||
useSourcePreprocessor(::SourceTransformer)
|
||||
}.runTest(filePath)
|
||||
}
|
||||
}
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.test.utils
|
||||
|
||||
import org.jetbrains.kotlin.test.model.TestFile
|
||||
import java.util.function.Function
|
||||
|
||||
class ReplacingSourceTransformer(val from: String, val to: String) : Function<String, String>, (String) -> String {
|
||||
init {
|
||||
require(from.isNotEmpty()) { "Cannot replace empty string" }
|
||||
require(from.lines().size == 1) { "Multiline text cannot be replaced yet" }
|
||||
require(to.lines().size == from.lines().size) { "Number of lines cannot change" }
|
||||
}
|
||||
|
||||
private val replacements: MutableMap<String?, List<List<String>>> = mutableMapOf()
|
||||
|
||||
fun invokeForTestFile(testFile: TestFile?, source: String): String {
|
||||
val value = source.lines().map { it.split(from) }
|
||||
replacements[testFile?.relativePath] = value
|
||||
return value.joinToString("\n") { it.joinToString(to) }
|
||||
}
|
||||
|
||||
fun revertForFile(testFile: TestFile?, actual: String): String = actual.lines().mapIndexed { index, line ->
|
||||
val partition = replacements[testFile?.relativePath]?.elementAtOrNull(index) ?: return@mapIndexed line
|
||||
if (partition.joinToString(to) == line) partition.joinToString(from) else line
|
||||
}.joinToString("\n")
|
||||
|
||||
override fun apply(source: String): String = invokeForTestFile(null, source)
|
||||
override fun invoke(source: String): String = invokeForTestFile(null, source)
|
||||
}
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
* 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
|
||||
package org.jetbrains.kotlin.test.utils
|
||||
|
||||
import java.io.File
|
||||
|
||||
+1
-1
@@ -126,7 +126,7 @@ private class TestGeneratorImplInstance(
|
||||
for (clazz in testClassModels.flatMapTo(mutableSetOf()) { classModel -> classModel.imports }) {
|
||||
val realName = when (clazz) {
|
||||
TransformingTestMethodModel.TransformerFunctionsClassPlaceHolder::class.java ->
|
||||
"org.jetbrains.kotlin.test.runners.TransformersFunctions"
|
||||
"org.jetbrains.kotlin.test.utils.TransformersFunctions"
|
||||
else -> clazz.name
|
||||
}
|
||||
p.println("import $realName;")
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
import org.jetbrains.kotlin.test.TargetBackend;
|
||||
import org.jetbrains.kotlin.test.runners.TransformersFunctions;
|
||||
import org.jetbrains.kotlin.test.utils.TransformersFunctions;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
|
||||
+1
-1
@@ -131,7 +131,7 @@ object NewTestGeneratorImpl : TestGenerator(METHOD_GENERATORS) {
|
||||
for (clazz in testClassModels.flatMapTo(mutableSetOf()) { classModel -> classModel.imports }) {
|
||||
val realName = when (clazz) {
|
||||
TransformingTestMethodModel.TransformerFunctionsClassPlaceHolder::class.java ->
|
||||
"org.jetbrains.kotlin.test.runners.TransformersFunctions"
|
||||
"org.jetbrains.kotlin.test.utils.TransformersFunctions"
|
||||
else -> clazz.name
|
||||
}
|
||||
p.println("import $realName;")
|
||||
|
||||
+13
-6
@@ -23,14 +23,21 @@ object TransformingTestMethodGenerator : MethodGenerator<TransformingTestMethodM
|
||||
|
||||
override fun generateBody(method: TransformingTestMethodModel, p: Printer) {
|
||||
with(method) {
|
||||
if (registerInConstructor) {
|
||||
val lines = transformer.lines()
|
||||
val message = "There is a registered source transformer for the testcase"
|
||||
if (lines.size > 1) {
|
||||
p.println("/*")
|
||||
p.println(" $message:")
|
||||
lines.forEach { p.println(" $it") }
|
||||
p.println("*/")
|
||||
} else {
|
||||
val restOfLine = lines.firstOrNull()?.takeIf { it.isNotBlank() }?.let { ": $it" } ?: ""
|
||||
p.println("// $message$restOfLine")
|
||||
}
|
||||
}
|
||||
val filePath = KtTestUtil.getFilePath(source.file) + if (source.file.isDirectory) "/" else ""
|
||||
p.println("${RunTestMethodModel.METHOD_NAME}(\"$filePath\"${if (registerInConstructor) "" else ", $transformer"});")
|
||||
if (registerInConstructor) {
|
||||
p.println("/*")
|
||||
p.println(" There is a registered source transformer for the testcase:")
|
||||
transformer.lines().forEach { p.println(" $it") }
|
||||
p.println("*/")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
-1
@@ -10,9 +10,13 @@ import org.jetbrains.kotlin.test.TargetBackend
|
||||
import java.io.File
|
||||
import java.util.regex.Pattern
|
||||
|
||||
const val WORKS_WHEN_VALUE_CLASS = "WORKS_WHEN_VALUE_CLASS"
|
||||
// will replace OPTIONAL_JVM_INLINE_ANNOTATION with @JvmInline or remove it depending on compiler backend
|
||||
// for JVM IR both ones are generated according to value classes feature (https://github.com/Kotlin/KEEP/issues/237)
|
||||
|
||||
fun TestEntityModel.containsWithoutJvmInline(): Boolean = when (this) {
|
||||
is ClassModel -> methods.any { it.containsWithoutJvmInline() } || innerTestClasses.any { it.containsWithoutJvmInline() }
|
||||
is SimpleTestMethodModel -> file.isFile && file.readLines().any { Regex("^\\s*//\\s*WORKS_WHEN_VALUE_CLASS\\s*$").matches(it) }
|
||||
is SimpleTestMethodModel -> file.isFile && file.readLines().any { Regex("^\\s*//\\s*$WORKS_WHEN_VALUE_CLASS\\s*$").matches(it) }
|
||||
else -> false
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.js.test;
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
import org.jetbrains.kotlin.test.TargetBackend;
|
||||
import org.jetbrains.kotlin.test.runners.TransformersFunctions;
|
||||
import org.jetbrains.kotlin.test.utils.TransformersFunctions;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.js.test.ir;
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
import org.jetbrains.kotlin.test.TargetBackend;
|
||||
import org.jetbrains.kotlin.test.runners.TransformersFunctions;
|
||||
import org.jetbrains.kotlin.test.utils.TransformersFunctions;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
import org.jetbrains.kotlin.test.TargetBackend;
|
||||
import org.jetbrains.kotlin.test.runners.TransformersFunctions;
|
||||
import org.jetbrains.kotlin.test.utils.TransformersFunctions;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
|
||||
+2
-5
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.group.NativeBlackBoxTestCaseGroupProvider;
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.group.ExtTestCaseGroupProvider;
|
||||
import org.jetbrains.kotlin.test.TargetBackend;
|
||||
import org.jetbrains.kotlin.test.runners.TransformersFunctions;
|
||||
import org.jetbrains.kotlin.test.utils.TransformersFunctions;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -15705,11 +15705,8 @@ public class NativeExtBlackBoxTestGenerated extends AbstractNativeBlackBoxTest {
|
||||
@Test
|
||||
@TestMetadata("boxResultInlineClassOfConstructorCall.kt")
|
||||
public void testBoxResultInlineClassOfConstructorCall() throws Exception {
|
||||
// There is a registered source transformer for the testcase: TransformersFunctions::removeOptionalJvmInlineAnnotation
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxResultInlineClassOfConstructorCall.kt");
|
||||
/*
|
||||
There is a registered source transformer for the testcase:
|
||||
TransformersFunctions::removeOptionalJvmInlineAnnotation
|
||||
*/
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user