[TEST] Invert dependency between :test-generator and :tests-common modules

This is needed to provide ability for declaring new implementations of
  test generators, based on existing infrastructure, which won't add
  dependency on :compiler:tests-common

Also this commit removes implicit dependency on :compiler:tests-common
  from :compiler:tests-common-new
This commit is contained in:
Dmitriy Novozhilov
2020-12-14 13:37:33 +03:00
parent bc7e18fb8a
commit d15c7861b2
27 changed files with 59 additions and 88 deletions
@@ -6,7 +6,7 @@
package org.jetbrains.kotlin.generators.tests
import org.jetbrains.kotlin.codegen.ir.AbstractCompileKotlinAgainstKlibTest
import org.jetbrains.kotlin.generators.generateTestGroupSuite
import org.jetbrains.kotlin.generators.impl.generateTestGroupSuite
import org.jetbrains.kotlin.test.TargetBackend
fun main(args: Array<String>) {
@@ -14,7 +14,7 @@ import org.junit.jupiter.api.Test;
import java.io.File;
import java.util.regex.Pattern;
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
/** This class is generated by {@link GenerateNewCompilerTests.kt}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
@Nested
@@ -14,7 +14,7 @@ import org.junit.jupiter.api.Test;
import java.io.File;
import java.util.regex.Pattern;
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
/** This class is generated by {@link GenerateNewCompilerTests.kt}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("compiler/testData/diagnostics/tests/javac")
@TestDataPath("$PROJECT_ROOT")
@@ -14,7 +14,7 @@ import org.junit.jupiter.api.Test;
import java.io.File;
import java.util.regex.Pattern;
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
/** This class is generated by {@link GenerateNewCompilerTests.kt}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
@Nested
@@ -14,7 +14,7 @@ import org.junit.jupiter.api.Test;
import java.io.File;
import java.util.regex.Pattern;
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
/** This class is generated by {@link GenerateNewCompilerTests.kt}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosticTest {
@Nested
@@ -36,3 +36,5 @@ fun main(args: Array<String>) {
}
}
}
const val TEST_GENERATOR_NAME = "GenerateNewCompilerTests.kt"
@@ -8,10 +8,11 @@ package org.jetbrains.kotlin.test.generators
import org.jetbrains.kotlin.generators.MethodGenerator
import org.jetbrains.kotlin.generators.TestGenerator
import org.jetbrains.kotlin.generators.TestGroup
import org.jetbrains.kotlin.generators.impl.*
import org.jetbrains.kotlin.generators.impl.SimpleTestClassModelTestAllFilesPresentMethodGenerator
import org.jetbrains.kotlin.generators.impl.SimpleTestMethodGenerator
import org.jetbrains.kotlin.generators.impl.SingleClassTestModelAllFilesPresentedMethodGenerator
import org.jetbrains.kotlin.generators.model.*
import org.jetbrains.kotlin.generators.util.GeneratorsFileUtil
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.TestMetadata
import org.jetbrains.kotlin.test.util.KtTestUtil
import org.jetbrains.kotlin.utils.Printer
@@ -22,7 +23,6 @@ import java.io.IOException
import java.util.*
private val METHOD_GENERATORS = listOf(
RunTestMethodGenerator,
SimpleTestClassModelTestAllFilesPresentMethodGenerator,
SimpleTestMethodGenerator,
SingleClassTestModelAllFilesPresentedMethodGenerator
@@ -82,15 +82,8 @@ object NewTestGeneratorImpl : TestGenerator(METHOD_GENERATORS) {
suiteTestClassFqName: String,
baseTestClassFqName: String,
private val testClassModels: Collection<TestClassModel>,
methodGenerators: Map<MethodModel.Kind, MethodGenerator<*>>
private val methodGenerators: Map<MethodModel.Kind, MethodGenerator<*>>
) {
private val methodGenerators = methodGenerators.toMutableMap().apply {
val newGenerator = this.computeIfPresent(CoroutinesTestMethodModel.Kind) { _, _ ->
SimpleTestMethodGenerator
} ?: return@apply
this[CoroutinesTestMethodModel.Kind] = newGenerator
}
private val baseTestClassPackage: String = baseTestClassFqName.substringBeforeLast('.', "")
private val baseTestClassName: String = baseTestClassFqName.substringAfterLast('.', baseTestClassFqName)
private val suiteClassPackage: String = suiteTestClassFqName.substringBeforeLast('.', baseTestClassPackage)
@@ -148,7 +141,7 @@ object NewTestGeneratorImpl : TestGenerator(METHOD_GENERATORS) {
p.println("import java.io.File;")
p.println("import java.util.regex.Pattern;")
p.println()
p.println("/** This class is generated by {@link ", KotlinTestUtils.TEST_GENERATOR_NAME, "}. DO NOT MODIFY MANUALLY */")
p.println("/** This class is generated by {@link ", TEST_GENERATOR_NAME, "}. DO NOT MODIFY MANUALLY */")
p.generateSuppressAllWarnings()
+2
View File
@@ -45,6 +45,8 @@ dependencies {
testCompile(project(":js:js.translator"))
testCompile(project(":native:frontend.native"))
testCompileOnly(project(":plugins:android-extensions-compiler"))
testApi(projectTests(":generators:test-generator"))
testCompile(projectTests(":compiler:tests-classic-compiler-utils"))
testCompile(project(":kotlin-test:kotlin-test-jvm"))
testCompile(projectTests(":compiler:tests-common-jvm6"))
testCompile(project(":kotlin-scripting-compiler-impl"))
@@ -0,0 +1,35 @@
/*
* 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.generators.impl
import org.jetbrains.kotlin.generators.model.MethodModel
import org.jetbrains.kotlin.generators.MethodGenerator
import org.jetbrains.kotlin.generators.model.RunTestMethodModel
import org.jetbrains.kotlin.test.TargetBackend
import org.jetbrains.kotlin.utils.Printer
object RunTestMethodGenerator : MethodGenerator<RunTestMethodModel>() {
override val kind: MethodModel.Kind
get() = RunTestMethodModel.Kind
override fun generateBody(method: RunTestMethodModel, p: Printer) {
with(method) {
if (!isWithTargetBackend()) {
p.println("KotlinTestUtils.${method.testRunnerMethodName}(this::$testMethodName, this, testDataFilePath);")
} else {
val className = TargetBackend::class.java.simpleName
val additionalArguments = if (additionalRunnerArguments.isNotEmpty())
additionalRunnerArguments.joinToString(separator = ", ", prefix = ", ")
else ""
p.println("KotlinTestUtils.$testRunnerMethodName(this::$testMethodName, $className.$targetBackend, testDataFilePath$additionalArguments);")
}
}
}
override fun generateSignature(method: RunTestMethodModel, p: Printer) {
p.print("private void ${method.name}(String testDataFilePath) throws Exception")
}
}
@@ -0,0 +1,33 @@
/*
* 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.generators.impl
import org.jetbrains.kotlin.generators.InconsistencyChecker
import org.jetbrains.kotlin.generators.InconsistencyChecker.Companion.inconsistencyChecker
import org.jetbrains.kotlin.generators.TestGroupSuite
import org.jetbrains.kotlin.generators.testGroupSuite
fun generateTestGroupSuite(
args: Array<String>,
init: TestGroupSuite.() -> Unit
) {
generateTestGroupSuite(InconsistencyChecker.hasDryRunArg(args), init)
}
fun generateTestGroupSuite(
dryRun: Boolean = false,
init: TestGroupSuite.() -> Unit
) {
val suite = testGroupSuite(init)
for (testGroup in suite.testGroups) {
for (testClass in testGroup.testClasses) {
val (changed, testSourceFilePath) = TestGeneratorImpl.generateAndSave(testClass, dryRun)
if (changed) {
inconsistencyChecker(dryRun).add(testSourceFilePath)
}
}
}
}
@@ -0,0 +1,265 @@
/*
* 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.generators.impl
import org.jetbrains.kotlin.generators.MethodGenerator
import org.jetbrains.kotlin.generators.TestGenerator
import org.jetbrains.kotlin.generators.TestGroup
import org.jetbrains.kotlin.generators.model.*
import org.jetbrains.kotlin.generators.util.GeneratorsFileUtil
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.TestMetadata
import org.jetbrains.kotlin.test.util.KtTestUtil
import org.jetbrains.kotlin.utils.Printer
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.BlockJUnit4ClassRunner
import java.io.File
import java.io.IOException
import java.util.*
private val METHOD_GENERATORS = listOf(
RunTestMethodGenerator,
SimpleTestClassModelTestAllFilesPresentMethodGenerator,
SimpleTestMethodGenerator,
SingleClassTestModelAllFilesPresentedMethodGenerator
)
object TestGeneratorImpl : TestGenerator(METHOD_GENERATORS) {
override fun generateAndSave(testClass: TestGroup.TestClass, dryRun: Boolean): GenerationResult {
val generatorInstance = TestGeneratorImplInstance(
testClass.baseDir,
testClass.suiteTestClassName,
testClass.baseTestClassName,
testClass.testModels,
testClass.useJunit4,
methodGenerators
)
return generatorInstance.generateAndSave(dryRun)
}
}
private class TestGeneratorImplInstance(
baseDir: String,
suiteTestClassFqName: String,
baseTestClassFqName: String,
private val testClassModels: Collection<TestClassModel>,
private val useJunit4: Boolean,
private val methodGenerators: Map<MethodModel.Kind, MethodGenerator<*>>
) {
companion object {
private val GENERATED_FILES = HashSet<String>()
private val RUNNER = JUnit3RunnerWithInners::class.java
private val JUNIT4_RUNNER = BlockJUnit4ClassRunner::class.java
private fun generateMetadata(p: Printer, testDataSource: TestEntityModel) {
val dataString = testDataSource.dataString
if (dataString != null) {
p.println("@TestMetadata(\"", dataString, "\")")
}
}
private fun generateTestDataPath(p: Printer, testClassModel: TestClassModel) {
val dataPathRoot = testClassModel.dataPathRoot
if (dataPathRoot != null) {
p.println("@TestDataPath(\"", dataPathRoot, "\")")
}
}
private fun generateParameterAnnotations(p: Printer, testClassModel: TestClassModel) {
for (annotationModel in testClassModel.annotations) {
annotationModel.generate(p)
p.println()
}
}
private fun generateSuppressAllWarnings(p: Printer) {
p.println("@SuppressWarnings(\"all\")")
}
}
private val baseTestClassPackage: String = baseTestClassFqName.substringBeforeLast('.', "")
private val baseTestClassName: String = baseTestClassFqName.substringAfterLast('.', baseTestClassFqName)
private val suiteClassPackage: String = suiteTestClassFqName.substringBeforeLast('.', baseTestClassPackage)
private val suiteClassName: String = suiteTestClassFqName.substringAfterLast('.', suiteTestClassFqName)
private val testSourceFilePath: String = baseDir + "/" + this.suiteClassPackage.replace(".", "/") + "/" + this.suiteClassName + ".java"
init {
if (!GENERATED_FILES.add(testSourceFilePath)) {
throw IllegalArgumentException("Same test file already generated in current session: $testSourceFilePath")
}
}
@Throws(IOException::class)
fun generateAndSave(dryRun: Boolean): TestGenerator.GenerationResult {
val generatedCode = generate()
val testSourceFile = File(testSourceFilePath)
val changed =
GeneratorsFileUtil.isFileContentChangedIgnoringLineSeparators(testSourceFile, generatedCode)
if (!dryRun) {
GeneratorsFileUtil.writeFileIfContentChanged(testSourceFile, generatedCode, false)
}
return TestGenerator.GenerationResult(changed, testSourceFilePath)
}
private fun generate(): String {
val out = StringBuilder()
val p = Printer(out)
val year = GregorianCalendar()[Calendar.YEAR]
p.println(
"""/*
| * Copyright 2010-$year 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.
| */
|""".trimMargin()
)
p.println("package ", suiteClassPackage, ";")
p.println()
p.println("import com.intellij.testFramework.TestDataPath;")
if (!useJunit4) {
p.println("import ", RUNNER.canonicalName, ";")
}
p.println("import " + KotlinTestUtils::class.java.canonicalName + ";")
p.println("import " + KtTestUtil::class.java.canonicalName + ";")
for (clazz in testClassModels.flatMapTo(mutableSetOf()) { classModel -> classModel.imports }) {
p.println("import ${clazz.name};")
}
if (suiteClassPackage != baseTestClassPackage) {
p.println("import $baseTestClassPackage.$baseTestClassName;")
}
p.println("import " + TestMetadata::class.java.canonicalName + ";")
p.println("import " + RunWith::class.java.canonicalName + ";")
if (useJunit4) {
p.println("import " + BlockJUnit4ClassRunner::class.java.canonicalName + ";")
p.println("import " + Test::class.java.canonicalName + ";")
}
p.println()
p.println("import java.io.File;")
p.println("import java.util.regex.Pattern;")
p.println()
p.println("/** This class is generated by {@link ", KotlinTestUtils.TEST_GENERATOR_NAME, "}. DO NOT MODIFY MANUALLY */")
generateSuppressAllWarnings(p)
val model: TestClassModel
if (testClassModels.size == 1) {
model = object : DelegatingTestClassModel(testClassModels.single()) {
override val name: String
get() = suiteClassName
}
} else {
model = object : TestClassModel() {
override val innerTestClasses: Collection<TestClassModel>
get() = testClassModels
override val methods: Collection<MethodModel>
get() = emptyList()
override val isEmpty: Boolean
get() = false
override val name: String
get() = suiteClassName
override val dataString: String?
get() = null
override val dataPathRoot: String?
get() = null
override val annotations: Collection<AnnotationModel>
get() = emptyList()
override val imports: Set<Class<*>>
get() = super.imports
}
}
generateTestClass(p, model, false)
return out.toString()
}
private fun generateTestClass(p: Printer, testClassModel: TestClassModel, isStatic: Boolean) {
val staticModifier = if (isStatic) "static " else ""
generateMetadata(p, testClassModel)
generateTestDataPath(p, testClassModel)
generateParameterAnnotations(p, testClassModel)
p.println("@RunWith(", if (useJunit4) JUNIT4_RUNNER.simpleName else RUNNER.simpleName, ".class)")
p.println("public " + staticModifier + "class ", testClassModel.name, " extends ", baseTestClassName, " {")
p.pushIndent()
val testMethods = testClassModel.methods
val innerTestClasses = testClassModel.innerTestClasses
var first = true
for (methodModel in testMethods) {
if (!methodModel.shouldBeGenerated()) continue
if (first) {
first = false
} else {
p.println()
}
generateTestMethod(p, methodModel, useJunit4)
}
for (innerTestClass in innerTestClasses) {
if (!innerTestClass.isEmpty) {
if (first) {
first = false
} else {
p.println()
}
generateTestClass(p, innerTestClass, true)
}
}
p.popIndent()
p.println("}")
}
private fun generateTestMethod(p: Printer, methodModel: MethodModel, useJunit4: Boolean) {
if (useJunit4 && (methodModel !is RunTestMethodModel)) {
p.println("@Test")
}
val generator = methodGenerators.getValue(methodModel.kind)
generateMetadata(p, methodModel)
generator.hackyGenerateSignature(methodModel, p)
p.printWithNoIndent(" {")
p.println()
p.pushIndent()
generator.hackyGenerateBody(methodModel, p)
p.popIndent()
p.println("}")
}
private fun <T : MethodModel> MethodGenerator<T>.hackyGenerateBody(method: MethodModel, p: Printer) {
@Suppress("UNCHECKED_CAST")
generateBody(method as T, p)
}
private fun <T : MethodModel> MethodGenerator<T>.hackyGenerateSignature(method: MethodModel, p: Printer) {
@Suppress("UNCHECKED_CAST")
generateSignature(method as T, p)
}
}
@@ -15,7 +15,7 @@ import org.junit.runner.RunWith;
import java.io.File;
import java.util.regex.Pattern;
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
/** This class is generated by {@link GenerateNewCompilerTests.kt}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("compiler/testData/diagnostics/testsWithJsStdLib")
@TestDataPath("$PROJECT_ROOT")
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.checkers.AbstractForeignJava8AnnotationsNoAnnotation
import org.jetbrains.kotlin.checkers.AbstractForeignJava8AnnotationsTest
import org.jetbrains.kotlin.checkers.AbstractJspecifyAnnotationsTest
import org.jetbrains.kotlin.checkers.javac.AbstractJavacForeignJava8AnnotationsTest
import org.jetbrains.kotlin.generators.generateTestGroupSuite
import org.jetbrains.kotlin.generators.impl.generateTestGroupSuite
import org.jetbrains.kotlin.jvm.compiler.AbstractLoadJava8Test
import org.jetbrains.kotlin.jvm.compiler.AbstractLoadJava8WithPsiClassReadingTest
import org.jetbrains.kotlin.jvm.compiler.javac.AbstractLoadJava8UsingJavacTest
@@ -5,7 +5,7 @@
package org.jetbrains.kotlin.spec.utils.tasks
import org.jetbrains.kotlin.generators.generateTestGroupSuite
import org.jetbrains.kotlin.generators.impl.generateTestGroupSuite
import org.jetbrains.kotlin.spec.checkers.AbstractDiagnosticsTestSpec
import org.jetbrains.kotlin.spec.checkers.AbstractFirDiagnosticsTestSpec
import org.jetbrains.kotlin.spec.codegen.AbstractBlackBoxCodegenTestSpec
@@ -29,7 +29,7 @@ import org.jetbrains.kotlin.fir.java.AbstractFirOldFrontendLightClassesTest
import org.jetbrains.kotlin.fir.java.AbstractFirTypeEnhancementTest
import org.jetbrains.kotlin.fir.java.AbstractOwnFirTypeEnhancementTest
import org.jetbrains.kotlin.fir.lightTree.AbstractLightTree2FirConverterTestCase
import org.jetbrains.kotlin.generators.generateTestGroupSuite
import org.jetbrains.kotlin.generators.impl.generateTestGroupSuite
import org.jetbrains.kotlin.generators.util.TestGeneratorUtil.KT_OR_KTS_WITHOUT_DOTS_IN_NAME
import org.jetbrains.kotlin.generators.util.TestGeneratorUtil.KT_WITHOUT_DOTS_IN_NAME
import org.jetbrains.kotlin.integration.AbstractAntTaskTest