diff --git a/android/app/src/androidTest/java/com/caoccao/javet/shell/ExampleInstrumentedTest.kt b/android/app/src/androidTest/java/com/caoccao/javet/shell/TestMainActivity.kt similarity index 50% rename from android/app/src/androidTest/java/com/caoccao/javet/shell/ExampleInstrumentedTest.kt rename to android/app/src/androidTest/java/com/caoccao/javet/shell/TestMainActivity.kt index e8a0e9a..38ff491 100644 --- a/android/app/src/androidTest/java/com/caoccao/javet/shell/ExampleInstrumentedTest.kt +++ b/android/app/src/androidTest/java/com/caoccao/javet/shell/TestMainActivity.kt @@ -16,23 +16,49 @@ package com.caoccao.javet.shell -import androidx.test.platform.app.InstrumentationRegistry +import androidx.compose.ui.test.assertTextEquals +import androidx.compose.ui.test.assertValueEquals +import androidx.compose.ui.test.junit4.createComposeRule +import androidx.compose.ui.test.onNodeWithTag +import androidx.compose.ui.test.onNodeWithText +import androidx.compose.ui.test.performClick +import androidx.compose.ui.test.performTextInput import androidx.test.ext.junit.runners.AndroidJUnit4 - +import androidx.test.platform.app.InstrumentationRegistry +import com.caoccao.javet.interop.V8Host +import com.caoccao.javet.interop.V8Runtime +import com.caoccao.javet.shell.ui.theme.JavetShellTheme +import org.junit.Assert.* +import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.junit.Assert.* - /** * Instrumented test, which will execute on an Android device. * * See [testing documentation](http://d.android.com/tools/testing). */ @RunWith(AndroidJUnit4::class) -class ExampleInstrumentedTest { +class TestMainActivity { + @get:Rule + val composeRule = createComposeRule() + + @Test + fun testExecute() { + V8Host.getV8Instance().createV8Runtime().use { v8Runtime -> + composeRule.setContent { + JavetShellTheme { + HomeScreen(v8Runtime = v8Runtime, stringBuilder = StringBuilder()) + } + } + composeRule.onNodeWithTag("basicTextFieldCodeString").performTextInput("1 + 1") + composeRule.onNodeWithTag("elevatedButtonExecute").performClick() + composeRule.onNodeWithTag("textResult").assertTextEquals("\n> 1 + 1\n2") + } + } + @Test - fun useAppContext() { + fun testAppContext() { // Context of the app under test. val appContext = InstrumentationRegistry.getInstrumentation().targetContext assertEquals("com.caoccao.javet.shell", appContext.packageName) diff --git a/android/app/src/main/java/com/caoccao/javet/shell/MainActivity.kt b/android/app/src/main/java/com/caoccao/javet/shell/MainActivity.kt index c3f5fbb..7fcbdad 100644 --- a/android/app/src/main/java/com/caoccao/javet/shell/MainActivity.kt +++ b/android/app/src/main/java/com/caoccao/javet/shell/MainActivity.kt @@ -47,6 +47,8 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.testTag +import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.caoccao.javet.interop.V8Host @@ -57,12 +59,12 @@ import com.caoccao.javet.utils.JavetOSUtils import com.caoccao.javet.values.V8Value class MainActivity : ComponentActivity() { - private lateinit var v8Runtime: V8Runtime + private var v8Runtime: V8Runtime? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) v8Runtime = V8Host.getV8Instance().createV8Runtime() - val now = v8Runtime.getExecutor("new Date()").executeZonedDateTime() + val now = v8Runtime?.getExecutor("new Date()")?.executeZonedDateTime() val stringBuilder = StringBuilder().append( """Javet is Java + V8 (JAVa + V + EighT). It is an awesome way of embedding Node.js and V8 in Java. | @@ -70,7 +72,7 @@ class MainActivity : ComponentActivity() { | | OS Name = ${JavetOSUtils.OS_NAME} | OS Arch = ${JavetOSUtils.OS_ARCH} - | V8 = ${v8Runtime.version} + | V8 = ${v8Runtime?.version} | Now = $now | """.trimMargin("| ") @@ -82,23 +84,24 @@ class MainActivity : ComponentActivity() { modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background ) { - HomeScreen(v8Runtime, stringBuilder) + HomeScreen(v8Runtime = v8Runtime, stringBuilder = stringBuilder) } } } } override fun onDestroy() { - v8Runtime.close() + v8Runtime?.close() + v8Runtime = null super.onDestroy() } } @Composable fun HomeScreen( - v8Runtime: V8Runtime, - stringBuilder: java.lang.StringBuilder, - modifier: Modifier = Modifier + modifier: Modifier = Modifier, + v8Runtime: V8Runtime? = null, + stringBuilder: StringBuilder = StringBuilder() ) { Scaffold( topBar = { @@ -108,7 +111,7 @@ fun HomeScreen( titleContentColor = MaterialTheme.colorScheme.primary, ), title = { - Text("Javet Shell") + Text(text = stringResource(id = R.string.app_name)) } ) }, @@ -117,6 +120,24 @@ fun HomeScreen( val scrollState = rememberScrollState(0) var resultString by remember { mutableStateOf(stringBuilder.toString()) } var codeString by remember { mutableStateOf("") } + val executeFunction = { + val trimmedCodeString = codeString.trim() + if (!trimmedCodeString.isNullOrBlank()) { + try { + v8Runtime!! + .getExecutor(codeString) + .execute() + .use { v8Value -> + stringBuilder.append("\n> $trimmedCodeString\n$v8Value") + } + codeString = "" + } catch (t: Throwable) { + stringBuilder.append("\n> $trimmedCodeString\n${t.message}") + } finally { + resultString = stringBuilder.toString() + } + } + } LaunchedEffect(resultString) { scrollState.scrollTo(scrollState.maxValue) } @@ -136,6 +157,7 @@ fun HomeScreen( .verticalScroll(scrollState) .padding(padding) .fillMaxSize() + .testTag("textResult") ) } Column( @@ -144,27 +166,14 @@ fun HomeScreen( .weight(0.3F) ) { ElevatedButton( - onClick = { - try { - v8Runtime - .getExecutor(codeString) - .execute() - .use { v8Value -> - stringBuilder.append("\n> $codeString\n$v8Value") - } - codeString = "" - } catch (t: Throwable) { - stringBuilder.append("\n> $codeString\n${t.message}") - } finally { - resultString = stringBuilder.toString() - } - }, + onClick = executeFunction, shape = RoundedCornerShape(10), modifier = modifier .fillMaxWidth() .padding(start = padding, end = padding) + .testTag("elevatedButtonExecute") ) { - Text(text = "Execute") + Text(text = stringResource(id = R.string.button_execute)) } BasicTextField( value = codeString, @@ -173,6 +182,7 @@ fun HomeScreen( .fillMaxSize() .padding(padding) .background(color = Color.LightGray) + .testTag("basicTextFieldCodeString") ) } } @@ -183,8 +193,6 @@ fun HomeScreen( @Composable fun JavetShellPreview() { JavetShellTheme { - V8Host.getV8Instance().createV8Runtime().use { v8Runtime -> - HomeScreen(v8Runtime, StringBuilder()) - } + HomeScreen() } } \ No newline at end of file diff --git a/android/app/src/main/java/com/caoccao/javet/shell/ui/theme/Color.kt b/android/app/src/main/java/com/caoccao/javet/shell/ui/theme/Color.kt index dcdb93f..ce8bde0 100644 --- a/android/app/src/main/java/com/caoccao/javet/shell/ui/theme/Color.kt +++ b/android/app/src/main/java/com/caoccao/javet/shell/ui/theme/Color.kt @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2024. caoccao.com Sam Cao + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.caoccao.javet.shell.ui.theme import androidx.compose.ui.graphics.Color diff --git a/android/app/src/main/java/com/caoccao/javet/shell/ui/theme/Theme.kt b/android/app/src/main/java/com/caoccao/javet/shell/ui/theme/Theme.kt index d07e4b2..e003c88 100644 --- a/android/app/src/main/java/com/caoccao/javet/shell/ui/theme/Theme.kt +++ b/android/app/src/main/java/com/caoccao/javet/shell/ui/theme/Theme.kt @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2024. caoccao.com Sam Cao + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.caoccao.javet.shell.ui.theme import android.app.Activity diff --git a/android/app/src/main/java/com/caoccao/javet/shell/ui/theme/Type.kt b/android/app/src/main/java/com/caoccao/javet/shell/ui/theme/Type.kt index 00af03c..8c67f39 100644 --- a/android/app/src/main/java/com/caoccao/javet/shell/ui/theme/Type.kt +++ b/android/app/src/main/java/com/caoccao/javet/shell/ui/theme/Type.kt @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2024. caoccao.com Sam Cao + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.caoccao.javet.shell.ui.theme import androidx.compose.material3.Typography diff --git a/android/app/src/main/res/values/colors.xml b/android/app/src/main/res/values/colors.xml index f8c6127..b666eaa 100644 --- a/android/app/src/main/res/values/colors.xml +++ b/android/app/src/main/res/values/colors.xml @@ -1,4 +1,20 @@ + + #FFBB86FC #FF6200EE diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index 65b33bd..56d2b4f 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -1,3 +1,21 @@ + + + - JavetShell + Javet Shell + Execute \ No newline at end of file diff --git a/android/app/src/main/res/values/themes.xml b/android/app/src/main/res/values/themes.xml index 0aedc0e..8afdfa6 100644 --- a/android/app/src/main/res/values/themes.xml +++ b/android/app/src/main/res/values/themes.xml @@ -1,4 +1,20 @@ + +