mirror of
https://github.com/apple/pkl.git
synced 2026-04-22 16:28:34 +02:00
Initial commit
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.pkl.config.kotlin;
|
||||
|
||||
import java.util.List;
|
||||
import org.pkl.config.java.mapper.Named;
|
||||
|
||||
public class JavaPerson {
|
||||
private final String name;
|
||||
private final int age;
|
||||
private final List<String> hobbies;
|
||||
|
||||
public JavaPerson(@Named("name") String name) {
|
||||
this.name = name;
|
||||
age = 0;
|
||||
hobbies = List.of();
|
||||
}
|
||||
|
||||
public JavaPerson(
|
||||
@Named("name") String name, @Named("age") int age, @Named("hobbies") List<String> hobbies) {
|
||||
this.name = name;
|
||||
this.age = age;
|
||||
this.hobbies = hobbies;
|
||||
}
|
||||
|
||||
public JavaPerson(@Named("age") int age) {
|
||||
this.age = age;
|
||||
name = "Default";
|
||||
hobbies = List.of();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public List<String> getHobbies() {
|
||||
return hobbies;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,257 @@
|
||||
/**
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.pkl.config.kotlin
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import org.pkl.config.java.ConfigEvaluator
|
||||
import org.pkl.config.java.ConfigEvaluatorBuilder
|
||||
import org.pkl.config.java.mapper.ConversionException
|
||||
import org.pkl.config.kotlin.ConfigExtensionsTest.Hobby.READING
|
||||
import org.pkl.config.kotlin.ConfigExtensionsTest.Hobby.SWIMMING
|
||||
import org.pkl.core.ModuleSource.text
|
||||
|
||||
class ConfigExtensionsTest {
|
||||
private val evaluator = ConfigEvaluator.preconfigured().forKotlin()
|
||||
|
||||
@Test
|
||||
fun `convert to kotlin classes`() {
|
||||
val config =
|
||||
evaluator.evaluate(
|
||||
text(
|
||||
"""
|
||||
pigeon {
|
||||
name = "pigeon"
|
||||
age = 30
|
||||
hobbies = List("swimming", "reading")
|
||||
address {
|
||||
street = "Fuzzy St."
|
||||
}
|
||||
}
|
||||
"""
|
||||
)
|
||||
)
|
||||
|
||||
val address = config["pigeon"]["address"].to<Address<String>>()
|
||||
assertThat(address.street).isEqualTo("Fuzzy St.")
|
||||
|
||||
val pigeon = config["pigeon"].to<Person<String>>()
|
||||
assertThat(pigeon).isNotNull
|
||||
assertThat(pigeon.name).isEqualTo("pigeon")
|
||||
assertThat(pigeon.age).isEqualTo(30)
|
||||
assertThat(pigeon.hobbies).isEqualTo(setOf(READING, SWIMMING))
|
||||
assertThat(pigeon.address.street).isEqualTo("Fuzzy St.")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `convert to kotlin class with nullable property`() {
|
||||
// cover ConfigEvaluatorBuilder.preconfigured()
|
||||
val evaluator = ConfigEvaluatorBuilder.preconfigured().forKotlin().build()
|
||||
|
||||
val config = evaluator.evaluate(text("pigeon { address = null }"))
|
||||
|
||||
val pigeon = config["pigeon"].to<Person2>()
|
||||
assertThat(pigeon.address).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `convert to kotlin class with covariant collection property type`() {
|
||||
val config =
|
||||
evaluator.evaluate(
|
||||
text(
|
||||
"""pigeon { addresses = List(new Dynamic { street = "Fuzzy St." }, new Dynamic { street = "Other St." }) }"""
|
||||
)
|
||||
)
|
||||
|
||||
config["pigeon"].to<Person3>()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `convert to nullable type`() {
|
||||
val config =
|
||||
evaluator.evaluate(text("""pigeon { address1 { street = "Fuzzy St." }; address2 = null }"""))
|
||||
|
||||
val address1 = config["pigeon"]["address1"].to<Address<String>?>()
|
||||
assertThat(address1).isEqualTo(Address(street = "Fuzzy St."))
|
||||
|
||||
val address2 = config["pigeon"]["address2"].to<Address<String>?>()
|
||||
assertThat(address2).isNull()
|
||||
|
||||
val e = assertThrows<ConversionException> { config["pigeon"]["address2"].to<Address<String>>() }
|
||||
assertThat(e)
|
||||
.hasMessage(
|
||||
"Expected a non-null value but got `null`. " +
|
||||
"To allow null values, convert to a nullable Kotlin type, for example `String?`."
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `convert to kotlin class that has defaults for constructor args`() {
|
||||
val config =
|
||||
evaluator.evaluate(
|
||||
text(
|
||||
"""
|
||||
pigeon {
|
||||
name = "Pigeon"
|
||||
age = 42
|
||||
hobbies = List()
|
||||
}
|
||||
"""
|
||||
)
|
||||
)
|
||||
|
||||
val pigeon = config["pigeon"].to<PersonWithDefaults>()
|
||||
assertThat(pigeon.name).isEqualTo("Pigeon")
|
||||
assertThat(pigeon.age).isEqualTo(42)
|
||||
assertThat(pigeon.hobbies).isEqualTo(listOf<String>())
|
||||
}
|
||||
|
||||
// check that java converter factory still kicks in
|
||||
@Test
|
||||
fun `convert to java class with multiple constructors`() {
|
||||
val config =
|
||||
evaluator.evaluate(
|
||||
text(
|
||||
"""
|
||||
pigeon {
|
||||
name = "Pigeon"
|
||||
age = 42
|
||||
hobbies = List()
|
||||
}
|
||||
"""
|
||||
)
|
||||
)
|
||||
|
||||
val pigeon = config["pigeon"].to<JavaPerson>()
|
||||
assertThat(pigeon.name).isEqualTo("Pigeon")
|
||||
assertThat(pigeon.age).isEqualTo(42)
|
||||
assertThat(pigeon.hobbies).isEqualTo(listOf<String>())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `convert list to parameterized list`() {
|
||||
val config =
|
||||
evaluator.evaluate(
|
||||
text(
|
||||
"""friends = List(new Dynamic { name = "lilly"}, new Dynamic {name = "bob"}, new Dynamic {name = "susan"})"""
|
||||
)
|
||||
)
|
||||
|
||||
val friends = config["friends"].to<List<SimplePerson>>()
|
||||
assertThat(friends)
|
||||
.isEqualTo(listOf(SimplePerson("lilly"), SimplePerson("bob"), SimplePerson("susan")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `convert map to parameterized map`() {
|
||||
val config =
|
||||
evaluator.evaluate(
|
||||
text(
|
||||
"""friends = Map("l", new Dynamic { name = "lilly"}, "b", new Dynamic { name = "bob"}, "s", new Dynamic { name = "susan"})"""
|
||||
)
|
||||
)
|
||||
|
||||
val friends = config["friends"].to<Map<String, SimplePerson>>()
|
||||
assertThat(friends)
|
||||
.isEqualTo(
|
||||
mapOf(
|
||||
"l" to SimplePerson("lilly"),
|
||||
"b" to SimplePerson("bob"),
|
||||
"s" to SimplePerson("susan")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `convert container to parameterized map`() {
|
||||
val config =
|
||||
evaluator.evaluate(
|
||||
text("""friends {l { name = "lilly"}; b { name = "bob"}; s { name = "susan"}}""")
|
||||
)
|
||||
|
||||
val friends = config["friends"].to<Map<String, SimplePerson>>()
|
||||
assertThat(friends)
|
||||
.isEqualTo(
|
||||
mapOf(
|
||||
"l" to SimplePerson("lilly"),
|
||||
"b" to SimplePerson("bob"),
|
||||
"s" to SimplePerson("susan")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `convert enum with mangled names`() {
|
||||
val values = MangledNameEnum.values().map { "\"$it\"" }
|
||||
val config =
|
||||
evaluator.evaluate(
|
||||
text(
|
||||
"""
|
||||
typealias MangledNameEnum = ${values.joinToString(" | ")}
|
||||
allEnumValues: Set<MangledNameEnum> = Set(${values.joinToString(", ")})
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
)
|
||||
val allEnumValues = config["allEnumValues"].to<Set<MangledNameEnum>>()
|
||||
assertThat(allEnumValues).isEqualTo(MangledNameEnum.values().toSet())
|
||||
}
|
||||
|
||||
data class SimplePerson(val name: String)
|
||||
|
||||
class Person<T>(val name: String, val age: Int, val hobbies: Set<Hobby>, val address: Address<T>)
|
||||
|
||||
enum class Hobby {
|
||||
SWIMMING,
|
||||
@Suppress("unused") SURFING,
|
||||
READING
|
||||
}
|
||||
|
||||
data class Address<out T>(val street: T)
|
||||
|
||||
class Person2(val address: Address<String>?)
|
||||
|
||||
class Person3(@Suppress("unused") val addresses: List<OpenAddress>)
|
||||
|
||||
open class OpenAddress(val street: String) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
return other is OpenAddress && street == other.street
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return street.hashCode()
|
||||
}
|
||||
}
|
||||
|
||||
class PersonWithDefaults(
|
||||
val name: String = "Pigeon",
|
||||
val age: Int = 42,
|
||||
val hobbies: List<String>
|
||||
)
|
||||
|
||||
@Suppress("NonAsciiCharacters", "EnumEntryName")
|
||||
enum class MangledNameEnum(val value: String) {
|
||||
FROM_CAMEL_CASE("fromCamelCase"),
|
||||
HYPHENATED_NAME("hyphenated-name"),
|
||||
EN_QUAD_EM_SPACE_IDEOGRAPHIC_SPACE_("EnQuad\\u2000EmSpace\\u2003IdeographicSpace\\u3000"),
|
||||
ᾊ_ᾨ("ᾊ\u0ABFᾨ"),
|
||||
_42_FROM_INVALID_START("42-from-invalid-start"),
|
||||
__EMOJI__("❎Emoji✅✅"),
|
||||
ÀŒÜ("àœü"),
|
||||
日本_つくば("日本-つくば")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/**
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.pkl.config.kotlin
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertDoesNotThrow
|
||||
import org.pkl.config.java.ConfigEvaluator
|
||||
import org.pkl.core.ModuleSource.text
|
||||
|
||||
class KotlinObjectMappingTest {
|
||||
data class TypedKey(val value: Int)
|
||||
|
||||
data class KotlinGenericTypesTest(
|
||||
// Sets
|
||||
val stringSet: Set<String>,
|
||||
val intSet: Set<Int>,
|
||||
val booleanSetSet: Set<Set<Boolean>>,
|
||||
|
||||
// Lists
|
||||
val stringList: List<String>,
|
||||
val intList: List<Int>,
|
||||
val booleanListList: List<List<Boolean>>,
|
||||
|
||||
// Maps
|
||||
val intStringMap: Map<Int, String>,
|
||||
val booleanIntStringMapMap: Map<Boolean, Map<Int, String>>,
|
||||
val booleanIntMapStringMap: Map<Map<Boolean, Int>, String>,
|
||||
val intSetListStringMap: Map<List<Set<Int>>, String>,
|
||||
val typedStringMap: Map<TypedKey, String>,
|
||||
val dynamicStringMap: Map<Map<String, Any>, String>,
|
||||
|
||||
// Listings
|
||||
val stringSetListing: List<Set<String>>,
|
||||
val intListingListing: List<List<Int>>,
|
||||
|
||||
// Mapping
|
||||
val intStringMapping: Map<Int, String>,
|
||||
val stringStringSetMapping: Map<String, Set<String>>,
|
||||
|
||||
// Map & Mapping with structured keys
|
||||
val intListingStringMapping: Map<List<Int>, String>,
|
||||
val intSetListStringMapping: Map<List<Set<Int>>, String>,
|
||||
val thisOneGoesToEleven: Map<List<Set<Int>>, Map<List<Int>, Map<Int, String>>>
|
||||
)
|
||||
|
||||
@Test
|
||||
fun `generic types correspond`() {
|
||||
val code =
|
||||
"""
|
||||
module KotlinGenericTypesTest
|
||||
|
||||
class Foo {
|
||||
value: Int
|
||||
}
|
||||
|
||||
// Sets
|
||||
stringSet: Set<String> = Set("in set")
|
||||
intSet: Set<Int> = Set(1,2,4,8,16,32)
|
||||
booleanSetSet: Set<Set<Boolean>> = Set(Set(false), Set(true), Set(true, false))
|
||||
|
||||
// Lists
|
||||
stringList: List<String> = List("in list")
|
||||
intList: List<Int> = List(1,2,3,5,7,11)
|
||||
booleanListList: List<List<Boolean>> = List(List(false), List(true), List(true, false))
|
||||
|
||||
// Maps
|
||||
intStringMap: Map<Int, String> = Map(0, "in map")
|
||||
booleanIntStringMapMap: Map<Boolean, Map<Int, String>> = Map(false, Map(0, "in map in map"))
|
||||
booleanIntMapStringMap: Map<Map<Boolean, Int>, String> = Map(Map(true, 42), "in map with map keys")
|
||||
|
||||
// Listings
|
||||
stringSetListing: Listing<Set<String>> = new { Set("in set in listing") }
|
||||
intListingListing: Listing<Listing<Int>> = new { new { 1337 } new { 100 } }
|
||||
|
||||
// Mappings
|
||||
intStringMapping: Mapping<Int, String> = new { [42] = "in map" }
|
||||
stringStringSetMapping: Mapping<String, Set<String>> = new { ["key"] = Set("in set in map") }
|
||||
|
||||
// Map & Mappings with structured keys
|
||||
intSetListStringMap: Map<List<Set<Int>>, String> = Map(List(Set(27)), "in map with structured key")
|
||||
typedStringMap: Map<Foo, String> = Map(
|
||||
new Foo { value = 1 }, "using typed objects",
|
||||
new Foo { value = 2 }, "also works")
|
||||
dynamicStringMap: Map<Dynamic, String> = Map(
|
||||
new Dynamic { value = 42 }, "using Dynamics",
|
||||
new Dynamic { hello = "world" }, "also works")
|
||||
|
||||
intListingStringMapping: Mapping<Listing<Int>, String> = new {
|
||||
[new Listing { 42 1337 }] = "structured key works"
|
||||
}
|
||||
intSetListStringMapping: Mapping<List<Set<Int>>, String> = new {
|
||||
[List(Set(27))] = "in mapping with structured key"
|
||||
}
|
||||
local intListing: Listing<Int> = new { 0 0 7 }
|
||||
thisOneGoesToEleven: Mapping<List<Set<Int>>, Map<Listing<Int>, Mapping<Int, String>>> = new {
|
||||
[List(Set(0), Set(0), Set(7))] = Map(intListing, intStringMapping)
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
val result = ConfigEvaluator.preconfigured().forKotlin().evaluate(text(code))
|
||||
assertDoesNotThrow { result.to<KotlinGenericTypesTest>() }
|
||||
.apply {
|
||||
assertThat(typedStringMap.keys).isEqualTo(setOf(TypedKey(1), TypedKey(2)))
|
||||
assertThat(dynamicStringMap.keys)
|
||||
.isEqualTo(setOf(hashMapOf("hello" to "world"), hashMapOf("value" to 42.toLong())))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.pkl.config.kotlin.mapper
|
||||
|
||||
import java.util.regex.Pattern
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import org.pkl.config.java.mapper.ConversionException
|
||||
import org.pkl.config.java.mapper.ValueMapperBuilder
|
||||
|
||||
class KotlinConversionsTest {
|
||||
private val mapper = ValueMapperBuilder.unconfigured().build()
|
||||
|
||||
@Test
|
||||
fun pStringToKotlinRegex() {
|
||||
val result = KotlinConversions.pStringToKotlinRegex.converter.convert("(?i)\\w*", mapper)
|
||||
assertThat(result.pattern).isEqualTo("(?i)\\w*")
|
||||
assertThat(result.options).isEqualTo(setOf(RegexOption.IGNORE_CASE))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun pRegexToKotlinRegex() {
|
||||
val result =
|
||||
KotlinConversions.pRegexToKotlinRegex.converter.convert(Pattern.compile("(?i)\\w*"), mapper)
|
||||
assertThat(result.pattern).isEqualTo("(?i)\\w*")
|
||||
assertThat(result.options).isEqualTo(setOf(RegexOption.IGNORE_CASE))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun pIntToULong() {
|
||||
assertThat(KotlinConversions.pIntToULong.converter.convert(0, mapper)).isEqualTo(0UL)
|
||||
|
||||
assertThat(KotlinConversions.pIntToULong.converter.convert(Long.MAX_VALUE, mapper))
|
||||
.isEqualTo(Long.MAX_VALUE.toULong())
|
||||
|
||||
assertThrows<ConversionException> {
|
||||
KotlinConversions.pIntToULong.converter.convert(-1, mapper)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun pIntToUInt() {
|
||||
assertThat(KotlinConversions.pIntToUInt.converter.convert(0, mapper)).isEqualTo(0u)
|
||||
|
||||
assertThat(KotlinConversions.pIntToUInt.converter.convert(UInt.MAX_VALUE.toLong(), mapper))
|
||||
.isEqualTo(UInt.MAX_VALUE)
|
||||
|
||||
assertThrows<ConversionException> {
|
||||
KotlinConversions.pIntToUInt.converter.convert(UInt.MAX_VALUE.toLong() + 1, mapper)
|
||||
}
|
||||
|
||||
assertThrows<ConversionException> { KotlinConversions.pIntToUInt.converter.convert(-1, mapper) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun pIntToUShort() {
|
||||
assertThat(KotlinConversions.pIntToUShort.converter.convert(0, mapper)).isEqualTo(0.toUShort())
|
||||
|
||||
assertThat(KotlinConversions.pIntToUShort.converter.convert(UShort.MAX_VALUE.toLong(), mapper))
|
||||
.isEqualTo(UShort.MAX_VALUE)
|
||||
|
||||
assertThrows<ConversionException> {
|
||||
KotlinConversions.pIntToUShort.converter.convert(UShort.MAX_VALUE.toLong() + 1, mapper)
|
||||
}
|
||||
|
||||
assertThrows<ConversionException> {
|
||||
KotlinConversions.pIntToUShort.converter.convert(-1, mapper)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.pkl.config.kotlin.mapper
|
||||
|
||||
import com.example.OverriddenProperty
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.pkl.config.java.ConfigEvaluatorBuilder
|
||||
import org.pkl.config.kotlin.forKotlin
|
||||
import org.pkl.config.kotlin.to
|
||||
import org.pkl.core.ModuleSource
|
||||
|
||||
class OverriddenPropertyTest {
|
||||
@Test
|
||||
fun `overridden property`() {
|
||||
ConfigEvaluatorBuilder.preconfigured().forKotlin().build().use { evaluator ->
|
||||
val config = evaluator.evaluate(ModuleSource.modulePath("/codegenPkl/OverriddenProperty.pkl"))
|
||||
val module = config.to<OverriddenProperty>()
|
||||
assertThat(module.theClass.bar[0].prop1).isEqualTo("hello")
|
||||
assertThat(module.theClass.bar[0].prop2).isEqualTo("hello again")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.pkl.config.kotlin.mapper
|
||||
|
||||
import kotlin.Pair
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.assertj.core.api.Assertions.entry
|
||||
import org.junit.jupiter.api.AfterAll
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.pkl.config.java.mapper.Types
|
||||
import org.pkl.config.java.mapper.ValueMapperBuilder
|
||||
import org.pkl.config.kotlin.forKotlin
|
||||
import org.pkl.core.*
|
||||
import org.pkl.core.ModuleSource.modulePath
|
||||
|
||||
class PPairToKotlinPairTest {
|
||||
companion object {
|
||||
private val evaluator = Evaluator.preconfigured()
|
||||
|
||||
private val module =
|
||||
evaluator.evaluate(modulePath("org/pkl/config/kotlin/mapper/PPairToKotlinPairTest.pkl"))
|
||||
|
||||
private val mapper = ValueMapperBuilder.preconfigured().forKotlin().build()
|
||||
|
||||
@AfterAll
|
||||
@Suppress("unused")
|
||||
@JvmStatic
|
||||
fun afterAll() {
|
||||
evaluator.close()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun ex1() {
|
||||
val ex1 = module.getProperty("ex1")
|
||||
val mapped: Pair<Int, Duration> =
|
||||
mapper.map(
|
||||
ex1,
|
||||
Types.parameterizedType(Pair::class.java, Integer::class.java, Duration::class.java)
|
||||
)
|
||||
assertThat(mapped).isEqualTo(Pair(1, Duration(3.0, DurationUnit.SECONDS)))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun ex2() {
|
||||
val ex2 = module.getProperty("ex2")
|
||||
val mapped: Pair<PObject, PObject> =
|
||||
mapper.map(
|
||||
ex2,
|
||||
Types.parameterizedType(Pair::class.java, PObject::class.java, PObject::class.java)
|
||||
)
|
||||
|
||||
assertThat(mapped.first.properties).containsOnly(entry("name", "pigeon"), entry("age", 40L))
|
||||
|
||||
assertThat(mapped.second.properties).containsOnly(entry("name", "parrot"), entry("age", 30L))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.pkl.config.kotlin.mapper
|
||||
|
||||
import com.example.PolymorphicLib
|
||||
import com.example.PolymorphicModuleTest
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.pkl.config.java.ConfigEvaluatorBuilder
|
||||
import org.pkl.config.kotlin.forKotlin
|
||||
import org.pkl.config.kotlin.to
|
||||
import org.pkl.core.ModuleSource.modulePath
|
||||
|
||||
class PolymorphicTest {
|
||||
@Test
|
||||
fun `deserializing polymorphic objects`() {
|
||||
val evaluator = ConfigEvaluatorBuilder.preconfigured().forKotlin().build()
|
||||
val config = evaluator.evaluate(modulePath("/codegenPkl/PolymorphicModuleTest.pkl"))
|
||||
val module = config.to<PolymorphicModuleTest>()
|
||||
assertThat(module.desserts[0]).isInstanceOf(PolymorphicModuleTest.Strudel::class.java)
|
||||
assertThat(module.desserts[1]).isInstanceOf(PolymorphicModuleTest.TurkishDelight::class.java)
|
||||
assertThat(module.planes[0]).isInstanceOf(PolymorphicLib.Jet::class.java)
|
||||
assertThat(module.planes[1]).isInstanceOf(PolymorphicLib.Propeller::class.java)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
module com.example.OverriddenProperty
|
||||
|
||||
abstract class BaseClass {
|
||||
fixed bar: Listing<BaseBar> = new {
|
||||
new {
|
||||
prop1 = "hello"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
theClass: TheClass
|
||||
|
||||
class TheClass extends BaseClass {
|
||||
fixed bar: Listing<Bar> = new {
|
||||
new {
|
||||
prop1 = "hello"
|
||||
prop2 = "hello again"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open class BaseBar {
|
||||
prop1: String
|
||||
}
|
||||
|
||||
class Bar extends BaseBar {
|
||||
prop2: String
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
module com.example.PolymorphicLib
|
||||
|
||||
open class Airplane {
|
||||
name: String
|
||||
numSeats: Int
|
||||
}
|
||||
|
||||
class Jet extends Airplane {
|
||||
isSuperSonic: Boolean
|
||||
}
|
||||
|
||||
class Propeller extends Airplane {
|
||||
isTurboprop: Boolean
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/// Gets generated into a Kotlin via Gradle task `generateTestConfigClasses`.
|
||||
module com.example.PolymorphicModuleTest
|
||||
|
||||
import "PolymorphicLib.pkl"
|
||||
|
||||
abstract class Dessert
|
||||
|
||||
class Strudel extends Dessert {
|
||||
numberOfRolls: Int
|
||||
}
|
||||
|
||||
class TurkishDelight extends Dessert {
|
||||
isOfferedToEdmund: Boolean
|
||||
}
|
||||
|
||||
desserts: Listing<Dessert> = new {
|
||||
new Strudel { numberOfRolls = 3 }
|
||||
new TurkishDelight { isOfferedToEdmund = true }
|
||||
}
|
||||
|
||||
planes: Listing<PolymorphicLib.Airplane> = new {
|
||||
new PolymorphicLib.Jet { name = "Concorde"; numSeats = 128; isSuperSonic = true }
|
||||
new PolymorphicLib.Propeller { name = "Cessna 172"; numSeats = 4; isTurboprop = true }
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
class Person {
|
||||
name: String
|
||||
age: Int
|
||||
}
|
||||
|
||||
ex1 = Pair(1, 3.s)
|
||||
ex2 = Pair(new Person {name = "pigeon"; age = 40}, new Dynamic {name = "parrot"; age = 30})
|
||||
Reference in New Issue
Block a user