Skip to content

Commit 9b44607

Browse files
committed
1 parent fe85552 commit 9b44607

File tree

5 files changed

+265
-0
lines changed

5 files changed

+265
-0
lines changed

src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/ValueClasses.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,17 @@ import com.fasterxml.jackson.core.JsonParser
44
import com.fasterxml.jackson.databind.DeserializationContext
55
import com.fasterxml.jackson.databind.deser.std.StdDeserializer
66
import com.fasterxml.jackson.module.kotlin.WrapsNullableValueClassDeserializer
7+
import com.fasterxml.jackson.databind.KeyDeserializer as JacksonKeyDeserializer
78

89
@JvmInline
910
value class Primitive(val v: Int) {
1011
class Deserializer : StdDeserializer<Primitive>(Primitive::class.java) {
1112
override fun deserialize(p: JsonParser, ctxt: DeserializationContext): Primitive = Primitive(p.intValue + 100)
1213
}
14+
15+
class KeyDeserializer : JacksonKeyDeserializer() {
16+
override fun deserializeKey(key: String, ctxt: DeserializationContext) = Primitive(key.toInt() + 100)
17+
}
1318
}
1419

1520
@JvmInline
@@ -18,6 +23,10 @@ value class NonNullObject(val v: String) {
1823
override fun deserialize(p: JsonParser, ctxt: DeserializationContext): NonNullObject =
1924
NonNullObject(p.valueAsString + "-deser")
2025
}
26+
27+
class KeyDeserializer : JacksonKeyDeserializer() {
28+
override fun deserializeKey(key: String, ctxt: DeserializationContext) = NonNullObject("$key-deser")
29+
}
2130
}
2231

2332
@JvmInline
@@ -28,4 +37,8 @@ value class NullableObject(val v: String?) {
2837

2938
override fun getBoxedNullValue(): NullableObject = NullableObject("null-value-deser")
3039
}
40+
41+
class KeyDeserializer : JacksonKeyDeserializer() {
42+
override fun deserializeKey(key: String, ctxt: DeserializationContext) = NullableObject("$key-deser")
43+
}
3144
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
package com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.mapKey
2+
3+
import com.fasterxml.jackson.databind.DeserializationContext
4+
import com.fasterxml.jackson.databind.JsonMappingException
5+
import com.fasterxml.jackson.databind.exc.InvalidDefinitionException
6+
import com.fasterxml.jackson.databind.module.SimpleModule
7+
import com.fasterxml.jackson.module.kotlin.defaultMapper
8+
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
9+
import com.fasterxml.jackson.module.kotlin.readValue
10+
import com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.NonNullObject
11+
import com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.NullableObject
12+
import com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.Primitive
13+
import org.junit.jupiter.api.Assertions.assertEquals
14+
import org.junit.jupiter.api.Assertions.assertTrue
15+
import org.junit.jupiter.api.Nested
16+
import org.junit.jupiter.api.Test
17+
import org.junit.jupiter.api.assertThrows
18+
import java.lang.reflect.InvocationTargetException
19+
import com.fasterxml.jackson.databind.KeyDeserializer as JacksonKeyDeserializer
20+
21+
class WithoutCustomDeserializeMethodTest {
22+
companion object {
23+
val throwable = IllegalArgumentException("test")
24+
}
25+
26+
@Nested
27+
inner class DirectDeserialize {
28+
@Test
29+
fun primitive() {
30+
val result = defaultMapper.readValue<Map<Primitive, String?>>("""{"1":null}""")
31+
assertEquals(mapOf(Primitive(1) to null), result)
32+
}
33+
34+
@Test
35+
fun nonNullObject() {
36+
val result = defaultMapper.readValue<Map<NonNullObject, String?>>("""{"foo":null}""")
37+
assertEquals(mapOf(NonNullObject("foo") to null), result)
38+
}
39+
40+
@Test
41+
fun nullableObject() {
42+
val result = defaultMapper.readValue<Map<NullableObject, String?>>("""{"bar":null}""")
43+
assertEquals(mapOf(NullableObject("bar") to null), result)
44+
}
45+
}
46+
47+
data class Dst(
48+
val p: Map<Primitive, String?>,
49+
val nn: Map<NonNullObject, String?>,
50+
val n: Map<NullableObject, String?>
51+
)
52+
53+
@Test
54+
fun wrapped() {
55+
val src = """
56+
{
57+
"p":{"1":null},
58+
"nn":{"foo":null},
59+
"n":{"bar":null}
60+
}
61+
""".trimIndent()
62+
val result = defaultMapper.readValue<Dst>(src)
63+
val expected = Dst(
64+
mapOf(Primitive(1) to null),
65+
mapOf(NonNullObject("foo") to null),
66+
mapOf(NullableObject("bar") to null)
67+
)
68+
69+
assertEquals(expected, result)
70+
}
71+
72+
@JvmInline
73+
value class HasCheckConstructor(val value: Int) {
74+
init {
75+
if (value < 0) throw throwable
76+
}
77+
}
78+
79+
@Test
80+
fun callConstructorCheckTest() {
81+
val e = assertThrows<InvocationTargetException> {
82+
defaultMapper.readValue<Map<HasCheckConstructor, String?>>("""{"-1":null}""")
83+
}
84+
assertTrue(e.cause === throwable)
85+
}
86+
87+
data class Wrapped(val first: String, val second: String) {
88+
class KeyDeserializer : JacksonKeyDeserializer() {
89+
override fun deserializeKey(key: String, ctxt: DeserializationContext) =
90+
key.split("-").let { Wrapped(it[0], it[1]) }
91+
}
92+
}
93+
94+
@JvmInline
95+
value class Wrapper(val w: Wrapped)
96+
97+
@Test
98+
fun wrappedCustomObject() {
99+
// If a type that cannot be deserialized is specified, the default is an error.
100+
val thrown = assertThrows<JsonMappingException> {
101+
defaultMapper.readValue<Map<Wrapper, String?>>("""{"foo-bar":null}""")
102+
}
103+
assertTrue(thrown.cause is InvalidDefinitionException)
104+
105+
val mapper = jacksonObjectMapper()
106+
.registerModule(
107+
object : SimpleModule() {
108+
init { addKeyDeserializer(Wrapped::class.java, Wrapped.KeyDeserializer()) }
109+
}
110+
)
111+
112+
val result = mapper.readValue<Map<Wrapper, String?>>("""{"foo-bar":null}""")
113+
val expected = mapOf(Wrapper(Wrapped("foo", "bar")) to null)
114+
115+
assertEquals(expected, result)
116+
}
117+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.mapKey.keyDeserializer
2+
3+
import com.fasterxml.jackson.databind.module.SimpleModule
4+
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
5+
import com.fasterxml.jackson.module.kotlin.readValue
6+
import com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.NonNullObject
7+
import com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.NullableObject
8+
import com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.Primitive
9+
import org.junit.jupiter.api.Assertions.assertEquals
10+
import org.junit.jupiter.api.Nested
11+
import org.junit.jupiter.api.Test
12+
13+
class SpecifiedForObjectMapperTest {
14+
companion object {
15+
val mapper = jacksonObjectMapper().apply {
16+
val module = SimpleModule().apply {
17+
this.addKeyDeserializer(Primitive::class.java, Primitive.KeyDeserializer())
18+
this.addKeyDeserializer(NonNullObject::class.java, NonNullObject.KeyDeserializer())
19+
this.addKeyDeserializer(NullableObject::class.java, NullableObject.KeyDeserializer())
20+
}
21+
this.registerModule(module)
22+
}
23+
}
24+
25+
@Nested
26+
inner class DirectDeserialize {
27+
@Test
28+
fun primitive() {
29+
val result = mapper.readValue<Map<Primitive, String?>>("""{"1":null}""")
30+
assertEquals(mapOf(Primitive(101) to null), result)
31+
}
32+
33+
@Test
34+
fun nonNullObject() {
35+
val result = mapper.readValue<Map<NonNullObject, String?>>("""{"foo":null}""")
36+
assertEquals(mapOf(NonNullObject("foo-deser") to null), result)
37+
}
38+
39+
@Test
40+
fun nullableObject() {
41+
val result = mapper.readValue<Map<NullableObject, String?>>("""{"bar":null}""")
42+
assertEquals(mapOf(NullableObject("bar-deser") to null), result)
43+
}
44+
}
45+
46+
data class Dst(
47+
val p: Map<Primitive, String?>,
48+
val nn: Map<NonNullObject, String?>,
49+
val n: Map<NullableObject, String?>
50+
)
51+
52+
@Test
53+
fun wrapped() {
54+
val src = """
55+
{
56+
"p":{"1":null},
57+
"nn":{"foo":null},
58+
"n":{"bar":null}
59+
}
60+
""".trimIndent()
61+
val result = mapper.readValue<Dst>(src)
62+
val expected = Dst(
63+
mapOf(Primitive(101) to null),
64+
mapOf(NonNullObject("foo-deser") to null),
65+
mapOf(NullableObject("bar-deser") to null)
66+
)
67+
68+
assertEquals(expected, result)
69+
}
70+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.mapKey.keyDeserializer.byAnnotation
2+
3+
import com.fasterxml.jackson.databind.DeserializationContext
4+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
5+
import com.fasterxml.jackson.module.kotlin.defaultMapper
6+
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
7+
import com.fasterxml.jackson.module.kotlin.readValue
8+
import org.junit.jupiter.api.Assertions.assertEquals
9+
import org.junit.jupiter.api.Test
10+
import com.fasterxml.jackson.databind.KeyDeserializer as JacksonKeyDeserializer
11+
12+
class SpecifiedForClassTest {
13+
@JsonDeserialize(keyUsing = Value.KeyDeserializer::class)
14+
@JvmInline
15+
value class Value(val v: Int) {
16+
class KeyDeserializer : JacksonKeyDeserializer() {
17+
override fun deserializeKey(key: String, ctxt: DeserializationContext) = Value(key.toInt() + 100)
18+
}
19+
}
20+
21+
@Test
22+
fun directDeserTest() {
23+
val result = defaultMapper.readValue<Map<Value, String?>>("""{"1":null}""")
24+
25+
assertEquals(mapOf(Value(101) to null), result)
26+
}
27+
28+
data class Wrapper(val v: Map<Value, String?>)
29+
30+
@Test
31+
fun paramDeserTest() {
32+
val mapper = jacksonObjectMapper()
33+
val result = mapper.readValue<Wrapper>("""{"v":{"1":null}}""")
34+
35+
assertEquals(Wrapper(mapOf(Value(101) to null)), result)
36+
}
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.mapKey.keyDeserializer.byAnnotation
2+
3+
import com.fasterxml.jackson.databind.DeserializationContext
4+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
5+
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
6+
import com.fasterxml.jackson.module.kotlin.readValue
7+
import org.junit.jupiter.api.Assertions.assertEquals
8+
import org.junit.jupiter.api.Test
9+
import com.fasterxml.jackson.databind.KeyDeserializer as JacksonKeyDeserializer
10+
11+
class SpecifiedForPropertyTest {
12+
@JvmInline
13+
value class Value(val v: Int) {
14+
class KeyDeserializer : JacksonKeyDeserializer() {
15+
override fun deserializeKey(key: String, ctxt: DeserializationContext) = Value(key.toInt() + 100)
16+
}
17+
}
18+
19+
data class Wrapper(@JsonDeserialize(keyUsing = Value.KeyDeserializer::class) val v: Map<Value, String?>)
20+
21+
@Test
22+
fun paramDeserTest() {
23+
val mapper = jacksonObjectMapper()
24+
val result = mapper.readValue<Wrapper>("""{"v":{"1":null}}""")
25+
26+
assertEquals(Wrapper(mapOf(Value(101) to null)), result)
27+
}
28+
}

0 commit comments

Comments
 (0)