lyng/lynglib/src/commonTest/kotlin/MapLiteralTest.kt

169 lines
4.4 KiB
Kotlin

/*
* 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.
*
*/
/*
* Map literal and merging tests
*/
import kotlinx.coroutines.test.runTest
import net.sergeych.lyng.ExecutionError
import net.sergeych.lyng.ScriptError
import net.sergeych.lyng.eval
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
class MapLiteralTest {
@Test
fun basicStringAndIdKeysAndShorthand() = runTest {
eval(
"""
val x = 2
val y = 2
val m = { "a": 1, x: x*10, y: }
assertEquals(1, m["a"])
assertEquals(20, m["x"])
assertEquals(2, m["y"])
""".trimIndent()
)
}
@Test
fun testSimpleLiteral() = runTest {
assertEquals("""{"a":1,"b":2}""", eval("{ a: 1, b: 2 }").toJson().toString())
assertEquals("""{"a":1,"b":2}""", eval("""
{
a: 1,
b: 2
}
""".trimIndent()).toJson().toString())
assertEquals("""{"a":1,"b":2}""", eval("""
object Contracts {
val POR = object {
fun f1() = 1
fun f2() = 2
}
}
{
a: Contracts.POR.f1(),
b: Contracts.POR.f2()
}
""".trimIndent()).toJson().toString())
}
@Test
fun spreadsAndOverwriteOrder() = runTest {
eval(
"""
val base = { a: 1, b: 2 }
val m = { a: 0, ...base, b: 3, c: 4 }
assertEquals(1, m["a"]) // base overwrites a:0
assertEquals(3, m["b"]) // literal overwrites spread
assertEquals(4, m["c"]) // new key
""".trimIndent()
)
}
@Test
fun trailingCommaAccepted() = runTest {
eval(
"""
val m = { "a": 1, b: 2, }
assertEquals(1, m["a"])
assertEquals(2, m["b"])
""".trimIndent()
)
}
@Test
fun duplicateLiteralKeysAreCompileTimeError() = runTest {
assertFailsWith<ScriptError> {
eval("""{ foo: 1, " + '"' + "foo" + '"' + ": 2 }""".trimIndent())
}
assertFailsWith<ScriptError> {
eval("""{ foo:, foo: 2 }""".trimIndent())
}
}
@Test
fun lambdaDisambiguationWithTypedArgs() = runTest {
eval(
"""
val f = { x: Int, y: Int -> x + y }
assertEquals(3, f(1,2))
""".trimIndent()
)
}
@Test
fun plusMergingAndPlusAssign() = runTest {
eval(
"""
val m1 = ("1" => 10) + ("2" => 20)
assertEquals(10, m1["1"])
assertEquals(20, m1["2"])
val m2 = { "1": 10 } + ("2" => 20)
assertEquals(10, m2["1"])
assertEquals(20, m2["2"])
val m3 = { "1": 10 } + { "2": 20 }
assertEquals(10, m3["1"])
assertEquals(20, m3["2"])
var m = { "a": 1 }
m += ("b" => 2)
assertEquals(1, m["a"])
assertEquals(2, m["b"])
""".trimIndent()
)
}
@Test
fun spreadNonMapIsRuntimeError() = runTest {
assertFailsWith<ExecutionError> {
eval("""{ ...[1,2,3] }""")
}
}
@Test
fun spreadNonStringKeysIsAllowed() = runTest {
eval("""
val m = { ...Map(1 => "x") }
assertEquals("x", m[1])
""")
}
@Test
fun mergeNonStringKeyIsAllowed() = runTest {
eval("""
val e = (1 => "x")
val m = { "a": 1 } + e
assertEquals(1, m["a"])
assertEquals("x", m[1])
""")
}
@Test
fun shorthandUndefinedIdIsError() = runTest {
assertFailsWith<ExecutionError> {
eval("""{ z: }""")
}
}
}