1 /* 2 * Copyright 2017-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 */ 4 5 package kotlinx.serialization.json 6 7 import kotlinx.serialization.* 8 import kotlinx.serialization.test.* 9 import kotlin.test.* 10 11 class JsonTreeTest : JsonTestBase() { 12 @Serializable 13 data class Data(val a: Int) 14 15 @Serializable 16 data class DataWrapper(val s: String, val d: Data?) 17 18 @Serializable 19 data class DataWrapperOptional(val s: String, val d: Data? = null) 20 21 @Serializable 22 data class IntList(val l: List<Int>) 23 24 @Serializable 25 data class DataList(val l: List<Data>) 26 27 @Serializable 28 data class ListOfLists(val l: List<List<Data>>) 29 30 @Serializable 31 data class MapWrapper(val m: Map<String, Int>) 32 33 @Serializable 34 data class ComplexMapWrapper(val m: Map<String, Data>) 35 36 @Serializable 37 data class AllTypes( 38 val b: Byte, 39 val s: Short, 40 val i: Int, 41 val f: Float, 42 val d: Double, 43 val c: Char, 44 val B: Boolean, 45 val S: String 46 ) 47 48 private val json = Json preparenull49 private fun prepare(input: String): JsonElement = lenient.parseToJsonElement(input) 50 51 @Test 52 fun testReadTreeSimple() { 53 val tree = prepare("{a: 42}") 54 val parsed = lenient.decodeFromJsonElement(Data.serializer(), tree) 55 assertEquals(Data(42), parsed) 56 } 57 58 @Test testReadTreeNestednull59 fun testReadTreeNested() { 60 val tree = prepare("""{s:"foo", d:{a:42}}""") 61 val parsed = lenient.decodeFromJsonElement(DataWrapper.serializer(), tree) 62 val expected = DataWrapper("foo", Data(42)) 63 assertEquals(expected, parsed) 64 assertEquals(3, parsed.s.length) 65 } 66 67 @Test testReadTreeAllTypesnull68 fun testReadTreeAllTypes() { 69 val tree = prepare("""{ b: 1, s: 2, i: 3, f: 1.0, d: 42.0, c: "a", B: true, S: "str"}""") 70 val kotlinObj = AllTypes(1, 2, 3, 1.0f, 42.0, 'a', true, "str") 71 72 assertEquals(kotlinObj, json.decodeFromJsonElement(AllTypes.serializer(), tree)) 73 } 74 75 @Test testReadTreeNullablenull76 fun testReadTreeNullable() { 77 val tree1 = prepare("""{s:"foo", d: null}""") 78 val tree2 = prepare("""{s:"foo"}""") 79 80 assertEquals(DataWrapper("foo", null), lenient.decodeFromJsonElement(DataWrapper.serializer(), tree1)) 81 assertFailsWithMissingField { lenient.decodeFromJsonElement(DataWrapper.serializer(), tree2) } 82 } 83 84 @Test testReadTreeOptionalnull85 fun testReadTreeOptional() { 86 val tree1 = prepare("""{s:"foo", d: null}""") 87 val tree2 = prepare("""{s:"foo"}""") 88 89 assertEquals(DataWrapperOptional("foo", null), json.decodeFromJsonElement(DataWrapperOptional.serializer(), tree1)) 90 assertEquals(DataWrapperOptional("foo", null), json.decodeFromJsonElement(DataWrapperOptional.serializer(), tree2)) 91 } 92 93 @Test testReadTreeListnull94 fun testReadTreeList() { 95 val tree1 = prepare("""{l:[1,2]}""") 96 val tree2 = prepare("""{l:[{a:42},{a:43}]}""") 97 val tree3 = prepare("""{l:[[],[{a:42}]]}""") 98 99 assertEquals(IntList(listOf(1, 2)), lenient.decodeFromJsonElement(IntList.serializer(), tree1)) 100 assertEquals(DataList(listOf(Data(42), Data(43))), lenient.decodeFromJsonElement(DataList.serializer(), tree2)) 101 assertEquals(ListOfLists(listOf(listOf(), listOf(Data(42)))), json.decodeFromJsonElement(ListOfLists.serializer(), tree3)) 102 } 103 104 @Test testReadTreeMapnull105 fun testReadTreeMap() { 106 val dyn = prepare("{m : {\"a\": 1, \"b\" : 2}}") 107 val m = MapWrapper(mapOf("a" to 1, "b" to 2)) 108 assertEquals(m, lenient.decodeFromJsonElement(MapWrapper.serializer(), dyn)) 109 } 110 111 @Test testReadTreeComplexMapnull112 fun testReadTreeComplexMap() { 113 val dyn = prepare("{m : {1: {a: 42}, 2: {a: 43}}}") 114 val m = ComplexMapWrapper(mapOf("1" to Data(42), "2" to Data(43))) 115 assertEquals(m, lenient.decodeFromJsonElement(ComplexMapWrapper.serializer(), dyn)) 116 } 117 writeAndTestnull118 private inline fun <reified T: Any> writeAndTest(obj: T, serial: KSerializer<T>, printDiagnostics: Boolean = false): Pair<JsonElement, T> { 119 val tree = lenient.encodeToJsonElement(serial, obj) 120 val str = tree.toString() 121 if (printDiagnostics) println(str) 122 val restored = lenient.decodeFromJsonElement(serial, lenient.parseToJsonElement(str)) 123 assertEquals(obj, restored) 124 return tree to restored 125 } 126 127 @Test testSaveSimpleNestedTreenull128 fun testSaveSimpleNestedTree() { 129 writeAndTest(DataWrapper("foo", Data(42)), DataWrapper.serializer()) 130 } 131 132 @Test testSaveComplexMapTreenull133 fun testSaveComplexMapTree() { 134 writeAndTest(ComplexMapWrapper(mapOf("foo" to Data(42), "bar" to Data(43))), ComplexMapWrapper.serializer()) 135 } 136 137 @Test testSaveNestedListsnull138 fun testSaveNestedLists() { 139 writeAndTest(ListOfLists(listOf(listOf(), listOf(Data(1), Data(2)))), ListOfLists.serializer()) 140 } 141 142 @Test testSaveOptionalnull143 fun testSaveOptional() { 144 writeAndTest(DataWrapperOptional("foo", null), DataWrapperOptional.serializer()) 145 } 146 147 @Test testSaveAllTypesnull148 fun testSaveAllTypes() { 149 writeAndTest(AllTypes(1, -2, 100500, 0.0f, 2048.2, 'a', true, "foobar"), AllTypes.serializer()) 150 } 151 } 152