1 package kotlinx.serialization.json 2 3 import kotlinx.serialization.* 4 import kotlin.test.* 5 6 /* 7 * Actual testing should be performed in subclasses. 8 * Subclasses implement serialization and deserialization for different types: serial Kotlin classes, JsonElement, dynamic etc 9 */ 10 @Ignore 11 abstract class AbstractJsonImplicitNullsTest { 12 @Serializable 13 data class Nullable( 14 val f0: Int?, 15 val f1: Int?, 16 val f2: Int?, 17 val f3: Int?, 18 ) 19 20 @Serializable 21 data class WithNotNull( 22 val f0: Int?, 23 val f1: Int?, 24 val f2: Int, 25 ) 26 27 @Serializable 28 data class WithOptional( 29 val f0: Int?, 30 val f1: Int? = 1, 31 val f2: Int = 2, 32 ) 33 34 @Serializable 35 data class Outer(val i: Inner) 36 37 @Serializable 38 data class Inner(val s1: String?, val s2: String?) 39 40 @Serializable 41 data class ListWithNullable(val l: List<Int?>) 42 43 @Serializable 44 data class MapWithNullable(val m: Map<Int?, Int?>) 45 46 @Serializable 47 data class NullableList(val l: List<Int>?) 48 49 @Serializable 50 data class NullableMap(val m: Map<Int, Int>?) 51 52 <lambda>null53 private val format = Json { explicitNulls = false } 54 encodenull55 protected abstract fun <T> Json.encode(value: T, serializer: KSerializer<T>): String 56 57 protected abstract fun <T> Json.decode(json: String, serializer: KSerializer<T>): T 58 59 @Test 60 fun testExplicit() { 61 val plain = Nullable(null, 10, null, null) 62 val json = """{"f0":null,"f1":10,"f2":null,"f3":null}""" 63 64 assertEquals(json, Json.encode(plain, Nullable.serializer())) 65 assertEquals(plain, Json.decode(json, Nullable.serializer())) 66 } 67 68 @Test testNullablenull69 fun testNullable() { 70 val plain = Nullable(null, 10, null, null) 71 val json = """{"f1":10}""" 72 73 assertEquals(json, format.encode(plain, Nullable.serializer())) 74 assertEquals(plain, format.decode(json, Nullable.serializer())) 75 } 76 77 @Test testMissingNotNullnull78 fun testMissingNotNull() { 79 val json = """{"f1":10}""" 80 81 assertFailsWith(SerializationException::class) { 82 format.decode(json, WithNotNull.serializer()) 83 } 84 } 85 86 @Test testOptionalnull87 fun testOptional() { 88 val encoded = format.encode(WithOptional(null), WithOptional.serializer()) 89 val json = """{}""" 90 assertEquals(json, encoded) 91 // Same result when `null` is used instead of `1`: 92 val encodedWithNullInsteadOfDefault = format.encode(WithOptional(null, null), WithOptional.serializer()) 93 assertEquals(json, encodedWithNullInsteadOfDefault) 94 95 val decoded = format.decode(json, WithOptional.serializer()) 96 assertEquals(WithOptional(null), decoded) 97 } 98 99 100 @Test testNestedJsonObjectnull101 fun testNestedJsonObject() { 102 val json = """{"i": {}}""" 103 104 val decoded = format.decode(json, Outer.serializer()) 105 assertEquals(Outer(Inner(null, null)), decoded) 106 } 107 108 @Test testListWithNullablenull109 fun testListWithNullable() { 110 val jsonWithNull = """{"l":[null]}""" 111 val jsonWithEmptyList = """{"l":[]}""" 112 113 val encoded = format.encode(ListWithNullable(listOf(null)), ListWithNullable.serializer()) 114 assertEquals(jsonWithNull, encoded) 115 116 val decoded = format.decode(jsonWithEmptyList, ListWithNullable.serializer()) 117 assertEquals(ListWithNullable(emptyList()), decoded) 118 } 119 120 @Test testMapWithNullablenull121 fun testMapWithNullable() { 122 val jsonWithNull = """{"m":{null:null}}""" 123 val jsonWithQuotedNull = """{"m":{"null":null}}""" 124 val jsonWithEmptyList = """{"m":{}}""" 125 126 val encoded = format.encode(MapWithNullable(mapOf(null to null)), MapWithNullable.serializer()) 127 //Json encode map null key as `null:` but other external utilities may encode it as a String `"null":` 128 assertTrue { listOf(jsonWithNull, jsonWithQuotedNull).contains(encoded) } 129 130 val decoded = format.decode(jsonWithEmptyList, MapWithNullable.serializer()) 131 assertEquals(MapWithNullable(emptyMap()), decoded) 132 } 133 134 @Test testNullableListnull135 fun testNullableList() { 136 val json = """{}""" 137 138 val encoded = format.encode(NullableList(null), NullableList.serializer()) 139 assertEquals(json, encoded) 140 141 val decoded = format.decode(json, NullableList.serializer()) 142 assertEquals(NullableList(null), decoded) 143 } 144 145 @Test testNullableMapnull146 fun testNullableMap() { 147 val json = """{}""" 148 149 val encoded = format.encode(NullableMap(null), NullableMap.serializer()) 150 assertEquals(json, encoded) 151 152 val decoded = format.decode(json, NullableMap.serializer()) 153 assertEquals(NullableMap(null), decoded) 154 } 155 156 } 157