Some changes in test generating infrastructure:

* add separate run function for each test class to simplify and deduplicate generated code
* move the code that process IGNORE_BACKEND directive to the separate function, outside of generated code.
** it reduces size and complexity of a generated code
** it allows to mute and unmute tests w/o regenerate tests
* add an ability to generate IGNORE_BACKEND directive automatically, it's disabled by default
* add an ability to remove IGNORE_BACKEND directive automatically, it's enabled by default
* remove whitelists
This commit is contained in:
Zalim Bashorov
2018-04-13 19:29:54 +03:00
parent 4227d8e73a
commit a63b2e1bbd
14 changed files with 346 additions and 249 deletions
@@ -0,0 +1,31 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. 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
import org.jetbrains.kotlin.test.TargetBackend
import org.jetbrains.kotlin.utils.Printer
class RunTestMethodModel(
private val targetBackend: TargetBackend,
private val testMethodName: String,
private val testRunnerMethodName: String
) : MethodModel {
override val name = METHOD_NAME
override val dataString: String? = null
override fun generateSignature(p: Printer) {
p.print("private void $name(String testDataFilePath) throws Exception")
}
override fun generateBody(p: Printer) {
val className = TargetBackend::class.java.simpleName
p.println("KotlinTestUtils.$testRunnerMethodName(this::$testMethodName, $className.$targetBackend, testDataFilePath);")
}
companion object {
const val METHOD_NAME = "runTest"
}
}
@@ -53,6 +53,7 @@ public class SimpleTestClassModel implements TestClassModel {
private Collection<MethodModel> testMethods;
private final boolean skipIgnored;
private final String testRunnerMethodName;
public SimpleTestClassModel(
@NotNull File rootFile,
@@ -64,7 +65,8 @@ public class SimpleTestClassModel implements TestClassModel {
@NotNull String testClassName,
@NotNull TargetBackend targetBackend,
@NotNull Collection<String> excludeDirs,
boolean skipIgnored
boolean skipIgnored,
String testRunnerMethodName
) {
this.rootFile = rootFile;
this.recursive = recursive;
@@ -76,6 +78,7 @@ public class SimpleTestClassModel implements TestClassModel {
this.checkFilenameStartsLowerCase = checkFilenameStartsLowerCase;
this.excludeDirs = excludeDirs.isEmpty() ? Collections.emptySet() : new LinkedHashSet<>(excludeDirs);
this.skipIgnored = skipIgnored;
this.testRunnerMethodName = testRunnerMethodName;
}
@NotNull
@@ -93,9 +96,9 @@ public class SimpleTestClassModel implements TestClassModel {
if (file.isDirectory() && dirHasFilesInside(file) && !excludeDirs.contains(file.getName())) {
String innerTestClassName = TestGeneratorUtil.fileNameToJavaIdentifier(file);
children.add(new SimpleTestClassModel(
file, true, excludeParentDirs, filenamePattern, checkFilenameStartsLowerCase,
doTestMethodName, innerTestClassName, targetBackend, excludesStripOneDirectory(file.getName()),
skipIgnored)
file, true, excludeParentDirs, filenamePattern, checkFilenameStartsLowerCase,
doTestMethodName, innerTestClassName, targetBackend, excludesStripOneDirectory(file.getName()),
skipIgnored, testRunnerMethodName)
);
}
}
@@ -144,12 +147,15 @@ public class SimpleTestClassModel implements TestClassModel {
if (testMethods == null) {
if (!rootFile.isDirectory()) {
testMethods = Collections.singletonList(new SimpleTestMethodModel(
rootFile, rootFile, doTestMethodName, filenamePattern, checkFilenameStartsLowerCase, targetBackend, skipIgnored
rootFile, rootFile, filenamePattern,
checkFilenameStartsLowerCase, targetBackend, skipIgnored
));
}
else {
List<MethodModel> result = new ArrayList<>();
result.add(new RunTestMethodModel(targetBackend, doTestMethodName, testRunnerMethodName));
result.add(new TestAllFilesPresentMethodModel());
File[] listFiles = rootFile.listFiles();
@@ -161,8 +167,9 @@ public class SimpleTestClassModel implements TestClassModel {
continue;
}
result.add(new SimpleTestMethodModel(rootFile, file, doTestMethodName, filenamePattern,
checkFilenameStartsLowerCase, targetBackend, skipIgnored));
result.add(new SimpleTestMethodModel(
rootFile, file, filenamePattern,
checkFilenameStartsLowerCase, targetBackend, skipIgnored));
}
}
}
@@ -28,8 +28,6 @@ public class SimpleTestMethodModel implements TestMethodModel {
@NotNull
private final File file;
@NotNull
private final String doTestMethodName;
@NotNull
private final Pattern filenamePattern;
@NotNull
private final TargetBackend targetBackend;
@@ -39,7 +37,6 @@ public class SimpleTestMethodModel implements TestMethodModel {
public SimpleTestMethodModel(
@NotNull File rootDir,
@NotNull File file,
@NotNull String doTestMethodName,
@NotNull Pattern filenamePattern,
@Nullable Boolean checkFilenameStartsLowerCase,
@NotNull TargetBackend targetBackend,
@@ -47,7 +44,6 @@ public class SimpleTestMethodModel implements TestMethodModel {
) {
this.rootDir = rootDir;
this.file = file;
this.doTestMethodName = doTestMethodName;
this.filenamePattern = filenamePattern;
this.targetBackend = targetBackend;
this.skipIgnored = skipIgnored;
@@ -66,35 +62,7 @@ public class SimpleTestMethodModel implements TestMethodModel {
@Override
public void generateBody(@NotNull Printer p) {
String filePath = KotlinTestUtils.getFilePath(file) + (file.isDirectory() ? "/" : "");
p.println("String fileName = KotlinTestUtils.navigationMetadata(\"", filePath, "\");");
boolean ignoredTarget = isIgnoredTarget(targetBackend, file);
if (ignoredTarget) {
p.println("if (KotlinTestUtils.RUN_IGNORED_TESTS_AS_REGULAR) {");
p.pushIndent();
p.println(doTestMethodName, "(fileName);");
p.println("return;");
p.popIndent();
p.println("}");
p.println("try {");
p.pushIndent();
}
p.println(doTestMethodName, "(fileName);");
if (ignoredTarget) {
p.popIndent();
p.println("}");
p.println("catch (Throwable ignore) {");
p.pushIndent();
p.println("ignore.printStackTrace();");
p.println("return;");
p.popIndent();
p.println("}");
p.println("throw new AssertionError(\"Looks like this test can be unmuted. Remove IGNORE_BACKEND directive or add it to whitelist for that.\");");
}
p.println(RunTestMethodModel.METHOD_NAME, "(\"", filePath, "\");");
}
@Override
@@ -49,6 +49,7 @@ public class SingleClassTestModel implements TestClassModel {
private Collection<MethodModel> methods;
private final boolean skipIgnored;
private final String testRunnerMethodName;
public SingleClassTestModel(
@NotNull File rootFile,
@@ -57,7 +58,8 @@ public class SingleClassTestModel implements TestClassModel {
@NotNull String doTestMethodName,
@NotNull String testClassName,
@NotNull TargetBackend targetBackend,
boolean skipIgnored
boolean skipIgnored,
String testRunnerMethodName
) {
this.rootFile = rootFile;
this.filenamePattern = filenamePattern;
@@ -66,6 +68,7 @@ public class SingleClassTestModel implements TestClassModel {
this.testClassName = testClassName;
this.targetBackend = targetBackend;
this.skipIgnored = skipIgnored;
this.testRunnerMethodName = testRunnerMethodName;
}
@NotNull
@@ -78,7 +81,9 @@ public class SingleClassTestModel implements TestClassModel {
@Override
public Collection<MethodModel> getMethods() {
if (methods == null) {
List<TestMethodModel> result = new ArrayList<>();
List<MethodModel> result = new ArrayList<>();
result.add(new RunTestMethodModel(targetBackend, doTestMethodName, testRunnerMethodName));
result.add(new TestAllFilesPresentMethodModel());
@@ -99,7 +104,7 @@ public class SingleClassTestModel implements TestClassModel {
@NotNull
private Collection<TestMethodModel> getTestMethodsFromFile(File file) {
return Collections.singletonList(new SimpleTestMethodModel(
rootFile, file, doTestMethodName, filenamePattern, checkFilenameStartsLowerCase, targetBackend, skipIgnored
rootFile, file, filenamePattern, checkFilenameStartsLowerCase, targetBackend, skipIgnored
));
}
@@ -20,10 +20,10 @@ import junit.framework.TestCase
import org.jetbrains.kotlin.test.TargetBackend
import java.io.File
import java.lang.IllegalArgumentException
import java.util.ArrayList
import java.util.*
import java.util.regex.Pattern
class TestGroup(private val testsRoot: String, val testDataRoot: String) {
class TestGroup(private val testsRoot: String, val testDataRoot: String, val testRunnerMethodName: String) {
inline fun <reified T: TestCase> testClass(
suiteTestClassName: String = getDefaultSuiteTestClassName(T::class.java.simpleName),
noinline init: TestClass.() -> Unit
@@ -68,20 +68,20 @@ class TestGroup(private val testsRoot: String, val testDataRoot: String) {
if (singleClass) {
if (excludeDirs.isNotEmpty()) error("excludeDirs is unsupported for SingleClassTestModel yet")
SingleClassTestModel(rootFile, compiledPattern, filenameStartsLowerCase, testMethod, className, targetBackend,
skipIgnored)
skipIgnored, testRunnerMethodName)
}
else {
SimpleTestClassModel(rootFile, recursive, excludeParentDirs,
compiledPattern, filenameStartsLowerCase, testMethod, className,
targetBackend, excludeDirs, skipIgnored)
targetBackend, excludeDirs, skipIgnored, testRunnerMethodName)
}
)
}
}
}
fun testGroup(testsRoot: String, testDataRoot: String, init: TestGroup.() -> Unit) {
TestGroup(testsRoot, testDataRoot).init()
fun testGroup(testsRoot: String, testDataRoot: String, testRunnerMethodName: String = RunTestMethodModel.METHOD_NAME, init: TestGroup.() -> Unit) {
TestGroup(testsRoot, testDataRoot, testRunnerMethodName).init()
}
fun getDefaultSuiteTestClassName(baseTestClassName: String): String {