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.script.*
import org.jetbrains.kotlin.types.KotlinType
import java.io.File
import java.net.URLClassLoader
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 fun isScript(file: VirtualFile): Boolean = file.name.endsWith(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
}
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) =
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> =
listOf(getKotlinType(scriptDescriptor, superclass))
}
class ReflectedSuperclassWithParamsTestScriptDefinition(extension: String, parameters: List<ScriptParameter>, superclass: KClass<out Any>, val superclassParameters: List<ScriptParameter>)
: ReflectedSuperclassTestScriptDefinition(extension, parameters, superclass)
class ReflectedSuperclassWithParamsTestScriptDefinition(extension: String,
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> =
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.Test
import java.io.File
import java.net.URLClassLoader
import java.util.*
class ScriptTest {
@Test
@@ -94,13 +92,28 @@ class ScriptTest {
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(
scriptPath: String,
scriptDefinition: KotlinScriptDefinition,
runIsolated: Boolean = true): Class<*>?
runIsolated: Boolean = true,
suppressOutput: Boolean = false): Class<*>?
{
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()
try {
@@ -108,8 +121,7 @@ class ScriptTest {
configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector)
configuration.addKotlinSourceRoot("compiler/testData/script/" + scriptPath)
configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, scriptDefinition)
if (!runIsolated)
configuration.addCurrentClasspathAsRoots()
scriptDefinition.getScriptDependenciesClasspath().forEach { configuration.addJvmClasspathRoot(File(it)) }
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> {
return listOf(ScriptParameter(Name.identifier(name), DefaultBuiltIns.Instance.intType))
}