1 package kotlinx.serialization.json 2 3 import kotlinx.serialization.* 4 import kotlinx.serialization.descriptors.* 5 import kotlinx.serialization.encoding.* 6 import kotlin.test.* 7 8 class JsonElementDecodingTest : JsonTestBase() { 9 10 @Serializable 11 data class A(val a: Int = 42) 12 13 @Test testTopLevelClassnull14 fun testTopLevelClass() = assertSerializedForm(A(), """{}""".trimMargin()) 15 16 @Test 17 fun testTopLevelNullableClass() { 18 assertSerializedForm<A?>(A(), """{}""") 19 assertSerializedForm<A?>(null, "null") 20 } 21 22 @Test testTopLevelPrimitivenull23 fun testTopLevelPrimitive() = assertSerializedForm(42, """42""") 24 25 @Test 26 fun testTopLevelNullablePrimitive() { 27 assertSerializedForm<Int?>(42, """42""") 28 assertSerializedForm<Int?>(null, """null""") 29 } 30 31 @Test testTopLevelListnull32 fun testTopLevelList() = assertSerializedForm(listOf(42), """[42]""") 33 34 @Test 35 fun testTopLevelNullableList() { 36 assertSerializedForm<List<Int>?>(listOf(42), """[42]""") 37 assertSerializedForm<List<Int>?>(null, """null""") 38 } 39 assertSerializedFormnull40 private inline fun <reified T> assertSerializedForm(value: T, expectedString: String) { 41 val element = Json.encodeToJsonElement(value) 42 assertEquals(expectedString, element.toString()) 43 assertEquals(value, Json.decodeFromJsonElement(element)) 44 } 45 46 @Test testDeepRecursionnull47 fun testDeepRecursion() { 48 // Reported as https://github.com/Kotlin/kotlinx.serialization/issues/1594 49 var json = """{ "a": %}""" 50 for (i in 0..12) { 51 json = json.replace("%", json) 52 } 53 json = json.replace("%", "0") 54 Json.parseToJsonElement(json) 55 } 56 57 private open class NullAsElementSerializer<T : Any>(private val serializer: KSerializer<T>, val nullElement: T) : KSerializer<T?> { 58 final override val descriptor: SerialDescriptor = serializer.descriptor.nullable 59 serializenull60 final override fun serialize(encoder: Encoder, value: T?) { 61 serializer.serialize(encoder, value ?: nullElement) 62 } 63 deserializenull64 final override fun deserialize(decoder: Decoder): T = serializer.deserialize(decoder) 65 } 66 67 private object NullAsJsonNullJsonElementSerializer : NullAsElementSerializer<JsonElement>(JsonElement.serializer(), JsonNull) 68 private object NullAsJsonNullJsonPrimitiveSerializer : NullAsElementSerializer<JsonPrimitive>(JsonPrimitive.serializer(), JsonNull) 69 private object NullAsJsonNullJsonNullSerializer : NullAsElementSerializer<JsonNull>(JsonNull.serializer(), JsonNull) 70 private val noExplicitNullsOrDefaultsJson = Json { 71 explicitNulls = false 72 encodeDefaults = false 73 } 74 75 @Test testNullableJsonElementDecodingnull76 fun testNullableJsonElementDecoding() { 77 @Serializable 78 data class Wrapper( 79 @Serializable(NullAsJsonNullJsonElementSerializer::class) 80 val value: JsonElement? = null, 81 ) 82 83 assertJsonFormAndRestored(Wrapper.serializer(), Wrapper(value = JsonNull), """{"value":null}""", noExplicitNullsOrDefaultsJson) 84 assertJsonFormAndRestored(Wrapper.serializer(), Wrapper(value = null), """{}""", noExplicitNullsOrDefaultsJson) 85 } 86 87 @Test testNullableJsonPrimitiveDecodingnull88 fun testNullableJsonPrimitiveDecoding() { 89 @Serializable 90 data class Wrapper( 91 @Serializable(NullAsJsonNullJsonPrimitiveSerializer::class) 92 val value: JsonPrimitive? = null, 93 ) 94 95 assertJsonFormAndRestored(Wrapper.serializer(), Wrapper(value = JsonNull), """{"value":null}""", noExplicitNullsOrDefaultsJson) 96 assertJsonFormAndRestored(Wrapper.serializer(), Wrapper(value = null), """{}""", noExplicitNullsOrDefaultsJson) 97 } 98 99 @Test testNullableJsonNullDecodingnull100 fun testNullableJsonNullDecoding() { 101 @Serializable 102 data class Wrapper( 103 @Serializable(NullAsJsonNullJsonNullSerializer::class) 104 val value: JsonNull? = null, 105 ) 106 107 assertJsonFormAndRestored(Wrapper.serializer(), Wrapper(value = JsonNull), """{"value":null}""", noExplicitNullsOrDefaultsJson) 108 assertJsonFormAndRestored(Wrapper.serializer(), Wrapper(value = null), """{}""", noExplicitNullsOrDefaultsJson) 109 } 110 } 111