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
|
/*
* Copyright 2017-2019 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.internal.*
import kotlinx.serialization.json.*
import kotlinx.serialization.modules.*
import kotlin.test.*
class ContextAndPolymorphicTest {
@Serializable
data class Data(val a: Int, val b: Int = 42)
@Serializable
data class EnhancedData(
val data: Data,
@ContextualSerialization val stringPayload: Payload,
@Serializable(with = BinaryPayloadSerializer::class) val binaryPayload: Payload
)
@Serializable
data class Payload(val s: String)
@Serializable
data class PayloadList(val ps: List<@ContextualSerialization Payload>)
@Serializer(forClass = Payload::class)
object PayloadSerializer {}
object BinaryPayloadSerializer : KSerializer<Payload> {
override val descriptor: SerialDescriptor = SerialClassDescImpl("Payload")
override fun serialize(encoder: Encoder, obj: Payload) {
encoder.encodeString(HexConverter.printHexBinary(obj.s.toUtf8Bytes()))
}
override fun deserialize(decoder: Decoder): Payload {
return Payload(stringFromUtf8Bytes(HexConverter.parseHexBinary(decoder.decodeString())))
}
}
private val obj = EnhancedData(Data(100500), Payload("string"), Payload("binary"))
private lateinit var json: Json
@BeforeTest
fun initContext() {
val scope = serializersModuleOf(Payload::class, PayloadSerializer)
val bPolymorphicModule = SerializersModule { polymorphic(Any::class) { Payload::class with PayloadSerializer } }
json = Json(
JsonConfiguration(unquoted = true, useArrayPolymorphism = true),
context = scope + bPolymorphicModule
)
}
@Test
fun testWriteCustom() {
val s = json.stringify(EnhancedData.serializer(), obj)
assertEquals("{data:{a:100500,b:42},stringPayload:{s:string},binaryPayload:62696E617279}", s)
}
@Test
fun testReadCustom() {
val s = json.parse(EnhancedData.serializer(), "{data:{a:100500,b:42},stringPayload:{s:string},binaryPayload:62696E617279}")
assertEquals(obj, s)
}
@Test
fun testWriteCustomList() {
val s = json.stringify(PayloadList.serializer(), PayloadList(listOf(Payload("1"), Payload("2"))))
assertEquals("{ps:[{s:1},{s:2}]}", s)
}
@Test
fun testPolymorphicResolve() {
val map = mapOf<String, Any>("Payload" to Payload("data"))
val serializer = (StringSerializer to PolymorphicSerializer(Any::class)).map
val s = json.stringify(serializer, map)
assertEquals("""{Payload:[kotlinx.serialization.features.ContextAndPolymorphicTest.Payload,{s:data}]}""", s)
}
@Test
fun testDifferentRepresentations() {
val simpleModule = serializersModule(PayloadSerializer)
// MapModule and CompositeModule are also available
val binaryModule = serializersModule(BinaryPayloadSerializer)
val json1 = Json { useArrayPolymorphism = true; serialModule = simpleModule }
val json2 = Json { useArrayPolymorphism = true; serialModule = binaryModule }
// in json1, Payload would be serialized with PayloadSerializer,
// in json2, Payload would be serialized with BinaryPayloadSerializer
val list = PayloadList(listOf(Payload("string")))
assertEquals("""{"ps":[{"s":"string"}]}""", json1.stringify(PayloadList.serializer(), list))
assertEquals("""{"ps":["737472696E67"]}""", json2.stringify(PayloadList.serializer(), list))
}
}
|