Skip to content

Commit f27d38a

Browse files
committed
Merge branch 'android-quickjs' into ios-javascript
# Conflicts: # buildSrc/src/main/kotlin/Deps.kt # sample/mpp-library/src/commonMain/kotlin/com/icerockdev/library/Calculator.kt
2 parents 295684e + 09b8bab commit f27d38a

File tree

7 files changed

+146
-4
lines changed

7 files changed

+146
-4
lines changed

buildSrc/src/main/kotlin/Deps.kt

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,20 @@ object Deps {
88
private const val androidAppCompatVersion = "1.1.0"
99
private const val materialDesignVersion = "1.0.0"
1010
private const val androidLifecycleVersion = "2.1.0"
11-
private const val androidCoreTestingVersion = "2.1.0"
11+
private const val androidCoreTestingVersion = "1.3.0"
12+
private const val testJUnitExtVersion = "1.1.2"
1213
private const val quickjsVersion = "0.9.0"
1314

1415
private const val coroutinesVersion = "1.4.2"
1516
private const val kotlinxSerializationVersion = "1.1.0"
1617
private const val mokoTestVersion = "0.3.0"
18+
1719
const val mokoJavascriptVersion = "0.1.0"
1820

1921
object Android {
2022
const val compileSdk = 30
2123
const val targetSdk = 30
22-
const val minSdk = 16
24+
const val minSdk = 18
2325
}
2426

2527
object Libs {
@@ -28,6 +30,11 @@ object Deps {
2830
const val material = "com.google.android.material:material:$materialDesignVersion"
2931
const val lifecycle = "androidx.lifecycle:lifecycle-extensions:$androidLifecycleVersion"
3032

33+
const val testRunner = "androidx.test:runner:$androidCoreTestingVersion"
34+
const val testRules = "androidx.test:rules:$androidCoreTestingVersion"
35+
const val testJUnitExt = "androidx.test.ext:junit:$testJUnitExtVersion"
36+
const val testJUnitExtKtx = "androidx.test.ext:junit-ktx:$testJUnitExtVersion"
37+
3138
const val quickjs = "app.cash.quickjs:quickjs-android:$quickjsVersion"
3239
}
3340

@@ -37,7 +44,13 @@ object Deps {
3744
const val kotlinSerialization =
3845
"org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinxSerializationVersion"
3946

47+
const val kotlinTest =
48+
"org.jetbrains.kotlin:kotlin-test-common:$kotlinTestVersion"
49+
const val kotlinTestAnnotations =
50+
"org.jetbrains.kotlin:kotlin-test-annotations-common:$kotlinTestVersion"
4051
const val mokoTest = "dev.icerock.moko:test-core:$mokoTestVersion"
52+
const val mokoTestRobolectric = "dev.icerock.moko:test-roboelectric:$mokoTestVersion"
53+
4154
const val mokoJavascript = "dev.icerock.moko:javascript:$mokoJavascriptVersion"
4255
}
4356
}

javascript/build.gradle.kts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,24 @@ plugins {
77
id("publication-convention")
88
}
99

10+
android {
11+
testOptions.unitTests.isIncludeAndroidResources = true
12+
defaultConfig {
13+
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
14+
}
15+
}
16+
1017
dependencies {
1118
androidMainImplementation(Deps.Libs.Android.quickjs)
1219

1320
commonMainImplementation(Deps.Libs.MultiPlatform.kotlinSerialization)
1421

22+
commonTestImplementation(Deps.Libs.MultiPlatform.kotlinTest)
23+
commonTestImplementation(Deps.Libs.MultiPlatform.kotlinTestAnnotations)
1524
commonTestImplementation(Deps.Libs.MultiPlatform.mokoTest)
25+
26+
androidTestImplementation(Deps.Libs.Android.testRunner)
27+
androidTestImplementation(Deps.Libs.Android.testRules)
28+
androidTestImplementation(Deps.Libs.Android.testJUnitExt)
29+
androidTestImplementation(Deps.Libs.Android.testJUnitExtKtx)
1630
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright 2021 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
package dev.icerock.moko.javascript
6+
7+
import org.junit.After
8+
import org.junit.Before
9+
import org.junit.Test
10+
11+
class JavaScriptEngineTest {
12+
private var _javaScriptEngine: JavaScriptEngine? = null
13+
14+
private val javaScriptEngine: JavaScriptEngine
15+
get() = _javaScriptEngine!!
16+
17+
@Before
18+
fun init() {
19+
_javaScriptEngine = JavaScriptEngine()
20+
}
21+
22+
@After
23+
fun dispose() {
24+
javaScriptEngine.close()
25+
}
26+
27+
@Test
28+
fun equalityTest() {
29+
val jsScript = """
30+
var a = 1 + 2;
31+
a
32+
""".trimIndent()
33+
val result = javaScriptEngine.evaluate(emptyMap(), jsScript)
34+
35+
println("DBG $result")
36+
37+
//assertTrue { result is JsType.IntNum }
38+
//assertEquals(expected = 3, actual = result.intValue())
39+
}
40+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<manifest package="dev.icerock.moko.javascript" />
2+
<manifest package="dev.icerock.moko.javascript" />
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* Copyright 2021 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
package dev.icerock.moko.javascript
6+
7+
import app.cash.quickjs.QuickJs
8+
import app.cash.quickjs.QuickJsException
9+
import kotlinx.serialization.SerializationException
10+
import kotlinx.serialization.json.Json
11+
import kotlinx.serialization.json.encodeToJsonElement
12+
13+
actual class JavaScriptEngine actual constructor(){
14+
private val quickJs: QuickJs = QuickJs.create()
15+
private val json: Json = Json.Default
16+
17+
@Volatile
18+
var isClosed = false
19+
private set
20+
21+
actual fun evaluate(
22+
context: Map<String, JsType>,
23+
script: String
24+
): JsType {
25+
if (isClosed) throw JavaScriptEvaluationException(message = "Engine already closed")
26+
27+
return try {
28+
internalEvaluate(context, script)
29+
} catch (exception: QuickJsException) {
30+
throw JavaScriptEvaluationException(exception)
31+
}
32+
}
33+
34+
actual fun close() {
35+
if (isClosed) return
36+
quickJs.close()
37+
isClosed = true
38+
}
39+
40+
private fun internalEvaluate(
41+
context: Map<String, JsType>,
42+
script: String
43+
): JsType {
44+
context.forEach { pair ->
45+
quickJs.set(pair.key, pair.value.javaClass, pair.value)
46+
}
47+
val result = quickJs.evaluate(script)
48+
return handleQuickJsResult(result)
49+
}
50+
51+
private fun handleQuickJsResult(result: Any?): JsType {
52+
return when (result) {
53+
result == null -> JsType.Null
54+
is Boolean -> JsType.Bool(result)
55+
is Int -> JsType.IntNum(result)
56+
is Double -> JsType.DoubleNum(result)
57+
is Float -> JsType.DoubleNum(result.toDouble())
58+
is String -> try {
59+
JsType.Json(json.encodeToJsonElement(result))
60+
} catch (ex: SerializationException) {
61+
JsType.Str(result)
62+
}
63+
else -> throw JavaScriptEvaluationException(
64+
message = "Impossible JavaScriptEngine handler state with result [$result]"
65+
)
66+
}
67+
}
68+
}

javascript/src/commonMain/kotlin/dev/icerock/moko/javascript/JsType.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,10 @@ sealed class JsType {
1818
*/
1919
object Null : JsType()
2020
}
21+
22+
fun JsType.boolValue(): Boolean = (this as JsType.Bool).value
23+
fun JsType.stringValue(): String = (this as JsType.Str).value
24+
fun JsType.intValue(): Int = (this as JsType.IntNum).value
25+
fun JsType.doubleValue(): Double = (this as JsType.DoubleNum).value
26+
fun JsType.jsonValue(): JsonElement = (this as JsType.Json).value
27+
fun JsType.nullValue(): Any? = (this as JsType.Null).let { null }

sample/android-app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<uses-permission android:name="android.permission.INTERNET" />
77

88
<application
9-
android:label="moko-fields test app"
9+
android:label="moko-javascript test app"
1010
android:theme="@style/Theme.AppCompat.DayNight"
1111
tools:ignore="GoogleAppIndexingWarning">
1212

0 commit comments

Comments
 (0)