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
@@ -10,7 +10,6 @@ import com.google.common.collect.Sets;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.ArrayUtil;
import kotlin.io.FilesKt;
import kotlin.text.StringsKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -27,6 +26,8 @@ public final class InTextDirectivesUtils {
private static final String DIRECTIVES_FILE_NAME = "directives.txt";
public static final String IGNORE_BACKEND_DIRECTIVE_PREFIX = "// IGNORE_BACKEND: ";
private InTextDirectivesUtils() {
}
@@ -225,19 +226,13 @@ public final class InTextDirectivesUtils {
return backends.isEmpty() || backends.contains(targetBackend.name()) || backends.contains(targetBackend.getCompatibleWith().name());
}
private static boolean isIgnoredTargetByPrefix(TargetBackend targetBackend, File file, String prefix) {
public static boolean isIgnoredTarget(TargetBackend targetBackend, File file) {
if (targetBackend == TargetBackend.ANY) return false;
List<String> ignoredBackends = findListWithPrefixes(textWithDirectives(file), prefix);
List<String> ignoredBackends = findListWithPrefixes(textWithDirectives(file), IGNORE_BACKEND_DIRECTIVE_PREFIX);
return ignoredBackends.contains(targetBackend.name());
}
public static boolean isIgnoredTarget(TargetBackend targetBackend, File file) {
if (!isAllowedByWhitelist(targetBackend, file)) return true;
return isIgnoredTargetByPrefix(targetBackend, file, "// IGNORE_BACKEND: ");
}
public static boolean isIgnoredTargetWithoutCheck(TargetBackend targetBackend, File file) {
return isIgnoredTargetByPrefix(targetBackend, file, "// IGNORE_BACKEND_WITHOUT_CHECK: ");
}
@@ -246,17 +241,4 @@ public final class InTextDirectivesUtils {
public static boolean isPassingTarget(TargetBackend targetBackend, File file) {
return isCompatibleTarget(targetBackend, file) && !isIgnoredTarget(targetBackend, file) && !isIgnoredTargetWithoutCheck(targetBackend, file);
}
private static boolean isAllowedByWhitelist(@NotNull TargetBackend targetBackend, @NotNull File file) {
List<File> whitelist = targetBackend.getWhitelist();
if (whitelist == null) return true;
for (File entry : whitelist) {
if (FilesKt.startsWith(file, entry)) {
return true;
}
}
return false;
}
}
@@ -87,18 +87,20 @@ import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.jetbrains.kotlin.test.InTextDirectivesUtils.isCompatibleTarget;
import static org.jetbrains.kotlin.test.InTextDirectivesUtils.isDirectiveDefined;
import static org.jetbrains.kotlin.test.InTextDirectivesUtils.*;
public class KotlinTestUtils {
public static String TEST_MODULE_NAME = "test-module";
public static final String TEST_GENERATOR_NAME = "org.jetbrains.kotlin.generators.tests.TestsPackage";
public static final String PLEASE_REGENERATE_TESTS = "Please regenerate tests (GenerateTests.kt)";
private static final String PLEASE_REGENERATE_TESTS = "Please regenerate tests (GenerateTests.kt)";
public static final boolean RUN_IGNORED_TESTS_AS_REGULAR =
private static final boolean RUN_IGNORED_TESTS_AS_REGULAR =
Boolean.getBoolean("org.jetbrains.kotlin.run.ignored.tests.as.regular");
private static final boolean AUTOMATICALLY_UNMUTE_PASSED_TESTS = true;
private static final boolean AUTOMATICALLY_MUTE_FAILED_TESTS = false;
private static final List<File> filesToDelete = new ArrayList<>();
/**
@@ -1011,6 +1013,69 @@ public class KotlinTestUtils {
return testFile;
}
public interface DoTest {
void invoke(String filePath) throws Exception;
}
// In this test runner version the `testDataFile` parameter is annotated by `TestDataFile`.
// So only file paths passed to this parameter will be used in navigation actions, like "Navigate to testdata" and "Related Symbol..."
public static void runTest(DoTest test, TargetBackend targetBackend, @TestDataFile String testDataFile) throws Exception {
runTest0(test, targetBackend, testDataFile);
}
// In this test runner version, NONE of the parameters are annotated by `TestDataFile`.
// So DevKit will use test name to determine related files in navigation actions, like "Navigate to testdata" and "Related Symbol..."
//
// Pro:
// * in most cases, it shows all related files including generated js files, for example.
// Cons:
// * sometimes, for too common/general names, it shows many variants to navigate
// * it adds an additional step for navigation -- you must choose an exact file to navigate
public static void runTest0(DoTest test, TargetBackend targetBackend, String testDataFilePath) throws Exception {
File testDataFile = new File(testDataFilePath);
boolean isIgnored = isIgnoredTarget(targetBackend, testDataFile);
try {
test.invoke(testDataFilePath);
}
catch (Throwable e) {
if (!isIgnored && AUTOMATICALLY_MUTE_FAILED_TESTS) {
String text = doLoadFile(testDataFile);
String directive = InTextDirectivesUtils.IGNORE_BACKEND_DIRECTIVE_PREFIX + targetBackend.name();
String newText = directive + "\n" + text;
if (!newText.equals(text)) {
System.err.println("\"" + directive + "\" was added to \"" + testDataFile + "\"");
FileUtil.writeToFile(testDataFile, newText);
}
}
if (RUN_IGNORED_TESTS_AS_REGULAR || !isIgnored) {
throw e;
}
e.printStackTrace();
return;
}
if (isIgnored) {
if (AUTOMATICALLY_UNMUTE_PASSED_TESTS) {
String text = doLoadFile(testDataFile);
String directive = InTextDirectivesUtils.IGNORE_BACKEND_DIRECTIVE_PREFIX + targetBackend.name();
String newText = Pattern.compile("^" + directive + "\n", Pattern.MULTILINE).matcher(text).replaceAll("");
if (!newText.equals(text)) {
System.err.println("\"" + directive + "\" was removed from \"" + testDataFile + "\"");
FileUtil.writeToFile(testDataFile, newText);
}
}
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive.");
}
}
public static String getTestsRoot(@NotNull Class<?> testCaseClass) {
TestMetadata testClassMetadata = testCaseClass.getAnnotation(TestMetadata.class);
Assert.assertNotNull("No metadata for class: " + testCaseClass, testClassMetadata);
@@ -87,18 +87,20 @@ import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.jetbrains.kotlin.test.InTextDirectivesUtils.isCompatibleTarget;
import static org.jetbrains.kotlin.test.InTextDirectivesUtils.isDirectiveDefined;
import static org.jetbrains.kotlin.test.InTextDirectivesUtils.*;
public class KotlinTestUtils {
public static String TEST_MODULE_NAME = "test-module";
public static final String TEST_GENERATOR_NAME = "org.jetbrains.kotlin.generators.tests.TestsPackage";
public static final String PLEASE_REGENERATE_TESTS = "Please regenerate tests (GenerateTests.kt)";
private static final String PLEASE_REGENERATE_TESTS = "Please regenerate tests (GenerateTests.kt)";
public static final boolean RUN_IGNORED_TESTS_AS_REGULAR =
private static final boolean RUN_IGNORED_TESTS_AS_REGULAR =
Boolean.getBoolean("org.jetbrains.kotlin.run.ignored.tests.as.regular");
private static final boolean AUTOMATICALLY_UNMUTE_PASSED_TESTS = true;
private static final boolean AUTOMATICALLY_MUTE_FAILED_TESTS = false;
private static final List<File> filesToDelete = new ArrayList<>();
/**
@@ -1011,6 +1013,69 @@ public class KotlinTestUtils {
return testFile;
}
public interface DoTest {
void invoke(String filePath) throws Exception;
}
// In this test runner version the `testDataFile` parameter is annotated by `TestDataFile`.
// So only file paths passed to this parameter will be used in navigation actions, like "Navigate to testdata" and "Related Symbol..."
public static void runTest(DoTest test, TargetBackend targetBackend, @TestDataFile String testDataFile) throws Exception {
runTest0(test, targetBackend, testDataFile);
}
// In this test runner version, NONE of the parameters are annotated by `TestDataFile`.
// So DevKit will use test name to determine related files in navigation actions, like "Navigate to testdata" and "Related Symbol..."
//
// Pro:
// * in most cases, it shows all related files including generated js files, for example.
// Cons:
// * sometimes, for too common/general names, it shows many variants to navigate
// * it adds an additional step for navigation -- you must choose an exact file to navigate
public static void runTest0(DoTest test, TargetBackend targetBackend, String testDataFilePath) throws Exception {
File testDataFile = new File(testDataFilePath);
boolean isIgnored = isIgnoredTarget(targetBackend, testDataFile);
try {
test.invoke(testDataFilePath);
}
catch (Throwable e) {
if (!isIgnored && AUTOMATICALLY_MUTE_FAILED_TESTS) {
String text = doLoadFile(testDataFile);
String directive = InTextDirectivesUtils.IGNORE_BACKEND_DIRECTIVE_PREFIX + targetBackend.name();
String newText = directive + "\n" + text;
if (!newText.equals(text)) {
System.err.println("\"" + directive + "\" was added to \"" + testDataFile + "\"");
FileUtil.writeToFile(testDataFile, newText);
}
}
if (RUN_IGNORED_TESTS_AS_REGULAR || !isIgnored) {
throw e;
}
e.printStackTrace();
return;
}
if (isIgnored) {
if (AUTOMATICALLY_UNMUTE_PASSED_TESTS) {
String text = doLoadFile(testDataFile);
String directive = InTextDirectivesUtils.IGNORE_BACKEND_DIRECTIVE_PREFIX + targetBackend.name();
String newText = Pattern.compile("^" + directive + "\n", Pattern.MULTILINE).matcher(text).replaceAll("");
if (!newText.equals(text)) {
System.err.println("\"" + directive + "\" was removed from \"" + testDataFile + "\"");
FileUtil.writeToFile(testDataFile, newText);
}
}
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive.");
}
}
public static String getTestsRoot(@NotNull Class<?> testCaseClass) {
TestMetadata testClassMetadata = testCaseClass.getAnnotation(TestMetadata.class);
Assert.assertNotNull("No metadata for class: " + testCaseClass, testClassMetadata);
@@ -87,18 +87,20 @@ import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.jetbrains.kotlin.test.InTextDirectivesUtils.isCompatibleTarget;
import static org.jetbrains.kotlin.test.InTextDirectivesUtils.isDirectiveDefined;
import static org.jetbrains.kotlin.test.InTextDirectivesUtils.*;
public class KotlinTestUtils {
public static String TEST_MODULE_NAME = "test-module";
public static final String TEST_GENERATOR_NAME = "org.jetbrains.kotlin.generators.tests.TestsPackage";
public static final String PLEASE_REGENERATE_TESTS = "Please regenerate tests (GenerateTests.kt)";
private static final String PLEASE_REGENERATE_TESTS = "Please regenerate tests (GenerateTests.kt)";
public static final boolean RUN_IGNORED_TESTS_AS_REGULAR =
private static final boolean RUN_IGNORED_TESTS_AS_REGULAR =
Boolean.getBoolean("org.jetbrains.kotlin.run.ignored.tests.as.regular");
private static final boolean AUTOMATICALLY_UNMUTE_PASSED_TESTS = true;
private static final boolean AUTOMATICALLY_MUTE_FAILED_TESTS = false;
private static final List<File> filesToDelete = new ArrayList<>();
/**
@@ -1011,6 +1013,69 @@ public class KotlinTestUtils {
return testFile;
}
public interface DoTest {
void invoke(String filePath) throws Exception;
}
// In this test runner version the `testDataFile` parameter is annotated by `TestDataFile`.
// So only file paths passed to this parameter will be used in navigation actions, like "Navigate to testdata" and "Related Symbol..."
public static void runTest(DoTest test, TargetBackend targetBackend, @TestDataFile String testDataFile) throws Exception {
runTest0(test, targetBackend, testDataFile);
}
// In this test runner version, NONE of the parameters are annotated by `TestDataFile`.
// So DevKit will use test name to determine related files in navigation actions, like "Navigate to testdata" and "Related Symbol..."
//
// Pro:
// * in most cases, it shows all related files including generated js files, for example.
// Cons:
// * sometimes, for too common/general names, it shows many variants to navigate
// * it adds an additional step for navigation -- you must choose an exact file to navigate
public static void runTest0(DoTest test, TargetBackend targetBackend, String testDataFilePath) throws Exception {
File testDataFile = new File(testDataFilePath);
boolean isIgnored = isIgnoredTarget(targetBackend, testDataFile);
try {
test.invoke(testDataFilePath);
}
catch (Throwable e) {
if (!isIgnored && AUTOMATICALLY_MUTE_FAILED_TESTS) {
String text = doLoadFile(testDataFile);
String directive = InTextDirectivesUtils.IGNORE_BACKEND_DIRECTIVE_PREFIX + targetBackend.name();
String newText = directive + "\n" + text;
if (!newText.equals(text)) {
System.err.println("\"" + directive + "\" was added to \"" + testDataFile + "\"");
FileUtil.writeToFile(testDataFile, newText);
}
}
if (RUN_IGNORED_TESTS_AS_REGULAR || !isIgnored) {
throw e;
}
e.printStackTrace();
return;
}
if (isIgnored) {
if (AUTOMATICALLY_UNMUTE_PASSED_TESTS) {
String text = doLoadFile(testDataFile);
String directive = InTextDirectivesUtils.IGNORE_BACKEND_DIRECTIVE_PREFIX + targetBackend.name();
String newText = Pattern.compile("^" + directive + "\n", Pattern.MULTILINE).matcher(text).replaceAll("");
if (!newText.equals(text)) {
System.err.println("\"" + directive + "\" was removed from \"" + testDataFile + "\"");
FileUtil.writeToFile(testDataFile, newText);
}
}
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive.");
}
}
public static String getTestsRoot(@NotNull Class<?> testCaseClass) {
TestMetadata testClassMetadata = testCaseClass.getAnnotation(TestMetadata.class);
Assert.assertNotNull("No metadata for class: " + testCaseClass, testClassMetadata);
@@ -87,18 +87,20 @@ import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.jetbrains.kotlin.test.InTextDirectivesUtils.isCompatibleTarget;
import static org.jetbrains.kotlin.test.InTextDirectivesUtils.isDirectiveDefined;
import static org.jetbrains.kotlin.test.InTextDirectivesUtils.*;
public class KotlinTestUtils {
public static String TEST_MODULE_NAME = "test-module";
public static final String TEST_GENERATOR_NAME = "org.jetbrains.kotlin.generators.tests.TestsPackage";
public static final String PLEASE_REGENERATE_TESTS = "Please regenerate tests (GenerateTests.kt)";
private static final String PLEASE_REGENERATE_TESTS = "Please regenerate tests (GenerateTests.kt)";
public static final boolean RUN_IGNORED_TESTS_AS_REGULAR =
private static final boolean RUN_IGNORED_TESTS_AS_REGULAR =
Boolean.getBoolean("org.jetbrains.kotlin.run.ignored.tests.as.regular");
private static final boolean AUTOMATICALLY_UNMUTE_PASSED_TESTS = true;
private static final boolean AUTOMATICALLY_MUTE_FAILED_TESTS = false;
private static final List<File> filesToDelete = new ArrayList<>();
/**
@@ -1011,6 +1013,69 @@ public class KotlinTestUtils {
return testFile;
}
public interface DoTest {
void invoke(String filePath) throws Exception;
}
// In this test runner version the `testDataFile` parameter is annotated by `TestDataFile`.
// So only file paths passed to this parameter will be used in navigation actions, like "Navigate to testdata" and "Related Symbol..."
public static void runTest(DoTest test, TargetBackend targetBackend, @TestDataFile String testDataFile) throws Exception {
runTest0(test, targetBackend, testDataFile);
}
// In this test runner version, NONE of the parameters are annotated by `TestDataFile`.
// So DevKit will use test name to determine related files in navigation actions, like "Navigate to testdata" and "Related Symbol..."
//
// Pro:
// * in most cases, it shows all related files including generated js files, for example.
// Cons:
// * sometimes, for too common/general names, it shows many variants to navigate
// * it adds an additional step for navigation -- you must choose an exact file to navigate
public static void runTest0(DoTest test, TargetBackend targetBackend, String testDataFilePath) throws Exception {
File testDataFile = new File(testDataFilePath);
boolean isIgnored = isIgnoredTarget(targetBackend, testDataFile);
try {
test.invoke(testDataFilePath);
}
catch (Throwable e) {
if (!isIgnored && AUTOMATICALLY_MUTE_FAILED_TESTS) {
String text = doLoadFile(testDataFile);
String directive = InTextDirectivesUtils.IGNORE_BACKEND_DIRECTIVE_PREFIX + targetBackend.name();
String newText = directive + "\n" + text;
if (!newText.equals(text)) {
System.err.println("\"" + directive + "\" was added to \"" + testDataFile + "\"");
FileUtil.writeToFile(testDataFile, newText);
}
}
if (RUN_IGNORED_TESTS_AS_REGULAR || !isIgnored) {
throw e;
}
e.printStackTrace();
return;
}
if (isIgnored) {
if (AUTOMATICALLY_UNMUTE_PASSED_TESTS) {
String text = doLoadFile(testDataFile);
String directive = InTextDirectivesUtils.IGNORE_BACKEND_DIRECTIVE_PREFIX + targetBackend.name();
String newText = Pattern.compile("^" + directive + "\n", Pattern.MULTILINE).matcher(text).replaceAll("");
if (!newText.equals(text)) {
System.err.println("\"" + directive + "\" was removed from \"" + testDataFile + "\"");
FileUtil.writeToFile(testDataFile, newText);
}
}
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive.");
}
}
public static String getTestsRoot(@NotNull Class<?> testCaseClass) {
TestMetadata testClassMetadata = testCaseClass.getAnnotation(TestMetadata.class);
Assert.assertNotNull("No metadata for class: " + testCaseClass, testClassMetadata);
@@ -5,20 +5,14 @@
package org.jetbrains.kotlin.test
import java.io.File
enum class TargetBackend(
private val compatibleWithTargetBackend: TargetBackend? = null,
// if whitelist === null it will not be used in test generator (will work as usual)
// if path to testData file starts with or equals to any entry from whitelist it will be processed as usual
// otherwise a testData file will be treated as ignored
val whitelist: List<File>? = null
private val compatibleWithTargetBackend: TargetBackend? = null
) {
ANY,
JVM,
JVM_IR(JVM),
JS,
JS_IR(JS, JS_IR_BACKEND_TEST_WHITELIST);
JS_IR(JS);
val compatibleWith get() = compatibleWithTargetBackend ?: ANY
}
@@ -1,151 +0,0 @@
/*
* 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.test
import java.io.File
val JS_IR_BACKEND_TEST_WHITELIST = listOf(
"js/js.translator/testData/box/examples/funDelegation.kt",
"js/js.translator/testData/box/examples/incrementProperty.kt",
"js/js.translator/testData/box/examples/inheritedMethod.kt",
"js/js.translator/testData/box/examples/initializerBlock.kt",
"js/js.translator/testData/box/examples/kt242.kt",
"js/js.translator/testData/box/examples/newInstanceDefaultConstructor.kt",
"js/js.translator/testData/box/examples/propertyDelegation.kt",
"js/js.translator/testData/box/examples/rightHandOverride.kt",
"js/js.translator/testData/box/expression/equals/stringsEqual.kt",
"js/js.translator/testData/box/expression/evaluationOrder/ifAsPlusArgument.kt",
"js/js.translator/testData/box/expression/evaluationOrder/secondaryConstructorTemporaryVars.kt",
"js/js.translator/testData/box/expression/identifierClash/overloadedFun.kt",
"js/js.translator/testData/box/expression/identifierClash/useVariableOfNameOfFunction.kt",
"js/js.translator/testData/box/expression/identityEquals/identityEqualsMethod.kt",
"js/js.translator/testData/box/expression/invoke/internalFunctionFromSuperclass.kt",
"js/js.translator/testData/box/expression/invoke/invokeWithDispatchReceiver.kt",
"js/js.translator/testData/box/expression/misc/classWithoutPackage.kt",
"js/js.translator/testData/box/expression/misc/KT-740-3.kt",
"js/js.translator/testData/box/expression/misc/localProperty.kt",
"js/js.translator/testData/box/expression/misc/propertiesWithExplicitlyDefinedAccessorsWithoutBodies.kt",
"js/js.translator/testData/box/expression/stringClass/kt2227_2.kt",
"js/js.translator/testData/box/expression/stringClass/kt2227.kt",
"js/js.translator/testData/box/expression/stringClass/objectToStringCallInTemplate.kt",
"js/js.translator/testData/box/expression/stringClass/stringAssignment.kt",
"js/js.translator/testData/box/expression/stringClass/stringConstant.kt",
"js/js.translator/testData/box/expression/stringTemplates/nonStrings.kt",
"js/js.translator/testData/box/expression/when/doWhileWithOneStmWhen.kt",
"js/js.translator/testData/box/expression/when/empty.kt",
"js/js.translator/testData/box/expression/when/ifWithOneStmWhen.kt",
"js/js.translator/testData/box/expression/when/kt1665.kt",
"js/js.translator/testData/box/expression/when/whenValue.kt",
"js/js.translator/testData/box/expression/when/whenWithOneStmWhen.kt",
"js/js.translator/testData/box/expression/when/whenWithOnlyElse.kt",
"js/js.translator/testData/box/expression/when/whenWithoutExpression.kt",
"js/js.translator/testData/box/extensionFunction/extensionFunctionCalledFromExtensionFunction.kt",
"js/js.translator/testData/box/extensionProperty/inClass.kt",
"js/js.translator/testData/box/inheritance/abstractVarOverride.kt",
"js/js.translator/testData/box/inheritance/baseCall.kt",
"js/js.translator/testData/box/inheritance/initializersOfBasicClassExecute.kt",
"js/js.translator/testData/box/inheritance/methodOverride.kt",
"js/js.translator/testData/box/inheritance/valOverride.kt",
"js/js.translator/testData/box/inheritance/valuePassedToAncestorConstructor.kt",
"js/js.translator/testData/box/inheritance/withInitializeMethod.kt",
"js/js.translator/testData/box/initialize/rootPackageValInit.kt",
"js/js.translator/testData/box/initialize/rootValInit.kt",
"js/js.translator/testData/box/inline/sameNameOfDeclarationsInSameModule.kt",
"js/js.translator/testData/box/multideclaration/multiValOrVar.kt",
"js/js.translator/testData/box/multiFile/functionsVisibleFromOtherFile.kt",
"js/js.translator/testData/box/multiPackage/createClassFromOtherPackage.kt",
"js/js.translator/testData/box/multiPackage/createClassFromOtherPackageUsingImport.kt",
"js/js.translator/testData/box/multiPackage/functionsVisibleFromOtherPackage.kt",
"js/js.translator/testData/box/multiPackage/nestedPackageFunctionCalledFromOtherPackage.kt",
"js/js.translator/testData/box/multiPackage/subpackagesWithClashingNames.kt",
"js/js.translator/testData/box/multiPackage/subpackagesWithClashingNamesUsingImport.kt",
"js/js.translator/testData/box/nameClashes/differenceInCapitalization.kt",
"js/js.translator/testData/box/nameClashes/methodOverload.kt",
"js/js.translator/testData/box/operatorOverloading/binaryDivOverload.kt",
"js/js.translator/testData/box/operatorOverloading/compareTo.kt",
"js/js.translator/testData/box/operatorOverloading/compareToByName.kt",
"js/js.translator/testData/box/operatorOverloading/notOverload.kt",
"js/js.translator/testData/box/operatorOverloading/plusOverload.kt",
"js/js.translator/testData/box/operatorOverloading/postfixInc.kt",
"js/js.translator/testData/box/operatorOverloading/prefixDecOverload.kt",
"js/js.translator/testData/box/operatorOverloading/prefixIncReturnsCorrectValue.kt",
"js/js.translator/testData/box/operatorOverloading/unaryOnIntPropertyAsStatement.kt",
"js/js.translator/testData/box/operatorOverloading/usingModInCaseModAssignNotAvailable.kt",
"js/js.translator/testData/box/package/classCreatedInDeeplyNestedPackage.kt",
"js/js.translator/testData/box/package/deeplyNestedPackage.kt",
"js/js.translator/testData/box/package/deeplyNestedPackageFunctionCalled.kt",
"js/js.translator/testData/box/package/initializersOfNestedPackagesExecute.kt",
"js/js.translator/testData/box/package/nestedPackage.kt",
"js/js.translator/testData/box/propertyAccess/accessToInstanceProperty.kt",
"js/js.translator/testData/box/propertyAccess/customGetter.kt",
"js/js.translator/testData/box/propertyAccess/customSetter.kt",
"js/js.translator/testData/box/propertyAccess/field.kt",
"js/js.translator/testData/box/propertyAccess/initInstanceProperties.kt",
"js/js.translator/testData/box/propertyAccess/initValInConstructor.kt",
"js/js.translator/testData/box/propertyAccess/packageCustomAccessors.kt",
"js/js.translator/testData/box/propertyAccess/packagePropertyInitializer.kt",
"js/js.translator/testData/box/propertyAccess/packagePropertySet.kt",
"js/js.translator/testData/box/propertyAccess/twoClassesWithProperties.kt",
"js/js.translator/testData/box/propertyOverride/overrideExtensionProperty.kt",
"js/js.translator/testData/box/safeCall/safeCall.kt",
"js/js.translator/testData/box/simple/assign.kt",
"js/js.translator/testData/box/simple/breakDoWhile.kt",
"js/js.translator/testData/box/simple/breakWhile.kt",
"js/js.translator/testData/box/simple/classInstantiation.kt",
"js/js.translator/testData/box/simple/comparison.kt",
"js/js.translator/testData/box/simple/complexExpressionAsConstructorParameter.kt",
"js/js.translator/testData/box/simple/constructorWithParameter.kt",
"js/js.translator/testData/box/simple/constructorWithPropertiesAsParameters.kt",
"js/js.translator/testData/box/simple/continueDoWhile.kt",
"js/js.translator/testData/box/simple/continueWhile.kt",
"js/js.translator/testData/box/simple/doWhile.kt",
"js/js.translator/testData/box/simple/doWhile2.kt",
"js/js.translator/testData/box/simple/elseif.kt",
"js/js.translator/testData/box/simple/if.kt",
"js/js.translator/testData/box/simple/ifElseAsExpression.kt",
"js/js.translator/testData/box/simple/methodDeclarationAndCall.kt",
"js/js.translator/testData/box/simple/minusAssignOnProperty.kt",
"js/js.translator/testData/box/simple/notBoolean.kt",
"js/js.translator/testData/box/simple/plusAssign.kt",
"js/js.translator/testData/box/simple/positiveAndNegativeNumbers.kt",
"js/js.translator/testData/box/simple/prefixIntOperations.kt",
"js/js.translator/testData/box/simple/primCtorDelegation1.kt",
"js/js.translator/testData/box/simple/propertiesAsParametersInitialized.kt",
"js/js.translator/testData/box/simple/propertyAccess.kt",
"js/js.translator/testData/box/simple/secCtorDelegation1.kt",
"js/js.translator/testData/box/simple/secCtorDelegation2.kt",
"js/js.translator/testData/box/simple/secCtorDelegation3.kt",
"js/js.translator/testData/box/simple/secCtorDelegation4.kt",
"js/js.translator/testData/box/simple/simpleInitializer.kt",
"js/js.translator/testData/box/simple/while.kt",
"js/js.translator/testData/box/simple/while2.kt",
"js/js.translator/testData/box/trait/funDelegation.kt"
).map { File(it) }
@@ -34,7 +34,8 @@ import java.io.IOException;
public abstract class AbstractModuleXmlParserTest extends TestCase {
protected static void doTest(String xmlPath) throws IOException {
@SuppressWarnings("MethodMayBeStatic")
protected void doTest(String xmlPath) throws IOException {
File txtFile = new File(FileUtil.getNameWithoutExtension(xmlPath) + ".txt");
ModuleChunk result = ModuleXmlParser.parseModuleScript(xmlPath, new MessageCollector() {
@@ -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 {
@@ -17,7 +17,7 @@ fun main(args: Array<String>) {
// TODO: repair these tests
//generateTestDataForReservedWords()
testGroup("js/js.tests/test", "js/js.translator/testData") {
testGroup("js/js.tests/test", "js/js.translator/testData", testRunnerMethodName = "runTest0") {
testClass<AbstractBoxJsTest> {
model("box/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS)
}
@@ -43,7 +43,7 @@ fun main(args: Array<String>) {
}
}
testGroup("js/js.tests/test", "compiler/testData") {
testGroup("js/js.tests/test", "compiler/testData", testRunnerMethodName = "runTest0") {
testClass<AbstractJsCodegenBoxTest> {
model("codegen/box", targetBackend = TargetBackend.JS)
}