commonTest.kotlinx.serialization.json.JsonCustomSerializersTest.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kotlinx-serialization-json
Show all versions of kotlinx-serialization-json
Kotlin multiplatform serialization runtime library
/*
* Copyright 2017-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/
@file:UseContextualSerialization(JsonCustomSerializersTest.B::class)
package kotlinx.serialization.json
import kotlinx.serialization.*
import kotlinx.serialization.builtins.*
import kotlinx.serialization.descriptors.*
import kotlinx.serialization.encoding.*
import kotlinx.serialization.modules.*
import kotlinx.serialization.test.*
import kotlin.test.*
class JsonCustomSerializersTest : JsonTestBase() {
@Serializable
data class A(@Id(1) val b: B)
data class B(@Id(1) val value: Int)
object BSerializer : KSerializer {
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("B", PrimitiveKind.INT)
override fun serialize(encoder: Encoder, value: B) {
encoder.encodeInt(value.value)
}
override fun deserialize(decoder: Decoder): B {
return B(decoder.decodeInt())
}
}
@Serializable
data class BList(@Id(1) val bs: List)
@Serializable
data class C(@Id(1) val a: Int = 31, @Id(2) val b: Int = 42) {
@Serializer(forClass = C::class)
companion object : KSerializer {
override fun serialize(encoder: Encoder, value: C) {
val elemOutput = encoder.beginStructure(descriptor)
elemOutput.encodeIntElement(descriptor, 1, value.b)
if (value.a != 31) elemOutput.encodeIntElement(descriptor, 0, value.a)
elemOutput.endStructure(descriptor)
}
}
}
@Serializable
data class CList1(@Id(1) val c: List)
@Serializable
data class CList2(@Id(1) val d: Int = 5, @Id(2) val c: List) {
@Serializer(forClass = CList2::class)
companion object : KSerializer {
override fun serialize(encoder: Encoder, value: CList2) {
val elemOutput = encoder.beginStructure(descriptor)
elemOutput.encodeSerializableElement(descriptor, 1, ListSerializer(C), value.c)
if (value.d != 5) elemOutput.encodeIntElement(descriptor, 0, value.d)
elemOutput.endStructure(descriptor)
}
}
}
@Serializable
data class CList3(@Id(1) val e: List = emptyList(), @Id(2) val f: Int) {
@Serializer(forClass = CList3::class)
companion object : KSerializer {
override fun serialize(encoder: Encoder, value: CList3) {
val elemOutput = encoder.beginStructure(descriptor)
if (value.e.isNotEmpty()) elemOutput.encodeSerializableElement(descriptor, 0, ListSerializer(C), value.e)
elemOutput.encodeIntElement(descriptor, 1, value.f)
elemOutput.endStructure(descriptor)
}
}
}
@Serializable
data class CList4(@Id(1) val g: List = emptyList(), @Id(2) val h: Int) {
@Serializer(forClass = CList4::class)
companion object : KSerializer {
override fun serialize(encoder: Encoder, value: CList4) {
val elemOutput = encoder.beginStructure(descriptor)
elemOutput.encodeIntElement(descriptor, 1, value.h)
if (value.g.isNotEmpty()) elemOutput.encodeSerializableElement(descriptor, 0, ListSerializer(C), value.g)
elemOutput.endStructure(descriptor)
}
}
}
@Serializable
data class CList5(@Id(1) val g: List = emptyList(), @Id(2) val h: Int) {
@Serializer(forClass = CList5::class)
companion object : KSerializer {
override fun serialize(encoder: Encoder, value: CList5) {
val elemOutput = encoder.beginStructure(descriptor)
elemOutput.encodeIntElement(descriptor, 1, value.h)
if (value.g.isNotEmpty()) elemOutput.encodeSerializableElement(
descriptor, 0, ListSerializer(Int.serializer()),
value.g
)
elemOutput.endStructure(descriptor)
}
}
}
private val moduleWithB = serializersModuleOf(B::class, BSerializer)
private fun createJsonWithB() = Json { isLenient = true; serializersModule = moduleWithB; useAlternativeNames = false }
// useAlternativeNames uses SerialDescriptor.hashCode,
// which is unavailable for partially-customized serializers such as in this file
private val jsonNoAltNames = Json { useAlternativeNames = false }
@Test
fun testWriteCustom() = parametrizedTest { jsonTestingMode ->
val a = A(B(2))
val j = createJsonWithB()
val s = j.encodeToString(a, jsonTestingMode)
assertEquals("""{"b":2}""", s)
}
@Test
fun testReadCustom() = parametrizedTest { jsonTestingMode ->
val a = A(B(2))
val j = createJsonWithB()
val s = j.decodeFromString("{b:2}", jsonTestingMode)
assertEquals(a, s)
}
@Test
fun testWriteCustomList() = parametrizedTest { jsonTestingMode ->
val obj = BList(listOf(B(1), B(2), B(3)))
val j = createJsonWithB()
val s = j.encodeToString(obj, jsonTestingMode)
assertEquals("""{"bs":[1,2,3]}""", s)
}
@Test
fun testReadCustomList() = parametrizedTest { jsonTestingMode ->
val obj = BList(listOf(B(1), B(2), B(3)))
val j = createJsonWithB()
val bs = j.decodeFromString("{bs:[1,2,3]}", jsonTestingMode)
assertEquals(obj, bs)
}
@Test
fun testWriteCustomListRootLevel() = parametrizedTest { jsonTestingMode ->
val obj = listOf(B(1), B(2), B(3))
val j = createJsonWithB()
val s = j.encodeToString(ListSerializer(BSerializer), obj, jsonTestingMode)
assertEquals("[1,2,3]", s)
}
@Test
fun testReadCustomListRootLevel() = parametrizedTest { jsonTestingMode ->
val obj = listOf(B(1), B(2), B(3))
val j = createJsonWithB()
val bs = j.decodeFromString(ListSerializer(BSerializer), "[1,2,3]", jsonTestingMode)
assertEquals(obj, bs)
}
@Test
fun testWriteCustomInvertedOrder() = parametrizedTest { jsonTestingMode ->
val obj = C(1, 2)
val s = jsonNoAltNames.encodeToString(obj, jsonTestingMode)
assertEquals("""{"b":2,"a":1}""", s)
}
@Test
fun testWriteCustomOmitDefault() = parametrizedTest { jsonTestingMode ->
val obj = C(b = 2)
val s = jsonNoAltNames.encodeToString(obj, jsonTestingMode)
assertEquals("""{"b":2}""", s)
}
@Test
fun testReadCustomInvertedOrder() = parametrizedTest { jsonTestingMode ->
val obj = C(1, 2)
val s = jsonNoAltNames.decodeFromString("""{"b":2,"a":1}""", jsonTestingMode)
assertEquals(obj, s)
}
@Test
fun testReadCustomOmitDefault() = parametrizedTest { jsonTestingMode ->
val obj = C(b = 2)
val s = jsonNoAltNames.decodeFromString("""{"b":2}""", jsonTestingMode)
assertEquals(obj, s)
}
@Test
fun testWriteListOfOptional() = parametrizedTest { jsonTestingMode ->
val obj = listOf(C(a = 1), C(b = 2), C(3, 4))
val s = jsonNoAltNames.encodeToString(ListSerializer(C), obj, jsonTestingMode)
assertEquals("""[{"b":42,"a":1},{"b":2},{"b":4,"a":3}]""", s)
}
@Test
fun testReadListOfOptional() = parametrizedTest { jsonTestingMode ->
val obj = listOf(C(a = 1), C(b = 2), C(3, 4))
val j = """[{"b":42,"a":1},{"b":2},{"b":4,"a":3}]"""
val s = jsonNoAltNames.decodeFromString(ListSerializer(C), j, jsonTestingMode)
assertEquals(obj, s)
}
@Test
fun testWriteOptionalList1() = parametrizedTest { jsonTestingMode ->
val obj = CList1(listOf(C(a = 1), C(b = 2), C(3, 4)))
val s = jsonNoAltNames.encodeToString(obj, jsonTestingMode)
assertEquals("""{"c":[{"b":42,"a":1},{"b":2},{"b":4,"a":3}]}""", s)
}
@Test
fun testWriteOptionalList1Quoted() = parametrizedTest { jsonTestingMode ->
val obj = CList1(listOf(C(a = 1), C(b = 2), C(3, 4)))
val s = jsonNoAltNames.encodeToString(obj, jsonTestingMode)
assertEquals("""{"c":[{"b":42,"a":1},{"b":2},{"b":4,"a":3}]}""", s)
}
@Test
fun testReadOptionalList1() = parametrizedTest { jsonTestingMode ->
val obj = CList1(listOf(C(a = 1), C(b = 2), C(3, 4)))
val j = """{"c":[{"b":42,"a":1},{"b":2},{"b":4,"a":3}]}"""
assertEquals(obj, jsonNoAltNames.decodeFromString(j, jsonTestingMode))
}
@Test
fun testWriteOptionalList2a() = parametrizedTest { jsonTestingMode ->
val obj = CList2(7, listOf(C(a = 5), C(b = 6), C(7, 8)))
val s = jsonNoAltNames.encodeToString(obj, jsonTestingMode)
assertEquals("""{"c":[{"b":42,"a":5},{"b":6},{"b":8,"a":7}],"d":7}""", s)
}
@Test
fun testReadOptionalList2a() = parametrizedTest { jsonTestingMode ->
val obj = CList2(7, listOf(C(a = 5), C(b = 6), C(7, 8)))
val j = """{"c":[{"b":42,"a":5},{"b":6},{"b":8,"a":7}],"d":7}"""
assertEquals(obj, jsonNoAltNames.decodeFromString(j, jsonTestingMode))
}
@Test
fun testWriteOptionalList2b() = parametrizedTest { jsonTestingMode ->
val obj = CList2(c = listOf(C(a = 5), C(b = 6), C(7, 8)))
val s = jsonNoAltNames.encodeToString(obj, jsonTestingMode)
assertEquals("""{"c":[{"b":42,"a":5},{"b":6},{"b":8,"a":7}]}""", s)
}
@Test
fun testReadOptionalList2b() = parametrizedTest { jsonTestingMode ->
val obj = CList2(c = listOf(C(a = 5), C(b = 6), C(7, 8)))
val j = """{"c":[{"b":42,"a":5},{"b":6},{"b":8,"a":7}]}"""
assertEquals(obj, jsonNoAltNames.decodeFromString(j, jsonTestingMode))
}
@Test
fun testWriteOptionalList3a() = parametrizedTest { jsonTestingMode ->
val obj = CList3(listOf(C(a = 1), C(b = 2), C(3, 4)), 99)
val s = jsonNoAltNames.encodeToString(obj, jsonTestingMode)
assertEquals("""{"e":[{"b":42,"a":1},{"b":2},{"b":4,"a":3}],"f":99}""", s)
}
@Test
fun testReadOptionalList3a() = parametrizedTest { jsonTestingMode ->
val obj = CList3(listOf(C(a = 1), C(b = 2), C(3, 4)), 99)
val j = """{"e":[{"b":42,"a":1},{"b":2},{"b":4,"a":3}],"f":99}"""
assertEquals(obj, jsonNoAltNames.decodeFromString(j, jsonTestingMode))
}
@Test
fun testWriteOptionalList3b() = parametrizedTest { jsonTestingMode ->
val obj = CList3(f = 99)
val s = jsonNoAltNames.encodeToString(obj, jsonTestingMode)
assertEquals("""{"f":99}""", s)
}
@Test
fun testReadOptionalList3b() = parametrizedTest { jsonTestingMode ->
val obj = CList3(f = 99)
val j = """{"f":99}"""
assertEquals(obj, jsonNoAltNames.decodeFromString(j, jsonTestingMode))
}
@Test
fun testWriteOptionalList4a() = parametrizedTest { jsonTestingMode ->
val obj = CList4(listOf(C(a = 1), C(b = 2), C(3, 4)), 54)
val s = jsonNoAltNames.encodeToString(obj, jsonTestingMode)
assertEquals("""{"h":54,"g":[{"b":42,"a":1},{"b":2},{"b":4,"a":3}]}""", s)
}
@Test
fun testReadOptionalList4a() = parametrizedTest { jsonTestingMode ->
val obj = CList4(listOf(C(a = 1), C(b = 2), C(3, 4)), 54)
val j = """{"h":54,"g":[{"b":42,"a":1},{"b":2},{"b":4,"a":3}]}"""
assertEquals(obj, jsonNoAltNames.decodeFromString(j, jsonTestingMode))
}
@Test
fun testWriteOptionalList4b() = parametrizedTest { jsonTestingMode ->
val obj = CList4(h = 97)
val j = """{"h":97}"""
val s = jsonNoAltNames.encodeToString(obj, jsonTestingMode)
assertEquals(j, s)
}
@Test
fun testReadOptionalList4b() = parametrizedTest { jsonTestingMode ->
val obj = CList4(h = 97)
val j = """{"h":97}"""
assertEquals(obj, jsonNoAltNames.decodeFromString(j, jsonTestingMode))
}
@Test
fun testWriteOptionalList5a() = parametrizedTest { jsonTestingMode ->
val obj = CList5(listOf(9, 8, 7, 6, 5), 5)
val s = jsonNoAltNames.encodeToString(obj, jsonTestingMode)
assertEquals("""{"h":5,"g":[9,8,7,6,5]}""", s)
}
@Test
fun testReadOptionalList5a() = parametrizedTest { jsonTestingMode ->
val obj = CList5(listOf(9, 8, 7, 6, 5), 5)
val j = """{"h":5,"g":[9,8,7,6,5]}"""
assertEquals(obj, jsonNoAltNames.decodeFromString(j, jsonTestingMode))
}
@Test
fun testWriteOptionalList5b() = parametrizedTest { jsonTestingMode ->
val obj = CList5(h = 999)
val s = jsonNoAltNames.encodeToString(obj, jsonTestingMode)
assertEquals("""{"h":999}""", s)
}
@Test
fun testReadOptionalList5b() = parametrizedTest { jsonTestingMode ->
val obj = CList5(h = 999)
val j = """{"h":999}"""
assertEquals(obj, jsonNoAltNames.decodeFromString(j, jsonTestingMode))
}
@Test
fun testMapBuiltinsTest() = parametrizedTest { jsonTestingMode ->
val map = mapOf(1 to "1", 2 to "2")
val serial = MapSerializer(Int.serializer(), String.serializer())
val s = jsonNoAltNames.encodeToString(serial, map, jsonTestingMode)
assertEquals("""{"1":"1","2":"2"}""", s)
}
@Test
fun testResolveAtRootLevel() = parametrizedTest { jsonTestingMode ->
val j = createJsonWithB()
val bs = j.decodeFromString("1", jsonTestingMode)
assertEquals(B(1), bs)
}
}