corrected home page samples
This commit is contained in:
parent
69156893d4
commit
2e7c28f735
260
lynglib/src/commonTest/kotlin/WebsiteSamplesTest.kt
Normal file
260
lynglib/src/commonTest/kotlin/WebsiteSamplesTest.kt
Normal file
@ -0,0 +1,260 @@
|
||||
/*
|
||||
* Copyright 2026 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng
|
||||
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import net.sergeych.lyng.obj.*
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class WebsiteSamplesTest {
|
||||
|
||||
@Test
|
||||
fun testEverythingIsAnExpression() = runTest {
|
||||
val scope = Script.newScope()
|
||||
val result = scope.eval("""
|
||||
// Everything is an expression
|
||||
val x: Int = 10
|
||||
val status: String = if (x > 0) "Positive" else "Zero or Negative"
|
||||
|
||||
// Even loops return values!
|
||||
val result = for (i in 1..5) {
|
||||
if (i == 3) break "Found 3!"
|
||||
} else "Not found"
|
||||
|
||||
result
|
||||
""".trimIndent())
|
||||
assertEquals("Found 3!", (result as ObjString).value)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFunctionalPower() = runTest {
|
||||
val scope = Script.newScope()
|
||||
val result = scope.eval("""
|
||||
// Functional power with generics and collections
|
||||
val squares: List<Int> = (1..10)
|
||||
.filter { it % 2 == 0 }
|
||||
.map { it * it }
|
||||
|
||||
squares
|
||||
""".trimIndent())
|
||||
assertTrue(result is ObjList)
|
||||
val list = (result as ObjList).list.map { (it as ObjInt).value }
|
||||
assertEquals(listOf(4L, 16L, 36L, 64L, 100L), list)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGenericsAndTypeAliases() = runTest {
|
||||
val scope = Script.newScope()
|
||||
val result = scope.eval("""
|
||||
// Generics and type aliases
|
||||
type Num = Int | Real
|
||||
|
||||
class Box<out T: Num>(val value: T) {
|
||||
fun get(): T = value
|
||||
}
|
||||
|
||||
val intBox = Box(42)
|
||||
val realBox = Box(3.14)
|
||||
[intBox.get(), realBox.get()]
|
||||
""".trimIndent())
|
||||
assertTrue(result is ObjList)
|
||||
val l = (result as ObjList).list
|
||||
assertEquals(42L, (l[0] as ObjInt).value)
|
||||
assertEquals(3.14, (l[1] as ObjReal).value)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testStrictCompileTimeTypes() = runTest {
|
||||
val scope = Script.newScope()
|
||||
scope.eval("""
|
||||
// Strict compile-time types and symbol resolution
|
||||
fun greet(name: String, count: Int) {
|
||||
for (i in 1..count) {
|
||||
println("Hello, " + name + "!")
|
||||
}
|
||||
}
|
||||
|
||||
greet("Lyng", 3)
|
||||
""".trimIndent())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFlexibleMapLiterals() = runTest {
|
||||
val scope = Script.newScope()
|
||||
val result = scope.eval("""
|
||||
// Flexible map literals and shorthands
|
||||
val id = 101
|
||||
val name = "Lyng"
|
||||
val base = { id:, name: } // Shorthand for id: id, name: name
|
||||
|
||||
val full = { ...base, version: "1.5.0-SNAPSHOT", status: "active" }
|
||||
full
|
||||
""".trimIndent())
|
||||
assertTrue(result is ObjMap)
|
||||
val m = (result as ObjMap).map
|
||||
assertEquals(101L, (m[ObjString("id")] as ObjInt).value)
|
||||
assertEquals("Lyng", (m[ObjString("name")] as ObjString).value)
|
||||
assertEquals("1.5.0-SNAPSHOT", (m[ObjString("version")] as ObjString).value)
|
||||
assertEquals("active", (m[ObjString("status")] as ObjString).value)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testModernNullSafety() = runTest {
|
||||
val scope = Script.newScope()
|
||||
val result = scope.eval("""
|
||||
// Modern null safety
|
||||
var config: Map<String, Int>? = null
|
||||
config ?= { timeout: 30 } // Assign only if null
|
||||
|
||||
val timeout = config?["timeout"] ?: 60
|
||||
timeout
|
||||
""".trimIndent())
|
||||
assertEquals(30L, (result as ObjInt).value)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDestructuringWithSplat() = runTest {
|
||||
val scope = Script.newScope()
|
||||
val result = scope.eval("""
|
||||
// Destructuring with splat operator
|
||||
val [first, middle..., last] = [1, 2, 3, 4, 5, 6]
|
||||
[first, middle, last]
|
||||
""".trimIndent())
|
||||
assertTrue(result is ObjList)
|
||||
val rl = (result as ObjList).list
|
||||
assertEquals(1L, (rl[0] as ObjInt).value)
|
||||
val middle = rl[1] as ObjList
|
||||
assertEquals(listOf(2L, 3L, 4L, 5L), middle.list.map { (it as ObjInt).value })
|
||||
assertEquals(6L, (rl[2] as ObjInt).value)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDiamondSafeMultipleInheritance() = runTest {
|
||||
val scope = Script.newScope()
|
||||
scope.eval("""
|
||||
// Diamond-safe Multiple Inheritance (C3 MRO)
|
||||
interface Logger {
|
||||
fun log(m: String) = println("[LOG] " + m)
|
||||
}
|
||||
interface Auth {
|
||||
fun login(u: String) = println("Login: " + u)
|
||||
}
|
||||
|
||||
class App() : Logger, Auth {
|
||||
override fun run() {
|
||||
log("Starting...")
|
||||
login("admin")
|
||||
}
|
||||
}
|
||||
App().run()
|
||||
""".trimIndent())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testExtensionFunctionsAndProperties() = runTest {
|
||||
val scope = Script.newScope()
|
||||
val result = scope.eval("""
|
||||
// Extension functions and properties
|
||||
fun String.shout(): String = this.uppercase() + "!!!"
|
||||
|
||||
val List<T>.second: T get() = this[1]
|
||||
["hello".shout(), [10, 20, 30].second]
|
||||
""".trimIndent())
|
||||
assertTrue(result is ObjList)
|
||||
val el = (result as ObjList).list
|
||||
assertEquals("HELLO!!!", (el[0] as ObjString).value)
|
||||
assertEquals(20L, (el[1] as ObjInt).value)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testNonLocalReturns() = runTest {
|
||||
val scope = Script.newScope()
|
||||
val result = scope.eval("""
|
||||
// Non-local returns from closures
|
||||
fun findFirst<T>(list: Iterable<T>, predicate: (T)->Bool): T? {
|
||||
list.forEach {
|
||||
if (predicate(it)) return@findFirst it
|
||||
}
|
||||
null
|
||||
}
|
||||
|
||||
val found: Int? = findFirst([1, 5, 8, 12]) { it > 10 }
|
||||
found
|
||||
""".trimIndent())
|
||||
assertEquals(12L, (result as ObjInt).value)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testEasyOperatorOverloading() = runTest {
|
||||
val scope = Script.newScope()
|
||||
val result = scope.eval("""
|
||||
// Easy operator overloading
|
||||
class Vector(val x: Real, val y: Real) {
|
||||
fun plus(other: Vector): Vector = Vector(x + other.x, y + other.y)
|
||||
override fun toString(): String = "Vector(%g, %g)"(x, y)
|
||||
}
|
||||
|
||||
val v1 = Vector(1, 2)
|
||||
val v2 = Vector(3, 4)
|
||||
(v1 + v2).toString()
|
||||
""".trimIndent())
|
||||
assertEquals("Vector(4, 6)", (result as ObjString).value)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPropertyDelegationToMap() = runTest {
|
||||
val scope = Script.newScope()
|
||||
val result = scope.eval("""
|
||||
// Property delegation to Map
|
||||
class User() {
|
||||
var name: String by Map()
|
||||
}
|
||||
|
||||
val u = User()
|
||||
u.name = "Sergey"
|
||||
u.name
|
||||
""".trimIndent())
|
||||
assertEquals("Sergey", (result as ObjString).value)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testImplicitCoroutines() = runTest {
|
||||
val scope = Script.newScope()
|
||||
val result = scope.eval("""
|
||||
// Implicit coroutines: parallelism without ceremony
|
||||
// import lyng.time // we don't need it for delay if it's available globally
|
||||
|
||||
val d1 = launch {
|
||||
delay(100.milliseconds)
|
||||
"Task A finished"
|
||||
}
|
||||
val d2 = launch {
|
||||
delay(50.milliseconds)
|
||||
"Task B finished"
|
||||
}
|
||||
|
||||
[d1.await(), d2.await()]
|
||||
""".trimIndent())
|
||||
assertTrue(result is ObjList)
|
||||
val dl = (result as ObjList).list
|
||||
assertEquals("Task A finished", (dl[0] as ObjString).value)
|
||||
assertEquals("Task B finished", (dl[1] as ObjString).value)
|
||||
}
|
||||
}
|
||||
@ -106,7 +106,7 @@ fun HomePage() {
|
||||
}
|
||||
|
||||
class App() : Logger, Auth {
|
||||
fun run() {
|
||||
override fun run() {
|
||||
log("Starting...")
|
||||
login("admin")
|
||||
}
|
||||
@ -137,7 +137,7 @@ fun HomePage() {
|
||||
"""
|
||||
// Easy operator overloading
|
||||
class Vector(val x: Real, val y: Real) {
|
||||
override fun plus(other: Vector): Vector = Vector(x + other.x, y + other.y)
|
||||
fun plus(other: Vector): Vector = Vector(x + other.x, y + other.y)
|
||||
override fun toString(): String = "Vector(%g, %g)"(x, y)
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user