Refactor CompileKotlinAgainstCustomBinariesTest

Combine compileLibrary and compileJava into a universal compileLibrary
which compiles both .java and .kt files, either to a directory or to a
.jar file. Also introduce compileJsLibrary for JS only
This commit is contained in:
Alexander Udalov
2017-05-25 19:52:43 +03:00
parent dae414854d
commit da0ecc6cf7
2 changed files with 77 additions and 74 deletions
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.jvm.compiler
import com.intellij.openapi.util.io.FileUtil
import com.intellij.util.io.ZipUtil
import org.jetbrains.kotlin.cli.AbstractCliTest
import org.jetbrains.kotlin.cli.WrongBytecodeVersionTest
import org.jetbrains.kotlin.cli.common.CLICompiler
@@ -59,18 +60,58 @@ class CompileKotlinAgainstCustomBinariesTest : TestCaseWithTmpdir() {
return File(testDataDirectory, "${getTestName(true)}.$extension")
}
/**
* Compiles all sources (.java and .kt) under the directory named [libraryName] to [destination].
* [destination] should be either a path to the directory under [tmpdir], or a path to the resulting .jar file (also under [tmpdir]).
* Kotlin sources are compiled first, and there should be no errors or warnings. Java sources are compiled next.
*
* @return [destination]
*/
private fun compileLibrary(
sourcePath: String,
compiler: CLICompiler<*> = K2JVMCompiler(),
destination: File = File(tmpdir, "$sourcePath.jar"),
libraryName: String,
destination: File = File(tmpdir, "$libraryName.jar"),
additionalOptions: List<String> = emptyList(),
vararg extraClassPath: File
): File {
val output = compileKotlin(sourcePath, destination, extraClassPath.toList(), compiler, additionalOptions, expectedFileName = null)
assertEquals(normalizeOutput("" to ExitCode.OK), normalizeOutput(output))
val javaFiles = FileUtil.findFilesByMask(JAVA_FILES, File(testDataDirectory, libraryName))
val kotlinFiles = FileUtil.findFilesByMask(KOTLIN_FILES, File(testDataDirectory, libraryName))
assert(javaFiles.isNotEmpty() || kotlinFiles.isNotEmpty()) { "There should be either .kt or .java files in the directory" }
val isJar = destination.name.endsWith(".jar")
val outputDir = if (isJar) File(tmpdir, "output-$libraryName") else destination
if (kotlinFiles.isNotEmpty()) {
val output = compileKotlin(libraryName, outputDir, extraClassPath.toList(), K2JVMCompiler(), additionalOptions, expectedFileName = null)
assertEquals(normalizeOutput("" to ExitCode.OK), normalizeOutput(output))
}
if (javaFiles.isNotEmpty()) {
outputDir.mkdirs()
KotlinTestUtils.compileJavaFiles(javaFiles, listOf("-d", outputDir.path))
}
if (isJar) {
destination.delete()
ZipOutputStream(destination.outputStream()).use { zip ->
ZipUtil.addDirToZipRecursively(zip, destination, outputDir, "", null, null)
}
}
return destination
}
/**
* Compiles all .kt sources under the directory named [libraryName] to a file named "[libraryName].js" in [tmpdir]
*
* @return the path to the corresponding .meta.js file, i.e. "[libraryName].meta.js"
*/
private fun compileJsLibrary(libraryName: String): File {
val destination = File(tmpdir, "$libraryName.js")
val output = compileKotlin(libraryName, destination, compiler = K2JSCompiler(), expectedFileName = null)
assertEquals(normalizeOutput("" to ExitCode.OK), normalizeOutput(output))
return File(tmpdir, "$libraryName.meta.js")
}
private fun normalizeOutput(output: Pair<String, ExitCode>): String {
return AbstractCliTest.getNormalizedCompilerOutput(output.first, output.second, testDataDirectory.path)
.replace(FileUtil.toSystemIndependentName(tmpdir.absolutePath), "\$TMP_DIR\$")
@@ -103,14 +144,6 @@ class CompileKotlinAgainstCustomBinariesTest : TestCaseWithTmpdir() {
private fun analyzeAndGetAllDescriptors(vararg extraClassPath: File): Collection<DeclarationDescriptor> =
DescriptorUtils.getAllDescriptors(analyzeFileToPackageView(*extraClassPath).memberScope)
private fun compileJava(libraryDir: String): File {
val allJavaFiles = FileUtil.findFilesByMask(JAVA_FILES, File(testDataDirectory, libraryDir))
val result = File(tmpdir, libraryDir)
assert(result.mkdirs()) { "Could not create directory: $result" }
KotlinTestUtils.compileJavaFiles(allJavaFiles, listOf("-d", result.path))
return result
}
private fun compileKotlin(
fileName: String,
output: File,
@@ -154,15 +187,9 @@ class CompileKotlinAgainstCustomBinariesTest : TestCaseWithTmpdir() {
return result
}
private fun doTestBrokenJavaLibrary(libraryName: String, vararg pathsToDelete: String) {
// This function compiles a Java library, then deletes one class file and attempts to compile a Kotlin source against
private fun doTestBrokenLibrary(libraryName: String, vararg pathsToDelete: String) {
// This function compiles a library, then deletes one class file and attempts to compile a Kotlin source against
// this broken library. The expected result is an error message from the compiler
val library = deletePaths(compileJava(libraryName), *pathsToDelete)
compileKotlin("source.kt", tmpdir, listOf(library))
}
private fun doTestBrokenKotlinLibrary(libraryName: String, vararg pathsToDelete: String) {
// Analogous to doTestBrokenJavaLibrary, but with a Kotlin library compiled to a JAR file
val library = copyJarFileWithoutEntry(compileLibrary(libraryName), *pathsToDelete)
compileKotlin("source.kt", tmpdir, listOf(library))
}
@@ -186,9 +213,8 @@ class CompileKotlinAgainstCustomBinariesTest : TestCaseWithTmpdir() {
}
private fun doTestKotlinLibraryWithWrongMetadataVersionJs(libraryName: String, vararg additionalOptions: String) {
compileLibrary(libraryName, K2JSCompiler(), File(tmpdir, "library.js"), emptyList())
val library = compileJsLibrary(libraryName)
val library = File(tmpdir, "library.meta.js")
library.writeText(library.readText(Charsets.UTF_8).replace(
"(" + JsMetadataVersion.INSTANCE.toInteger() + ", ",
"(" + JsMetadataVersion(42, 0, 0).toInteger() + ", "
@@ -200,16 +226,18 @@ class CompileKotlinAgainstCustomBinariesTest : TestCaseWithTmpdir() {
private fun doTestPreReleaseKotlinLibrary(
compiler: CLICompiler<*>,
libraryName: String,
destination: File,
result: File,
usageDestination: File,
vararg additionalOptions: String
) {
// Compiles the library with the "pre-release" flag, then compiles a usage of this library in the release mode
try {
val result = try {
System.setProperty(TEST_IS_PRE_RELEASE_SYSTEM_PROPERTY, "true")
compileLibrary(libraryName, compiler, destination)
when (compiler) {
is K2JSCompiler -> compileJsLibrary(libraryName)
is K2JVMCompiler -> compileLibrary(libraryName)
else -> throw UnsupportedOperationException(compiler.toString())
}
}
finally {
System.clearProperty(TEST_IS_PRE_RELEASE_SYSTEM_PROPERTY)
@@ -227,9 +255,7 @@ class CompileKotlinAgainstCustomBinariesTest : TestCaseWithTmpdir() {
// ------------------------------------------------------------------------------
fun testRawTypes() {
val libraryOutput = compileJava("library")
compileKotlin("library", libraryOutput, listOf(libraryOutput))
compileKotlin("main.kt", tmpdir, listOf(libraryOutput))
compileKotlin("main.kt", tmpdir, listOf(compileLibrary("library")))
}
fun testDuplicateObjectInBinaryAndSources() {
@@ -259,8 +285,8 @@ class CompileKotlinAgainstCustomBinariesTest : TestCaseWithTmpdir() {
// This test checks that there are no PARAMETER_NAME_CHANGED_ON_OVERRIDE or DIFFERENT_NAMES_FOR_THE_SAME_PARAMETER_IN_SUPERTYPES
// warnings when subclassing in Kotlin from Java binaries (in case when no parameter names are available for Java classes)
val libraryOutput = compileJava("library")
val environment = createEnvironment(listOf(libraryOutput))
val library = compileLibrary("library")
val environment = createEnvironment(listOf(library))
val ktFile = KotlinTestUtils.loadJetFile(environment.project, getTestDataFileWithExtension("kt"))
val result = JvmResolveUtil.analyze(ktFile, environment)
@@ -275,23 +301,23 @@ class CompileKotlinAgainstCustomBinariesTest : TestCaseWithTmpdir() {
}
fun testIncompleteHierarchyInJava() {
doTestBrokenJavaLibrary("library", "test/Super.class")
doTestBrokenLibrary("library", "test/Super.class")
}
fun testIncompleteHierarchyInKotlin() {
doTestBrokenKotlinLibrary("library", "test/Super.class")
doTestBrokenLibrary("library", "test/Super.class")
}
fun testMissingDependencySimple() {
doTestBrokenKotlinLibrary("library", "a/A.class")
doTestBrokenLibrary("library", "a/A.class")
}
fun testMissingDependencyDifferentCases() {
doTestBrokenKotlinLibrary("library", "a/A.class")
doTestBrokenLibrary("library", "a/A.class")
}
fun testMissingDependencyNestedAnnotation() {
doTestBrokenKotlinLibrary("library", "a/A\$Anno.class")
doTestBrokenLibrary("library", "a/A\$Anno.class")
}
fun testMissingDependencyConflictingLibraries() {
@@ -303,48 +329,33 @@ class CompileKotlinAgainstCustomBinariesTest : TestCaseWithTmpdir() {
}
fun testMissingDependencyJava() {
doTestBrokenJavaLibrary("library", "test/Bar.class")
doTestBrokenLibrary("library", "test/Bar.class")
}
fun testMissingDependencyJavaConflictingLibraries() {
val library1 = deletePaths(compileJava("library1"), "test/A.class", "test/A\$Inner.class")
val library2 = deletePaths(compileJava("library2"), "test/A.class", "test/A\$Inner.class")
val library1 = copyJarFileWithoutEntry(compileLibrary("library1"), "test/A.class", "test/A\$Inner.class")
val library2 = copyJarFileWithoutEntry(compileLibrary("library2"), "test/A.class", "test/A\$Inner.class")
compileKotlin("source.kt", tmpdir, listOf(library1, library2))
}
fun testMissingDependencyJavaNestedAnnotation() {
doTestBrokenJavaLibrary("library", "test/A\$Anno.class")
doTestBrokenLibrary("library", "test/A\$Anno.class")
}
fun testReleaseCompilerAgainstPreReleaseLibrary() {
val destination = File(tmpdir, "library.jar")
doTestPreReleaseKotlinLibrary(K2JVMCompiler(), "library", destination, destination, tmpdir)
doTestPreReleaseKotlinLibrary(K2JVMCompiler(), "library", tmpdir)
}
fun testReleaseCompilerAgainstPreReleaseLibraryJs() {
doTestPreReleaseKotlinLibrary(
K2JSCompiler(), "library",
File(tmpdir, "library.js"), File(tmpdir, "library.meta.js"),
File(tmpdir, "usage.js")
)
doTestPreReleaseKotlinLibrary(K2JSCompiler(), "library", File(tmpdir, "usage.js"))
}
fun testReleaseCompilerAgainstPreReleaseLibrarySkipVersionCheck() {
val destination = File(tmpdir, "library.jar")
doTestPreReleaseKotlinLibrary(
K2JVMCompiler(), "library",
destination, destination, tmpdir,
"-Xskip-metadata-version-check"
)
doTestPreReleaseKotlinLibrary(K2JVMCompiler(), "library", tmpdir, "-Xskip-metadata-version-check")
}
fun testReleaseCompilerAgainstPreReleaseLibraryJsSkipVersionCheck() {
doTestPreReleaseKotlinLibrary(
K2JSCompiler(), "library",
File(tmpdir, "library.js"), File(tmpdir, "library.meta.js"),
File(tmpdir, "usage.js"),
"-Xskip-metadata-version-check"
)
doTestPreReleaseKotlinLibrary(K2JSCompiler(), "library", File(tmpdir, "usage.js"), "-Xskip-metadata-version-check")
}
fun testWrongMetadataVersion() {
@@ -439,25 +450,24 @@ class CompileKotlinAgainstCustomBinariesTest : TestCaseWithTmpdir() {
fun testProhibitNestedClassesByDollarName() {
val library = compileLibrary("library")
val javaLibraryOutput = compileJava("library")
compileKotlin("main.kt", tmpdir, listOf(javaLibraryOutput, library))
compileKotlin("main.kt", tmpdir, listOf(library))
}
fun testTypeAliasesAreInvisibleInCompatibilityMode() {
val library = compileLibrary("typeAliases.kt")
val library = compileLibrary("library")
compileKotlin("main.kt", tmpdir, listOf(library), K2JVMCompiler(), listOf("-language-version", "1.0"))
}
fun testInnerClassPackageConflict() {
val output = compileJava("library")
val output = compileLibrary("library", destination = File(tmpdir, "library"))
File(testDataDirectory, "library/test/Foo/x.txt").copyTo(File(output, "test/Foo/x.txt"))
MockLibraryUtil.createJarFile(tmpdir, output, null, "library", false)
compileKotlin("source.kt", tmpdir, listOf(File(tmpdir, "library.jar")))
}
fun testInnerClassPackageConflict2() {
val library1 = compileJava("library1")
val library2 = compileJava("library2")
val library1 = compileLibrary("library1", destination = File(tmpdir, "library1"))
val library2 = compileLibrary("library2", destination = File(tmpdir, "library2"))
// Copy everything from library2 to library1
FileUtil.visitFiles(library2) { file ->
@@ -481,6 +491,7 @@ class CompileKotlinAgainstCustomBinariesTest : TestCaseWithTmpdir() {
companion object {
private val TEST_DATA_PATH = "compiler/testData/compileKotlinAgainstCustomBinaries/"
private val KOTLIN_FILES = Pattern.compile(".*\\.kt$")
private val JAVA_FILES = Pattern.compile(".*\\.java$")
private fun copyJarFileWithoutEntry(jarPath: File, vararg entriesToDelete: String): File =
@@ -512,13 +523,5 @@ class CompileKotlinAgainstCustomBinariesTest : TestCaseWithTmpdir() {
return outputFile
}
private fun deletePaths(library: File, vararg pathsToDelete: String): File {
for (pathToDelete in pathsToDelete) {
val fileToDelete = File(library, pathToDelete)
assert(fileToDelete.delete()) { "Can't delete $fileToDelete" }
}
return library
}
}
}