Add tests with partial classpath for script compilation

This commit is contained in:
Ilya Chernikov
2016-04-07 17:08:28 +02:00
parent 9d9fe97a8e
commit 834bb51643
3 changed files with 68 additions and 25 deletions
+16
View File
@@ -0,0 +1,16 @@
// this script expected parameter num : Int
fun fib(n: Int): Int {
val v = if(n < 2) 1 else fib(n-1) + fib(n-2)
System.out.println("fib($n)=$v")
return v
}
val hdr = "Num".decapitalize()
org.junit.Assert.assertTrue(false)
System.out.println("$hdr: $num")
val result = fib(num)
@@ -22,31 +22,59 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtScript import org.jetbrains.kotlin.psi.KtScript
import org.jetbrains.kotlin.script.* import org.jetbrains.kotlin.script.*
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import java.io.File
import java.net.URLClassLoader
import kotlin.reflect.KClass import kotlin.reflect.KClass
abstract class BaseScriptDefinition (val extension: String) : KotlinScriptDefinition { abstract class BaseScriptDefinition (val extension: String, val classpath: List<String>? = null) : KotlinScriptDefinition {
override val name = "Test Kotlin Script" override val name = "Test Kotlin Script"
override fun isScript(file: VirtualFile): Boolean = file.name.endsWith(extension) override fun isScript(file: VirtualFile): Boolean = file.name.endsWith(extension)
override fun getScriptName(script: KtScript): Name = ScriptNameUtil.fileNameWithExtensionStripped(script, extension) override fun getScriptName(script: KtScript): Name = ScriptNameUtil.fileNameWithExtensionStripped(script, extension)
override fun getScriptDependenciesClasspath(): List<String> =
classpath ?: (classpathFromProperty() + classpathFromClassloader(BaseScriptDefinition::class.java.classLoader)).distinct()
} }
open class SimpleParamsTestScriptDefinition(extension: String, val parameters: List<ScriptParameter>) : BaseScriptDefinition(extension) { open class SimpleParamsWithClasspathTestScriptDefinition(extension: String, val parameters: List<ScriptParameter>, classpath: List<String>? = null)
: BaseScriptDefinition(extension, classpath)
{
override fun getScriptParameters(scriptDescriptor: ScriptDescriptor) = parameters override fun getScriptParameters(scriptDescriptor: ScriptDescriptor) = parameters
} }
class ReflectedParamClassTestScriptDefinition(extension: String, val paramName: String, val parameter: KClass<out Any>) : BaseScriptDefinition(extension) { open class SimpleParamsTestScriptDefinition(extension: String, parameters: List<ScriptParameter>) : SimpleParamsWithClasspathTestScriptDefinition(extension, parameters)
class ReflectedParamClassTestScriptDefinition(extension: String, val paramName: String, val parameter: KClass<out Any>, classpath: List<String>? = null)
: BaseScriptDefinition(extension, classpath)
{
override fun getScriptParameters(scriptDescriptor: ScriptDescriptor) = override fun getScriptParameters(scriptDescriptor: ScriptDescriptor) =
listOf(makeReflectedClassScriptParameter(scriptDescriptor, Name.identifier(paramName), parameter)) listOf(makeReflectedClassScriptParameter(scriptDescriptor, Name.identifier(paramName), parameter))
} }
open class ReflectedSuperclassTestScriptDefinition(extension: String, parameters: List<ScriptParameter>, val superclass: KClass<out Any>) : SimpleParamsTestScriptDefinition(extension, parameters) { open class ReflectedSuperclassTestScriptDefinition(extension: String, parameters: List<ScriptParameter>, val superclass: KClass<out Any>, classpath: List<String>? = null)
: SimpleParamsWithClasspathTestScriptDefinition(extension, parameters, classpath)
{
override fun getScriptSupertypes(scriptDescriptor: ScriptDescriptor): List<KotlinType> = override fun getScriptSupertypes(scriptDescriptor: ScriptDescriptor): List<KotlinType> =
listOf(getKotlinType(scriptDescriptor, superclass)) listOf(getKotlinType(scriptDescriptor, superclass))
} }
class ReflectedSuperclassWithParamsTestScriptDefinition(extension: String, parameters: List<ScriptParameter>, superclass: KClass<out Any>, val superclassParameters: List<ScriptParameter>) class ReflectedSuperclassWithParamsTestScriptDefinition(extension: String,
: ReflectedSuperclassTestScriptDefinition(extension, parameters, superclass) parameters: List<ScriptParameter>,
superclass: KClass<out Any>,
val superclassParameters: List<ScriptParameter>,
classpath: List<String>? = null)
: ReflectedSuperclassTestScriptDefinition(extension, parameters, superclass, classpath)
{ {
override fun getScriptParametersToPassToSuperclass(scriptDescriptor: ScriptDescriptor): List<Name> = override fun getScriptParametersToPassToSuperclass(scriptDescriptor: ScriptDescriptor): List<Name> =
superclassParameters.map { it.name } superclassParameters.map { it.name }
} }
fun classpathFromProperty(): List<String> =
System.getProperty("java.class.path")?.let {
it.split(String.format("\\%s", File.pathSeparatorChar).toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
.map { File(it).canonicalPath }
} ?: emptyList()
fun classpathFromClassloader(classLoader: ClassLoader): List<String> =
(classLoader as? URLClassLoader)?.urLs
?.map { File(it.toURI()).canonicalPath }
?: emptyList()
@@ -38,8 +38,6 @@ import org.jetbrains.kotlin.utils.PathUtil
import org.junit.Assert import org.junit.Assert
import org.junit.Test import org.junit.Test
import java.io.File import java.io.File
import java.net.URLClassLoader
import java.util.*
class ScriptTest { class ScriptTest {
@Test @Test
@@ -94,13 +92,28 @@ class ScriptTest {
aClass!!.getConstructor(Integer.TYPE).newInstance(4) aClass!!.getConstructor(Integer.TYPE).newInstance(4)
} }
@Test
fun testScriptWithClasspath() {
val aClass1 = compileScript("fib_ext.kts", SimpleParamsWithClasspathTestScriptDefinition(".kts", numIntParam(), classpath = emptyList()), runIsolated = true, suppressOutput = true)
Assert.assertNull(aClass1)
val cp = classpathFromClassloader(ScriptTest::class.java.classLoader).filter { it.contains("kotlin-runtime") || it.contains("junit") }
Assert.assertFalse(cp.isEmpty())
val aClass2 = compileScript("fib_ext.kts", SimpleParamsWithClasspathTestScriptDefinition(".kts", numIntParam(), classpath = cp), runIsolated = true)
Assert.assertNotNull(aClass2)
}
private fun compileScript( private fun compileScript(
scriptPath: String, scriptPath: String,
scriptDefinition: KotlinScriptDefinition, scriptDefinition: KotlinScriptDefinition,
runIsolated: Boolean = true): Class<*>? runIsolated: Boolean = true,
suppressOutput: Boolean = false): Class<*>?
{ {
val paths = PathUtil.getKotlinPathsForDistDirectory() val paths = PathUtil.getKotlinPathsForDistDirectory()
val messageCollector = PrintingMessageCollector(System.err, MessageRenderer.PLAIN_FULL_PATHS, false) val messageCollector =
if (suppressOutput) MessageCollector.NONE
else PrintingMessageCollector(System.err, MessageRenderer.PLAIN_FULL_PATHS, false)
val rootDisposable = Disposer.newDisposable() val rootDisposable = Disposer.newDisposable()
try { try {
@@ -108,8 +121,7 @@ class ScriptTest {
configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector) configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector)
configuration.addKotlinSourceRoot("compiler/testData/script/" + scriptPath) configuration.addKotlinSourceRoot("compiler/testData/script/" + scriptPath)
configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, scriptDefinition) configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, scriptDefinition)
if (!runIsolated) scriptDefinition.getScriptDependenciesClasspath().forEach { configuration.addJvmClasspathRoot(File(it)) }
configuration.addCurrentClasspathAsRoots()
val environment = KotlinCoreEnvironment.createForProduction(rootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES) val environment = KotlinCoreEnvironment.createForProduction(rootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES)
@@ -133,19 +145,6 @@ class ScriptTest {
} }
} }
private fun CompilerConfiguration.addCurrentClasspathAsRoots() {
val cp: MutableSet<File> = System.getProperty("java.class.path")?.let {
it.split(String.format("\\%s", File.pathSeparatorChar).toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
.map { File(it).canonicalFile }.toMutableSet()
} ?: LinkedHashSet<File>()
(this.javaClass.classLoader as? URLClassLoader)?.urLs
?.map { File(it.toURI()).canonicalFile }
?.filter { it.exists() }
?.forEach { cp.add(it) }
cp.forEach { addJvmClasspathRoot(it) }
}
private fun numIntParam(name: String = "num"): List<ScriptParameter> { private fun numIntParam(name: String = "num"): List<ScriptParameter> {
return listOf(ScriptParameter(Name.identifier(name), DefaultBuiltIns.Instance.intType)) return listOf(ScriptParameter(Name.identifier(name), DefaultBuiltIns.Instance.intType))
} }