@@ -7,18 +7,33 @@ package kotlinx.serialization.json
77import kotlinx.serialization.*
88import kotlinx.serialization.json.internal.*
99import kotlinx.serialization.test.*
10+ import kotlin.jvm.*
1011import kotlin.test.*
1112
13+ @JvmInline
14+ @Serializable
15+ value class ComplexCarrier (val c : IntData )
16+
17+ @JvmInline
18+ @Serializable
19+ value class PrimitiveCarrier (val c : String )
20+
1221class JsonMapKeysTest : JsonTestBase () {
1322 @Serializable
1423 private data class WithMap (val map : Map <Long , Long >)
1524
25+ @Serializable
26+ private data class WithValueKeyMap (val map : Map <PrimitiveCarrier , Long >)
27+
1628 @Serializable
1729 private data class WithEnum (val map : Map <SampleEnum , Long >)
1830
1931 @Serializable
2032 private data class WithComplexKey (val map : Map <IntData , String >)
2133
34+ @Serializable
35+ private data class WithComplexValueKey (val map : Map <ComplexCarrier , String >)
36+
2237 @Test
2338 fun testMapKeysShouldBeStrings () = parametrizedTest(default) {
2439 assertStringFormAndRestored(
@@ -30,13 +45,16 @@ class JsonMapKeysTest : JsonTestBase() {
3045 }
3146
3247 @Test
33- fun structuredMapKeysShouldBeBannedByDefault () = parametrizedTest { streaming ->
48+ fun testStructuredMapKeysShouldBeProhibitedByDefault () = parametrizedTest { streaming ->
49+ noLegacyJs {
50+ verifyProhibition(WithComplexKey (mapOf (IntData (42 ) to " 42" )), streaming)
51+ verifyProhibition(WithComplexValueKey (mapOf (ComplexCarrier (IntData (42 )) to " 42" )), streaming)
52+ }
53+ }
54+
55+ private inline fun <reified T : Any > verifyProhibition (value : T , streaming : Boolean ) {
3456 val e = assertFailsWith<JsonException > {
35- Json .encodeToString(
36- WithComplexKey .serializer(),
37- WithComplexKey (mapOf (IntData (42 ) to " 42" )),
38- streaming
39- )
57+ Json .encodeToString(value, streaming)
4058 }
4159 assertTrue(e.message?.contains(" can't be used in JSON as a key in the map" ) == true )
4260 }
@@ -49,11 +67,31 @@ class JsonMapKeysTest : JsonTestBase() {
4967 Json { allowStructuredMapKeys = true }
5068 )
5169
70+ @Test
71+ fun testStructuredValueMapKeysAllowedWithFlag () = noLegacyJs {
72+ assertJsonFormAndRestored(
73+ WithComplexValueKey .serializer(),
74+ WithComplexValueKey (mapOf (ComplexCarrier (IntData (42 )) to " 42" )),
75+ """ {"map":[{"intV":42},"42"]}""" ,
76+ Json { allowStructuredMapKeys = true }
77+ )
78+ }
79+
5280 @Test
5381 fun testEnumsAreAllowedAsMapKeys () = assertJsonFormAndRestored(
5482 WithEnum .serializer(),
5583 WithEnum (mapOf (SampleEnum .OptionA to 1L , SampleEnum .OptionC to 3L )),
5684 """ {"map":{"OptionA":1,"OptionC":3}}""" ,
5785 Json
5886 )
87+
88+ @Test
89+ fun testPrimitivesAreAllowedAsValueMapKeys () = noLegacyJs {
90+ assertJsonFormAndRestored(
91+ WithValueKeyMap .serializer(),
92+ WithValueKeyMap (mapOf (PrimitiveCarrier (" fooKey" ) to 1 )),
93+ """ {"map":{"fooKey":1}}""" ,
94+ Json
95+ )
96+ }
5997}
0 commit comments