提交 9319c4c9 编写于 作者: V Vladimir Dolzhenko

DryRun mode for GenerateTests is added

Relates to #KTI-17
上级 cd927302
......@@ -20,48 +20,50 @@ import org.jetbrains.kotlin.checkers.AbstractForeignJava8AnnotationsNoAnnotation
import org.jetbrains.kotlin.checkers.AbstractForeignJava8AnnotationsNoAnnotationInClasspathWithPsiClassReadingTest
import org.jetbrains.kotlin.checkers.AbstractForeignJava8AnnotationsTest
import org.jetbrains.kotlin.checkers.javac.AbstractJavacForeignJava8AnnotationsTest
import org.jetbrains.kotlin.generators.tests.generator.testGroup
import org.jetbrains.kotlin.generators.tests.generator.testGroupSuite
import org.jetbrains.kotlin.jvm.compiler.AbstractLoadJava8Test
import org.jetbrains.kotlin.jvm.compiler.AbstractLoadJava8WithPsiClassReadingTest
import org.jetbrains.kotlin.jvm.compiler.javac.AbstractLoadJava8UsingJavacTest
import org.jetbrains.kotlin.resolve.calls.AbstractEnhancedSignaturesResolvedCallsTest
fun main() {
fun main(args: Array<String>) {
System.setProperty("java.awt.headless", "true")
testGroup("compiler/tests-java8/tests", "compiler/testData") {
testClass<AbstractForeignJava8AnnotationsTest> {
model("foreignAnnotationsJava8/tests")
}
testGroupSuite(args) {
testGroup("compiler/tests-java8/tests", "compiler/testData") {
testClass<AbstractForeignJava8AnnotationsTest> {
model("foreignAnnotationsJava8/tests")
}
testClass<AbstractJavacForeignJava8AnnotationsTest> {
model("foreignAnnotationsJava8/tests")
}
testClass<AbstractJavacForeignJava8AnnotationsTest> {
model("foreignAnnotationsJava8/tests")
}
testClass<AbstractForeignJava8AnnotationsNoAnnotationInClasspathTest> {
model("foreignAnnotationsJava8/tests")
}
testClass<AbstractForeignJava8AnnotationsNoAnnotationInClasspathTest> {
model("foreignAnnotationsJava8/tests")
}
testClass<AbstractForeignJava8AnnotationsNoAnnotationInClasspathWithPsiClassReadingTest> {
model("foreignAnnotationsJava8/tests")
}
testClass<AbstractForeignJava8AnnotationsNoAnnotationInClasspathWithPsiClassReadingTest> {
model("foreignAnnotationsJava8/tests")
}
testClass<AbstractLoadJava8Test> {
model("loadJava8/compiledJava", extension = "java", testMethod = "doTestCompiledJava")
model("loadJava8/sourceJava", extension = "java", testMethod = "doTestSourceJava")
}
testClass<AbstractLoadJava8Test> {
model("loadJava8/compiledJava", extension = "java", testMethod = "doTestCompiledJava")
model("loadJava8/sourceJava", extension = "java", testMethod = "doTestSourceJava")
}
testClass<AbstractLoadJava8UsingJavacTest> {
model("loadJava8/compiledJava", extension = "java", testMethod = "doTestCompiledJava")
model("loadJava8/sourceJava", extension = "java", testMethod = "doTestSourceJava")
}
testClass<AbstractLoadJava8UsingJavacTest> {
model("loadJava8/compiledJava", extension = "java", testMethod = "doTestCompiledJava")
model("loadJava8/sourceJava", extension = "java", testMethod = "doTestSourceJava")
}
testClass<AbstractLoadJava8WithPsiClassReadingTest> {
model("loadJava8/compiledJava", extension = "java", testMethod = "doTestCompiledJava")
}
testClass<AbstractLoadJava8WithPsiClassReadingTest> {
model("loadJava8/compiledJava", extension = "java", testMethod = "doTestCompiledJava")
}
testClass<AbstractEnhancedSignaturesResolvedCallsTest> {
model("resolvedCalls/enhancedSignatures")
testClass<AbstractEnhancedSignaturesResolvedCallsTest> {
model("resolvedCalls/enhancedSignatures")
}
}
}
}
......@@ -5,7 +5,7 @@
package org.jetbrains.kotlin.spec.utils.tasks
import org.jetbrains.kotlin.generators.tests.generator.testGroup
import org.jetbrains.kotlin.generators.tests.generator.testGroupSuite
import org.jetbrains.kotlin.spec.checkers.AbstractDiagnosticsTestSpec
import org.jetbrains.kotlin.spec.checkers.AbstractFirDiagnosticsTestSpec
import org.jetbrains.kotlin.spec.codegen.AbstractBlackBoxCodegenTestSpec
......@@ -38,32 +38,34 @@ fun detectDirsWithTestsMapFileOnly(dirName: String): List<String> {
fun generateTests() {
val excludedFirTestdataPattern = "^(.+)\\.fir\\.kts?\$"
testGroup(SPEC_TEST_PATH, SPEC_TESTDATA_PATH) {
testClass<AbstractDiagnosticsTestSpec> {
model(
"diagnostics",
excludeDirs = listOf("helpers") + detectDirsWithTestsMapFileOnly("diagnostics"),
excludedPattern = excludedFirTestdataPattern
)
}
testGroupSuite {
testGroup(SPEC_TEST_PATH, SPEC_TESTDATA_PATH) {
testClass<AbstractDiagnosticsTestSpec> {
model(
"diagnostics",
excludeDirs = listOf("helpers") + detectDirsWithTestsMapFileOnly("diagnostics"),
excludedPattern = excludedFirTestdataPattern
)
}
testClass<AbstractFirDiagnosticsTestSpec> {
model(
"diagnostics",
excludeDirs = listOf("helpers") + detectDirsWithTestsMapFileOnly("diagnostics"),
excludedPattern = excludedFirTestdataPattern
)
}
testClass<AbstractFirDiagnosticsTestSpec> {
model(
"diagnostics",
excludeDirs = listOf("helpers") + detectDirsWithTestsMapFileOnly("diagnostics"),
excludedPattern = excludedFirTestdataPattern
)
}
testClass<AbstractParsingTestSpec> {
model(
relativeRootPath = "psi",
testMethod = "doParsingTest",
excludeDirs = listOf("helpers", "templates") + detectDirsWithTestsMapFileOnly("psi")
)
}
testClass<AbstractBlackBoxCodegenTestSpec> {
model("codegen/box", excludeDirs = listOf("helpers", "templates") + detectDirsWithTestsMapFileOnly("codegen/box"))
testClass<AbstractParsingTestSpec> {
model(
relativeRootPath = "psi",
testMethod = "doParsingTest",
excludeDirs = listOf("helpers", "templates") + detectDirsWithTestsMapFileOnly("psi")
)
}
testClass<AbstractBlackBoxCodegenTestSpec> {
model("codegen/box", excludeDirs = listOf("helpers", "templates") + detectDirsWithTestsMapFileOnly("codegen/box"))
}
}
}
}
......
......@@ -16,21 +16,23 @@
package org.jetbrains.kotlin.generators.tests
import org.jetbrains.kotlin.generators.tests.generator.testGroup
import org.jetbrains.kotlin.generators.tests.generator.testGroupSuite
import org.jetbrains.kotlin.jvm.runtime.AbstractJvm8RuntimeDescriptorLoaderTest
import org.jetbrains.kotlin.jvm.runtime.AbstractJvmRuntimeDescriptorLoaderTest
fun main() {
fun main(args: Array<String>) {
System.setProperty("java.awt.headless", "true")
testGroup("core/descriptors.runtime/tests", "compiler/testData") {
testClass<AbstractJvmRuntimeDescriptorLoaderTest> {
model("loadJava/compiledKotlin")
model("loadJava/compiledJava", extension = "java", excludeDirs = listOf("sam", "kotlinSignature/propagation"))
}
testGroupSuite(args) {
testGroup("core/descriptors.runtime/tests", "compiler/testData") {
testClass<AbstractJvmRuntimeDescriptorLoaderTest> {
model("loadJava/compiledKotlin")
model("loadJava/compiledJava", extension = "java", excludeDirs = listOf("sam", "kotlinSignature/propagation"))
}
testClass<AbstractJvm8RuntimeDescriptorLoaderTest> {
model("loadJava8/compiledJava", extension = "java")
testClass<AbstractJvm8RuntimeDescriptorLoaderTest> {
model("loadJava8/compiledJava", extension = "java")
}
}
}
}
......@@ -24,7 +24,7 @@ object GeneratorsFileUtil {
throw IllegalStateException("Cannot create directory: $parentFile")
}
}
if (checkFileIgnoringLineSeparators(file, newText)) {
if (!isFileContentChangedIgnoringLineSeparators(file, newText)) {
if (logNotChanged) {
println("Not changed: " + file.absolutePath)
}
......@@ -42,12 +42,12 @@ object GeneratorsFileUtil {
println()
}
private fun checkFileIgnoringLineSeparators(file: File, content: String): Boolean {
fun isFileContentChangedIgnoringLineSeparators(file: File, content: String): Boolean {
val currentContent: String = try {
StringUtil.convertLineSeparators(file.readText(Charsets.UTF_8))
} catch (ignored: Throwable) {
return false
return true
}
return StringUtil.convertLineSeparators(content) == currentContent
return StringUtil.convertLineSeparators(content) != currentContent
}
}
\ No newline at end of file
......@@ -6,6 +6,8 @@
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.test.TargetBackend
import java.io.File
import java.util.*
......@@ -16,7 +18,8 @@ class TestGroup(
val testDataRoot: String,
val testRunnerMethodName: String,
val additionalRunnerArguments: List<String> = emptyList(),
val annotations: List<AnnotationModel> = emptyList()
val annotations: List<AnnotationModel> = emptyList(),
private val dryRun: Boolean = false
) {
inline fun <reified T : TestCase> testClass(
suiteTestClassName: String = getDefaultSuiteTestClassName(T::class.java.simpleName),
......@@ -34,13 +37,16 @@ class TestGroup(
annotations: List<AnnotationModel> = emptyList(),
init: TestClass.() -> Unit
) {
TestGenerator(
val testGenerator = TestGenerator(
testsRoot,
suiteTestClassName,
baseTestClassName,
TestClass(annotations).apply(init).testModels,
useJunit4
).generateAndSave()
)
if (testGenerator.generateAndSave(dryRun)) {
inconsistencyChecker(dryRun).add(testGenerator.testSourceFilePath)
}
}
inner class TestClass(val annotations: List<AnnotationModel>) {
......@@ -85,14 +91,67 @@ class TestGroup(
}
}
fun testGroup(
testsRoot: String,
testDataRoot: String,
testRunnerMethodName: String = RunTestMethodModel.METHOD_NAME,
additionalRunnerArguments: List<String> = emptyList(),
init: TestGroup.() -> Unit
fun testGroupSuite(
args: Array<String>,
init: TestGroupSuite.() -> Unit
) {
testGroupSuite(hasDryRunArg(args), init)
}
fun testGroupSuite(
dryRun: Boolean = false,
init: TestGroupSuite.() -> Unit
) {
TestGroup(testsRoot, testDataRoot, testRunnerMethodName, additionalRunnerArguments).init()
TestGroupSuite(dryRun).init()
}
class TestGroupSuite(private val dryRun: Boolean) {
fun testGroup(
testsRoot: String,
testDataRoot: String,
testRunnerMethodName: String = RunTestMethodModel.METHOD_NAME,
additionalRunnerArguments: List<String> = emptyList(),
init: TestGroup.() -> Unit
) {
TestGroup(
testsRoot,
testDataRoot,
testRunnerMethodName,
additionalRunnerArguments,
dryRun = dryRun
).init()
}
}
interface InconsistencyChecker {
fun add(affectedFile: String)
val affectedFiles: List<String>
companion object {
fun hasDryRunArg(args: Array<String>) = args.any { it == "dryRun" }
fun inconsistencyChecker(dryRun: Boolean) = if (dryRun) DefaultInconsistencyChecker else EmptyInconsistencyChecker
}
}
object DefaultInconsistencyChecker : InconsistencyChecker {
private val files = mutableListOf<String>()
override fun add(affectedFile: String) {
files.add(affectedFile)
}
override val affectedFiles: List<String>
get() = files
}
object EmptyInconsistencyChecker : InconsistencyChecker {
override fun add(affectedFile: String) {
}
override val affectedFiles: List<String>
get() = emptyList()
}
fun getDefaultSuiteTestClassName(baseTestClassName: String): String {
......
......@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.generators.tests.generator
import org.jetbrains.kotlin.generators.util.GeneratorsFileUtil
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.TargetBackend
import org.jetbrains.kotlin.test.TestMetadata
import org.jetbrains.kotlin.utils.Printer
import org.junit.Test
......@@ -31,7 +30,7 @@ class TestGenerator(
private val baseTestClassName: String
private val testClassModels: Collection<TestClassModel>
private val useJunit4: Boolean
private val testSourceFilePath: String
internal val testSourceFilePath: String
init {
this.baseTestClassPackage = baseTestClassFqName.substringBeforeLast('.', "")
......@@ -48,18 +47,33 @@ class TestGenerator(
}
}
/**
* @return true if a new file is generated
*/
@Throws(IOException::class)
fun generateAndSave() {
fun generateAndSave(dryRun: Boolean): Boolean {
val generatedCode = generate()
val testSourceFile = File(testSourceFilePath)
val changed =
GeneratorsFileUtil.isFileContentChangedIgnoringLineSeparators(testSourceFile, generatedCode)
if (!dryRun) {
GeneratorsFileUtil.writeFileIfContentChanged(testSourceFile, generatedCode, false)
}
return changed
}
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()
| * 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()
......@@ -126,9 +140,7 @@ class TestGenerator(
}
generateTestClass(p, model, false)
val testSourceFile = File(testSourceFilePath)
GeneratorsFileUtil.writeFileIfContentChanged(testSourceFile, out.toString(), false)
return out.toString()
}
private fun generateTestClass(p: Printer, testClassModel: TestClassModel, isStatic: Boolean) {
......
......@@ -5,7 +5,7 @@
package org.jetbrains.kotlin.generators.tests
import org.jetbrains.kotlin.generators.tests.generator.testGroup
import org.jetbrains.kotlin.generators.tests.generator.testGroupSuite
import org.jetbrains.kotlin.js.test.AbstractDceTest
import org.jetbrains.kotlin.js.test.AbstractJsLineNumberTest
import org.jetbrains.kotlin.js.test.es6.semantics.*
......@@ -14,90 +14,92 @@ import org.jetbrains.kotlin.js.test.semantics.*
import org.jetbrains.kotlin.js.test.wasm.semantics.AbstractIrWasmBoxWasmTest
import org.jetbrains.kotlin.test.TargetBackend
fun main() {
fun main(args: Array<String>) {
System.setProperty("java.awt.headless", "true")
// TODO: repair these tests
//generateTestDataForReservedWords()
testGroup("js/js.tests/test", "js/js.translator/testData", testRunnerMethodName = "runTest0") {
testClass<AbstractBoxJsTest> {
model("box/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS)
}
testGroupSuite(args) {
testGroup("js/js.tests/test", "js/js.translator/testData", testRunnerMethodName = "runTest0") {
testClass<AbstractBoxJsTest> {
model("box/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS)
}
testClass<AbstractIrBoxJsTest> {
model("box/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS_IR)
}
testClass<AbstractIrBoxJsTest> {
model("box/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS_IR)
}
testClass<AbstractIrBoxJsES6Test> {
model("box/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS_IR_ES6)
}
testClass<AbstractIrBoxJsES6Test> {
model("box/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS_IR_ES6)
}
testClass<AbstractIrJsTypeScriptExportTest> {
model("typescript-export/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS_IR)
}
testClass<AbstractIrJsTypeScriptExportTest> {
model("typescript-export/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS_IR)
}
testClass<AbstractIrJsTypeScriptExportES6Test> {
model("typescript-export/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS_IR_ES6)
}
testClass<AbstractIrJsTypeScriptExportES6Test> {
model("typescript-export/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS_IR_ES6)
}
testClass<AbstractLegacyJsTypeScriptExportTest> {
model("typescript-export/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS)
}
testClass<AbstractLegacyJsTypeScriptExportTest> {
model("typescript-export/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS)
}
testClass<AbstractSourceMapGenerationSmokeTest> {
model("sourcemap/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS)
}
testClass<AbstractSourceMapGenerationSmokeTest> {
model("sourcemap/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS)
}
testClass<AbstractOutputPrefixPostfixTest> {
model("outputPrefixPostfix/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS)
}
testClass<AbstractOutputPrefixPostfixTest> {
model("outputPrefixPostfix/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS)
}
testClass<AbstractDceTest> {
model("dce/", pattern = "(.+)\\.js", targetBackend = TargetBackend.JS)
}
testClass<AbstractDceTest> {
model("dce/", pattern = "(.+)\\.js", targetBackend = TargetBackend.JS)
}
testClass<AbstractJsLineNumberTest> {
model("lineNumbers/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS)
}
testClass<AbstractJsLineNumberTest> {
model("lineNumbers/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS)
}
testClass<AbstractIrWasmBoxWasmTest> {
model("wasmBox", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.WASM)
}
testClass<AbstractIrWasmBoxWasmTest> {
model("wasmBox", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.WASM)
}
testClass<AbstractIrWasmBoxJsTest> {
model("wasmBox", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS_IR)
testClass<AbstractIrWasmBoxJsTest> {
model("wasmBox", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS_IR)
}
}
}
testGroup("js/js.tests/test", "compiler/testData", testRunnerMethodName = "runTest0") {
testClass<AbstractJsCodegenBoxTest> {
model("codegen/box", targetBackend = TargetBackend.JS)
}
testGroup("js/js.tests/test", "compiler/testData", testRunnerMethodName = "runTest0") {
testClass<AbstractJsCodegenBoxTest> {
model("codegen/box", targetBackend = TargetBackend.JS)
}
testClass<AbstractIrJsCodegenBoxTest> {
model("codegen/box", targetBackend = TargetBackend.JS_IR)
}
testClass<AbstractIrJsCodegenBoxTest> {
model("codegen/box", targetBackend = TargetBackend.JS_IR)
}
testClass<AbstractIrJsCodegenBoxES6Test> {
model("codegen/box", targetBackend = TargetBackend.JS_IR_ES6)
}
testClass<AbstractIrJsCodegenBoxES6Test> {
model("codegen/box", targetBackend = TargetBackend.JS_IR_ES6)
}
testClass<AbstractJsCodegenInlineTest> {
model("codegen/boxInline/", targetBackend = TargetBackend.JS)
}
testClass<AbstractJsCodegenInlineTest> {
model("codegen/boxInline/", targetBackend = TargetBackend.JS)
}
testClass<AbstractIrJsCodegenInlineTest> {
model("codegen/boxInline/", targetBackend = TargetBackend.JS_IR)
}
testClass<AbstractIrJsCodegenInlineTest> {
model("codegen/boxInline/", targetBackend = TargetBackend.JS_IR)
}
testClass<AbstractIrJsCodegenInlineES6Test> {
model("codegen/boxInline/", targetBackend = TargetBackend.JS_IR_ES6)
}
testClass<AbstractIrJsCodegenInlineES6Test> {
model("codegen/boxInline/", targetBackend = TargetBackend.JS_IR_ES6)
}
testClass<AbstractJsLegacyPrimitiveArraysBoxTest> {
model("codegen/box/arrays", targetBackend = TargetBackend.JS)
testClass<AbstractJsLegacyPrimitiveArraysBoxTest> {
model("codegen/box/arrays", targetBackend = TargetBackend.JS)
}
}
}
}
......@@ -6,13 +6,24 @@
package org.jetbrains.kotlin.pill.generateAllTests;
import org.jetbrains.kotlin.generators.tests.*;
import org.jetbrains.kotlin.generators.tests.generator.InconsistencyChecker;
import java.util.List;
public class Main {
public static void main(String[] args) {
GenerateCompilerTestsKt.main();
GenerateTestsKt.main();
GenerateJsTestsKt.main();
GenerateJava8TestsKt.main();
GenerateRuntimeDescriptorTestsKt.main();
GenerateCompilerTestsKt.main(args);
GenerateTestsKt.main(args);
GenerateJsTestsKt.main(args);
GenerateJava8TestsKt.main(args);
GenerateRuntimeDescriptorTestsKt.main(args);
boolean dryRun = InconsistencyChecker.Companion.hasDryRunArg(args);
List<String> affectedFiles = InconsistencyChecker.Companion.inconsistencyChecker(dryRun).getAffectedFiles();
int size = affectedFiles.size();
if (size > 0) {
throw new IllegalStateException("There " + (size == 1 ? "is a test" : "are " + size + " tests") + " to be regenerated:\n"
+ String.join("\n", affectedFiles));
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册