Handle qualifiers, names, and transient in generated adapters
This commit is contained in:
parent
e0d84e1fee
commit
d555d24d94
4 changed files with 249 additions and 191 deletions
|
@ -27,6 +27,7 @@ import me.eugeniomarletti.kotlin.metadata.KotlinClassMetadata
|
|||
import me.eugeniomarletti.kotlin.metadata.KotlinMetadataUtils
|
||||
import me.eugeniomarletti.kotlin.metadata.classKind
|
||||
import me.eugeniomarletti.kotlin.metadata.declaresDefaultValue
|
||||
import me.eugeniomarletti.kotlin.metadata.getPropertyOrNull
|
||||
import me.eugeniomarletti.kotlin.metadata.isDataClass
|
||||
import me.eugeniomarletti.kotlin.metadata.isPrimary
|
||||
import me.eugeniomarletti.kotlin.metadata.jvm.getJvmConstructorSignature
|
||||
|
@ -34,6 +35,7 @@ import me.eugeniomarletti.kotlin.metadata.kotlinMetadata
|
|||
import me.eugeniomarletti.kotlin.metadata.visibility
|
||||
import me.eugeniomarletti.kotlin.processing.KotlinAbstractProcessor
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf.Property
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf.ValueParameter
|
||||
import java.io.File
|
||||
import javax.annotation.processing.Processor
|
||||
|
@ -43,6 +45,7 @@ import javax.lang.model.element.AnnotationMirror
|
|||
import javax.lang.model.element.Element
|
||||
import javax.lang.model.element.ElementKind
|
||||
import javax.lang.model.element.ExecutableElement
|
||||
import javax.lang.model.element.Modifier
|
||||
import javax.lang.model.element.TypeElement
|
||||
import javax.lang.model.element.VariableElement
|
||||
import javax.tools.Diagnostic.Kind.ERROR
|
||||
|
@ -127,6 +130,14 @@ class JsonClassCodeGenProcessor : KotlinAbstractProcessor(), KotlinMetadataUtils
|
|||
nameResolver.getString(it.name)
|
||||
}
|
||||
|
||||
// The compiler might emit methods just so it has a place to put annotations. Find these.
|
||||
val annotatedElements = mutableMapOf<Property, ExecutableElement>()
|
||||
for (enclosedElement in element.enclosedElements) {
|
||||
if (enclosedElement !is ExecutableElement) continue
|
||||
val property = classData.getPropertyOrNull(enclosedElement) ?: continue
|
||||
annotatedElements[property] = enclosedElement
|
||||
}
|
||||
|
||||
val propertyGenerators = mutableListOf<PropertyGenerator>()
|
||||
for (enclosedElement in element.enclosedElements) {
|
||||
if (enclosedElement !is VariableElement) continue
|
||||
|
@ -142,6 +153,8 @@ class JsonClassCodeGenProcessor : KotlinAbstractProcessor(), KotlinMetadataUtils
|
|||
null
|
||||
}
|
||||
|
||||
val annotatedElement = annotatedElements[property]
|
||||
|
||||
if (property.visibility != ProtoBuf.Visibility.INTERNAL
|
||||
&& property.visibility != ProtoBuf.Visibility.PROTECTED
|
||||
&& property.visibility != ProtoBuf.Visibility.PUBLIC) {
|
||||
|
@ -149,15 +162,24 @@ class JsonClassCodeGenProcessor : KotlinAbstractProcessor(), KotlinMetadataUtils
|
|||
return null
|
||||
}
|
||||
|
||||
val hasDefault = parameter?.declaresDefaultValue ?: true
|
||||
|
||||
if (enclosedElement.modifiers.contains(Modifier.TRANSIENT)) {
|
||||
if (!hasDefault) {
|
||||
throw IllegalArgumentException("No default value for transient property $name")
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
propertyGenerators += PropertyGenerator(
|
||||
name,
|
||||
serializedName(name, enclosedElement, parameterElement),
|
||||
jsonName(name, enclosedElement, annotatedElement, parameterElement),
|
||||
parameter != null,
|
||||
parameter?.declaresDefaultValue ?: true,
|
||||
hasDefault,
|
||||
property.returnType.nullable,
|
||||
property.returnType.asTypeName(nameResolver, classProto::getTypeParameter),
|
||||
property.returnType.asTypeName(nameResolver, classProto::getTypeParameter, true),
|
||||
jsonQualifiers(enclosedElement, parameterElement))
|
||||
jsonQualifiers(enclosedElement, annotatedElement, parameterElement))
|
||||
}
|
||||
|
||||
// Sort properties so that those with constructor parameters come first.
|
||||
|
@ -202,38 +224,39 @@ class JsonClassCodeGenProcessor : KotlinAbstractProcessor(), KotlinMetadataUtils
|
|||
/** Returns the JsonQualifiers on the field and parameter of a property. */
|
||||
private fun jsonQualifiers(
|
||||
field: VariableElement,
|
||||
method: ExecutableElement?,
|
||||
parameter: VariableElement?
|
||||
): Set<AnnotationMirror> {
|
||||
val fieldJsonQualifiers = AnnotationMirrors.getAnnotatedAnnotations(
|
||||
field, JsonQualifier::class.java)
|
||||
|
||||
val parameterJsonQualifiers: Set<AnnotationMirror> = if (parameter != null) {
|
||||
AnnotationMirrors.getAnnotatedAnnotations(parameter, JsonQualifier::class.java)
|
||||
} else {
|
||||
setOf()
|
||||
}
|
||||
val fieldQualifiers = field.qualifiers
|
||||
val methodQualifiers = method.qualifiers
|
||||
val parameterQualifiers = parameter.qualifiers
|
||||
|
||||
// TODO(jwilson): union the qualifiers somehow?
|
||||
if (fieldJsonQualifiers.isNotEmpty()) {
|
||||
return fieldJsonQualifiers
|
||||
} else {
|
||||
return parameterJsonQualifiers
|
||||
return when {
|
||||
fieldQualifiers.isNotEmpty() -> fieldQualifiers
|
||||
methodQualifiers.isNotEmpty() -> methodQualifiers
|
||||
parameterQualifiers.isNotEmpty() -> parameterQualifiers
|
||||
else -> setOf()
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the @Json name of a property, or `propertyName` if none is provided. */
|
||||
private fun serializedName(
|
||||
private fun jsonName(
|
||||
propertyName: String,
|
||||
field: VariableElement,
|
||||
method: ExecutableElement?,
|
||||
parameter: VariableElement?
|
||||
): String {
|
||||
val fieldAnnotation = field.getAnnotation(Json::class.java)
|
||||
if (fieldAnnotation != null) return fieldAnnotation.name
|
||||
val fieldJsonName = field.jsonName
|
||||
val methodJsonName = method.jsonName
|
||||
val parameterJsonName = parameter.jsonName
|
||||
|
||||
val parameterAnnotation = parameter?.getAnnotation(Json::class.java)
|
||||
if (parameterAnnotation != null) return parameterAnnotation.name
|
||||
|
||||
return propertyName
|
||||
return when {
|
||||
fieldJsonName != null -> fieldJsonName
|
||||
methodJsonName != null -> methodJsonName
|
||||
parameterJsonName != null -> parameterJsonName
|
||||
else -> propertyName
|
||||
}
|
||||
}
|
||||
|
||||
private fun errorMustBeKotlinClass(element: Element) {
|
||||
|
@ -255,5 +278,16 @@ class JsonClassCodeGenProcessor : KotlinAbstractProcessor(), KotlinMetadataUtils
|
|||
val file = filer.createSourceFile(adapterName).toUri().let(::File)
|
||||
return file.parentFile.also { file.delete() }
|
||||
}
|
||||
}
|
||||
|
||||
private val Element?.qualifiers: Set<AnnotationMirror>
|
||||
get() {
|
||||
if (this == null) return setOf()
|
||||
return AnnotationMirrors.getAnnotatedAnnotations(this, JsonQualifier::class.java)
|
||||
}
|
||||
|
||||
private val Element?.jsonName: String?
|
||||
get() {
|
||||
if (this == null) return null
|
||||
return getAnnotation(Json::class.java)?.name
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ internal class PropertyGenerator(
|
|||
|
||||
fun reserveDelegateNames(nameAllocator: NameAllocator) {
|
||||
val qualifierNames = jsonQualifiers.joinToString("") {
|
||||
"at${it.annotationType.asElement().simpleName.toString().capitalize()}"
|
||||
"At${it.annotationType.asElement().simpleName.toString().capitalize()}"
|
||||
}
|
||||
nameAllocator.newName("${unaliasedName.toVariableName()}${qualifierNames}Adapter",
|
||||
delegateKey())
|
||||
|
|
|
@ -16,9 +16,10 @@
|
|||
package com.squareup.moshi
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.assertj.core.api.Assertions.fail
|
||||
import org.intellij.lang.annotations.Language
|
||||
import org.junit.Assert.fail
|
||||
import org.junit.Test
|
||||
import java.util.Locale
|
||||
|
||||
class GeneratedAdaptersTest {
|
||||
|
||||
|
@ -353,6 +354,190 @@ class GeneratedAdaptersTest {
|
|||
|
||||
@JsonClass(generateAdapter = true)
|
||||
class ConstructorDefaultValues(var a: Int = -1, var b: Int = -2)
|
||||
|
||||
@Test fun requiredValueAbsent() {
|
||||
val moshi = Moshi.Builder().build()
|
||||
val jsonAdapter = moshi.adapter(RequiredValueAbsent::class.java)
|
||||
|
||||
try {
|
||||
jsonAdapter.fromJson("""{"a":4}""")
|
||||
fail()
|
||||
} catch(expected: JsonDataException) {
|
||||
assertThat(expected).hasMessage("Required property 'b' missing at \$")
|
||||
}
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
class RequiredValueAbsent(var a: Int = 3, var b: Int)
|
||||
|
||||
@Test fun nonNullConstructorParameterCalledWithNullFailsWithJsonDataException() {
|
||||
val moshi = Moshi.Builder().build()
|
||||
val jsonAdapter = moshi.adapter(HasNonNullConstructorParameter::class.java)
|
||||
|
||||
try {
|
||||
jsonAdapter.fromJson("{\"a\":null}")
|
||||
fail()
|
||||
} catch (expected: JsonDataException) {
|
||||
assertThat(expected).hasMessage("Required property 'a' missing at \$")
|
||||
}
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
class HasNonNullConstructorParameter(val a: String)
|
||||
|
||||
@Test fun explicitNull() {
|
||||
val moshi = Moshi.Builder().build()
|
||||
val jsonAdapter = moshi.adapter(ExplicitNull::class.java)
|
||||
|
||||
val encoded = ExplicitNull(null, 5)
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("""{"b":5}""")
|
||||
assertThat(jsonAdapter.serializeNulls().toJson(encoded)).isEqualTo("""{"a":null,"b":5}""")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("""{"a":null,"b":6}""")!!
|
||||
assertThat(decoded.a).isEqualTo(null)
|
||||
assertThat(decoded.b).isEqualTo(6)
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
class ExplicitNull(var a: Int?, var b: Int?)
|
||||
|
||||
@Test fun absentNull() {
|
||||
val moshi = Moshi.Builder().build()
|
||||
val jsonAdapter = moshi.adapter(AbsentNull::class.java)
|
||||
|
||||
val encoded = AbsentNull(null, 5)
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("""{"b":5}""")
|
||||
assertThat(jsonAdapter.serializeNulls().toJson(encoded)).isEqualTo("""{"a":null,"b":5}""")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("""{"b":6}""")!!
|
||||
assertThat(decoded.a).isNull()
|
||||
assertThat(decoded.b).isEqualTo(6)
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
class AbsentNull(var a: Int?, var b: Int?)
|
||||
|
||||
@Test fun constructorParameterWithQualifier() {
|
||||
val moshi = Moshi.Builder()
|
||||
.add(UppercaseJsonAdapter())
|
||||
.build()
|
||||
val jsonAdapter = moshi.adapter(ConstructorParameterWithQualifier::class.java)
|
||||
|
||||
val encoded = ConstructorParameterWithQualifier("Android", "Banana")
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("""{"a":"ANDROID","b":"Banana"}""")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("""{"a":"Android","b":"Banana"}""")!!
|
||||
assertThat(decoded.a).isEqualTo("android")
|
||||
assertThat(decoded.b).isEqualTo("Banana")
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
class ConstructorParameterWithQualifier(@Uppercase var a: String, var b: String)
|
||||
|
||||
@Test fun propertyWithQualifier() {
|
||||
val moshi = Moshi.Builder()
|
||||
.add(UppercaseJsonAdapter())
|
||||
.build()
|
||||
val jsonAdapter = moshi.adapter(PropertyWithQualifier::class.java)
|
||||
|
||||
val encoded = PropertyWithQualifier()
|
||||
encoded.a = "Android"
|
||||
encoded.b = "Banana"
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("""{"a":"ANDROID","b":"Banana"}""")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("""{"a":"Android","b":"Banana"}""")!!
|
||||
assertThat(decoded.a).isEqualTo("android")
|
||||
assertThat(decoded.b).isEqualTo("Banana")
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
class PropertyWithQualifier {
|
||||
@Uppercase var a: String = ""
|
||||
var b: String = ""
|
||||
}
|
||||
|
||||
@Test fun constructorParameterWithJsonName() {
|
||||
val moshi = Moshi.Builder().build()
|
||||
val jsonAdapter = moshi.adapter(ConstructorParameterWithJsonName::class.java)
|
||||
|
||||
val encoded = ConstructorParameterWithJsonName(3, 5)
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("""{"key a":3,"b":5}""")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("""{"key a":4,"b":6}""")!!
|
||||
assertThat(decoded.a).isEqualTo(4)
|
||||
assertThat(decoded.b).isEqualTo(6)
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
class ConstructorParameterWithJsonName(@Json(name = "key a") var a: Int, var b: Int)
|
||||
|
||||
@Test fun propertyWithJsonName() {
|
||||
val moshi = Moshi.Builder().build()
|
||||
val jsonAdapter = moshi.adapter(PropertyWithJsonName::class.java)
|
||||
|
||||
val encoded = PropertyWithJsonName()
|
||||
encoded.a = 3
|
||||
encoded.b = 5
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("""{"key a":3,"b":5}""")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("""{"key a":4,"b":6}""")!!
|
||||
assertThat(decoded.a).isEqualTo(4)
|
||||
assertThat(decoded.b).isEqualTo(6)
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
class PropertyWithJsonName {
|
||||
@Json(name = "key a") var a: Int = -1
|
||||
var b: Int = -1
|
||||
}
|
||||
|
||||
@Test fun transientConstructorParameter() {
|
||||
val moshi = Moshi.Builder().build()
|
||||
val jsonAdapter = moshi.adapter(TransientConstructorParameter::class.java)
|
||||
|
||||
val encoded = TransientConstructorParameter(3, 5)
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("""{"b":5}""")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("""{"a":4,"b":6}""")!!
|
||||
assertThat(decoded.a).isEqualTo(-1)
|
||||
assertThat(decoded.b).isEqualTo(6)
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
class TransientConstructorParameter(@Transient var a: Int = -1, var b: Int = -1)
|
||||
|
||||
@Test fun transientProperty() {
|
||||
val moshi = Moshi.Builder().build()
|
||||
val jsonAdapter = moshi.adapter(TransientProperty::class.java)
|
||||
|
||||
val encoded = TransientProperty()
|
||||
encoded.a = 3
|
||||
encoded.b = 5
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("""{"b":5}""")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("""{"a":4,"b":6}""")!!
|
||||
assertThat(decoded.a).isEqualTo(-1)
|
||||
assertThat(decoded.b).isEqualTo(6)
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
class TransientProperty {
|
||||
@Transient var a: Int = -1
|
||||
var b: Int = -1
|
||||
}
|
||||
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
@JsonQualifier
|
||||
annotation class Uppercase
|
||||
|
||||
class UppercaseJsonAdapter {
|
||||
@ToJson fun toJson(@Uppercase s: String) : String {
|
||||
return s.toUpperCase(Locale.US)
|
||||
}
|
||||
@FromJson @Uppercase fun fromJson(s: String) : String {
|
||||
return s.toLowerCase(Locale.US)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Has to be outside to avoid Types seeing an owning class
|
||||
|
|
|
@ -25,33 +25,19 @@ import java.util.SimpleTimeZone
|
|||
import kotlin.annotation.AnnotationRetention.RUNTIME
|
||||
|
||||
class KotlinCodeGenTest {
|
||||
@Ignore @Test fun requiredValueAbsent() {
|
||||
@Ignore @Test fun duplicatedValue() {
|
||||
val moshi = Moshi.Builder().build()
|
||||
val jsonAdapter = moshi.adapter(RequiredValueAbsent::class.java)
|
||||
val jsonAdapter = moshi.adapter(DuplicateValue::class.java)
|
||||
|
||||
try {
|
||||
jsonAdapter.fromJson("""{"a":4}""")
|
||||
jsonAdapter.fromJson("""{"a":4,"a":4}""")
|
||||
fail()
|
||||
} catch(expected: JsonDataException) {
|
||||
assertThat(expected).hasMessage("Required value b missing at $")
|
||||
assertThat(expected).hasMessage("Multiple values for a at $.a")
|
||||
}
|
||||
}
|
||||
|
||||
class RequiredValueAbsent(var a: Int = 3, var b: Int)
|
||||
|
||||
@Ignore @Test fun nonNullConstructorParameterCalledWithNullFailsWithJsonDataException() {
|
||||
val moshi = Moshi.Builder().build()
|
||||
val jsonAdapter = moshi.adapter(HasNonNullConstructorParameter::class.java)
|
||||
|
||||
try {
|
||||
jsonAdapter.fromJson("{\"a\":null}")
|
||||
fail()
|
||||
} catch (expected: JsonDataException) {
|
||||
assertThat(expected).hasMessage("Non-null value a was null at \$")
|
||||
}
|
||||
}
|
||||
|
||||
class HasNonNullConstructorParameter(val a: String)
|
||||
class DuplicateValue(var a: Int = -1, var b: Int = -2)
|
||||
|
||||
@Ignore @Test fun nonNullPropertySetToNullFailsWithJsonDataException() {
|
||||
val moshi = Moshi.Builder().build()
|
||||
|
@ -69,50 +55,6 @@ class KotlinCodeGenTest {
|
|||
var a: String = ""
|
||||
}
|
||||
|
||||
@Ignore @Test fun duplicatedValue() {
|
||||
val moshi = Moshi.Builder().build()
|
||||
val jsonAdapter = moshi.adapter(DuplicateValue::class.java)
|
||||
|
||||
try {
|
||||
jsonAdapter.fromJson("""{"a":4,"a":4}""")
|
||||
fail()
|
||||
} catch(expected: JsonDataException) {
|
||||
assertThat(expected).hasMessage("Multiple values for a at $.a")
|
||||
}
|
||||
}
|
||||
|
||||
class DuplicateValue(var a: Int = -1, var b: Int = -2)
|
||||
|
||||
@Ignore @Test fun explicitNull() {
|
||||
val moshi = Moshi.Builder().build()
|
||||
val jsonAdapter = moshi.adapter(ExplicitNull::class.java)
|
||||
|
||||
val encoded = ExplicitNull(null, 5)
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("""{"b":5}""")
|
||||
assertThat(jsonAdapter.serializeNulls().toJson(encoded)).isEqualTo("""{"a":null,"b":5}""")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("""{"a":null,"b":6}""")!!
|
||||
assertThat(decoded.a).isEqualTo(null)
|
||||
assertThat(decoded.b).isEqualTo(6)
|
||||
}
|
||||
|
||||
class ExplicitNull(var a: Int?, var b: Int?)
|
||||
|
||||
@Ignore @Test fun absentNull() {
|
||||
val moshi = Moshi.Builder().build()
|
||||
val jsonAdapter = moshi.adapter(AbsentNull::class.java)
|
||||
|
||||
val encoded = AbsentNull(null, 5)
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("""{"b":5}""")
|
||||
assertThat(jsonAdapter.serializeNulls().toJson(encoded)).isEqualTo("""{"a":null,"b":5}""")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("""{"b":6}""")!!
|
||||
assertThat(decoded.a).isNull()
|
||||
assertThat(decoded.b).isEqualTo(6)
|
||||
}
|
||||
|
||||
class AbsentNull(var a: Int?, var b: Int?)
|
||||
|
||||
@Ignore @Test fun repeatedValue() {
|
||||
val moshi = Moshi.Builder().build()
|
||||
val jsonAdapter = moshi.adapter(RepeatedValue::class.java)
|
||||
|
@ -127,90 +69,6 @@ class KotlinCodeGenTest {
|
|||
|
||||
class RepeatedValue(var a: Int, var b: Int?)
|
||||
|
||||
@Ignore @Test fun constructorParameterWithQualifier() {
|
||||
val moshi = Moshi.Builder()
|
||||
.add(UppercaseJsonAdapter())
|
||||
.build()
|
||||
val jsonAdapter = moshi.adapter(ConstructorParameterWithQualifier::class.java)
|
||||
|
||||
val encoded = ConstructorParameterWithQualifier("Android", "Banana")
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("""{"a":"ANDROID","b":"Banana"}""")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("""{"a":"Android","b":"Banana"}""")!!
|
||||
assertThat(decoded.a).isEqualTo("android")
|
||||
assertThat(decoded.b).isEqualTo("Banana")
|
||||
}
|
||||
|
||||
class ConstructorParameterWithQualifier(@Uppercase var a: String, var b: String)
|
||||
|
||||
@Ignore @Test fun propertyWithQualifier() {
|
||||
val moshi = Moshi.Builder()
|
||||
.add(UppercaseJsonAdapter())
|
||||
.build()
|
||||
val jsonAdapter = moshi.adapter(PropertyWithQualifier::class.java)
|
||||
|
||||
val encoded = PropertyWithQualifier()
|
||||
encoded.a = "Android"
|
||||
encoded.b = "Banana"
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("""{"a":"ANDROID","b":"Banana"}""")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("""{"a":"Android","b":"Banana"}""")!!
|
||||
assertThat(decoded.a).isEqualTo("android")
|
||||
assertThat(decoded.b).isEqualTo("Banana")
|
||||
}
|
||||
|
||||
class PropertyWithQualifier {
|
||||
@Uppercase var a: String = ""
|
||||
var b: String = ""
|
||||
}
|
||||
|
||||
@Ignore @Test fun constructorParameterWithJsonName() {
|
||||
val moshi = Moshi.Builder().build()
|
||||
val jsonAdapter = moshi.adapter(ConstructorParameterWithJsonName::class.java)
|
||||
|
||||
val encoded = ConstructorParameterWithJsonName(3, 5)
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("""{"key a":3,"b":5}""")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("""{"key a":4,"b":6}""")!!
|
||||
assertThat(decoded.a).isEqualTo(4)
|
||||
assertThat(decoded.b).isEqualTo(6)
|
||||
}
|
||||
|
||||
class ConstructorParameterWithJsonName(@Json(name = "key a") var a: Int, var b: Int)
|
||||
|
||||
@Ignore @Test fun propertyWithJsonName() {
|
||||
val moshi = Moshi.Builder().build()
|
||||
val jsonAdapter = moshi.adapter(PropertyWithJsonName::class.java)
|
||||
|
||||
val encoded = PropertyWithJsonName()
|
||||
encoded.a = 3
|
||||
encoded.b = 5
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("""{"key a":3,"b":5}""")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("""{"key a":4,"b":6}""")!!
|
||||
assertThat(decoded.a).isEqualTo(4)
|
||||
assertThat(decoded.b).isEqualTo(6)
|
||||
}
|
||||
|
||||
class PropertyWithJsonName {
|
||||
@Json(name = "key a") var a: Int = -1
|
||||
var b: Int = -1
|
||||
}
|
||||
|
||||
@Ignore @Test fun transientConstructorParameter() {
|
||||
val moshi = Moshi.Builder().build()
|
||||
val jsonAdapter = moshi.adapter(TransientConstructorParameter::class.java)
|
||||
|
||||
val encoded = TransientConstructorParameter(3, 5)
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("""{"b":5}""")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("""{"a":4,"b":6}""")!!
|
||||
assertThat(decoded.a).isEqualTo(-1)
|
||||
assertThat(decoded.b).isEqualTo(6)
|
||||
}
|
||||
|
||||
class TransientConstructorParameter(@Transient var a: Int = -1, var b: Int = -1)
|
||||
|
||||
@Ignore @Test fun requiredTransientConstructorParameterFails() {
|
||||
val moshi = Moshi.Builder().build()
|
||||
try {
|
||||
|
@ -225,25 +83,6 @@ class KotlinCodeGenTest {
|
|||
|
||||
class RequiredTransientConstructorParameter(@Transient var a: Int)
|
||||
|
||||
@Ignore @Test fun transientProperty() {
|
||||
val moshi = Moshi.Builder().build()
|
||||
val jsonAdapter = moshi.adapter(TransientProperty::class.java)
|
||||
|
||||
val encoded = TransientProperty()
|
||||
encoded.a = 3
|
||||
encoded.b = 5
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("""{"b":5}""")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("""{"a":4,"b":6}""")!!
|
||||
assertThat(decoded.a).isEqualTo(-1)
|
||||
assertThat(decoded.b).isEqualTo(6)
|
||||
}
|
||||
|
||||
class TransientProperty {
|
||||
@Transient var a: Int = -1
|
||||
var b: Int = -1
|
||||
}
|
||||
|
||||
@Ignore @Test fun supertypeConstructorParameters() {
|
||||
val moshi = Moshi.Builder().build()
|
||||
val jsonAdapter = moshi.adapter(SubtypeConstructorParameters::class.java)
|
||||
|
|
Loading…
Reference in a new issue