diff --git a/plugins/scripting/scripting-compiler/tests/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptingCompilerPluginTest.kt b/plugins/scripting/scripting-compiler/tests/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptingCompilerPluginTest.kt index 1ab75f8fdf5..340fd877e1b 100644 --- a/plugins/scripting/scripting-compiler/tests/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptingCompilerPluginTest.kt +++ b/plugins/scripting/scripting-compiler/tests/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptingCompilerPluginTest.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.scripting.compiler.plugin +import com.intellij.openapi.Disposable import junit.framework.TestCase import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys import org.jetbrains.kotlin.cli.common.ExitCode @@ -29,7 +30,6 @@ import org.jetbrains.kotlin.scripting.definitions.discoverScriptTemplatesInClass import org.jetbrains.kotlin.scripting.definitions.loadScriptTemplatesFromClasspath import org.jetbrains.kotlin.test.ConfigurationKind import org.jetbrains.kotlin.test.KotlinTestUtils -import org.jetbrains.kotlin.test.TestCaseWithTmpdir import org.jetbrains.kotlin.test.TestJdkKind import org.jetbrains.kotlin.utils.KotlinPaths import org.jetbrains.kotlin.utils.PathUtil @@ -37,7 +37,7 @@ import org.junit.Assert import java.io.File import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration -class ScriptingCompilerPluginTest : TestCaseWithTmpdir() { +class ScriptingCompilerPluginTest : TestCase() { companion object { const val TEST_DATA_DIR = "plugins/scripting/scripting-compiler/testData" @@ -54,7 +54,11 @@ class ScriptingCompilerPluginTest : TestCaseWithTmpdir() { val scriptingClasspath = listOf("kotlin-scripting-common.jar").map { File(kotlinPaths.libPath, it) } private fun createEnvironment( - sources: List, destDir: File, messageCollector: MessageCollector, confBody: CompilerConfiguration.() -> Unit + sources: List, + destDir: File, + messageCollector: MessageCollector, + disposable: Disposable, + confBody: CompilerConfiguration.() -> Unit ): KotlinCoreEnvironment { val configuration = KotlinTestUtils.newConfiguration(ConfigurationKind.NO_KOTLIN_REFLECT, TestJdkKind.FULL_JDK).apply { put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector) @@ -64,7 +68,7 @@ class ScriptingCompilerPluginTest : TestCaseWithTmpdir() { } configuration.add(ComponentRegistrar.PLUGIN_COMPONENT_REGISTRARS, ScriptingCompilerConfigurationComponentRegistrar()) - return KotlinCoreEnvironment.createForTests(testRootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES) + return KotlinCoreEnvironment.createForTests(disposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES) } fun testScriptResolverEnvironmentArgsParsing() { @@ -90,138 +94,150 @@ class ScriptingCompilerPluginTest : TestCaseWithTmpdir() { fun testLazyScriptDefinitionDiscovery() { - // Three tests in one function: the direct loading, the discovery code separately, and as a part of regular compilation - // tests are combined to avoid multiple compilation of script definition modules + withTempDir { tmpdir -> + withDisposable { disposable -> + // Three tests in one function: the direct loading, the discovery code separately, and as a part of regular compilation + // tests are combined to avoid multiple compilation of script definition modules - val defsOut = File(tmpdir, "testLazyScriptDefinition/out/defs") - val defsSrc = File(TEST_DATA_DIR, "lazyDefinitions/definitions") - val scriptsOut = File(tmpdir, "testLazyScriptDefinition/out/scripts") - val scriptsSrc = File(TEST_DATA_DIR, "lazyDefinitions/scripts") - val scriptsOut2 = File(tmpdir, "testLazyScriptDefinition/out/scripts2") - val defClasses = listOf("TestScriptWithReceivers", "TestScriptWithSimpleEnvVars") + val defsOut = File(tmpdir, "testLazyScriptDefinition/out/defs") + val defsSrc = File(TEST_DATA_DIR, "lazyDefinitions/definitions") + val scriptsOut = File(tmpdir, "testLazyScriptDefinition/out/scripts") + val scriptsSrc = File(TEST_DATA_DIR, "lazyDefinitions/scripts") + val scriptsOut2 = File(tmpdir, "testLazyScriptDefinition/out/scripts2") + val defClasses = listOf("TestScriptWithReceivers", "TestScriptWithSimpleEnvVars") - val messageCollector = TestMessageCollector() + val messageCollector = TestMessageCollector() - val definitionsCompileResult = KotlinToJVMBytecodeCompiler.compileBunchOfSources( - createEnvironment(defClasses.map { File(defsSrc, "$it.kt").canonicalPath }, defsOut, messageCollector) { - addJvmClasspathRoots(runtimeClasspath) - addJvmClasspathRoots(scriptingClasspath) - } - ) + val definitionsCompileResult = KotlinToJVMBytecodeCompiler.compileBunchOfSources( + createEnvironment(defClasses.map { File(defsSrc, "$it.kt").canonicalPath }, defsOut, messageCollector, disposable) { + addJvmClasspathRoots(runtimeClasspath) + addJvmClasspathRoots(scriptingClasspath) + } + ) - assertTrue(definitionsCompileResult) { - "Compilation of script definitions failed: $messageCollector" - } + assertTrue(definitionsCompileResult) { + "Compilation of script definitions failed: $messageCollector" + } - messageCollector.clear() + messageCollector.clear() - loadScriptTemplatesFromClasspath( - listOf("TestScriptWithReceivers", "TestScriptWithSimpleEnvVars"), - listOf(defsOut), emptyList(), this::class.java.classLoader, defaultJvmScriptingHostConfiguration, messageCollector.reporter - ).toList() + loadScriptTemplatesFromClasspath( + listOf("TestScriptWithReceivers", "TestScriptWithSimpleEnvVars"), + listOf(defsOut), + emptyList(), + this::class.java.classLoader, + defaultJvmScriptingHostConfiguration, + messageCollector.reporter + ).toList() - for (def in defClasses) { - assertTrue(messageCollector.messages.any { it.message.contains("Configure scripting: Added template $def") }) { - "Missing messages from loading sequence (should contain \"Added template $def\"):\n$messageCollector" - } - assertTrue(messageCollector.messages.none { it.message.contains("Configure scripting: loading script definition class $def") }) { - "Unexpected messages from loading sequence (should not contain \"loading script definition class $def\"):\n$messageCollector" + for (def in defClasses) { + assertTrue(messageCollector.messages.any { it.message.contains("Configure scripting: Added template $def") }) { + "Missing messages from loading sequence (should contain \"Added template $def\"):\n$messageCollector" + } + assertTrue(messageCollector.messages.none { it.message.contains("Configure scripting: loading script definition class $def") }) { + "Unexpected messages from loading sequence (should not contain \"loading script definition class $def\"):\n$messageCollector" + } + } + + messageCollector.clear() + + // chacking lazy discovery + + val templatesDir = File(defsOut, SCRIPT_DEFINITION_MARKERS_PATH).also { it.mkdirs() } + for (def in defClasses) { + File(templatesDir, def).createNewFile() + } + + val lazyDefsSeq = + discoverScriptTemplatesInClasspath( + listOf(defsOut), + this::class.java.classLoader, + defaultJvmScriptingHostConfiguration, + messageCollector.reporter + ) + + assertTrue(messageCollector.messages.isEmpty()) { + "Unexpected messages from discovery sequence (should be empty):\n$messageCollector" + } + + val lazyDefs = lazyDefsSeq.toList() + + for (def in defClasses) { + assertTrue(messageCollector.messages.any { it.message.contains("Configure scripting: Added template $def") }) { + "Missing messages from discovery sequence (should contain \"Added template $def\"):\n$messageCollector" + } + assertTrue(messageCollector.messages.none { it.message.contains("Configure scripting: loading script definition class $def") }) { + "Unexpected messages from discovery sequence (should not contain \"loading script definition class $def\"):\n$messageCollector" + } + } + + messageCollector.clear() + + val scriptFiles = scriptsSrc.listFiles { file: File -> file.extension == "kts" }.map { it.canonicalPath } + + val scriptsCompileEnv = createEnvironment(scriptFiles, scriptsOut, messageCollector, disposable) { + addJvmClasspathRoots(runtimeClasspath) + addJvmClasspathRoots(scriptingClasspath) + addJvmClasspathRoot(defsOut) + addAll(ScriptingConfigurationKeys.SCRIPT_DEFINITIONS, lazyDefs) + } + + val res = KotlinToJVMBytecodeCompiler.compileBunchOfSources(scriptsCompileEnv) + + assertTrue(res) { + "Failed to compile scripts:\n$messageCollector" + } + + val cp = (runtimeClasspath + scriptingClasspath + defsOut).joinToString(File.pathSeparator) + val exitCode = K2JVMCompiler().exec(System.err, "-cp", cp, *(scriptFiles.toTypedArray()), "-d", scriptsOut2.canonicalPath) + + Assert.assertEquals(ExitCode.OK, exitCode) } } - - messageCollector.clear() - - // chacking lazy discovery - - val templatesDir = File(defsOut, SCRIPT_DEFINITION_MARKERS_PATH).also { it.mkdirs() } - for (def in defClasses) { - File(templatesDir, def).createNewFile() - } - - val lazyDefsSeq = - discoverScriptTemplatesInClasspath( - listOf(defsOut), - this::class.java.classLoader, - defaultJvmScriptingHostConfiguration, - messageCollector.reporter - ) - - assertTrue(messageCollector.messages.isEmpty()) { - "Unexpected messages from discovery sequence (should be empty):\n$messageCollector" - } - - val lazyDefs = lazyDefsSeq.toList() - - for (def in defClasses) { - assertTrue(messageCollector.messages.any { it.message.contains("Configure scripting: Added template $def") }) { - "Missing messages from discovery sequence (should contain \"Added template $def\"):\n$messageCollector" - } - assertTrue(messageCollector.messages.none { it.message.contains("Configure scripting: loading script definition class $def") }) { - "Unexpected messages from discovery sequence (should not contain \"loading script definition class $def\"):\n$messageCollector" - } - } - - messageCollector.clear() - - val scriptFiles = scriptsSrc.listFiles { file: File -> file.extension == "kts" }.map { it.canonicalPath} - - val scriptsCompileEnv = createEnvironment(scriptFiles, scriptsOut, messageCollector) { - addJvmClasspathRoots(runtimeClasspath) - addJvmClasspathRoots(scriptingClasspath) - addJvmClasspathRoot(defsOut) - addAll(ScriptingConfigurationKeys.SCRIPT_DEFINITIONS, lazyDefs) - } - - val res = KotlinToJVMBytecodeCompiler.compileBunchOfSources(scriptsCompileEnv) - - assertTrue(res) { - "Failed to compile scripts:\n$messageCollector" - } - - val cp = (runtimeClasspath + scriptingClasspath + defsOut).joinToString(File.pathSeparator) - val exitCode = K2JVMCompiler().exec(System.err, "-cp", cp, *(scriptFiles.toTypedArray()), "-d", scriptsOut2.canonicalPath) - - Assert.assertEquals(ExitCode.OK, exitCode) } fun testLazyScriptDefinitionOtherAnnotation() { - val defsOut = File(tmpdir, "testLazyScriptDefinition/out/otherAnn") - val defsSrc = File(TEST_DATA_DIR, "lazyDefinitions/definitions") - val defClasses = listOf("TestScriptWithOtherAnnotation") + withTempDir { tmpdir -> + withDisposable { disposable -> + val defsOut = File(tmpdir, "testLazyScriptDefinition/out/otherAnn") + val defsSrc = File(TEST_DATA_DIR, "lazyDefinitions/definitions") + val defClasses = listOf("TestScriptWithOtherAnnotation") - val messageCollector = TestMessageCollector() + val messageCollector = TestMessageCollector() - val definitionsCompileResult = KotlinToJVMBytecodeCompiler.compileBunchOfSources( - createEnvironment(defClasses.map { File(defsSrc, "$it.kt").canonicalPath }, defsOut, messageCollector) { - addJvmClasspathRoots(runtimeClasspath) - addJvmClasspathRoots(scriptingClasspath) + val definitionsCompileResult = KotlinToJVMBytecodeCompiler.compileBunchOfSources( + createEnvironment(defClasses.map { File(defsSrc, "$it.kt").canonicalPath }, defsOut, messageCollector, disposable) { + addJvmClasspathRoots(runtimeClasspath) + addJvmClasspathRoots(scriptingClasspath) + } + ) + + assertTrue(definitionsCompileResult) { + "Compilation of script definitions failed: $messageCollector" + } + + val templatesDir = File(defsOut, SCRIPT_DEFINITION_MARKERS_PATH).also { it.mkdirs() } + for (def in defClasses) { + File(templatesDir, def).createNewFile() + } + + messageCollector.clear() + + discoverScriptTemplatesInClasspath( + listOf(defsOut), + this::class.java.classLoader, + defaultJvmScriptingHostConfiguration, + messageCollector.reporter + ).toList() + + assertTrue( + messageCollector.messages.isNotEmpty() + && messageCollector.messages.all { it.message.contains("s not marked with any known kotlin script annotation") } + ) { + "Unexpected messages from discovery sequence:\n$messageCollector" + } } - ) - - assertTrue(definitionsCompileResult) { - "Compilation of script definitions failed: $messageCollector" - } - - val templatesDir = File(defsOut, SCRIPT_DEFINITION_MARKERS_PATH).also { it.mkdirs() } - for (def in defClasses) { - File(templatesDir, def).createNewFile() - } - - messageCollector.clear() - - discoverScriptTemplatesInClasspath( - listOf(defsOut), - this::class.java.classLoader, - defaultJvmScriptingHostConfiguration, - messageCollector.reporter - ).toList() - - assertTrue( - messageCollector.messages.isNotEmpty() - && messageCollector.messages.all { it.message.contains("s not marked with any known kotlin script annotation") } - ) { - "Unexpected messages from discovery sequence:\n$messageCollector" } } } diff --git a/plugins/scripting/scripting-compiler/tests/org/jetbrains/kotlin/scripting/compiler/plugin/testUtil.kt b/plugins/scripting/scripting-compiler/tests/org/jetbrains/kotlin/scripting/compiler/plugin/testUtil.kt index 5ca69dd93c2..3e893a1504e 100644 --- a/plugins/scripting/scripting-compiler/tests/org/jetbrains/kotlin/scripting/compiler/plugin/testUtil.kt +++ b/plugins/scripting/scripting-compiler/tests/org/jetbrains/kotlin/scripting/compiler/plugin/testUtil.kt @@ -5,6 +5,8 @@ package org.jetbrains.kotlin.scripting.compiler.plugin +import com.intellij.openapi.Disposable +import com.intellij.openapi.util.Disposer import junit.framework.Assert import org.jetbrains.kotlin.cli.common.CLITool import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler @@ -12,6 +14,7 @@ import java.io.ByteArrayOutputStream import java.io.File import java.io.InputStream import java.io.PrintStream +import java.nio.file.Files import java.util.concurrent.TimeUnit import kotlin.concurrent.thread @@ -151,3 +154,22 @@ internal fun captureOutErrRet(body: () -> T): Triple { return Triple(outStream.toString().trim(), errStream.toString().trim(), ret) } +internal fun withTempDir(keyName: String = "tmp", body: (File) -> R) { + val tempDir = Files.createTempDirectory(keyName).toFile() + try { + body(tempDir) + } finally { + tempDir.deleteRecursively() + } +} + +internal fun withDisposable(body: (Disposable) -> R) { + val disposable = Disposer.newDisposable() + try { + body(disposable) + } finally { + Disposer.dispose(disposable) + } +} + +