Add more JSR 223 and repl tests, fix double aggregation of GenericRepl state

- repl test with compilation error
- JSR 223 compilable tests
This commit is contained in:
Ilya Chernikov
2017-03-21 13:30:04 +01:00
parent adc541c3b1
commit 319440718c
3 changed files with 126 additions and 81 deletions
@@ -38,7 +38,7 @@ open class GenericRepl protected constructor(
protected val compiler: ReplCompiler by lazy { GenericReplCompiler(disposable, scriptDefinition, compilerConfiguration, messageCollector) } protected val compiler: ReplCompiler by lazy { GenericReplCompiler(disposable, scriptDefinition, compilerConfiguration, messageCollector) }
protected val evaluator: ReplFullEvaluator by lazy { GenericReplCompilingEvaluator(compiler, compilerConfiguration.jvmClasspathRoots, baseClassloader, fallbackScriptArgs, repeatingMode) } protected val evaluator: ReplFullEvaluator by lazy { GenericReplCompilingEvaluator(compiler, compilerConfiguration.jvmClasspathRoots, baseClassloader, fallbackScriptArgs, repeatingMode) }
override fun createState(lock: ReentrantReadWriteLock): IReplStageState<*> = AggregatedReplStageState(compiler.createState(lock), evaluator.createState(lock), lock) override fun createState(lock: ReentrantReadWriteLock): IReplStageState<*> = evaluator.createState(lock)
override fun check(state: IReplStageState<*>, codeLine: ReplCodeLine): ReplCheckResult = compiler.check(state, codeLine) override fun check(state: IReplStageState<*>, codeLine: ReplCodeLine): ReplCheckResult = compiler.check(state, codeLine)
@@ -30,21 +30,18 @@ import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromAnnotatedTemplate
import org.jetbrains.kotlin.test.ConfigurationKind import org.jetbrains.kotlin.test.ConfigurationKind
import org.jetbrains.kotlin.test.KotlinTestUtils import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.TestJdkKind import org.jetbrains.kotlin.test.TestJdkKind
import org.jetbrains.kotlin.util.KotlinFrontEndException
import org.junit.Test import org.junit.Test
import java.io.Closeable
import java.io.File import java.io.File
import java.net.URLClassLoader import java.net.URLClassLoader
import java.util.concurrent.locks.ReentrantReadWriteLock import java.util.concurrent.locks.ReentrantReadWriteLock
class GenericReplTest : TestCase() { class GenericReplTest : TestCase() {
@Test @Test
fun testReplBasics() { fun testReplBasics() {
TestRepl().use { repl ->
val disposable = Disposer.newDisposable()
val repl = TestRepl(disposable,
listOf(File(KotlinIntegrationTestBase.getCompilerLib(), "kotlin-runtime.jar")),
"kotlin.script.templates.standard.ScriptTemplateWithArgs")
val state = repl.createState() val state = repl.createState()
val res1 = repl.replCompiler.check(state, ReplCodeLine(0, 0, "val x =")) val res1 = repl.replCompiler.check(state, ReplCodeLine(0, 0, "val x ="))
@@ -78,38 +75,38 @@ class GenericReplTest : TestCase() {
val res41e = res41 as? ReplEvalResult.ValueResult val res41e = res41 as? ReplEvalResult.ValueResult
TestCase.assertNotNull("Unexpected eval result: $res41", res41e) TestCase.assertNotNull("Unexpected eval result: $res41", res41e)
TestCase.assertEquals(7, res41e!!.value) TestCase.assertEquals(7, res41e!!.value)
}
}
Disposer.dispose(disposable) @Test
fun testReplErrors() {
TestRepl().use { repl ->
val state = repl.createState()
repl.compileAndEval(state, ReplCodeLine(0, 0, "val x = 10"))
val res = repl.compileAndEval(state, ReplCodeLine(1, 0, "java.util.fish"))
TestCase.assertTrue("Expected compile error", res.first is ReplCompileResult.Error)
val result = repl.compileAndEval(state, ReplCodeLine(2, 0, "x"))
assertEquals(10, (result.second as ReplEvalResult.ValueResult).value)
}
} }
@Test @Test
fun testReplCodeFormat() { fun testReplCodeFormat() {
TestRepl().use { repl ->
val disposable = Disposer.newDisposable()
val repl = TestRepl(disposable,
listOf(File(KotlinIntegrationTestBase.getCompilerLib(), "kotlin-runtime.jar")),
"kotlin.script.templates.standard.ScriptTemplateWithArgs")
val state = repl.createState() val state = repl.createState()
val codeLine0 = ReplCodeLine(0, 0, "val l1 = 1\r\nl1\r\n") val codeLine0 = ReplCodeLine(0, 0, "val l1 = 1\r\nl1\r\n")
val res0 = repl.replCompiler?.check(state, codeLine0) val res0 = repl.replCompiler?.check(state, codeLine0)
val res0c = res0 as? ReplCheckResult.Ok val res0c = res0 as? ReplCheckResult.Ok
TestCase.assertNotNull("Unexpected compile result: $res0", res0c) TestCase.assertNotNull("Unexpected compile result: $res0", res0c)
}
Disposer.dispose(disposable)
} }
@Test @Test
fun testRepPackage() { fun testRepPackage() {
TestRepl().use { repl ->
val disposable = Disposer.newDisposable()
val repl = TestRepl(disposable,
listOf(File(KotlinIntegrationTestBase.getCompilerLib(), "kotlin-runtime.jar")),
"kotlin.script.templates.standard.ScriptTemplateWithArgs")
val state = repl.createState() val state = repl.createState()
val codeLine1 = ReplCodeLine(0, 0, "package mypackage\n\nval x = 1\nx+2") val codeLine1 = ReplCodeLine(0, 0, "package mypackage\n\nval x = 1\nx+2")
@@ -131,16 +128,18 @@ class GenericReplTest : TestCase() {
val res21e = res21 as? ReplEvalResult.ValueResult val res21e = res21 as? ReplEvalResult.ValueResult
TestCase.assertNotNull("Unexpected eval result: $res21", res21e) TestCase.assertNotNull("Unexpected eval result: $res21", res21e)
TestCase.assertEquals(5, res21e!!.value) TestCase.assertEquals(5, res21e!!.value)
}
Disposer.dispose(disposable)
} }
} }
internal class TestRepl( internal class TestRepl(
disposable: Disposable, templateClasspath: List<File> = listOf(File(KotlinIntegrationTestBase.getCompilerLib(), "kotlin-runtime.jar")),
templateClasspath: List<File>, templateClassName: String = "kotlin.script.templates.standard.ScriptTemplateWithArgs"
templateClassName: String ) : Closeable {
) {
private val disposable: Disposable by lazy { Disposer.newDisposable() }
val emptyScriptArgs = ScriptArgsWithTypes(arrayOf(emptyArray<String>()), arrayOf(Array<String>::class)) val emptyScriptArgs = ScriptArgsWithTypes(arrayOf(emptyArray<String>()), arrayOf(Array<String>::class))
private val configuration = KotlinTestUtils.newConfiguration(ConfigurationKind.ALL, TestJdkKind.MOCK_JDK, *templateClasspath.toTypedArray()).apply { private val configuration = KotlinTestUtils.newConfiguration(ConfigurationKind.ALL, TestJdkKind.MOCK_JDK, *templateClasspath.toTypedArray()).apply {
@@ -165,5 +164,19 @@ internal class TestRepl(
fun createState(lock: ReentrantReadWriteLock = ReentrantReadWriteLock()): IReplStageState<*> = fun createState(lock: ReentrantReadWriteLock = ReentrantReadWriteLock()): IReplStageState<*> =
AggregatedReplStageState(replCompiler.createState(lock), compiledEvaluator.createState(lock), lock) AggregatedReplStageState(replCompiler.createState(lock), compiledEvaluator.createState(lock), lock)
override fun close() {
Disposer.dispose(disposable)
}
} }
private fun TestRepl.compileAndEval(state: IReplStageState<*>, codeLine: ReplCodeLine): Pair<ReplCompileResult, ReplEvalResult?> {
val compRes = replCompiler.compile(state, codeLine)
val evalRes = (compRes as? ReplCompileResult.CompiledClasses)?.let {
compiledEvaluator.eval(state, it)
}
return compRes to evalRes
}
@@ -22,10 +22,7 @@ import org.junit.Assert
import org.junit.Test import org.junit.Test
import java.lang.management.ManagementFactory import java.lang.management.ManagementFactory
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import javax.script.Invocable import javax.script.*
import javax.script.ScriptEngine
import javax.script.ScriptEngineManager
import javax.script.SimpleBindings
class KotlinJsr223LocalScriptEngineIT { class KotlinJsr223LocalScriptEngineIT {
@@ -96,6 +93,41 @@ obj
Assert.assertEquals(6, res3) Assert.assertEquals(6, res3)
} }
@Test
fun testSimpleCompilable() {
val engine = ScriptEngineManager().getEngineByExtension("kts") as KotlinJsr223JvmLocalScriptEngine
val comp1 = engine.compile("val x = 3")
val comp2 = engine.compile("x + 2")
val res1 = comp1.eval()
Assert.assertNull(res1)
val res2 = comp2.eval()
Assert.assertEquals(5, res2)
}
@Test
fun testMultipleCompilable() {
val engine = ScriptEngineManager().getEngineByExtension("kts") as KotlinJsr223JvmLocalScriptEngine
val compiled1 = engine.compile("""listOf(1,2,3).joinToString(",")""")
val compiled2 = engine.compile("""val x = bindings["boundValue"] as Int + bindings["z"] as Int""")
val compiled3 = engine.compile("""x""")
Assert.assertEquals("1,2,3", compiled1.eval())
Assert.assertEquals("1,2,3", compiled1.eval())
Assert.assertEquals("1,2,3", compiled1.eval())
Assert.assertEquals("1,2,3", compiled1.eval())
engine.getBindings(ScriptContext.ENGINE_SCOPE).apply {
put("boundValue", 100)
put("z", 33)
}
compiled2.eval()
Assert.assertEquals(133, compiled3.eval())
Assert.assertEquals(133, compiled3.eval())
Assert.assertEquals(133, compiled3.eval())
}
@Test @Test
fun testEvalWithContext() { fun testEvalWithContext() {
val engine = ScriptEngineManager().getEngineByExtension("kts")!! val engine = ScriptEngineManager().getEngineByExtension("kts")!!