From 0c8ca5f930f259f443f368fb61d27b5f2e4e6223 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Fri, 26 May 2017 12:40:47 +0300 Subject: [PATCH] Extract some functions from test class into base class To be used in other tests which will be subclasses of AbstractKotlinCompilerIntegrationTest --- .../AbstractKotlinCompilerIntegrationTest.kt | 146 ++++++++++++++++++ .../CompileKotlinAgainstCustomBinariesTest.kt | 123 +-------------- 2 files changed, 153 insertions(+), 116 deletions(-) create mode 100644 compiler/tests/org/jetbrains/kotlin/jvm/compiler/AbstractKotlinCompilerIntegrationTest.kt diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/AbstractKotlinCompilerIntegrationTest.kt b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/AbstractKotlinCompilerIntegrationTest.kt new file mode 100644 index 00000000000..faeaac17ab5 --- /dev/null +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/AbstractKotlinCompilerIntegrationTest.kt @@ -0,0 +1,146 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +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.common.CLICompiler +import org.jetbrains.kotlin.cli.common.ExitCode +import org.jetbrains.kotlin.cli.js.K2JSCompiler +import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler +import org.jetbrains.kotlin.test.KotlinTestUtils +import org.jetbrains.kotlin.test.TestCaseWithTmpdir +import java.io.File +import java.util.regex.Pattern +import java.util.zip.ZipOutputStream + +abstract class AbstractKotlinCompilerIntegrationTest : TestCaseWithTmpdir() { + protected abstract val testDataPath: String + + protected val testDataDirectory: File + get() = File(testDataPath, getTestName(true)) + + protected fun getTestDataFileWithExtension(extension: String): File { + 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] + */ + protected fun compileLibrary( + libraryName: String, + destination: File = File(tmpdir, "$libraryName.jar"), + additionalOptions: List = emptyList(), + vararg extraClassPath: File + ): File { + 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" + */ + protected 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 { + return AbstractCliTest.getNormalizedCompilerOutput(output.first, output.second, testDataDirectory.path) + .replace(FileUtil.toSystemIndependentName(tmpdir.absolutePath), "\$TMP_DIR\$") + } + + protected fun compileKotlin( + fileName: String, + output: File, + classpath: List = emptyList(), + compiler: CLICompiler<*> = K2JVMCompiler(), + additionalOptions: List = emptyList(), + expectedFileName: String? = "output.txt" + ): Pair { + val args = mutableListOf() + val sourceFile = File(testDataDirectory, fileName) + assert(sourceFile.exists()) { "Source file does not exist: ${sourceFile.absolutePath}" } + args.add(sourceFile.path) + + if (compiler is K2JSCompiler) { + if (classpath.isNotEmpty()) { + args.add("-libraries") + args.add(classpath.joinToString(File.pathSeparator)) + } + args.add("-output") + args.add(output.path) + args.add("-meta-info") + } + else if (compiler is K2JVMCompiler) { + if (classpath.isNotEmpty()) { + args.add("-classpath") + args.add(classpath.joinToString(File.pathSeparator)) + } + args.add("-d") + args.add(output.path) + } + else { + throw UnsupportedOperationException(compiler.toString()) + } + + args.addAll(additionalOptions) + + val result = AbstractCliTest.executeCompilerGrabOutput(compiler, args) + if (expectedFileName != null) { + KotlinTestUtils.assertEqualsToFile(File(testDataDirectory, expectedFileName), normalizeOutput(result)) + } + return result + } + + companion object { + private val KOTLIN_FILES = Pattern.compile(".*\\.kt$") + private val JAVA_FILES = Pattern.compile(".*\\.java$") + } +} diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt index a3579148808..92e7dff3aa1 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt @@ -17,11 +17,8 @@ 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 -import org.jetbrains.kotlin.cli.common.ExitCode import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport import org.jetbrains.kotlin.cli.common.messages.MessageRenderer import org.jetbrains.kotlin.cli.common.messages.PrintingMessageCollector @@ -38,7 +35,10 @@ import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils.isObject import org.jetbrains.kotlin.resolve.lazy.JvmResolveUtil -import org.jetbrains.kotlin.test.* +import org.jetbrains.kotlin.test.ConfigurationKind +import org.jetbrains.kotlin.test.KotlinTestUtils +import org.jetbrains.kotlin.test.MockLibraryUtil +import org.jetbrains.kotlin.test.TestJdkKind import org.jetbrains.kotlin.test.util.RecursiveDescriptorComparator.validateAndCompareDescriptorWithFile import org.jetbrains.kotlin.utils.JsMetadataVersion import org.jetbrains.org.objectweb.asm.ClassReader @@ -48,74 +48,12 @@ import org.jetbrains.org.objectweb.asm.Opcodes import java.io.File import java.util.jar.JarEntry import java.util.jar.JarFile -import java.util.regex.Pattern import java.util.zip.ZipOutputStream import kotlin.experimental.xor -class CompileKotlinAgainstCustomBinariesTest : TestCaseWithTmpdir() { - private val testDataDirectory: File - get() = File(TEST_DATA_PATH, getTestName(true)) - - private fun getTestDataFileWithExtension(extension: String): File { - 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( - libraryName: String, - destination: File = File(tmpdir, "$libraryName.jar"), - additionalOptions: List = emptyList(), - vararg extraClassPath: File - ): File { - 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 { - return AbstractCliTest.getNormalizedCompilerOutput(output.first, output.second, testDataDirectory.path) - .replace(FileUtil.toSystemIndependentName(tmpdir.absolutePath), "\$TMP_DIR\$") - } +class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegrationTest() { + override val testDataPath: String + get() = "compiler/testData/compileKotlinAgainstCustomBinaries/" private fun doTestWithTxt(vararg extraClassPath: File) { validateAndCompareDescriptorWithFile( @@ -144,49 +82,6 @@ class CompileKotlinAgainstCustomBinariesTest : TestCaseWithTmpdir() { private fun analyzeAndGetAllDescriptors(vararg extraClassPath: File): Collection = DescriptorUtils.getAllDescriptors(analyzeFileToPackageView(*extraClassPath).memberScope) - private fun compileKotlin( - fileName: String, - output: File, - classpath: List = emptyList(), - compiler: CLICompiler<*> = K2JVMCompiler(), - additionalOptions: List = emptyList(), - expectedFileName: String? = "output.txt" - ): Pair { - val args = mutableListOf() - val sourceFile = File(testDataDirectory, fileName) - assert(sourceFile.exists()) { "Source file does not exist: ${sourceFile.absolutePath}" } - args.add(sourceFile.path) - - if (compiler is K2JSCompiler) { - if (classpath.isNotEmpty()) { - args.add("-libraries") - args.add(classpath.joinToString(File.pathSeparator)) - } - args.add("-output") - args.add(output.path) - args.add("-meta-info") - } - else if (compiler is K2JVMCompiler) { - if (classpath.isNotEmpty()) { - args.add("-classpath") - args.add(classpath.joinToString(File.pathSeparator)) - } - args.add("-d") - args.add(output.path) - } - else { - throw UnsupportedOperationException(compiler.toString()) - } - - args.addAll(additionalOptions) - - val result = AbstractCliTest.executeCompilerGrabOutput(compiler, args) - if (expectedFileName != null) { - KotlinTestUtils.assertEqualsToFile(File(testDataDirectory, expectedFileName), normalizeOutput(result)) - } - return result - } - 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 @@ -490,10 +385,6 @@ 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 = transformJar(jarPath, { _, bytes -> bytes }, entriesToDelete.toSet())