REPL: Extract IDE-specific tests to a separate test set
diff --git a/plugins/scripting/scripting-ide-services-test/build.gradle.kts b/plugins/scripting/scripting-ide-services-test/build.gradle.kts
index 283b7af..85465d2 100644
--- a/plugins/scripting/scripting-ide-services-test/build.gradle.kts
+++ b/plugins/scripting/scripting-ide-services-test/build.gradle.kts
@@ -67,4 +67,6 @@
workingDir = rootDir
dependsOn(embeddableTestRuntime)
classpath = embeddableTestRuntime
+
+ exclude("**/JvmReplIdeTest.class")
}
diff --git a/plugins/scripting/scripting-ide-services-test/test/org/jetbrains/kotlin/scripting/ide_services/JvmReplIdeTest.kt b/plugins/scripting/scripting-ide-services-test/test/org/jetbrains/kotlin/scripting/ide_services/JvmReplIdeTest.kt
new file mode 100644
index 0000000..7d8357b
--- /dev/null
+++ b/plugins/scripting/scripting-ide-services-test/test/org/jetbrains/kotlin/scripting/ide_services/JvmReplIdeTest.kt
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * 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.scripting.ide_services
+
+import com.intellij.mock.MockApplication
+import com.intellij.openapi.application.ApplicationManager
+import com.intellij.openapi.vfs.VirtualFileManager
+import com.intellij.util.indexing.FileContentImpl
+import junit.framework.TestCase
+import org.jetbrains.kotlin.analysis.decompiler.psi.KotlinClassFileDecompiler
+import org.jetbrains.kotlin.analysis.decompiler.stub.file.ClsKotlinBinaryClassCache
+import org.jetbrains.kotlin.analysis.decompiler.stub.file.FileAttributeService
+import org.jetbrains.kotlin.analysis.decompiler.stub.files.DummyFileAttributeService
+import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
+import org.jetbrains.kotlin.psi.stubs.KotlinClassStub
+import org.jetbrains.kotlin.scripting.compiler.plugin.impl.KJvmCompiledModuleInMemoryImpl
+import org.jetbrains.kotlin.scripting.ide_services.test_util.JvmTestRepl
+import org.jetbrains.kotlin.scripting.ide_services.test_util.checkCompile
+import java.io.File
+import kotlin.io.path.ExperimentalPathApi
+import kotlin.io.path.createTempDirectory
+import kotlin.script.experimental.jvm.impl.KJvmCompiledModuleInMemory
+import kotlin.script.experimental.util.get
+
+// This test checks the functionality that works only in IDE
+// and doesn't run with embeddableTest configuration
+class JvmReplIdeTest : TestCase() {
+ fun testReplScriptClassFileDecompilation() {
+ JvmTestRepl()
+ .use { repl ->
+ val compiledSnippet = checkCompile(repl, "10 + 10")
+ val snippetValue = compiledSnippet.get()!!
+
+ val compiledModule = snippetValue.getCompiledModule() as KJvmCompiledModuleInMemoryImpl
+ val folder = saveCompiledOutput("repl-script-decompilation", compiledModule)
+
+ val scriptClassName = "Line_0_simplescript"
+ val fileUrl = "file://" + folder.resolve("$scriptClassName.class").invariantSeparatorsPath
+ val vFile = VirtualFileManager.getInstance().findFileByUrl(fileUrl)!!
+ val fileContent = FileContentImpl.createByContent(vFile, vFile.contentsToByteArray(false))
+
+ val application = ApplicationManager.getApplication() as MockApplication
+ KotlinCoreEnvironment.underApplicationLock {
+ registerDecompilerServices(application)
+ }
+
+ val fileStub = KotlinClassFileDecompiler().stubBuilder.buildFileStub(fileContent)!!
+ val childrenStubs = fileStub.childrenStubs
+ assertTrue(childrenStubs.any { it is KotlinClassStub && it.name == scriptClassName })
+ }
+ }
+
+ @OptIn(ExperimentalPathApi::class)
+ companion object {
+ private val outputJarDir = createTempDirectory("temp-ide-services-ide-test")
+
+ private fun saveCompiledOutput(subfolder: String, module: KJvmCompiledModuleInMemory): File {
+ val folder = outputJarDir.resolve(subfolder).toFile()
+ module.compilerOutputFiles.forEach { (name, contents) ->
+ val file = folder.resolve(name)
+ file.parentFile.mkdirs()
+ file.writeBytes(contents)
+ }
+ return folder
+ }
+
+ private fun registerDecompilerServices(application: MockApplication) {
+ application.registerService(FileAttributeService::class.java, DummyFileAttributeService)
+ application.registerService(ClsKotlinBinaryClassCache::class.java, ClsKotlinBinaryClassCache())
+ }
+ }
+}
\ No newline at end of file
diff --git a/plugins/scripting/scripting-ide-services-test/test/org/jetbrains/kotlin/scripting/ide_services/JvmReplTest.kt b/plugins/scripting/scripting-ide-services-test/test/org/jetbrains/kotlin/scripting/ide_services/JvmReplTest.kt
index 222200a..b9afcd8 100644
--- a/plugins/scripting/scripting-ide-services-test/test/org/jetbrains/kotlin/scripting/ide_services/JvmReplTest.kt
+++ b/plugins/scripting/scripting-ide-services-test/test/org/jetbrains/kotlin/scripting/ide_services/JvmReplTest.kt
@@ -5,23 +5,12 @@
package org.jetbrains.kotlin.scripting.ide_services
-import com.intellij.mock.MockApplication
-import com.intellij.openapi.application.ApplicationManager
-import com.intellij.openapi.vfs.VirtualFileManager
-import com.intellij.util.indexing.FileContentImpl
import junit.framework.TestCase
-import org.jetbrains.kotlin.analysis.decompiler.psi.KotlinClassFileDecompiler
-import org.jetbrains.kotlin.analysis.decompiler.stub.file.ClsKotlinBinaryClassCache
-import org.jetbrains.kotlin.analysis.decompiler.stub.file.FileAttributeService
-import org.jetbrains.kotlin.analysis.decompiler.stub.files.DummyFileAttributeService
import org.jetbrains.kotlin.cli.common.ExitCode
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
-import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocationWithRange
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
-import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.config.Services
-import org.jetbrains.kotlin.scripting.compiler.plugin.impl.KJvmCompiledModuleInMemoryImpl
import org.jetbrains.kotlin.scripting.ide_services.test_util.*
import java.io.File
import kotlin.io.path.ExperimentalPathApi
@@ -29,15 +18,11 @@
import kotlin.io.path.invariantSeparatorsPathString
import kotlin.reflect.full.isSubclassOf
import kotlin.script.experimental.api.*
-import kotlin.script.experimental.jvm.impl.KJvmCompiledModuleInMemory
-import kotlin.script.experimental.jvm.impl.KJvmCompiledScript
import kotlin.script.experimental.jvm.jvm
import kotlin.script.experimental.jvm.updateClasspath
import kotlin.script.experimental.jvm.util.isError
import kotlin.script.experimental.jvm.util.isIncomplete
import kotlin.script.experimental.jvm.util.scriptCompilationClasspathFromContext
-import kotlin.script.experimental.util.LinkedSnippet
-import kotlin.script.experimental.util.get
// Adapted form GenericReplTest
@@ -353,28 +338,6 @@
}
}
- fun testReplScriptClassFileDecompilation() {
- JvmTestRepl()
- .use { repl ->
- val compiledSnippet = checkCompile(repl, "10 + 10")
- val snippetValue = compiledSnippet.get()!!
-
- val compiledModule = snippetValue.getCompiledModule() as KJvmCompiledModuleInMemoryImpl
- val folder = saveCompiledOutput("repl-script-decompilation", compiledModule)
-
- val vFile = VirtualFileManager.getInstance().findFileByNioPath(folder.resolve("Line_0_simplescript.class").toPath())!!
- val fileContent = FileContentImpl.createByFile(vFile)
-
- val application = ApplicationManager.getApplication() as MockApplication
- KotlinCoreEnvironment.underApplicationLock {
- registerDecompilerServices(application)
- }
-
- val fileStub = KotlinClassFileDecompiler().stubBuilder.buildFileStub(fileContent)
- assertNotNull(fileStub)
- }
- }
-
@OptIn(ExperimentalPathApi::class)
companion object {
private const val MODULE_PATH = "plugins/scripting/scripting-ide-services-test"
@@ -401,21 +364,6 @@
return CliCompilationResult(exitCode, jarPath)
}
-
- private fun saveCompiledOutput(subfolder: String, module: KJvmCompiledModuleInMemory): File {
- val folder = outputJarDir.resolve(subfolder).toFile()
- module.compilerOutputFiles.forEach { (name, contents) ->
- val file = folder.resolve(name)
- file.parentFile.mkdirs()
- file.writeBytes(contents)
- }
- return folder
- }
-
- private fun registerDecompilerServices(application: MockApplication) {
- application.registerService(ClsKotlinBinaryClassCache::class.java)
- application.registerService(FileAttributeService::class.java, DummyFileAttributeService)
- }
}
}
@@ -472,109 +420,3 @@
}
}
}
-
-private fun JvmTestRepl.compileAndEval(codeLine: SourceCode): Pair<ResultWithDiagnostics<LinkedSnippet<out CompiledSnippet>>, EvaluatedSnippet?> {
-
- val compRes = compile(codeLine)
-
- val evalRes = compRes.valueOrNull()?.let {
- eval(it)
- }
- return compRes to evalRes?.valueOrNull().get()
-}
-
-private fun assertCompileFails(
- repl: JvmTestRepl,
- @Suppress("SameParameterValue")
- line: String
-) {
- val compiledSnippet =
- checkCompile(repl, line)
-
- TestCase.assertNull(compiledSnippet)
-}
-
-private fun assertEvalUnit(
- repl: JvmTestRepl,
- @Suppress("SameParameterValue")
- line: String
-) {
- val compiledSnippet =
- checkCompile(repl, line)
-
- val evalResult = repl.eval(compiledSnippet!!)
- val valueResult = evalResult.valueOrNull().get()
-
- TestCase.assertNotNull("Unexpected eval result: $evalResult", valueResult)
- TestCase.assertTrue(valueResult!!.result is ResultValue.Unit)
-}
-
-private fun <R> assertEvalResult(repl: JvmTestRepl, line: String, expectedResult: R) {
- val compiledSnippet =
- checkCompile(repl, line)
-
- val evalResult = repl.eval(compiledSnippet!!)
- val valueResult = evalResult.valueOrNull().get()
-
- TestCase.assertNotNull("Unexpected eval result: $evalResult", valueResult)
- TestCase.assertTrue(valueResult!!.result is ResultValue.Value)
- TestCase.assertEquals(expectedResult, (valueResult.result as ResultValue.Value).value)
-}
-
-private inline fun <reified R> assertEvalResultIs(repl: JvmTestRepl, line: String) {
- val compiledSnippet =
- checkCompile(repl, line)
-
- val evalResult = repl.eval(compiledSnippet!!)
- val valueResult = evalResult.valueOrNull().get()
-
- TestCase.assertNotNull("Unexpected eval result: $evalResult", valueResult)
- TestCase.assertTrue(valueResult!!.result is ResultValue.Value)
- TestCase.assertTrue((valueResult.result as ResultValue.Value).value is R)
-}
-
-private fun checkCompile(repl: JvmTestRepl, line: String): LinkedSnippet<KJvmCompiledScript>? {
- val codeLine = repl.nextCodeLine(line)
- val compileResult = repl.compile(codeLine)
- return compileResult.valueOrNull()
-}
-
-private data class CompilationErrors(
- val message: String,
- val location: CompilerMessageLocationWithRange?
-)
-
-private fun <T> ResultWithDiagnostics<T>.getErrors(): CompilationErrors =
- CompilationErrors(
- reports.joinToString("\n") { report ->
- report.location?.let { loc ->
- CompilerMessageLocationWithRange.create(
- report.sourcePath,
- loc.start.line,
- loc.start.col,
- loc.end?.line,
- loc.end?.col,
- null
- )?.toString()?.let {
- "$it "
- }
- }.orEmpty() + report.message
- },
- reports.firstOrNull {
- when (it.severity) {
- ScriptDiagnostic.Severity.ERROR -> true
- ScriptDiagnostic.Severity.FATAL -> true
- else -> false
- }
- }?.let {
- val loc = it.location ?: return@let null
- CompilerMessageLocationWithRange.create(
- it.sourcePath,
- loc.start.line,
- loc.start.col,
- loc.end?.line,
- loc.end?.col,
- null
- )
- }
- )
diff --git a/plugins/scripting/scripting-ide-services-test/test/org/jetbrains/kotlin/scripting/ide_services/test_util/testUtil.kt b/plugins/scripting/scripting-ide-services-test/test/org/jetbrains/kotlin/scripting/ide_services/test_util/testUtil.kt
index 37d958f..e9a4be6 100644
--- a/plugins/scripting/scripting-ide-services-test/test/org/jetbrains/kotlin/scripting/ide_services/test_util/testUtil.kt
+++ b/plugins/scripting/scripting-ide-services-test/test/org/jetbrains/kotlin/scripting/ide_services/test_util/testUtil.kt
@@ -5,14 +5,18 @@
package org.jetbrains.kotlin.scripting.ide_services.test_util
+import junit.framework.TestCase
import kotlinx.coroutines.runBlocking
+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocationWithRange
import org.jetbrains.kotlin.scripting.ide_services.compiler.KJvmReplCompilerWithIdeServices
import java.io.Closeable
import java.util.concurrent.atomic.AtomicInteger
import kotlin.script.experimental.api.*
import kotlin.script.experimental.jvm.BasicJvmReplEvaluator
+import kotlin.script.experimental.jvm.impl.KJvmCompiledScript
import kotlin.script.experimental.util.LinkedSnippet
import kotlin.script.experimental.jvm.util.toSourceCodePosition
+import kotlin.script.experimental.util.get
internal class JvmTestRepl (
private val compileConfiguration: ScriptCompilationConfiguration = simpleScriptCompilationConfiguration,
@@ -55,3 +59,110 @@
@JvmName("sequenceToList")
fun <T> ResultWithDiagnostics<Sequence<T>>.toList() = this.valueOrNull()?.toList().orEmpty()
+
+internal fun JvmTestRepl.compileAndEval(codeLine: SourceCode): Pair<ResultWithDiagnostics<LinkedSnippet<out CompiledSnippet>>, EvaluatedSnippet?> {
+
+ val compRes = compile(codeLine)
+
+ val evalRes = compRes.valueOrNull()?.let {
+ eval(it)
+ }
+ return compRes to evalRes?.valueOrNull().get()
+}
+
+internal fun assertCompileFails(
+ repl: JvmTestRepl,
+ @Suppress("SameParameterValue")
+ line: String
+) {
+ val compiledSnippet =
+ checkCompile(repl, line)
+
+ TestCase.assertNull(compiledSnippet)
+}
+
+internal fun assertEvalUnit(
+ repl: JvmTestRepl,
+ @Suppress("SameParameterValue")
+ line: String
+) {
+ val compiledSnippet =
+ checkCompile(repl, line)
+
+ val evalResult = repl.eval(compiledSnippet!!)
+ val valueResult = evalResult.valueOrNull().get()
+
+ TestCase.assertNotNull("Unexpected eval result: $evalResult", valueResult)
+ TestCase.assertTrue(valueResult!!.result is ResultValue.Unit)
+}
+
+internal fun <R> assertEvalResult(repl: JvmTestRepl, line: String, expectedResult: R) {
+ val compiledSnippet =
+ checkCompile(repl, line)
+
+ val evalResult = repl.eval(compiledSnippet!!)
+ val valueResult = evalResult.valueOrNull().get()
+
+ TestCase.assertNotNull("Unexpected eval result: $evalResult", valueResult)
+ TestCase.assertTrue(valueResult!!.result is ResultValue.Value)
+ TestCase.assertEquals(expectedResult, (valueResult.result as ResultValue.Value).value)
+}
+
+internal inline fun <reified R> assertEvalResultIs(repl: JvmTestRepl, line: String) {
+ val compiledSnippet =
+ checkCompile(repl, line)
+
+ val evalResult = repl.eval(compiledSnippet!!)
+ val valueResult = evalResult.valueOrNull().get()
+
+ TestCase.assertNotNull("Unexpected eval result: $evalResult", valueResult)
+ TestCase.assertTrue(valueResult!!.result is ResultValue.Value)
+ TestCase.assertTrue((valueResult.result as ResultValue.Value).value is R)
+}
+
+internal fun checkCompile(repl: JvmTestRepl, line: String): LinkedSnippet<KJvmCompiledScript>? {
+ val codeLine = repl.nextCodeLine(line)
+ val compileResult = repl.compile(codeLine)
+ return compileResult.valueOrNull()
+}
+
+internal data class CompilationErrors(
+ val message: String,
+ val location: CompilerMessageLocationWithRange?
+)
+
+internal fun <T> ResultWithDiagnostics<T>.getErrors(): CompilationErrors =
+ CompilationErrors(
+ reports.joinToString("\n") { report ->
+ report.location?.let { loc ->
+ CompilerMessageLocationWithRange.create(
+ report.sourcePath,
+ loc.start.line,
+ loc.start.col,
+ loc.end?.line,
+ loc.end?.col,
+ null
+ )?.toString()?.let {
+ "$it "
+ }
+ }.orEmpty() + report.message
+ },
+ reports.firstOrNull {
+ when (it.severity) {
+ ScriptDiagnostic.Severity.ERROR -> true
+ ScriptDiagnostic.Severity.FATAL -> true
+ else -> false
+ }
+ }?.let {
+ val loc = it.location ?: return@let null
+ CompilerMessageLocationWithRange.create(
+ it.sourcePath,
+ loc.start.line,
+ loc.start.col,
+ loc.end?.line,
+ loc.end?.col,
+ null
+ )
+ }
+ )
+