summaryrefslogtreecommitdiff
path: root/formats/json-tests/commonTest/src/kotlinx/serialization
diff options
context:
space:
mode:
authorLeonid Startsev <sandwwraith@users.noreply.github.com>2023-04-20 12:18:38 +0200
committerGitHub <noreply@github.com>2023-04-20 12:18:38 +0200
commitfc9aef532349fa910394c03b1cc741a4ef575712 (patch)
tree00833814f5dfe0afadbb873f324b7959e5994232 /formats/json-tests/commonTest/src/kotlinx/serialization
parent508443504bd0609d117aef5467869427d5e26b35 (diff)
downloadkotlinx.serialization-fc9aef532349fa910394c03b1cc741a4ef575712.tar.gz
Fix value class encoding in various corner cases (#2242)
- Value class is located at top-level, but wraps non-primitive and thus does not fall in 'primitive on top-level' branch - Value class is a subclass in a polymorphic hierarchy, but either is primitive or explicitly recorded without type info Note that type info is omitted in the latter case and 'can't add type info to primitive' error is not thrown deliberately, as there seems to be use-cases for that. Fixes #1774 Fixes #2159
Diffstat (limited to 'formats/json-tests/commonTest/src/kotlinx/serialization')
-rw-r--r--formats/json-tests/commonTest/src/kotlinx/serialization/features/inline/InlineClassesTest.kt37
-rw-r--r--formats/json-tests/commonTest/src/kotlinx/serialization/features/inline/ValueClassesInSealedHierarchyTest.kt74
2 files changed, 109 insertions, 2 deletions
diff --git a/formats/json-tests/commonTest/src/kotlinx/serialization/features/inline/InlineClassesTest.kt b/formats/json-tests/commonTest/src/kotlinx/serialization/features/inline/InlineClassesTest.kt
index fdbb74af..0d30fc11 100644
--- a/formats/json-tests/commonTest/src/kotlinx/serialization/features/inline/InlineClassesTest.kt
+++ b/formats/json-tests/commonTest/src/kotlinx/serialization/features/inline/InlineClassesTest.kt
@@ -22,7 +22,7 @@ data class SimpleContainerForUInt(val i: UInt)
@JvmInline
value class MyUInt(val m: Int)
-object MyUIntSerializer: KSerializer<MyUInt> {
+object MyUIntSerializer : KSerializer<MyUInt> {
override val descriptor = UInt.serializer().descriptor
override fun serialize(encoder: Encoder, value: MyUInt) {
encoder.encodeInline(descriptor).encodeInt(value.m)
@@ -73,13 +73,46 @@ value class ResourceKind(val kind: SampleEnum)
@Serializable
data class ResourceIdentifier(val id: ResourceId, val type: ResourceType, val type2: ValueWrapper)
-@Serializable @JvmInline
+@Serializable
+@JvmInline
value class ValueWrapper(val wrapped: ResourceType)
+@Serializable
+@JvmInline
+value class Outer(val inner: Inner)
+
+@Serializable
+data class Inner(val n: Int)
+
+@Serializable
+data class OuterOuter(val outer: Outer)
+
+@Serializable
+@JvmInline
+value class WithList(val value: List<Int>)
+
class InlineClassesTest : JsonTestBase() {
private val precedent: UInt = Int.MAX_VALUE.toUInt() + 10.toUInt()
@Test
+ fun withList() = noLegacyJs {
+ val withList = WithList(listOf(1, 2, 3))
+ assertJsonFormAndRestored(WithList.serializer(), withList, """[1,2,3]""")
+ }
+
+ @Test
+ fun testOuterInner() = noLegacyJs {
+ val o = Outer(Inner(10))
+ assertJsonFormAndRestored(Outer.serializer(), o, """{"n":10}""")
+ }
+
+ @Test
+ fun testOuterOuterInner() = noLegacyJs {
+ val o = OuterOuter(Outer(Inner(10)))
+ assertJsonFormAndRestored(OuterOuter.serializer(), o, """{"outer":{"n":10}}""")
+ }
+
+ @Test
fun testTopLevel() = noLegacyJs {
assertJsonFormAndRestored(
ResourceType.serializer(),
diff --git a/formats/json-tests/commonTest/src/kotlinx/serialization/features/inline/ValueClassesInSealedHierarchyTest.kt b/formats/json-tests/commonTest/src/kotlinx/serialization/features/inline/ValueClassesInSealedHierarchyTest.kt
new file mode 100644
index 00000000..f3b482f1
--- /dev/null
+++ b/formats/json-tests/commonTest/src/kotlinx/serialization/features/inline/ValueClassesInSealedHierarchyTest.kt
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2017-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
+ */
+
+package kotlinx.serialization.features.inline
+
+import kotlinx.serialization.*
+import kotlinx.serialization.json.*
+import kotlinx.serialization.test.*
+import kotlin.jvm.*
+import kotlin.test.*
+
+class ValueClassesInSealedHierarchyTest : JsonTestBase() {
+ @Test
+ fun testSingle() = noLegacyJs {
+ val single = "foo"
+ assertJsonFormAndRestored(
+ AnyValue.serializer(),
+ AnyValue.Single(single),
+ "\"$single\""
+ )
+ }
+
+ @Test
+ fun testComplex() = noLegacyJs {
+ val complexJson = """{"id":"1","name":"object"}"""
+ assertJsonFormAndRestored(
+ AnyValue.serializer(),
+ AnyValue.Complex(mapOf("id" to "1", "name" to "object")),
+ complexJson
+ )
+ }
+
+ @Test
+ fun testMulti() = noLegacyJs {
+ val multiJson = """["list","of","strings"]"""
+ assertJsonFormAndRestored(AnyValue.serializer(), AnyValue.Multi(listOf("list", "of", "strings")), multiJson)
+ }
+}
+
+
+// From https://github.com/Kotlin/kotlinx.serialization/issues/2159
+@Serializable(with = AnyValue.Companion.Serializer::class)
+sealed interface AnyValue {
+
+ @JvmInline
+ @Serializable
+ value class Single(val value: String) : AnyValue
+
+ @JvmInline
+ @Serializable
+ value class Multi(val values: List<String>) : AnyValue
+
+ @JvmInline
+ @Serializable
+ value class Complex(val values: Map<String, String>) : AnyValue
+
+ @JvmInline
+ @Serializable
+ value class Unknown(val value: JsonElement) : AnyValue
+
+ companion object {
+ object Serializer : JsonContentPolymorphicSerializer<AnyValue>(AnyValue::class) {
+
+ override fun selectDeserializer(element: JsonElement): DeserializationStrategy<AnyValue> =
+ when {
+ element is JsonArray && element.all { it is JsonPrimitive && it.isString } -> Multi.serializer()
+ element is JsonObject && element.values.all { it is JsonPrimitive && it.isString } -> Complex.serializer()
+ element is JsonPrimitive && element.isString -> Single.serializer()
+ else -> Unknown.serializer()
+ }
+ }
+ }
+}