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:
@@ -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,117 +30,116 @@ 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 state = repl.createState()
|
||||||
|
|
||||||
val disposable = Disposer.newDisposable()
|
val res1 = repl.replCompiler.check(state, ReplCodeLine(0, 0, "val x ="))
|
||||||
|
TestCase.assertTrue("Unexpected check results: $res1", res1 is ReplCheckResult.Incomplete)
|
||||||
|
|
||||||
val repl = TestRepl(disposable,
|
val codeLine0 = ReplCodeLine(0, 0, "val l1 = listOf(1 + 2)\nl1.first()")
|
||||||
listOf(File(KotlinIntegrationTestBase.getCompilerLib(), "kotlin-runtime.jar")),
|
val res2 = repl.replCompiler.compile(state, codeLine0)
|
||||||
"kotlin.script.templates.standard.ScriptTemplateWithArgs")
|
val res2c = res2 as? ReplCompileResult.CompiledClasses
|
||||||
|
TestCase.assertNotNull("Unexpected compile result: $res2", res2c)
|
||||||
|
|
||||||
val state = repl.createState()
|
val res21 = repl.compiledEvaluator.eval(state, res2c!!)
|
||||||
|
val res21e = res21 as? ReplEvalResult.ValueResult
|
||||||
|
TestCase.assertNotNull("Unexpected eval result: $res21", res21e)
|
||||||
|
TestCase.assertEquals(3, res21e!!.value)
|
||||||
|
|
||||||
val res1 = repl.replCompiler.check(state, ReplCodeLine(0, 0, "val x ="))
|
val codeLine1 = ReplCodeLine(1, 0, "val x = 5")
|
||||||
TestCase.assertTrue("Unexpected check results: $res1", res1 is ReplCheckResult.Incomplete)
|
val res3 = repl.replCompiler.compile(state, codeLine1)
|
||||||
|
val res3c = res3 as? ReplCompileResult.CompiledClasses
|
||||||
|
TestCase.assertNotNull("Unexpected compile result: $res3", res3c)
|
||||||
|
|
||||||
val codeLine0 = ReplCodeLine(0, 0, "val l1 = listOf(1 + 2)\nl1.first()")
|
val res31 = repl.compiledEvaluator.eval(state, res3c!!)
|
||||||
val res2 = repl.replCompiler.compile(state, codeLine0)
|
val res31e = res31 as? ReplEvalResult.UnitResult
|
||||||
val res2c = res2 as? ReplCompileResult.CompiledClasses
|
TestCase.assertNotNull("Unexpected eval result: $res31", res31e)
|
||||||
TestCase.assertNotNull("Unexpected compile result: $res2", res2c)
|
|
||||||
|
|
||||||
val res21 = repl.compiledEvaluator.eval(state, res2c!!)
|
val codeLine2 = ReplCodeLine(2, 0, "x + 2")
|
||||||
val res21e = res21 as? ReplEvalResult.ValueResult
|
val res4 = repl.replCompiler.compile(state, codeLine2)
|
||||||
TestCase.assertNotNull("Unexpected eval result: $res21", res21e)
|
val res4c = res4 as? ReplCompileResult.CompiledClasses
|
||||||
TestCase.assertEquals(3, res21e!!.value)
|
TestCase.assertNotNull("Unexpected compile result: $res4", res4c)
|
||||||
|
|
||||||
val codeLine1 = ReplCodeLine(1, 0, "val x = 5")
|
val res41 = repl.compiledEvaluator.eval(state, res4c!!)
|
||||||
val res3 = repl.replCompiler.compile(state, codeLine1)
|
val res41e = res41 as? ReplEvalResult.ValueResult
|
||||||
val res3c = res3 as? ReplCompileResult.CompiledClasses
|
TestCase.assertNotNull("Unexpected eval result: $res41", res41e)
|
||||||
TestCase.assertNotNull("Unexpected compile result: $res3", res3c)
|
TestCase.assertEquals(7, res41e!!.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val res31 = repl.compiledEvaluator.eval(state, res3c!!)
|
@Test
|
||||||
val res31e = res31 as? ReplEvalResult.UnitResult
|
fun testReplErrors() {
|
||||||
TestCase.assertNotNull("Unexpected eval result: $res31", res31e)
|
TestRepl().use { repl ->
|
||||||
|
val state = repl.createState()
|
||||||
|
repl.compileAndEval(state, ReplCodeLine(0, 0, "val x = 10"))
|
||||||
|
|
||||||
val codeLine2 = ReplCodeLine(2, 0, "x + 2")
|
val res = repl.compileAndEval(state, ReplCodeLine(1, 0, "java.util.fish"))
|
||||||
val res4 = repl.replCompiler.compile(state, codeLine2)
|
TestCase.assertTrue("Expected compile error", res.first is ReplCompileResult.Error)
|
||||||
val res4c = res4 as? ReplCompileResult.CompiledClasses
|
|
||||||
TestCase.assertNotNull("Unexpected compile result: $res4", res4c)
|
|
||||||
|
|
||||||
val res41 = repl.compiledEvaluator.eval(state, res4c!!)
|
val result = repl.compileAndEval(state, ReplCodeLine(2, 0, "x"))
|
||||||
val res41e = res41 as? ReplEvalResult.ValueResult
|
assertEquals(10, (result.second as ReplEvalResult.ValueResult).value)
|
||||||
TestCase.assertNotNull("Unexpected eval result: $res41", res41e)
|
}
|
||||||
TestCase.assertEquals(7, res41e!!.value)
|
|
||||||
|
|
||||||
Disposer.dispose(disposable)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testReplCodeFormat() {
|
fun testReplCodeFormat() {
|
||||||
|
TestRepl().use { repl ->
|
||||||
|
val state = repl.createState()
|
||||||
|
|
||||||
val disposable = Disposer.newDisposable()
|
val codeLine0 = ReplCodeLine(0, 0, "val l1 = 1\r\nl1\r\n")
|
||||||
|
val res0 = repl.replCompiler?.check(state, codeLine0)
|
||||||
val repl = TestRepl(disposable,
|
val res0c = res0 as? ReplCheckResult.Ok
|
||||||
listOf(File(KotlinIntegrationTestBase.getCompilerLib(), "kotlin-runtime.jar")),
|
TestCase.assertNotNull("Unexpected compile result: $res0", res0c)
|
||||||
"kotlin.script.templates.standard.ScriptTemplateWithArgs")
|
}
|
||||||
|
|
||||||
val state = repl.createState()
|
|
||||||
|
|
||||||
val codeLine0 = ReplCodeLine(0, 0, "val l1 = 1\r\nl1\r\n")
|
|
||||||
val res0 = repl.replCompiler?.check(state, codeLine0)
|
|
||||||
val res0c = res0 as? ReplCheckResult.Ok
|
|
||||||
TestCase.assertNotNull("Unexpected compile result: $res0", res0c)
|
|
||||||
|
|
||||||
Disposer.dispose(disposable)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testRepPackage() {
|
fun testRepPackage() {
|
||||||
|
TestRepl().use { repl ->
|
||||||
|
val state = repl.createState()
|
||||||
|
|
||||||
val disposable = Disposer.newDisposable()
|
val codeLine1 = ReplCodeLine(0, 0, "package mypackage\n\nval x = 1\nx+2")
|
||||||
|
val res1 = repl.replCompiler.compile(state, codeLine1)
|
||||||
|
val res1c = res1 as? ReplCompileResult.CompiledClasses
|
||||||
|
TestCase.assertNotNull("Unexpected compile result: $res1", res1c)
|
||||||
|
|
||||||
val repl = TestRepl(disposable,
|
val res11 = repl.compiledEvaluator.eval(state, res1c!!)
|
||||||
listOf(File(KotlinIntegrationTestBase.getCompilerLib(), "kotlin-runtime.jar")),
|
val res11e = res11 as? ReplEvalResult.ValueResult
|
||||||
"kotlin.script.templates.standard.ScriptTemplateWithArgs")
|
TestCase.assertNotNull("Unexpected eval result: $res11", res11e)
|
||||||
|
TestCase.assertEquals(3, res11e!!.value)
|
||||||
|
|
||||||
val state = repl.createState()
|
val codeLine2 = ReplCodeLine(1, 0, "x+4")
|
||||||
|
val res2 = repl.replCompiler.compile(state, codeLine2)
|
||||||
|
val res2c = res2 as? ReplCompileResult.CompiledClasses
|
||||||
|
TestCase.assertNotNull("Unexpected compile result: $res2", res2c)
|
||||||
|
|
||||||
val codeLine1 = ReplCodeLine(0, 0, "package mypackage\n\nval x = 1\nx+2")
|
val res21 = repl.compiledEvaluator.eval(state, res2c!!)
|
||||||
val res1 = repl.replCompiler.compile(state, codeLine1)
|
val res21e = res21 as? ReplEvalResult.ValueResult
|
||||||
val res1c = res1 as? ReplCompileResult.CompiledClasses
|
TestCase.assertNotNull("Unexpected eval result: $res21", res21e)
|
||||||
TestCase.assertNotNull("Unexpected compile result: $res1", res1c)
|
TestCase.assertEquals(5, res21e!!.value)
|
||||||
|
}
|
||||||
val res11 = repl.compiledEvaluator.eval(state, res1c!!)
|
|
||||||
val res11e = res11 as? ReplEvalResult.ValueResult
|
|
||||||
TestCase.assertNotNull("Unexpected eval result: $res11", res11e)
|
|
||||||
TestCase.assertEquals(3, res11e!!.value)
|
|
||||||
|
|
||||||
val codeLine2 = ReplCodeLine(1, 0, "x+4")
|
|
||||||
val res2 = repl.replCompiler.compile(state, codeLine2)
|
|
||||||
val res2c = res2 as? ReplCompileResult.CompiledClasses
|
|
||||||
TestCase.assertNotNull("Unexpected compile result: $res2", res2c)
|
|
||||||
|
|
||||||
val res21 = repl.compiledEvaluator.eval(state, res2c!!)
|
|
||||||
val res21e = res21 as? ReplEvalResult.ValueResult
|
|
||||||
TestCase.assertNotNull("Unexpected eval result: $res21", res21e)
|
|
||||||
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
|
||||||
|
}
|
||||||
|
|||||||
+36
-4
@@ -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")!!
|
||||||
|
|||||||
Reference in New Issue
Block a user