1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
/*
* Copyright 2017-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/
package kotlinx.serialization.features
import kotlinx.serialization.*
import kotlinx.serialization.builtins.*
import kotlinx.serialization.json.*
import kotlinx.serialization.modules.*
import kotlin.test.*
class JsonClassDiscriminatorTest : JsonTestBase() {
@Serializable
@JsonClassDiscriminator("sealedType")
sealed class SealedMessage {
@Serializable
@SerialName("SealedMessage.StringMessage")
data class StringMessage(val description: String, val message: String) : SealedMessage()
@SerialName("EOF")
@Serializable
object EOF : SealedMessage()
}
@Serializable
@JsonClassDiscriminator("abstractType")
abstract class AbstractMessage {
@Serializable
@SerialName("Message.StringMessage")
data class StringMessage(val description: String, val message: String) : AbstractMessage()
@Serializable
@SerialName("Message.IntMessage")
data class IntMessage(val description: String, val message: Int) : AbstractMessage()
}
@Test
fun testSealedClassesHaveCustomDiscriminator() {
val messages = listOf(
SealedMessage.StringMessage("string message", "foo"),
SealedMessage.EOF
)
val expected =
"""[{"sealedType":"SealedMessage.StringMessage","description":"string message","message":"foo"},{"sealedType":"EOF"}]"""
assertJsonFormAndRestored(
ListSerializer(SealedMessage.serializer()),
messages,
expected,
)
}
@Test
fun testAbstractClassesHaveCustomDiscriminator() {
val messages = listOf(
AbstractMessage.StringMessage("string message", "foo"),
AbstractMessage.IntMessage("int message", 42),
)
val module = SerializersModule {
polymorphic(AbstractMessage::class) {
subclass(AbstractMessage.StringMessage.serializer())
subclass(AbstractMessage.IntMessage.serializer())
}
}
val json = Json { serializersModule = module }
val expected =
"""[{"abstractType":"Message.StringMessage","description":"string message","message":"foo"},{"abstractType":"Message.IntMessage","description":"int message","message":42}]"""
assertJsonFormAndRestored(
ListSerializer(
AbstractMessage.serializer()
), messages, expected, json
)
}
@Serializable
@JsonClassDiscriminator("message_type")
abstract class Base
@Serializable
abstract class ErrorClass : Base()
@Serializable
data class Message(val message: Base, val error: ErrorClass?)
@Serializable
@SerialName("my.app.BaseMessage")
data class BaseMessage(val message: String) : Base()
@Serializable
@SerialName("my.app.GenericError")
data class GenericError(@SerialName("error_code") val errorCode: Int) : ErrorClass()
@Test
fun testDocumentationInheritanceSample() {
val module = SerializersModule {
polymorphic(Base::class) {
subclass(BaseMessage.serializer())
}
polymorphic(ErrorClass::class) {
subclass(GenericError.serializer())
}
}
val json = Json { serializersModule = module }
assertJsonFormAndRestored(
Message.serializer(),
Message(BaseMessage("not found"), GenericError(404)),
"""{"message":{"message_type":"my.app.BaseMessage","message":"not found"},"error":{"message_type":"my.app.GenericError","error_code":404}}""",
json
)
}
}
|