diff --git a/libraries/scripting/jvm-host-test/test/kotlin/script/experimental/jvmhost/test/ResolveDependenciesTest.kt b/libraries/scripting/jvm-host-test/test/kotlin/script/experimental/jvmhost/test/ResolveDependenciesTest.kt new file mode 100644 index 00000000000..ac03e8d4749 --- /dev/null +++ b/libraries/scripting/jvm-host-test/test/kotlin/script/experimental/jvmhost/test/ResolveDependenciesTest.kt @@ -0,0 +1,121 @@ +/* + * Copyright 2010-2019 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 kotlin.script.experimental.jvmhost.test + +import junit.framework.TestCase +import org.junit.Ignore +import org.junit.Test +import java.io.File +import kotlin.script.experimental.api.* +import kotlin.script.experimental.host.toScriptSource +import kotlin.script.experimental.jvm.* +import kotlin.script.experimental.jvm.util.classpathFromClass +import kotlin.script.experimental.jvmhost.BasicJvmScriptingHost + +class ResolveDependenciesTest : TestCase() { + + private val configurationWithDependenciesFromClassloader = ScriptCompilationConfiguration { + dependencies(JvmDependencyFromClassLoader { ShouldBeVisibleFromScript::class.java.classLoader }) + } + + private val configurationWithDependenciesFromClasspath = ScriptCompilationConfiguration { + updateClasspath(classpathFromClass(ShouldBeVisibleFromScript::class)) + } + + private val thisPackage = ShouldBeVisibleFromScript::class.java.`package`.name + + private val classAccessScript = "${thisPackage}.ShouldBeVisibleFromScript().x".toScriptSource() + private val classImportScript = "import ${thisPackage}.ShouldBeVisibleFromScript\nShouldBeVisibleFromScript().x".toScriptSource() + + private val funAndValAccessScript = + "$thisPackage.funShouldBeVisibleFromScript($thisPackage.valShouldBeVisibleFromScript)".toScriptSource() + + private val funAndValImportScript = + """ + import $thisPackage.funShouldBeVisibleFromScript + import $thisPackage.valShouldBeVisibleFromScript + funShouldBeVisibleFromScript(valShouldBeVisibleFromScript) + """.trimMargin().toScriptSource() + + @Test + fun testResolveClassFromClassloader() { + runScriptAndCheckResult(classAccessScript, configurationWithDependenciesFromClassloader, null, 42) + runScriptAndCheckResult(classImportScript, configurationWithDependenciesFromClassloader, null, 42) + } + + @Test + fun testResolveClassFromClasspath() { + runScriptAndCheckResult(classAccessScript, configurationWithDependenciesFromClasspath, null, 42) + runScriptAndCheckResult(classImportScript, configurationWithDependenciesFromClasspath, null, 42) + } + + @Ignore + @Test + // This doesn't work since there is no way to resolve a top-level function/property via reflection now (see #KT-33892) + fun ignore_testResolveFunAndValFromClassloader() { + runScriptAndCheckResult(funAndValAccessScript, configurationWithDependenciesFromClassloader, null, 42) + runScriptAndCheckResult(funAndValImportScript, configurationWithDependenciesFromClassloader, null, 42) + } + + @Test + fun testResolveFunAndValFromClasspath() { + runScriptAndCheckResult(funAndValAccessScript, configurationWithDependenciesFromClasspath, null, 42) + runScriptAndCheckResult(funAndValImportScript, configurationWithDependenciesFromClasspath, null, 42) + } + + @Test + fun testResolveClassFromClassloaderIsolated() { + val evaluationConfiguration = ScriptEvaluationConfiguration { + jvm { + baseClassLoader(null) + } + } + runScriptAndCheckResult(classAccessScript, configurationWithDependenciesFromClassloader, evaluationConfiguration, 42) + } + + @Test + fun testResolveClassesFromClassloaderAndClassPath() { + val script = """ + org.jetbrains.kotlin.mainKts.MainKtsConfigurator() + ${thisPackage}.ShouldBeVisibleFromScript().x + """.trimIndent().toScriptSource() + val classpath = listOf( + File("dist/kotlinc/lib/kotlin-main-kts.jar").also { + assertTrue("kotlin-main-kts.jar not found, run dist task: ${it.absolutePath}", it.exists()) + } + ) + val compilationConfiguration = configurationWithDependenciesFromClassloader.with { + updateClasspath(classpath) + } + runScriptAndCheckResult(script, compilationConfiguration, null, 42) + } + + private fun runScriptAndCheckResult( + script: SourceCode, + compilationConfiguration: ScriptCompilationConfiguration, + evaluationConfiguration: ScriptEvaluationConfiguration?, + expectedResult: T + ) { + val res = BasicJvmScriptingHost().eval(script, compilationConfiguration, evaluationConfiguration).valueOrThrow().returnValue + when (res) { + is ResultValue.Value -> assertEquals(expectedResult, res.value) + is ResultValue.Error -> throw res.error + else -> throw Exception("Unexpected evaluation result: $res") + } + } + +} + +@Suppress("unused") +class ShouldBeVisibleFromScript { + val x = 42 +} + +@Suppress("unused") +fun funShouldBeVisibleFromScript(x: Int) = x * 7 + +@Suppress("unused") +val valShouldBeVisibleFromScript = 6 diff --git a/libraries/scripting/jvm-host-test/test/kotlin/script/experimental/jvmhost/test/ResolveFromClassloaderTest.kt b/libraries/scripting/jvm-host-test/test/kotlin/script/experimental/jvmhost/test/ResolveFromClassloaderTest.kt deleted file mode 100644 index f0713f2310e..00000000000 --- a/libraries/scripting/jvm-host-test/test/kotlin/script/experimental/jvmhost/test/ResolveFromClassloaderTest.kt +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2010-2019 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 kotlin.script.experimental.jvmhost.test - -import junit.framework.TestCase -import org.junit.Test -import java.io.File -import kotlin.script.experimental.api.* -import kotlin.script.experimental.host.toScriptSource -import kotlin.script.experimental.jvm.JvmDependency -import kotlin.script.experimental.jvm.JvmDependencyFromClassLoader -import kotlin.script.experimental.jvm.baseClassLoader -import kotlin.script.experimental.jvm.jvm -import kotlin.script.experimental.jvmhost.BasicJvmScriptingHost - -class ResolveFromClassloaderTest : TestCase() { - - @Test - fun testResolveFromClassloader() { - val script = "${ShouldBeVisibleFromScript::class.java.name}().x".toScriptSource() - val compilationConfiguration = ScriptCompilationConfiguration { - dependencies(JvmDependencyFromClassLoader { ShouldBeVisibleFromScript::class.java.classLoader }) - } - val res = BasicJvmScriptingHost().eval(script, compilationConfiguration, null).valueOrThrow().returnValue as ResultValue.Value - assertEquals(42, res.value) - } - - @Test - fun testResolveFromClassloaderIsolated() { - val script = "${ShouldBeVisibleFromScript::class.java.name}().x".toScriptSource() - val compilationConfiguration = ScriptCompilationConfiguration { - dependencies(JvmDependencyFromClassLoader { ShouldBeVisibleFromScript::class.java.classLoader }) - } - val evaluationConfiguration = ScriptEvaluationConfiguration { - jvm { - baseClassLoader(null) - } - } - val res = BasicJvmScriptingHost().eval(script, compilationConfiguration, evaluationConfiguration).valueOrThrow().returnValue - when (res) { - is ResultValue.Value -> assertEquals(42, res.value) - is ResultValue.Error -> throw res.error - else -> throw Exception("Unexpected evaluation result: $res") - } - } - - @Test - fun testResolveFromClassloaderAndClassPath() { - val script = """ - org.jetbrains.kotlin.mainKts.MainKtsConfigurator() - ${ShouldBeVisibleFromScript::class.java.name}().x - """.trimIndent().toScriptSource() - val classpath = listOf( - File("dist/kotlinc/lib/kotlin-main-kts.jar").also { - assertTrue("kotlin-main-kts.jar not found, run dist task: ${it.absolutePath}", it.exists()) - } - ) - val compilationConfiguration = ScriptCompilationConfiguration { - dependencies( - JvmDependencyFromClassLoader { ShouldBeVisibleFromScript::class.java.classLoader }, - JvmDependency(classpath) - ) - } - val res = BasicJvmScriptingHost().eval(script, compilationConfiguration, null).valueOrThrow().returnValue as ResultValue.Value - assertEquals(42, res.value) - } -} - -@Suppress("unused") -class ShouldBeVisibleFromScript { - val x = 42 -} diff --git a/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/util/jvmClasspathUtil.kt b/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/util/jvmClasspathUtil.kt index 6ba5e6bd538..fd61e3dea6c 100644 --- a/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/util/jvmClasspathUtil.kt +++ b/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/util/jvmClasspathUtil.kt @@ -115,10 +115,10 @@ internal fun ClassLoader.rawClassPathFromKeyResourcePath(keyResourcePath: String (url.openConnection() as? JarURLConnection)?.jarFileURL?.toFileOrNull() } else url.toFileOrNull()?.let { file -> if (keyResourcePathDepth < 0) { - keyResourcePathDepth = keyResourcePath.trim('/').count { it == '/' } + keyResourcePathDepth = if (keyResourcePath.isBlank()) 0 else (keyResourcePath.trim('/').count { it == '/' } + 1) } var root = file - for (i in 0..keyResourcePathDepth) { + for (i in 0 until keyResourcePathDepth) { root = root.parentFile } root