141 lines
4.2 KiB
Kotlin
141 lines
4.2 KiB
Kotlin
/*
|
|
* Copyright 2025 Sergey S. Chernov real.sergeych@gmail.com
|
|
*
|
|
* 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.
|
|
*
|
|
*/
|
|
|
|
import kotlinx.coroutines.runBlocking
|
|
import net.sergeych.lyng.Scope
|
|
import net.sergeych.lyng.obj.ObjInt
|
|
import net.sergeych.lyng.obj.ObjList
|
|
import kotlin.test.Ignore
|
|
import kotlin.test.Test
|
|
import kotlin.test.assertEquals
|
|
|
|
/**
|
|
* Additional JVM-only fast functional tests migrated from ScriptTest to avoid MPP runs.
|
|
* Keep each test fast (<1s) and with clear assertions.
|
|
*/
|
|
@Ignore("TODO(bytecode-only): uses fallback (binarySearch/logical chains)")
|
|
class ScriptSubsetJvmTest_Additions {
|
|
private suspend fun evalInt(code: String): Long = (Scope().eval(code) as ObjInt).value
|
|
private suspend fun evalList(code: String): List<Any?> = (Scope().eval(code) as ObjList).list.map { (it as? ObjInt)?.value ?: it }
|
|
|
|
@Test
|
|
fun rangesAndForLoop_jvm_only() = runBlocking {
|
|
val code = """
|
|
var s = 0
|
|
for (i in 1..100) s = s + i
|
|
s
|
|
""".trimIndent()
|
|
val r = evalInt(code)
|
|
assertEquals(5050L, r)
|
|
}
|
|
|
|
@Test
|
|
fun classFieldsAndMethods_jvm_only() = runBlocking {
|
|
val n = 20000
|
|
val code = """
|
|
class Counter() {
|
|
var x = 0
|
|
fun inc() { x = x + 1 }
|
|
fun get() { x }
|
|
}
|
|
val c = Counter()
|
|
var i = 0
|
|
while (i < $n) { c.inc(); i = i + 1 }
|
|
c.get()
|
|
""".trimIndent()
|
|
val r = evalInt(code)
|
|
assertEquals(n.toLong(), r)
|
|
}
|
|
|
|
@Test
|
|
fun elvisAndLogicalChains_jvm_only() = runBlocking {
|
|
val n = 10000
|
|
val code = """
|
|
val maybe: Int? = null
|
|
var s = 0
|
|
var i = 0
|
|
while (i < $n) {
|
|
s = s + (maybe ?: 0)
|
|
if ((i % 3 == 0 && true) || false) { s = s + 1 } else { s = s + 2 }
|
|
s = s + (i - (i / 2) * 2)
|
|
i = i + 1
|
|
}
|
|
s
|
|
""".trimIndent()
|
|
val r = evalInt(code)
|
|
// Kotlin mirror for correctness
|
|
var s = 0L
|
|
var i = 0
|
|
while (i < n) {
|
|
if ((i % 3 == 0 && true) || false) s += 1 else s += 2
|
|
s += (i - (i / 2) * 2)
|
|
i += 1
|
|
}
|
|
assertEquals(s, r)
|
|
}
|
|
|
|
@Test
|
|
fun sortedInsertWithBinarySearch_jvm_only() = runBlocking {
|
|
val code = """
|
|
val src = [3,1,2]
|
|
val result: List<Int> = []
|
|
for (x in src) {
|
|
val i = result.binarySearch(x)
|
|
result.insertAt(if (i < 0) -i-1 else i, x)
|
|
}
|
|
result
|
|
""".trimIndent()
|
|
val r = evalList(code)
|
|
assertEquals(listOf(1L, 2L, 3L), r)
|
|
}
|
|
}
|
|
|
|
|
|
@Ignore("TODO(bytecode-only): hangs (while/continue?)")
|
|
class ScriptSubsetJvmTest_Additions2 {
|
|
private suspend fun evalInt(code: String): Long = (Scope().eval(code) as ObjInt).value
|
|
|
|
@Test
|
|
fun optionalMethodCallWithElvis_jvm_only() = runBlocking {
|
|
val code = """
|
|
class C() { fun get() { 5 } }
|
|
val a: C? = null
|
|
(a?.get() ?: 7)
|
|
""".trimIndent()
|
|
val r = evalInt(code)
|
|
assertEquals(7L, r)
|
|
}
|
|
|
|
@Test
|
|
fun continueAndBreakInWhile_jvm_only() = runBlocking {
|
|
val code = """
|
|
var s = 0
|
|
var i = 0
|
|
while (i <= 100) {
|
|
if (i > 50) break
|
|
if (i % 2 == 1) { i = i + 1; continue }
|
|
s = s + i
|
|
i = i + 1
|
|
}
|
|
s
|
|
""".trimIndent()
|
|
val r = evalInt(code)
|
|
// Sum of even numbers from 0 to 50 inclusive: 2 * (0+1+...+25) = 2 * 325 = 650
|
|
assertEquals(650L, r)
|
|
}
|
|
}
|