Compare commits

...

11 Commits

Author SHA1 Message Date
Shagen Ogandzhanian
8934df9e60 stuck and lost 2019-03-01 11:46:11 +01:00
Shagen Ogandzhanian
e0a293cd80 I think I'm fucking lost 2019-03-01 11:22:14 +01:00
Shagen Ogandzhanian
672d95b97f InteropGlobalContext for Nashorn is fully functional
now the easy part )
2019-03-01 10:20:33 +01:00
Shagen Ogandzhanian
03fa12921b private fun GlobalRuntimeContext.updateState(state: Map<String, Any?>) { 2019-03-01 10:04:33 +01:00
Shagen Ogandzhanian
db985b8a78 InteropEngine::getGlobalContext 2019-03-01 01:24:07 +01:00
Shagen Ogandzhanian
2404ac115a removed redundant variable 2019-02-28 23:54:38 +01:00
Shagen Ogandzhanian
47f821ddaa InteropV8::createParams 2019-02-28 22:14:45 +01:00
Shagen Ogandzhanian
46c24b8154 Fix for accessing package name 2019-02-28 18:41:49 +01:00
Shagen Ogandzhanian
ea8a84c062 Conditional flag for j2v8 interop 2019-02-28 15:50:48 +01:00
Shagen Ogandzhanian
5cdc5d0fa3 Make com.eclipsesource.j2v8 dependency platform-specific 2019-02-28 15:39:41 +01:00
Shagen Ogandzhanian
5f96b27558 Introduce support optional j2v8-backed interop for tests 2019-02-28 13:17:27 +01:00
12 changed files with 201 additions and 58 deletions

View File

@@ -107,7 +107,6 @@ public class KotlinTestUtils {
private static final boolean DONT_IGNORE_TESTS_WORKING_ON_COMPATIBLE_BACKEND =
Boolean.getBoolean("org.jetbrains.kotlin.dont.ignore.tests.working.on.compatible.backend");
private static final boolean AUTOMATICALLY_UNMUTE_PASSED_TESTS = false;
private static final boolean AUTOMATICALLY_MUTE_FAILED_TESTS = false;

View File

@@ -1,7 +1,6 @@
import com.moowork.gradle.node.NodeExtension
import com.moowork.gradle.node.exec.ExecRunner
import com.moowork.gradle.node.npm.NpmExecRunner
import com.moowork.gradle.node.npm.NpmTask
import org.gradle.internal.os.OperatingSystem
plugins {
kotlin("jvm")
@@ -42,6 +41,13 @@ dependencies {
testRuntime(project(":compiler:backend-common"))
testRuntime(commonDep("org.fusesource.jansi", "jansi"))
when {
OperatingSystem.current().isWindows() -> testCompile("com.eclipsesource.j2v8:j2v8_win32_x86:4.6.0")
OperatingSystem.current().isLinux() -> testCompile("com.eclipsesource.j2v8:j2v8_linux_x86_64:4.8.0")
OperatingSystem.current().isMacOsX() -> testCompile("com.eclipsesource.j2v8:j2v8_macosx_x86_64:4.6.0")
else -> logger.error("unsupported platform - can not compile com.eclipsesource.j2v8 dependency")
}
antLauncherJar(commonDep("org.apache.ant", "ant"))
antLauncherJar(files(toolsJar()))
}
@@ -65,7 +71,7 @@ projectTest {
}
val prefixForPpropertiesToForward = "fd."
for((key, value) in properties) {
for ((key, value) in properties) {
if (key.startsWith(prefixForPpropertiesToForward)) {
systemProperty(key.substring(prefixForPpropertiesToForward.length), value)
}

View File

@@ -671,7 +671,7 @@ abstract class BasicBoxTest(
val result = engineForMinifier.runAndRestoreContext {
runList.forEach(this::loadFile)
overrideAsserter()
eval(NashornJsTestChecker.SETUP_KOTLIN_OUTPUT)
eval<String>(NashornJsTestChecker.SETUP_KOTLIN_OUTPUT)
runTestFunction(testModuleName, testPackage, testFunction, withModuleSystem)
}
TestCase.assertEquals(expectedResult, result)

View File

@@ -5,66 +5,51 @@
package org.jetbrains.kotlin.js.test
import jdk.nashorn.api.scripting.NashornScriptEngineFactory
import jdk.nashorn.api.scripting.ScriptObjectMirror
import jdk.nashorn.internal.runtime.ScriptRuntime
import org.jetbrains.kotlin.js.test.interop.*
import org.junit.Assert
import javax.script.Invocable
import javax.script.ScriptEngine
fun createScriptEngine(): ScriptEngine =
// TODO use "-strict"
NashornScriptEngineFactory().getScriptEngine("--language=es5", "--no-java", "--no-syntax-extensions")
private val USE_J2V8_INTEROP_FOR_JS_TESTS = java.lang.Boolean.getBoolean("org.jetbrains.kotlin.use.j2v8.interop.for.js.tests")
fun ScriptEngine.overrideAsserter() {
eval("this['kotlin-test'].kotlin.test.overrideAsserter_wbnzx$(this['kotlin-test'].kotlin.test.DefaultAsserter);")
fun createScriptEngine(): InteropEngine {
return if (USE_J2V8_INTEROP_FOR_JS_TESTS) {
InteropV8()
} else {
InteropNashorn()
}
}
fun ScriptEngine.runTestFunction(
fun InteropEngine.overrideAsserter() {
evalVoid("this['kotlin-test'].kotlin.test.overrideAsserter_wbnzx$(this['kotlin-test'].kotlin.test.DefaultAsserter);")
}
fun InteropEngine.runTestFunction(
testModuleName: String?,
testPackageName: String?,
testFunctionName: String,
withModuleSystem: Boolean
): Any? {
val testModule =
when {
withModuleSystem ->
eval(BasicBoxTest.KOTLIN_TEST_INTERNAL + ".require('" + testModuleName!! + "')")
testModuleName === null ->
eval("this")
else ->
get(testModuleName)
}
testModule as ScriptObjectMirror
): String? {
var script = when {
withModuleSystem -> BasicBoxTest.KOTLIN_TEST_INTERNAL + ".require('" + testModuleName!! + "')"
testModuleName === null -> "this"
else -> testModuleName
}
val testPackage =
when {
testPackageName === null ->
testModule
testPackageName.contains(".") ->
testPackageName.split(".").fold(testModule) { p, part -> p[part] as ScriptObjectMirror }
else ->
testModule[testPackageName]!!
}
if (testPackageName !== null) {
script += ".$testPackageName"
}
return (this as Invocable).invokeMethod(testPackage, testFunctionName)
return callMethod(eval(script), testFunctionName)
}
fun ScriptEngine.loadFile(path: String) {
eval("load('${path.replace('\\', '/')}');")
}
fun ScriptEngine.runAndRestoreContext(
globalObject: ScriptObjectMirror = eval("this") as ScriptObjectMirror,
fun InteropEngine.runAndRestoreContext(
globalObject: InteropGlobalContext = getGlobalContext(),
originalState: Map<String, Any?> = globalObject.toMap(),
f: ScriptEngine.() -> Any?
f: InteropEngine.() -> Any?
): Any? {
return try {
this.f()
} finally {
for (key in globalObject.keys) {
globalObject[key] = originalState[key] ?: ScriptRuntime.UNDEFINED
}
globalObject.updateState(originalState)
}
}
@@ -72,14 +57,14 @@ abstract class AbstractNashornJsTestChecker {
private var engineUsageCnt = 0
private var engineCache: ScriptEngine? = null
private var globalObject: ScriptObjectMirror? = null
private var engineCache: InteropEngine? = null
private var globalObject: InteropGlobalContext? = null
private var originalState: Map<String, Any?>? = null
protected val engine
get() = engineCache ?: createScriptEngineForTest().also {
engineCache = it
globalObject = it.eval("this") as ScriptObjectMirror
globalObject = it.getGlobalContext()
originalState = globalObject?.toMap()
}
@@ -113,7 +98,7 @@ abstract class AbstractNashornJsTestChecker {
private fun run(
files: List<String>,
f: ScriptEngine.() -> Any?
f: InteropEngine.() -> Any?
): Any? {
// Recreate the engine once in a while
if (engineUsageCnt++ > 100) {
@@ -129,7 +114,7 @@ abstract class AbstractNashornJsTestChecker {
}
}
protected abstract fun createScriptEngineForTest(): ScriptEngine
protected abstract fun createScriptEngineForTest(): InteropEngine
}
object NashornJsTestChecker : AbstractNashornJsTestChecker() {
@@ -137,16 +122,16 @@ object NashornJsTestChecker : AbstractNashornJsTestChecker() {
private const val GET_KOTLIN_OUTPUT = "kotlin.kotlin.io.output.buffer;"
override fun beforeRun() {
engine.eval(SETUP_KOTLIN_OUTPUT)
engine.evalVoid(SETUP_KOTLIN_OUTPUT)
}
fun checkStdout(files: List<String>, expectedResult: String) {
run(files)
val actualResult = engine.eval(GET_KOTLIN_OUTPUT)
val actualResult = engine.eval<String>(GET_KOTLIN_OUTPUT)
Assert.assertEquals(expectedResult, actualResult)
}
override fun createScriptEngineForTest(): ScriptEngine {
override fun createScriptEngineForTest(): InteropEngine {
val engine = createScriptEngine()
listOf(
@@ -162,7 +147,7 @@ object NashornJsTestChecker : AbstractNashornJsTestChecker() {
}
class NashornIrJsTestChecker(private val runtime: JsIrTestRuntime) : AbstractNashornJsTestChecker() {
override fun createScriptEngineForTest(): ScriptEngine {
override fun createScriptEngineForTest(): InteropEngine {
val engine = createScriptEngine()
listOf(

View File

@@ -0,0 +1,8 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.js.test.interop
typealias GlobalRuntimeContext = MutableMap<String, Any?>

View File

@@ -0,0 +1,14 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.js.test.interop
interface InteropEngine {
fun <T> eval(script: String): T
fun getGlobalContext(): InteropGlobalContext
fun evalVoid(script: String)
fun <T> callMethod(obj: Any, name: String, vararg args: Any?): T
fun loadFile(path: String)
}

View File

@@ -0,0 +1,12 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.js.test.interop
interface InteropGlobalContext {
fun updateState(state: Map<String, Any?>)
fun toMap(): Map<String, Any?>
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.js.test.interop
import jdk.nashorn.api.scripting.NashornScriptEngineFactory
import javax.script.Invocable
class InteropNashorn : InteropEngine {
// TODO use "-strict"
private val myEngine = NashornScriptEngineFactory().getScriptEngine("--language=es5", "--no-java", "--no-syntax-extensions")
@Suppress("UNCHECKED_CAST")
override fun <T> eval(script: String): T {
return myEngine.eval(script) as T
}
override fun evalVoid(script: String) {
myEngine.eval(script)
}
override fun getGlobalContext(): InteropGlobalContext {
return NashornGlobalContext(eval("this"))
}
@Suppress("UNCHECKED_CAST")
override fun <T> callMethod(obj: Any, name: String, vararg args: Any?): T {
return (myEngine as Invocable).invokeMethod(obj, name, *args) as T
}
override fun loadFile(path: String) {
evalVoid("load('${path.replace('\\', '/')}');")
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.js.test.interop
import com.eclipsesource.v8.V8
import com.eclipsesource.v8.V8Array
import com.eclipsesource.v8.V8Object
import java.io.File
class InteropV8 : InteropEngine {
private val myRuntime: V8 = V8.createV8Runtime("global")
@Suppress("UNCHECKED_CAST")
override fun <T> eval(script: String): T {
return myRuntime.executeScript(script) as T
}
override fun evalVoid(script: String) {
return myRuntime.executeVoidScript(script)
}
override fun getGlobalContext(): InteropGlobalContext {
return V8GlobalContext(eval<V8Object>("this"))
}
@Suppress("UNCHECKED_CAST")
override fun <T> callMethod(obj: Any, name: String, vararg args: Any?): T {
if (obj !is V8Object) {
throw Exception("InteropV8 can deal only with V8Object")
}
return obj.executeFunction(name, V8Array(myRuntime)) as T
}
override fun loadFile(path: String) {
evalVoid(File(path).bufferedReader().use { it.readText() })
}
}

View File

@@ -0,0 +1,22 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.js.test.interop
import jdk.nashorn.internal.runtime.ScriptRuntime
class NashornGlobalContext(private val myState: GlobalRuntimeContext) : InteropGlobalContext {
override fun updateState(state: Map<String, Any?>) {
for (key in myState.keys) {
myState[key] = state[key] ?: ScriptRuntime.UNDEFINED
}
}
override fun toMap(): Map<String, Any?> {
return myState.toMap()
}
}

View File

@@ -0,0 +1,20 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.js.test.interop
import com.eclipsesource.v8.V8Object
import com.eclipsesource.v8.utils.V8ObjectUtils
class V8GlobalContext(val myState: V8Object) : InteropGlobalContext {
override fun updateState(state: Map<String, Any?>) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun toMap(): Map<String, Any?> {
return V8ObjectUtils.toMap(myState)
}
}

View File

@@ -128,8 +128,8 @@ abstract class BasicOptimizerTest(private var basePath: String) {
private fun runScript(fileName: String, code: String) {
val engine = createScriptEngine()
engine.eval(code)
val result = engine.eval("box()")
engine.evalVoid(code)
val result = engine.eval<String>("box()")
Assert.assertEquals("$fileName: box() function must return 'OK'", "OK", result)
}