/* * 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. * */ import kotlinx.coroutines.test.runTest import net.sergeych.lyng.eval import kotlin.test.Test class StdlibTest { @Test fun testIterableFilter() = runTest { eval(""" assertEquals([2,4,6,8], (1..8).filter{ println("call2"); it % 2 == 0 }.toList() ) println("-------------------") assertEquals([1,3,5,7], (1..8).filter{ println("call1"); it % 2 == 1 }.toList() ) """.trimIndent()) } @Test fun testFirstLast() = runTest { eval(""" assertEquals(1, (1..8).first ) assertEquals(8, (1..8).last ) """.trimIndent()) } @Test fun testTake() = runTest { eval(""" val r = 1..8 assertEquals([1,2,3], r.take(3).toList() ) assertEquals([7,8], r.takeLast(2).toList() ) """.trimIndent()) } @Test fun testAnyAndAll() = runTest { eval(""" assert( [1,2,3].any { it > 2 } ) assert( ![1,2,3].any { it > 4 } ) assert( [1,2,3].all { it <= 3 } ) """.trimIndent()) } @Test fun testRingBuffer() = runTest { eval(""" val r = RingBuffer(3) assert( r is RingBuffer ) assertEquals(0, r.size) assertEquals(3, r.capacity) r += 10 assertEquals(1, r.size) assertEquals(10, r.first) r += 20 assertEquals(2, r.size) assertEquals( [10, 20], r.toList() ) r += 30 assertEquals(3, r.size) assertEquals( [10, 20, 30], r.toList() ) r += 40 assertEquals(3, r.size) assertEquals( [20, 30, 40], r.toList() ) """.trimIndent()) } @Test fun testDrop() = runTest { eval(""" assertEquals([7,8], (1..8).drop(6).toList() ) assertEquals([1,2], (1..8).dropLast(6).toList() ) """.trimIndent()) } @Test fun testFlattenAndFilter() = runTest { eval(""" assertEquals([1,2,3,4,5,6], [1,3,5].map { [it, it+1] }.flatten() ) assertEquals([1,3,5], [null,1,null, 3,5].filterNotNull().toList()) """) } @Test fun testFlatMap() = runTest { eval(""" assertEquals([1,2,3,4,5,6], [1,3,5].flatMap { [it,it+1] }.toList() ) """) } @Test fun testCount() = runTest { eval(""" assertEquals(5, (1..10).toList().count { it % 2 == 1 } ) """) } @Test fun testWith() = runTest { eval(""" class Person(val name, var age) val p = Person("Alice", 30) val result = with(p) { assertEquals("Alice", name) assertEquals(30, age) age = 31 "done" } assertEquals("done", result) assertEquals(31, p.age) """.trimIndent()) } @Test fun testFilter1() = runTest { // range should be iterable if it is intrange eval(""" val data = 1..5 // or [1, 2, 3, 4, 5] assert( data is Iterable ) fun test() { data.filter { it % 2 == 0 }.map { it * it } } test() """.trimIndent()) } @Test fun testFilter2() = runTest { eval(""" val data = [1, 2, 3, 4, 5] assert( data is Iterable ) fun test() { data.filter { it % 2 == 0 }.map { it * it } } test() """ ) } @Test fun testFilter3() = runTest { eval(""" type Numeric = Int | Real fun process(items: List): List { items.filter { it > 0 }.map { it * it } } val data = [-2, -1, 0, 1, 2] println("Processed: " + process(data)) """.trimIndent()) } @Test fun testRandomSeededDeterministic() = runTest { eval(""" val a = Random.seeded(123456) val b = Random.seeded(123456) for( i in 1..20 ) { assertEquals(a.nextInt(), b.nextInt()) assertEquals(a.nextFloat(), b.nextFloat()) assertEquals(a.next(1..100), b.next(1..100)) } """.trimIndent()) } @Test fun testRandomNextFloatBounds() = runTest { eval(""" for( i in 1..400 ) { val x = Random.nextFloat() assert(x >= 0.0) assert(x < 1.0) } """.trimIndent()) } @Test fun testRandomNextRangeVariants() = runTest { eval(""" val rnd = Random.seeded(77) for( i in 1..300 ) { val x = rnd.next(10..<20) assert(x in 10..<20) } val allowed = [0, 3, 6, 9] for( i in 1..300 ) { val x = rnd.next(0..9 step 3) assert(x in allowed) } for( i in 1..300 ) { val ch = rnd.next('a'..<'f') assert(ch in 'a'..<'f') } for( i in 1..300 ) { val rf = rnd.next(1.5..<4.5) assert(rf >= 1.5) assert(rf < 4.5) } val qAllowed = [0.0, 0.25, 0.5, 0.75, 1.0] for( i in 1..300 ) { val q = rnd.next(0.0..1.0 step 0.25) assert(q in qAllowed) } """.trimIndent()) } @Test fun testRandomRejectsOpenRange() = runTest { eval(""" assertThrows(IllegalArgumentException) { Random.next(1..) } assertThrows(IllegalArgumentException) { Random.next(..10) } assertThrows(IllegalArgumentException) { Random.next(..) } """.trimIndent()) } }