Skip to content

Commit

Permalink
Merge pull request #878 from k163377/876
Browse files Browse the repository at this point in the history
Fix for #876
  • Loading branch information
k163377 authored Jan 5, 2025
2 parents 9d4ad6a + 4c0a067 commit f8921c1
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 2 deletions.
1 change: 1 addition & 0 deletions release-notes/CREDITS-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Contributors:
# 2.19.0 (not yet released)

WrongWrong (@k163377)
* #878: Fix for #876
* #868: Added test case for FAIL_ON_NULL_FOR_PRIMITIVES
* #866: Upgrade to JUnit5
* #861: Update Kotlin to 1.9.24
Expand Down
1 change: 1 addition & 0 deletions release-notes/VERSION-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Co-maintainers:

2.19.0 (not yet released)

#878: Fixed a problem where settings like `@JsonSetter(nulls = AS_EMPTY)` were not being applied when the input was `undefined`.
#869: By using Enum.entries in the acquisition of KotlinFeature.defaults, the initialization load was reduced, albeit slightly.
#861: Kotlin has been upgraded to 1.9.24.
#858: Minor performance improvement of findDefaultCreator in edge cases.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ internal class KotlinValueInstantiator(
paramType.isMarkedNullable -> null
// Primitive types always try to get from a buffer, considering several settings
jsonProp.type.isPrimitive -> buffer.getParameter(jsonProp)
// to get suitable "missing" value provided by deserializer
else -> valueDeserializer?.getAbsentValue(ctxt)
// to get suitable "missing" value provided by nullValueProvider
else -> jsonProp.nullValueProvider?.getAbsentValue(ctxt)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
package com.fasterxml.jackson.module.kotlin.test.github

import com.fasterxml.jackson.annotation.JsonSetter
import com.fasterxml.jackson.annotation.Nulls
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.Test
import kotlin.test.assertEquals

class GitHub876 {
data class WithAnnotationWithoutDefault(
@JsonSetter(nulls = Nulls.AS_EMPTY)
val list: List<String>,
@JsonSetter(nulls = Nulls.AS_EMPTY)
val map: Map<String, String>,
@JsonSetter(nulls = Nulls.AS_EMPTY)
val string: String
)

@Nested
inner class WithAnnotationWithoutDefaultTest {
val mapper = jacksonObjectMapper()

@Test
fun nullInput() {
val input = """{"list": null, "map": null, "string": null}"""
val expected = WithAnnotationWithoutDefault(emptyList(), emptyMap(), "")

val actual = mapper.readValue<WithAnnotationWithoutDefault>(input)

assertEquals(expected, actual)
}

@Test
fun undefinedInput() {
val input = """{}"""
val expected = WithAnnotationWithoutDefault(emptyList(), emptyMap(), "")

val actual = mapper.readValue<WithAnnotationWithoutDefault>(input)

assertEquals(expected, actual)
}
}

data class WithAnnotationWithDefault(
@JsonSetter(nulls = Nulls.AS_EMPTY)
val list: List<String> = listOf("default"),
@JsonSetter(nulls = Nulls.AS_EMPTY)
val map: Map<String, String> = mapOf("default" to "default"),
@JsonSetter(nulls = Nulls.AS_EMPTY)
val string: String = "default"
)

@Nested
inner class WithAnnotationWithDefaultTest {
val mapper = jacksonObjectMapper()

@Test
fun nullInput() {
// If null is explicitly specified, the default value is not used
val input = """{"list": null, "map": null, "string": null}"""
val expected = WithAnnotationWithDefault(emptyList(), emptyMap(), "")

val actual = mapper.readValue<WithAnnotationWithDefault>(input)

assertEquals(expected, actual)
}

@Test
fun undefinedInput() {
// If the input is undefined, the default value is used
val input = """{}"""
val expected = WithAnnotationWithDefault()

val actual = mapper.readValue<WithAnnotationWithDefault>(input)

assertEquals(expected, actual)
}
}

// If it is set by configOverride, it is treated in the same way as if it were set by annotation
data class WithoutAnnotationWithoutDefault(
val list: List<String>,
val map: Map<String, String>,
val string: String
)

@Nested
inner class WithoutAnnotationWithoutDefaultTest {
val mapper = jacksonObjectMapper().apply {
configOverride(List::class.java).setterInfo = JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY)
configOverride(Map::class.java).setterInfo = JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY)
configOverride(String::class.java).setterInfo = JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY)
}

@Test
fun nullInput() {
val input = """{"list": null, "map": null, "string": null}"""
val expected = WithoutAnnotationWithoutDefault(emptyList(), emptyMap(), "")

val actual = mapper.readValue<WithoutAnnotationWithoutDefault>(input)

assertEquals(expected, actual)
}

@Test
fun undefinedInput() {
val input = """{}"""
val expected = WithoutAnnotationWithoutDefault(emptyList(), emptyMap(), "")

val actual = mapper.readValue<WithoutAnnotationWithoutDefault>(input)

assertEquals(expected, actual)
}
}

data class WithoutAnnotationWithDefault(
val list: List<String> = listOf("default"),
val map: Map<String, String> = mapOf("default" to "default"),
val string: String = "default"
)

@Nested
inner class WithoutAnnotationWithDefaultTest {
val mapper = jacksonObjectMapper().apply {
configOverride(List::class.java).setterInfo = JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY)
configOverride(Map::class.java).setterInfo = JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY)
configOverride(String::class.java).setterInfo = JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY)
}

@Test
fun nullInput() {
val input = """{"list": null, "map": null, "string": null}"""
val expected = WithoutAnnotationWithDefault(emptyList(), emptyMap(), "")

val actual = mapper.readValue<WithoutAnnotationWithDefault>(input)

assertEquals(expected, actual)
}

@Test
fun undefinedInput() {
val input = """{}"""
val expected = WithoutAnnotationWithDefault()

val actual = mapper.readValue<WithoutAnnotationWithDefault>(input)

assertEquals(expected, actual)
}
}
}

0 comments on commit f8921c1

Please sign in to comment.