Correct error for duplicate JSON key for Kotlin. (#789)

Before, the KotlinJsonAdapter threw "java.lang.IndexOutOfBoundsException: Index: 0, Size: 0" on a duplicate key when the key matched a property that was not a constructor parameter.
This commit is contained in:
Eric Cochran 2019-02-15 11:18:50 -08:00 committed by GitHub
parent 126c8ea961
commit 13a40edf5b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 43 additions and 10 deletions

View file

@ -17,7 +17,6 @@ package com.squareup.moshi.kotlin.reflect
import com.squareup.moshi.Json import com.squareup.moshi.Json
import com.squareup.moshi.JsonAdapter import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.JsonClass
import com.squareup.moshi.JsonDataException import com.squareup.moshi.JsonDataException
import com.squareup.moshi.JsonReader import com.squareup.moshi.JsonReader
import com.squareup.moshi.JsonWriter import com.squareup.moshi.JsonWriter
@ -77,7 +76,7 @@ internal class KotlinJsonAdapter<T>(
if (values[index] !== ABSENT_VALUE) { if (values[index] !== ABSENT_VALUE) {
throw JsonDataException( throw JsonDataException(
"Multiple values for '${constructor.parameters[index].name}' at ${reader.path}") "Multiple values for '${binding.property.name}' at ${reader.path}")
} }
values[index] = binding.adapter.fromJson(reader) values[index] = binding.adapter.fromJson(reader)

View file

@ -818,20 +818,37 @@ class GeneratedAdaptersTest {
} }
/** Generated adapters don't track enough state to detect duplicated values. */ /** Generated adapters don't track enough state to detect duplicated values. */
@Ignore @Test fun duplicatedValue() { @Ignore @Test fun duplicatedValueParameter() {
val moshi = Moshi.Builder().build() val moshi = Moshi.Builder().build()
val jsonAdapter = moshi.adapter(DuplicateValue::class.java) val jsonAdapter = moshi.adapter(DuplicateValueParameter::class.java)
try { try {
jsonAdapter.fromJson("""{"a":4,"a":4}""") jsonAdapter.fromJson("""{"a":4,"a":4}""")
fail() fail()
} catch(expected: JsonDataException) { } catch(expected: JsonDataException) {
assertThat(expected).hasMessage("Multiple values for a at $.a") assertThat(expected).hasMessage("Multiple values for 'a' at $.a")
} }
} }
@JsonClass(generateAdapter = true) class DuplicateValueParameter(var a: Int = -1, var b: Int = -2)
class DuplicateValue(var a: Int = -1, var b: Int = -2)
/** Generated adapters don't track enough state to detect duplicated values. */
@Ignore @Test fun duplicatedValueProperty() {
val moshi = Moshi.Builder().build()
val jsonAdapter = moshi.adapter(DuplicateValueProperty::class.java)
try {
jsonAdapter.fromJson("""{"a":4,"a":4}""")
fail()
} catch(expected: JsonDataException) {
assertThat(expected).hasMessage("Multiple values for 'a' at $.a")
}
}
class DuplicateValueProperty {
var a: Int = -1
var b: Int = -2
}
@Test fun extensionProperty() { @Test fun extensionProperty() {
val moshi = Moshi.Builder().build() val moshi = Moshi.Builder().build()

View file

@ -205,9 +205,9 @@ class KotlinJsonAdapterTest {
var a: String = "" var a: String = ""
} }
@Test fun duplicatedValue() { @Test fun duplicatedValueParameter() {
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build() val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
val jsonAdapter = moshi.adapter(DuplicateValue::class.java) val jsonAdapter = moshi.adapter(DuplicateValueParameter::class.java)
try { try {
jsonAdapter.fromJson("""{"a":4,"a":4}""") jsonAdapter.fromJson("""{"a":4,"a":4}""")
@ -217,7 +217,24 @@ class KotlinJsonAdapterTest {
} }
} }
class DuplicateValue(var a: Int = -1, var b: Int = -2) class DuplicateValueParameter(var a: Int = -1, var b: Int = -2)
@Test fun duplicatedValueProperty() {
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
val jsonAdapter = moshi.adapter(DuplicateValueProperty::class.java)
try {
jsonAdapter.fromJson("""{"a":4,"a":4}""")
fail()
} catch(expected: JsonDataException) {
assertThat(expected).hasMessage("Multiple values for 'a' at $.a")
}
}
class DuplicateValueProperty {
var a: Int = -1
var b: Int = -2
}
@Test fun explicitNull() { @Test fun explicitNull() {
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build() val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()