Improve multi-file test framework in CodegenTestCase

Instead of inheriting from KotlinMultiFileTestWithJava, invoke
KotlinTestUtils.createTestFiles directly. This helps to avoid constructing
unnecessary environment (createEnvironment() was called in setUp, but codegen
tests ignored the created environment because it's not possible to do
generically in codegen tests; the environment kind depends on the source file
usually)
This commit is contained in:
Alexander Udalov
2016-02-29 11:50:49 +03:00
parent 4b96a8131b
commit 0b26e749f6
7 changed files with 61 additions and 42 deletions
@@ -54,6 +54,7 @@ public abstract class KotlinMultiFileTestWithJava<M, F> extends KotlinTestWithEn
@Override
protected KotlinCoreEnvironment createEnvironment() throws Exception {
// TODO: do not create temporary directory for tests without Java sources
javaFilesDir = KotlinTestUtils.tmpDir("java-files");
CompilerConfiguration configuration = KotlinTestUtils.compilerConfigurationForTests(
getConfigurationKind(),
@@ -93,11 +94,6 @@ public abstract class KotlinMultiFileTestWithJava<M, F> extends KotlinTestWithEn
return false;
}
@NotNull
protected final File getJavaFilesDir() {
return javaFilesDir;
}
protected void doTest(String filePath) throws Exception {
File file = new File(filePath);
@@ -45,16 +45,15 @@ import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import static org.jetbrains.kotlin.codegen.CodegenTestUtil.compileJava;
public abstract class AbstractBlackBoxCodegenTest extends CodegenTestCase {
@Override
protected void doMultiFileTest(File file, Map<String, ModuleAndDependencies> modules, List<TestFile> files) throws Exception {
protected void doMultiFileTest(@NotNull File wholeFile, @NotNull List<TestFile> files, @Nullable File javaFilesDir) throws Exception {
if (files.size() == 1) {
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
blackBoxFileByFullPath(file.getPath());
blackBoxFileByFullPath(wholeFile.getPath());
}
else {
doTestMultiFile(files);
@@ -16,14 +16,11 @@
package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.checkers.KotlinMultiFileTestWithJava
import org.jetbrains.kotlin.test.ConfigurationKind
import java.io.File
abstract class AbstractBlackBoxInlineCodegenTest : AbstractBlackBoxCodegenTest() {
override fun doMultiFileTest(
file: File, modules: Map<String, KotlinMultiFileTestWithJava<Void, TestFile>.ModuleAndDependencies>, files: List<TestFile>
) {
override fun doMultiFileTest(file: File, files: List<TestFile>, javaFilesDir: File?) {
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.ALL)
loadMultiFiles(files)
blackBox()
@@ -20,6 +20,7 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import kotlin.text.Charsets;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.test.ConfigurationKind;
import org.jetbrains.kotlin.utils.ExceptionUtilsKt;
@@ -36,15 +37,15 @@ public abstract class AbstractBytecodeTextTest extends CodegenTestCase {
private static final Pattern EXPECTED_OCCURRENCES_PATTERN = Pattern.compile("^\\s*//\\s*(\\d+)\\s*(.*)$");
@Override
protected void doMultiFileTest(File file, Map<String, ModuleAndDependencies> modules, List<TestFile> files) throws Exception {
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.ALL, getJavaFilesDir());
protected void doMultiFileTest(@NotNull File wholeFile, @NotNull List<TestFile> files, @Nullable File javaFilesDir) throws Exception {
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.ALL, javaFilesDir);
loadMultiFiles(files);
if (isMultiFileTest(files)) {
doTestMultiFile(files);
}
else {
List<OccurrenceInfo> expected = readExpectedOccurrences(file.getPath());
List<OccurrenceInfo> expected = readExpectedOccurrences(wholeFile.getPath());
String actual = generateToText();
checkGeneratedTextAgainstExpectedOccurrences(actual, expected);
}
@@ -16,14 +16,11 @@
package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.checkers.KotlinMultiFileTestWithJava
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
import java.io.File
abstract class AbstractCompileKotlinAgainstInlineKotlinTest : AbstractCompileKotlinAgainstKotlinTest() {
override fun doMultiFileTest(
file: File, modules: Map<String, KotlinMultiFileTestWithJava<Void, TestFile>.ModuleAndDependencies>, files: List<TestFile>
) {
override fun doMultiFileTest(wholeFile: File, files: List<TestFile>, javaFilesDir: File?) {
val kotlinFiles = files.filter { it.name.endsWith(".kt") }
assert(kotlinFiles.size == 2) { "There should be exactly two files in this test" }
@@ -20,6 +20,7 @@ import com.intellij.openapi.Disposable;
import com.intellij.openapi.util.Disposer;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.cli.common.modules.ModuleBuilder;
import org.jetbrains.kotlin.cli.common.output.outputUtils.OutputUtilsKt;
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles;
@@ -39,7 +40,6 @@ import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.List;
import java.util.Map;
public abstract class AbstractCompileKotlinAgainstKotlinTest extends CodegenTestCase {
private File tmpdir;
@@ -57,7 +57,7 @@ public abstract class AbstractCompileKotlinAgainstKotlinTest extends CodegenTest
}
@Override
protected void doMultiFileTest(File file, Map<String, ModuleAndDependencies> modules, List<TestFile> files) throws Exception {
protected void doMultiFileTest(@NotNull File wholeFile, @NotNull List<TestFile> files, @Nullable File javaFilesDir) throws Exception {
// Note that it may be beneficial to improve this test to handle many files, compiling them successively against all previous
assert files.size() == 2 : "There should be exactly two files in this test";
TestFile fileA = files.get(0);
@@ -17,14 +17,17 @@
package org.jetbrains.kotlin.codegen;
import com.google.common.collect.Lists;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.testFramework.TestDataFile;
import com.intellij.util.SmartList;
import com.intellij.testFramework.UsefulTestCase;
import kotlin.collections.ArraysKt;
import kotlin.io.FilesKt;
import kotlin.text.Charsets;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.backend.common.output.OutputFile;
import org.jetbrains.kotlin.checkers.CheckerTestUtil;
import org.jetbrains.kotlin.checkers.KotlinMultiFileTestWithJava;
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles;
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment;
import org.jetbrains.kotlin.cli.jvm.config.JvmContentRootsKt;
@@ -63,7 +66,7 @@ import static org.jetbrains.kotlin.codegen.CodegenTestUtil.*;
import static org.jetbrains.kotlin.test.KotlinTestUtils.compilerConfigurationForTests;
import static org.jetbrains.kotlin.test.KotlinTestUtils.getAnnotationsJar;
public abstract class CodegenTestCase extends KotlinMultiFileTestWithJava<Void, CodegenTestCase.TestFile> {
public abstract class CodegenTestCase extends UsefulTestCase {
private static final String DEFAULT_TEST_FILE_NAME = "a_test";
protected KotlinCoreEnvironment myEnvironment;
@@ -72,19 +75,22 @@ public abstract class CodegenTestCase extends KotlinMultiFileTestWithJava<Void,
protected GeneratedClassLoader initializedClassLoader;
protected ConfigurationKind configurationKind;
final protected void createEnvironmentWithMockJdkAndIdeaAnnotations(@NotNull ConfigurationKind configurationKind, File... javaSourceRoot) {
protected final void createEnvironmentWithMockJdkAndIdeaAnnotations(
@NotNull ConfigurationKind configurationKind,
@Nullable File... javaSourceRoots
) {
if (myEnvironment != null) {
throw new IllegalStateException("must not set up myEnvironment twice");
}
CompilerConfiguration configuration =
compilerConfigurationForTests(configurationKind, TestJdkKind.MOCK_JDK,
Collections.singletonList(getAnnotationsJar()), new SmartList<File>(javaSourceRoot));
CompilerConfiguration configuration = compilerConfigurationForTests(
configurationKind, TestJdkKind.MOCK_JDK, Collections.singletonList(getAnnotationsJar()),
ArraysKt.filterNotNull(javaSourceRoots)
);
myEnvironment = KotlinCoreEnvironment.createForTests(
getTestRootDisposable(),
configuration,
EnvironmentConfigFiles.JVM_CONFIG_FILES);
getTestRootDisposable(), configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES
);
}
@Override
@@ -373,19 +379,42 @@ public abstract class CodegenTestCase extends KotlinMultiFileTestWithJava<Void,
}
}
@Override
protected Void createTestModule(@NotNull String name) {
// TODO: support multi-module codegen tests
throw new UnsupportedOperationException("Multi-module codegen tests are not yet supported");
protected void doTest(String filePath) throws Exception {
File file = new File(filePath);
String expectedText = KotlinTestUtils.doLoadFile(file);
final Ref<File> javaFilesDir = Ref.create();
List<TestFile> testFiles =
KotlinTestUtils.createTestFiles(file.getName(), expectedText, new KotlinTestUtils.TestFileFactoryNoModules<TestFile>() {
@NotNull
@Override
public TestFile create(@NotNull String fileName, @NotNull String text, @NotNull Map<String, String> directives) {
if (fileName.endsWith(".java")) {
if (javaFilesDir.isNull()) {
try {
javaFilesDir.set(KotlinTestUtils.tmpDir("java-files"));
}
catch (IOException e) {
throw ExceptionUtilsKt.rethrow(e);
}
}
writeSourceFile(fileName, text, javaFilesDir.get());
}
return new TestFile(fileName, text);
}
private void writeSourceFile(@NotNull String fileName, @NotNull String content, @NotNull File targetDir) {
File file = new File(targetDir, fileName);
KotlinTestUtils.mkdirs(file.getParentFile());
FilesKt.writeText(file, content, Charsets.UTF_8);
}
});
doMultiFileTest(file, testFiles, javaFilesDir.get());
}
@Override
protected TestFile createTestFile(Void module, String fileName, String text, Map<String, String> directives) {
return new TestFile(fileName, text);
}
@Override
protected void doMultiFileTest(File file, Map<String, ModuleAndDependencies> modules, List<TestFile> files) throws Exception {
protected void doMultiFileTest(@NotNull File wholeFile, @NotNull List<TestFile> files, @Nullable File javaFilesDir) throws Exception {
throw new UnsupportedOperationException("Multi-file test cases are not supported in this test");
}
}