diff --git a/generators/test-generator/tests/org/jetbrains/kotlin/generators/tests/generator/TestGenerationDSL.kt b/generators/test-generator/tests/org/jetbrains/kotlin/generators/tests/generator/TestGenerationDSL.kt index 1b86ade0fda..9e5fa863078 100644 --- a/generators/test-generator/tests/org/jetbrains/kotlin/generators/tests/generator/TestGenerationDSL.kt +++ b/generators/test-generator/tests/org/jetbrains/kotlin/generators/tests/generator/TestGenerationDSL.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.generators.tests.generator import junit.framework.TestCase import org.jetbrains.kotlin.generators.tests.generator.InconsistencyChecker.Companion.hasDryRunArg import org.jetbrains.kotlin.generators.tests.generator.InconsistencyChecker.Companion.inconsistencyChecker +import org.jetbrains.kotlin.generators.tests.generator.generators.TestGenerator import org.jetbrains.kotlin.generators.tests.generator.generators.impl.* import org.jetbrains.kotlin.test.TargetBackend import java.io.File @@ -38,23 +39,16 @@ class TestGroup( annotations: List = emptyList(), init: TestClass.() -> Unit ) { - val testGenerator = TestGenerator( + val generationData = TestGenerator.GenerationData( testsRoot, suiteTestClassName, baseTestClassName, TestClass(annotations).apply(init).testModels, useJunit4, - methodGenerators = listOf( - CoroutinesTestMethodGenerator, - RunTestMethodGenerator, - RunTestMethodWithPackageReplacementGenerator, - SimpleTestClassModelTestAllFilesPresentMethodGenerator, - SimpleTestMethodGenerator, - SingleClassTestModelAllFilesPresentedMethodGenerator - ) ) - if (testGenerator.generateAndSave(dryRun)) { - inconsistencyChecker(dryRun).add(testGenerator.testSourceFilePath) + val (changed, testSourceFilePath) = TestGeneratorImpl.generateAndSave(generationData, dryRun) + if (changed) { + inconsistencyChecker(dryRun).add(testSourceFilePath) } } @@ -69,7 +63,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 flattern to single class + singleClass: Boolean = false, // if true then tests from subdirectories will be flatten 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 diff --git a/generators/test-generator/tests/org/jetbrains/kotlin/generators/tests/generator/generators/MethodGenerator.kt b/generators/test-generator/tests/org/jetbrains/kotlin/generators/tests/generator/generators/MethodGenerator.kt index 7a3f60da356..7b8bbac5fe0 100644 --- a/generators/test-generator/tests/org/jetbrains/kotlin/generators/tests/generator/generators/MethodGenerator.kt +++ b/generators/test-generator/tests/org/jetbrains/kotlin/generators/tests/generator/generators/MethodGenerator.kt @@ -17,6 +17,6 @@ abstract class MethodGenerator { abstract val kind: MethodModel.Kind - abstract fun generateSignature(method: @UnsafeVariance T, p: Printer) - abstract fun generateBody(method: @UnsafeVariance T, p: Printer) + abstract fun generateSignature(method: T, p: Printer) + abstract fun generateBody(method: T, p: Printer) } diff --git a/generators/test-generator/tests/org/jetbrains/kotlin/generators/tests/generator/generators/TestGenerator.kt b/generators/test-generator/tests/org/jetbrains/kotlin/generators/tests/generator/generators/TestGenerator.kt new file mode 100644 index 00000000000..5c717493a36 --- /dev/null +++ b/generators/test-generator/tests/org/jetbrains/kotlin/generators/tests/generator/generators/TestGenerator.kt @@ -0,0 +1,29 @@ +/* + * 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.tests.generator.generators + +import org.jetbrains.kotlin.generators.tests.generator.MethodModel +import org.jetbrains.kotlin.generators.tests.generator.TestClassModel + +abstract class TestGenerator( + methodGenerators: List> +) { + protected val methodGenerators: Map> = + methodGenerators.associateBy { it.kind }.withDefault { error("Generator for method with kind $it not found") } + + abstract fun generateAndSave(data: GenerationData, dryRun: Boolean): GenerationResult + + data class GenerationData( + val baseDir: String, + val suiteTestClassFqName: String, + val baseTestClassFqName: String, + val testClassModels: Collection, + val useJunit4: Boolean + ) + + data class GenerationResult(val newFileGenerated: Boolean, val testSourceFilePath: String) +} + diff --git a/generators/test-generator/tests/org/jetbrains/kotlin/generators/tests/generator/TestGenerator.kt b/generators/test-generator/tests/org/jetbrains/kotlin/generators/tests/generator/generators/impl/TestGeneratorImpl.kt similarity index 74% rename from generators/test-generator/tests/org/jetbrains/kotlin/generators/tests/generator/TestGenerator.kt rename to generators/test-generator/tests/org/jetbrains/kotlin/generators/tests/generator/generators/impl/TestGeneratorImpl.kt index 3f6e770969d..31a25535eb6 100644 --- a/generators/test-generator/tests/org/jetbrains/kotlin/generators/tests/generator/TestGenerator.kt +++ b/generators/test-generator/tests/org/jetbrains/kotlin/generators/tests/generator/generators/impl/TestGeneratorImpl.kt @@ -1,11 +1,13 @@ /* - * Copyright 2000-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. + * 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.tests.generator +package org.jetbrains.kotlin.generators.tests.generator.generators.impl +import org.jetbrains.kotlin.generators.tests.generator.* import org.jetbrains.kotlin.generators.tests.generator.generators.MethodGenerator +import org.jetbrains.kotlin.generators.tests.generator.generators.TestGenerator import org.jetbrains.kotlin.generators.util.GeneratorsFileUtil import org.jetbrains.kotlin.test.JUnit3RunnerWithInners import org.jetbrains.kotlin.test.KotlinTestUtils @@ -18,45 +20,81 @@ import java.io.File import java.io.IOException import java.util.* -class TestGenerator( +private val METHOD_GENERATORS = listOf( + RunTestMethodGenerator, + SimpleTestClassModelTestAllFilesPresentMethodGenerator, + SimpleTestMethodGenerator, + SingleClassTestModelAllFilesPresentedMethodGenerator +) + +object TestGeneratorImpl : TestGenerator(METHOD_GENERATORS) { + override fun generateAndSave(data: GenerationData, dryRun: Boolean): GenerationResult { + val (baseDir, suiteTestClassFqName, baseTestClassFqName, testClassModels, useJunit4) = data + val generatorInstance = TestGeneratorImplInstance( + baseDir, + suiteTestClassFqName, + baseTestClassFqName, + testClassModels, + useJunit4, + methodGenerators + ) + return generatorInstance.generateAndSave(dryRun) + } +} + +private class TestGeneratorImplInstance( baseDir: String, suiteTestClassFqName: String, baseTestClassFqName: String, - testClassModels: Collection, - useJunit4: Boolean, - methodGenerators: List> + private val testClassModels: Collection, + private val useJunit4: Boolean, + private val methodGenerators: Map> ) { - private val methodGenerators: Map> = - methodGenerators.associateBy { it.kind }.withDefault { error("Generator for method with kind $it not found") } + companion object { + private val GENERATED_FILES = HashSet() + private val RUNNER = JUnit3RunnerWithInners::class.java + private val JUNIT4_RUNNER = BlockJUnit4ClassRunner::class.java - private val baseTestClassPackage: String - private val suiteClassPackage: String - private val suiteClassName: String - private val baseTestClassName: String - private val testClassModels: Collection - private val useJunit4: Boolean - internal val testSourceFilePath: String + private fun generateMetadata(p: Printer, testDataSource: TestEntityModel) { + val dataString = testDataSource.dataString + if (dataString != null) { + p.println("@TestMetadata(\"", dataString, "\")") + } + } - init { - this.baseTestClassPackage = baseTestClassFqName.substringBeforeLast('.', "") - this.baseTestClassName = baseTestClassFqName.substringAfterLast('.', baseTestClassFqName) - this.suiteClassPackage = suiteTestClassFqName.substringBeforeLast('.', baseTestClassPackage) - this.suiteClassName = suiteTestClassFqName.substringAfterLast('.', suiteTestClassFqName) - this.testClassModels = ArrayList(testClassModels) - this.useJunit4 = useJunit4 + private fun generateTestDataPath(p: Printer, testClassModel: TestClassModel) { + val dataPathRoot = testClassModel.dataPathRoot + if (dataPathRoot != null) { + p.println("@TestDataPath(\"", dataPathRoot, "\")") + } + } - this.testSourceFilePath = baseDir + "/" + this.suiteClassPackage.replace(".", "/") + "/" + this.suiteClassName + ".java" + private fun generateParameterAnnotations(p: Printer, testClassModel: TestClassModel) { + for (annotationModel in testClassModel.annotations) { + annotationModel.generate(p) + p.println() + } + } - if (!GENERATED_FILES.add(testSourceFilePath)) { - throw IllegalArgumentException("Same test file already generated in current session: " + testSourceFilePath) + 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") } } - /** - * @return true if a new file is generated - */ @Throws(IOException::class) - fun generateAndSave(dryRun: Boolean): Boolean { + fun generateAndSave(dryRun: Boolean): TestGenerator.GenerationResult { val generatedCode = generate() val testSourceFile = File(testSourceFilePath) @@ -65,7 +103,7 @@ class TestGenerator( if (!dryRun) { GeneratorsFileUtil.writeFileIfContentChanged(testSourceFile, generatedCode, false) } - return changed + return TestGenerator.GenerationResult(changed, testSourceFilePath) } private fun generate(): String { @@ -201,47 +239,25 @@ class TestGenerator( val generator = methodGenerators.getValue(methodModel.kind) generateMetadata(p, methodModel) - generator.generateSignature(methodModel, p) + generator.hackyGenerateSignature(methodModel, p) p.printWithNoIndent(" {") p.println() p.pushIndent() - generator.generateBody(methodModel, p) + generator.hackyGenerateBody(methodModel, p) p.popIndent() p.println("}") } - companion object { - private val GENERATED_FILES = HashSet() - private val RUNNER = JUnit3RunnerWithInners::class.java - private val JUNIT4_RUNNER = BlockJUnit4ClassRunner::class.java + private fun MethodGenerator.hackyGenerateBody(method: MethodModel, p: Printer) { + @Suppress("UNCHECKED_CAST") + generateBody(method as T, p) + } - - 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 fun MethodGenerator.hackyGenerateSignature(method: MethodModel, p: Printer) { + @Suppress("UNCHECKED_CAST") + generateSignature(method as T, p) } }