1 /*
<lambda>null2  * Copyright 2017-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3  */
4 
5 package kotlinx.serialization.builtins
6 
7 import kotlinx.serialization.*
8 import kotlinx.serialization.json.*
9 import kotlinx.serialization.test.*
10 import kotlin.test.*
11 
12 class KeyValueSerializersTest : JsonTestBase() {
13 
14     @Test
15     fun testPair() = parametrizedTest { jsonTestingMode ->
16         testPair(Pair(42, 42), Int.serializer(), Int.serializer(), jsonTestingMode, """{"first":42,"second":42}""")
17         testPair(
18             Pair(42, Pair("a", "b")),
19             Int.serializer(),
20             serializer(),
21             jsonTestingMode,
22             """{"first":42,"second":{"first":"a","second":"b"}}"""
23         )
24         testPair(
25             Pair(42, null),
26             Int.serializer(),
27             Int.serializer().nullable,
28             jsonTestingMode,
29             """{"first":42,"second":null}"""
30         )
31     }
32 
33     private fun <K, V> testPair(
34         pairInstance: Pair<K, V>,
35         kSerializer: KSerializer<K>,
36         vSerializer: KSerializer<V>,
37         jsonTestingMode: JsonTestingMode,
38         expectedJson: String
39     ) {
40         val serializer = PairSerializer(kSerializer, vSerializer)
41         val json = default.encodeToString(serializer, pairInstance, jsonTestingMode)
42         assertEquals(expectedJson, json)
43         val pair = default.decodeFromString(serializer, json, jsonTestingMode)
44         assertEquals(pairInstance, pair)
45     }
46 
47     @Test
48     fun testTriple() = parametrizedTest { jsonTestingMode ->
49         testTriple(
50             Triple(42, 42, "42"),
51             Int.serializer(),
52             Int.serializer(),
53             String.serializer(),
54             jsonTestingMode,
55             """{"first":42,"second":42,"third":"42"}"""
56         )
57 
58         testTriple(
59             Triple(42, Triple(42, "f", 'c'), "42"),
60             Int.serializer(),
61             serializer(),
62             String.serializer(),
63             jsonTestingMode,
64             """{"first":42,"second":{"first":42,"second":"f","third":"c"},"third":"42"}"""
65         )
66 
67         testTriple(
68             Triple(42, null, null),
69             Int.serializer(),
70             Int.serializer().nullable,
71             String.serializer().nullable,
72             jsonTestingMode,
73             """{"first":42,"second":null,"third":null}"""
74         )
75     }
76 
77     private fun  <A, B, C> testTriple(
78         tripleInstance: Triple<A, B, C>,
79         aSerializer: KSerializer<A>,
80         bSerializer: KSerializer<B>,
81         cSerializer: KSerializer<C>,
82         jsonTestingMode: JsonTestingMode,
83         expectedJson: String
84     ) {
85         val serializer = TripleSerializer(aSerializer, bSerializer, cSerializer)
86         val json = default.encodeToString(serializer, tripleInstance, jsonTestingMode)
87         assertEquals(expectedJson, json)
88         val triple = default.decodeFromString(serializer, json, jsonTestingMode)
89         assertEquals(tripleInstance, triple)
90     }
91 
92     class Entry<K, V>(override val key: K, override val value: V) : Map.Entry<K, V> {
93         override fun equals(other: Any?): Boolean {
94             if (this === other) return true
95             if (other == null || other !is Map.Entry<*, *>) return false
96             if (key != other.key) return false
97             if (value != other.value) return false
98             return true
99         }
100 
101         override fun hashCode(): Int {
102             var result = key?.hashCode() ?: 0
103             result = 31 * result + (value?.hashCode() ?: 0)
104             return result
105         }
106     }
107 
108     @Test
109     fun testKeyValuePair() = parametrizedTest { jsonTestingMode ->
110         jvmOnly {
111             testEntry(Entry(42, 42), Int.serializer(), Int.serializer(), jsonTestingMode, """{"42":42}""")
112             testEntry(
113                 Entry(42, Entry("a", "b")),
114                 Int.serializer(),
115                 serializer<Map.Entry<String, String>>(),
116                 jsonTestingMode,
117                 """{"42":{"a":"b"}}"""
118             )
119             testEntry(
120                 Entry(42, null),
121                 Int.serializer(),
122                 Int.serializer().nullable,
123                 jsonTestingMode,
124                 """{"42":null}"""
125             )
126         }
127     }
128 
129     private inline fun <reified K, reified V> testEntry(
130         entryInstance: Map.Entry<K, V>,
131         kSerializer: KSerializer<K>,
132         vSerializer: KSerializer<V>,
133         jsonTestingMode: JsonTestingMode,
134         expectedJson: String
135     ) {
136         val serializer = MapEntrySerializer(kSerializer, vSerializer)
137         val json = default.encodeToString(serializer, entryInstance, jsonTestingMode)
138         assertEquals(expectedJson, json)
139         val entry = default.decodeFromString(serializer, json, jsonTestingMode)
140         assertEquals(entryInstance, entry)
141     }
142 }
143