test(vm): add method and stdlib tests

This commit is contained in:
dualfroz committed 2026-08-27 19:15:00 +02:00
1 parent 7e0c12ffb6
commit e4ee9baa36
2 files changed
+136

No files matched your search

+59
View File
@@ -0,0 +1,59 @@
package lumen
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
class MethodTest {
private fun output(source: String) = Lumen.runToString(source)
@Test
fun methodOnLiteralReceiver() {
assertEquals("ABC\n", output("println(\"abc\".upper())"))
assertEquals("[1, 2, 3]\n", output("println([3, 2, 1].sort())"))
}
@Test
fun chainedMethodCalls() {
assertEquals("CBA\n", output("println(\"abc\".upper().chars().reverse().join(\"\"))"))
}
@Test
fun methodMutatesReceiverInPlace() {
val program = """
let xs = [1, 2]
xs.push(3)
println(xs)
println(xs.len())
""".trimIndent()
assertEquals("[1, 2, 3]\n3\n", output(program))
}
@Test
fun dispatchDependsOnReceiverType() {
assertEquals("true\n", output("println([1, 2, 3].contains(2))"))
assertEquals("true\n", output("println(\"abc\".contains(\"b\"))"))
}
@Test
fun higherOrderMethods() {
assertEquals("[2, 4, 6]\n", output("println([1, 2, 3].map(fn(x) { return x * 2 }))"))
assertEquals("[2, 4]\n", output("println([1, 2, 3, 4].filter(fn(x) { return x % 2 == 0 }))"))
assertEquals("10\n", output("println([1, 2, 3, 4].reduce(fn(a, b) { return a + b }, 0))"))
}
@Test
fun unknownMethodFails() {
assertFailsWith<RuntimeError> { output("println([1].frobnicate())") }
}
@Test
fun methodWrongArityFails() {
assertFailsWith<RuntimeError> { output("println(\"a\".upper(1))") }
}
@Test
fun methodOnWrongTypeFails() {
assertFailsWith<RuntimeError> { output("println(42.upper())") }
}
}
+77
View File
@@ -0,0 +1,77 @@
package lumen
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertTrue
class StdlibTest {
private fun output(source: String) = Lumen.runToString(source)
@Test
fun mathFunctions() {
assertEquals("5\n", output("println(abs(-5))"))
assertEquals("5.0\n", output("println(abs(-5.0))"))
assertEquals("4.0\n", output("println(sqrt(16))"))
assertEquals("8.0\n", output("println(pow(2, 3))"))
assertEquals("3\n", output("println(floor(3.9))"))
assertEquals("4\n", output("println(ceil(3.1))"))
assertEquals("3\n", output("println(round(2.5))"))
assertEquals("2\n", output("println(min(2, 7))"))
assertEquals("7\n", output("println(max(2, 7))"))
}
@Test
fun piConstantIsAvailable() {
assertEquals("true\n", output("println(PI > 3.14 and PI < 3.15)"))
}
@Test
fun stringOperations() {
assertEquals("HELLO\n", output("println(\"hello\".upper())"))
assertEquals("hi\n", output("println(\"HI\".lower())"))
assertEquals("trimmed\n", output("println(\" trimmed \".trim())"))
assertEquals("[\"a\", \"b\", \"c\"]\n", output("println(\"a,b,c\".split(\",\"))"))
assertEquals("hexxo\n", output("println(\"hello\".replace(\"l\", \"x\"))"))
assertEquals("true\n", output("println(\"hello\".contains(\"ell\"))"))
assertEquals("1\n", output("println(\"hello\".indexOf(\"ell\"))"))
assertEquals("ell\n", output("println(\"hello\".substring(1, 4))"))
assertEquals("[\"h\", \"i\"]\n", output("println(\"hi\".chars())"))
assertEquals("true\n", output("println(\"lumen\".startsWith(\"lum\"))"))
assertEquals("true\n", output("println(\"lumen\".endsWith(\"men\"))"))
}
@Test
fun listOperations() {
assertEquals("[1, 2, 3]\n", output("println([3, 1, 2].sort())"))
assertEquals("[3, 2, 1]\n", output("println([1, 2, 3].reverse())"))
assertEquals("[2, 3]\n", output("println([1, 2, 3, 4].slice(1, 3))"))
assertEquals("6\n", output("println([1, 2, 3].sum())"))
assertEquals("1\n", output("println([3, 1, 2].min())"))
assertEquals("3\n", output("println([3, 1, 2].max())"))
assertEquals("2\n", output("println([1, 2, 3].indexOf(3))"))
assertEquals("true\n", output("println([1, 2, 3].contains(2))"))
assertEquals("a-b-c\n", output("println([\"a\", \"b\", \"c\"].join(\"-\"))"))
}
@Test
fun mapOperations() {
assertEquals("true\n", output("println({\"a\": 1}.has(\"a\"))"))
assertEquals("false\n", output("let m = {\"a\": 1}\nm.remove(\"a\")\nprintln(m.has(\"a\"))"))
assertEquals("[\"a\", \"b\"]\n", output("println({\"a\": 1, \"b\": 2}.keys())"))
assertEquals("[1, 2]\n", output("println({\"a\": 1, \"b\": 2}.values())"))
assertEquals("[[\"a\", 1]]\n", output("println({\"a\": 1}.entries())"))
}
@Test
fun sortHandlesStrings() {
assertEquals("[\"apple\", \"cherry\", \"pear\"]\n", output("println([\"pear\", \"apple\", \"cherry\"].sort())"))
}
@Test
fun assertPassesSilentlyAndFailsLoudly() {
assertEquals("ok\n", output("assert(1 == 1)\nprintln(\"ok\")"))
val error = assertFailsWith<RuntimeError> { output("assert(1 == 2, \"nope\")") }
assertTrue(error.message!!.contains("nope"), "expected message to carry the assertion text")
}
}