1 /*
2  * Copyright 2019 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package kotlinx.serialization
18 
19 import kotlinx.serialization.json.Json
20 import kotlinx.serialization.test.typeTokenOf
21 import org.junit.Test
22 import java.util.HashMap
23 import java.util.HashSet
24 import kotlin.collections.LinkedHashMap
25 import kotlin.collections.Map
26 import kotlin.collections.hashMapOf
27 import kotlin.collections.hashSetOf
28 import kotlin.reflect.*
29 import kotlin.test.*
30 
31 
32 class JavaCollectionsTest {
33     @Serializable
34     data class HasHashMap(
35         val s: String,
36         val hashMap: HashMap<Int, String>,
37         val hashSet: HashSet<Int>,
38         val linkedHashMap: LinkedHashMap<Int, String>,
39         val kEntry: Map.Entry<Int, String>?
40     )
41 
42     @Test
testJavaCollectionsInsideClassnull43     fun testJavaCollectionsInsideClass() {
44         val original = HasHashMap("42", hashMapOf(1 to "1", 2 to "2"), hashSetOf(11), LinkedHashMap(), null)
45         val serializer = HasHashMap.serializer()
46         val string = Json.encodeToString(serializer = serializer, value = original)
47         assertEquals(
48             expected = """{"s":"42","hashMap":{"1":"1","2":"2"},"hashSet":[11],"linkedHashMap":{},"kEntry":null}""",
49             actual = string
50         )
51         val restored = Json.decodeFromString(deserializer = serializer, string = string)
52         assertEquals(expected = original, actual = restored)
53     }
54 
55     @Test
testTopLevelMapsnull56     fun testTopLevelMaps() {
57         // Returning null here is a deliberate choice: map constructor functions may return different specialized
58         // implementations (e.g., kotlin.collections.EmptyMap or java.util.Collections.SingletonMap)
59         // that may or may not be generic. Since we generally cannot return a generic serializer using Java class only,
60         // all attempts to get map serializer using only .javaClass should return null.
61         assertNull(serializerOrNull(emptyMap<String, String>().javaClass))
62         assertNull(serializerOrNull(mapOf<String, String>("a" to "b").javaClass))
63         assertNull(serializerOrNull(mapOf<String, String>("a" to "b", "b" to "c").javaClass))
64         // Correct ways of retrieving map serializer:
65         assertContains(
66             serializer(typeTokenOf<Map<String, String>>()).descriptor.serialName,
67             "kotlin.collections.LinkedHashMap"
68         )
69         assertContains(
70             serializer(typeTokenOf<java.util.LinkedHashMap<String, String>>()).descriptor.serialName,
71             "kotlin.collections.LinkedHashMap"
72         )
73         assertContains(
74             serializer(typeOf<LinkedHashMap<String, String>>()).descriptor.serialName,
75             "kotlin.collections.LinkedHashMap"
76         )
77     }
78 
79     @Test
testTopLevelSetsAndListsnull80     fun testTopLevelSetsAndLists() {
81         // Same reasoning as for maps
82         assertNull(serializerOrNull(emptyList<String>().javaClass))
83         assertNull(serializerOrNull(listOf<String>("a").javaClass))
84         assertNull(serializerOrNull(listOf<String>("a", "b").javaClass))
85         assertNull(serializerOrNull(emptySet<String>().javaClass))
86         assertNull(serializerOrNull(setOf<String>("a").javaClass))
87         assertNull(serializerOrNull(setOf<String>("a", "b").javaClass))
88         assertContains(
89             serializer(typeTokenOf<Set<String>>()).descriptor.serialName,
90             "kotlin.collections.LinkedHashSet"
91         )
92         assertContains(
93             serializer(typeTokenOf<List<String>>()).descriptor.serialName,
94             "kotlin.collections.ArrayList"
95         )
96         assertContains(
97             serializer(typeTokenOf<java.util.LinkedHashSet<String>>()).descriptor.serialName,
98             "kotlin.collections.LinkedHashSet"
99         )
100         assertContains(
101             serializer(typeTokenOf<java.util.ArrayList<String>>()).descriptor.serialName,
102             "kotlin.collections.ArrayList"
103         )
104     }
105 
106     @Test
testAnonymousObjectnull107     fun testAnonymousObject() {
108         val obj: Any = object {}
109         assertNull(serializerOrNull(obj.javaClass))
110     }
111 }
112 
113