Skip to content

Commit f6c71e8

Browse files
authored
test StreamReadCapability.DUPLICATE_PROPERTIES (IntMap/LongMap) (#607)
1 parent 201f06c commit f6c71e8

File tree

5 files changed

+182
-10
lines changed

5 files changed

+182
-10
lines changed

src/main/scala/com/fasterxml/jackson/module/scala/deser/IntMapDeserializerResolver.scala

+12-3
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,18 @@ private[deser] object IntMapDeserializerResolver extends Deserializers.Base {
7676

7777
override def put(k: Object, v: Object): Object = {
7878
k match {
79-
case n: Number => baseMap += (n.intValue() -> v)
80-
case s: String => baseMap += (s.toInt -> v)
79+
case n: Number => {
80+
val i = n.intValue()
81+
val oldValue = baseMap.get(i)
82+
baseMap += (i -> v)
83+
oldValue.orNull
84+
}
85+
case s: String => {
86+
val i = s.toInt
87+
val oldValue = baseMap.get(i)
88+
baseMap += (i -> v)
89+
oldValue.orNull
90+
}
8191
case _ => {
8292
val typeName = Option(k) match {
8393
case Some(n) => n.getClass.getName
@@ -86,7 +96,6 @@ private[deser] object IntMapDeserializerResolver extends Deserializers.Base {
8696
throw new IllegalArgumentException(s"IntMap does not support keys of type $typeName")
8797
}
8898
}
89-
v
9099
}
91100

92101
// Used by the deserializer when using readerForUpdating

src/main/scala/com/fasterxml/jackson/module/scala/deser/LongMapDeserializerResolver.scala

+24-6
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,18 @@ private[deser] object LongMapDeserializerResolver extends Deserializers.Base {
118118

119119
override def put(k: Object, v: Object): Object = {
120120
k match {
121-
case n: Number => baseMap += (n.longValue() -> v)
122-
case s: String => baseMap += (s.toLong -> v)
121+
case n: Number => {
122+
val l = n.longValue()
123+
val oldValue = baseMap.get(l)
124+
baseMap += (l -> v)
125+
oldValue.orNull
126+
}
127+
case s: String => {
128+
val l = s.toLong
129+
val oldValue = baseMap.get(l)
130+
baseMap += (l -> v)
131+
oldValue.orNull
132+
}
123133
case _ => {
124134
val typeName = Option(k) match {
125135
case Some(n) => n.getClass.getName
@@ -128,7 +138,6 @@ private[deser] object LongMapDeserializerResolver extends Deserializers.Base {
128138
throw new IllegalArgumentException(s"LongMap does not support keys of type $typeName")
129139
}
130140
}
131-
v
132141
}
133142

134143
// Used by the deserializer when using readerForUpdating
@@ -150,8 +159,18 @@ private[deser] object LongMapDeserializerResolver extends Deserializers.Base {
150159

151160
override def put(k: Object, v: Object): Object = {
152161
k match {
153-
case n: Number => baseMap += (n.longValue() -> v)
154-
case s: String => baseMap += (s.toLong -> v)
162+
case n: Number => {
163+
val l = n.longValue()
164+
val oldValue = baseMap.get(l)
165+
baseMap += (l -> v)
166+
oldValue.orNull
167+
}
168+
case s: String => {
169+
val l = s.toLong
170+
val oldValue = baseMap.get(l)
171+
baseMap += (l -> v)
172+
oldValue.orNull
173+
}
155174
case _ => {
156175
val typeName = Option(k) match {
157176
case Some(n) => n.getClass.getName
@@ -160,7 +179,6 @@ private[deser] object LongMapDeserializerResolver extends Deserializers.Base {
160179
throw new IllegalArgumentException(s"LongMap does not support keys of type $typeName")
161180
}
162181
}
163-
v
164182
}
165183

166184
// Used by the deserializer when using readerForUpdating

src/test/scala/com/fasterxml/jackson/module/scala/deser/IntMapDeserializerTest.scala

+38-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.fasterxml.jackson.module.scala.deser
22

33
import com.fasterxml.jackson.core.`type`.TypeReference
4-
import com.fasterxml.jackson.module.scala.{ClassTagExtensions, DefaultScalaModule}
4+
import com.fasterxml.jackson.module.scala.DefaultScalaModule
55
import com.fasterxml.jackson.module.scala.deser.IntMapDeserializerTest.{Event, IntMapWrapper}
66

77
import java.util.UUID
@@ -87,4 +87,41 @@ class IntMapDeserializerTest extends DeserializerTest {
8787
read(1) shouldEqual "true"
8888
read(2) shouldEqual Map("id" -> event.id.toString, "description" -> event.description)
8989
}
90+
91+
it should "deserialize IntMap (Object values, duplicate keys - default mode)" in {
92+
val mapper = newMapper
93+
val json = """{"1": 123, "2": 123, "2": 123.456}"""
94+
val read = mapper.readValue(json, classOf[IntMap[Any]])
95+
read(1) shouldEqual 123
96+
read(2) shouldEqual 123.456
97+
}
98+
99+
it should "deserialize IntMap (Object values, duplicate keys - optional mode)" in {
100+
val mapper = newMapper
101+
val json = """{"1": 123, "2": 123, "2": 123.456}"""
102+
val parser = new WithDupsParser(mapper.createParser(json))
103+
val read = try {
104+
mapper.readValue(parser, classOf[IntMap[Any]])
105+
} finally {
106+
parser.close()
107+
}
108+
read(1) shouldEqual 123
109+
val expected = new java.util.ArrayList[Object]()
110+
expected.add(java.lang.Integer.valueOf(123))
111+
expected.add(java.lang.Double.valueOf(123.456))
112+
read(2) shouldEqual expected
113+
}
114+
115+
it should "deserialize IntMap (Double values, duplicate key mode is ignored)" in {
116+
val mapper = newMapper
117+
val json = """{"1": "123", "2": "123", "2": "123.456"}"""
118+
val parser = new WithDupsParser(mapper.createParser(json))
119+
val read = try {
120+
mapper.readValue(parser, new TypeReference[IntMap[String]]{})
121+
} finally {
122+
parser.close()
123+
}
124+
read(1) shouldEqual "123"
125+
read(2) shouldEqual "123.456"
126+
}
90127
}

src/test/scala/com/fasterxml/jackson/module/scala/deser/LongMapDeserializerTest.scala

+98
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ package com.fasterxml.jackson.module.scala.deser
22

33
import com.fasterxml.jackson.core.`type`.TypeReference
44
import com.fasterxml.jackson.module.scala.DefaultScalaModule
5+
import com.fasterxml.jackson.module.scala.deser.IntMapDeserializerTest.Event
56

7+
import java.util.UUID
68
import scala.collection.{immutable, mutable}
79

810
class LongMapDeserializerTest extends DeserializerTest {
@@ -45,6 +47,54 @@ class LongMapDeserializerTest extends DeserializerTest {
4547
read(402) shouldBe true
4648
}
4749

50+
it should "deserialize immutable LongMap (Object values)" in {
51+
val event = Event(UUID.randomUUID(), "event1")
52+
val map = mutable.LongMap(0L -> false, 1L -> "true", 2L -> event)
53+
val mapper = newMapper
54+
val json = mapper.writeValueAsString(map)
55+
val read = mapper.readValue(json, classOf[immutable.LongMap[Any]])
56+
read(0) shouldBe false
57+
read(1) shouldEqual "true"
58+
read(2) shouldEqual Map("id" -> event.id.toString, "description" -> event.description)
59+
}
60+
61+
it should "deserialize immutable LongMap (Object values, duplicate keys - default mode)" in {
62+
val mapper = newMapper
63+
val json = """{"1": 123, "2": 123, "2": 123.456}"""
64+
val read = mapper.readValue(json, classOf[immutable.LongMap[Any]])
65+
read(1) shouldEqual 123
66+
read(2) shouldEqual 123.456
67+
}
68+
69+
it should "deserialize immutable LongMap (Object values, duplicate keys - optional mode)" in {
70+
val mapper = newMapper
71+
val json = """{"1": 123, "2": 123, "2": 123.456}"""
72+
val parser = new WithDupsParser(mapper.createParser(json))
73+
val read = try {
74+
mapper.readValue(parser, classOf[immutable.LongMap[Any]])
75+
} finally {
76+
parser.close()
77+
}
78+
read(1) shouldEqual 123
79+
val expected = new java.util.ArrayList[Object]()
80+
expected.add(java.lang.Integer.valueOf(123))
81+
expected.add(java.lang.Double.valueOf(123.456))
82+
read(2) shouldEqual expected
83+
}
84+
85+
it should "deserialize immutable LongMap (Double values, duplicate key mode is ignored)" in {
86+
val mapper = newMapper
87+
val json = """{"1": "123", "2": "123", "2": "123.456"}"""
88+
val parser = new WithDupsParser(mapper.createParser(json))
89+
val read = try {
90+
mapper.readValue(parser, new TypeReference[immutable.LongMap[String]] {})
91+
} finally {
92+
parser.close()
93+
}
94+
read(1) shouldEqual "123"
95+
read(2) shouldEqual "123.456"
96+
}
97+
4898
it should "deserialize mutable LongMap" in {
4999
val map = mutable.LongMap(1L -> "one", 2L -> "two")
50100

@@ -80,4 +130,52 @@ class LongMapDeserializerTest extends DeserializerTest {
80130
read(0) shouldBe false
81131
read(402) shouldBe true
82132
}
133+
134+
it should "deserialize mutable LongMap (Object values)" in {
135+
val event = Event(UUID.randomUUID(), "event1")
136+
val map = mutable.LongMap(0L -> false, 1L -> "true", 2L -> event)
137+
val mapper = newMapper
138+
val json = mapper.writeValueAsString(map)
139+
val read = mapper.readValue(json, classOf[mutable.LongMap[Any]])
140+
read(0) shouldBe false
141+
read(1) shouldEqual "true"
142+
read(2) shouldEqual Map("id" -> event.id.toString, "description" -> event.description)
143+
}
144+
145+
it should "deserialize mutable LongMap (Object values, duplicate keys - default mode)" in {
146+
val mapper = newMapper
147+
val json = """{"1": 123, "2": 123, "2": 123.456}"""
148+
val read = mapper.readValue(json, classOf[mutable.LongMap[Any]])
149+
read(1) shouldEqual 123
150+
read(2) shouldEqual 123.456
151+
}
152+
153+
it should "deserialize mutable LongMap (Object values, duplicate keys - optional mode)" in {
154+
val mapper = newMapper
155+
val json = """{"1": 123, "2": 123, "2": 123.456}"""
156+
val parser = new WithDupsParser(mapper.createParser(json))
157+
val read = try {
158+
mapper.readValue(parser, classOf[mutable.LongMap[Any]])
159+
} finally {
160+
parser.close()
161+
}
162+
read(1) shouldEqual 123
163+
val expected = new java.util.ArrayList[Object]()
164+
expected.add(java.lang.Integer.valueOf(123))
165+
expected.add(java.lang.Double.valueOf(123.456))
166+
read(2) shouldEqual expected
167+
}
168+
169+
it should "deserialize mutable LongMap (Double values, duplicate key mode is ignored)" in {
170+
val mapper = newMapper
171+
val json = """{"1": "123", "2": "123", "2": "123.456"}"""
172+
val parser = new WithDupsParser(mapper.createParser(json))
173+
val read = try {
174+
mapper.readValue(parser, new TypeReference[mutable.LongMap[String]] {})
175+
} finally {
176+
parser.close()
177+
}
178+
read(1) shouldEqual "123"
179+
read(2) shouldEqual "123.456"
180+
}
83181
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.fasterxml.jackson.module.scala.deser
2+
3+
import com.fasterxml.jackson.core.{JsonParser, StreamReadCapability}
4+
import com.fasterxml.jackson.core.util.{JacksonFeatureSet, JsonParserDelegate}
5+
6+
class WithDupsParser(p: JsonParser) extends JsonParserDelegate(p) {
7+
override def getReadCapabilities: JacksonFeatureSet[StreamReadCapability] = {
8+
super.getReadCapabilities.`with`(StreamReadCapability.DUPLICATE_PROPERTIES)
9+
}
10+
}

0 commit comments

Comments
 (0)