mirror of
https://github.com/fankes/moshi.git
synced 2025-10-20 00:19:21 +08:00
Kotlin Code Gen module (#435)
* Add kotlin code gen modules * Update kotlin to 1.2 * Add a serializable dummy class * Try using kapt configuration from kotlin-examples repo Still no luck! * Use proper allocated name for assignment too * Use selectName() API * Clean up constructor parameter annotations & plumbing for qualifiers * Updates poms and kotlin code gen processor to support tests. * Ignore kotlin code gen tests for now None of these are data classes tests right now, which is the only thing this supports right now * Replace $ with _ in class names for consistency * Shortcut Array types to arrayOf * Add DataClassTest * Try generated option first, fall back to maven after * More idiomatic handling * Only use nonnullable types for adapter properties * Code dump of kotshi tests * Comment out specifics to get compiling * Generics support! * Fix double primitive default * Pick up temporary snapshot for Any fix * Invariance should just be null * Better handling of nullably-bound variance * Just assume the first jvm constructor for now as jvmMethodSig is flaky * Specify types param if needed * Don't do lazy delegation * Clean up nullable typevariablename boundaries * Add type variables to extension function on companion object * Use properties instead of allocated names for more robustness Since we're already on a snapshot * If there are no type variables, make it null for simpler handling * Fix generics and Type[] handling * Fix unnecessary as casts on primitive defaults * Reference spec directly for possible bangs * Use nullSafe() adapters for anything nullable or with default values * Use object type in makeType() Types.java cares * Make TestPrimitiveDefaultValues work * Re-enable TestClassWithJavaKeyword * Ignore remaining tests that are pending decisions or JsonQualifier support * Remove customnames test as we're just going to stick with simple @Json * Add toString() implementations * Reenable default values testing, adapt to kotlin lang support * Remove primitive adapters bits since we're not using it * Clean up a bunch of leftover comments * Switch to only nullable handling, report missing properties This makes all nullable handling for local properties the same, and removes defaults for primitives in the process. It simplifies the handling a lot, and leans on kotlin language features to take care of null handling (null checking and then throwing the lazily evaluated list of missing properties). One minor change from what kotshi does - this reports the serialized name in the missing properties, not the property name. We could look at supporting this though if we want. * Implement JsonQualifier support * Use Kapt for AutoService/processor declaration * Checkstyle * Remove unused primite type checks * Add test verifying mutable and immutable collections work * Fix test name * Standardize isRequired checks * Add more nullability and mutability tests * Kotlinpoet 0.7.0 final * Switch to new vararg overload for annotation class adapter() * Make suffix just JsonAdapter without underscore * Switch to just a regular constructor for MoshiSerializableFactory * Remove constructor caching * Remove unnecessary framework class checks * Nix unnecessary superclass lookups, inline constructor lookup * Nix null token check in reads * Nix null check in writes, do !! on first value use * Nix null checks in favor of serializeNulls * Inline null checks and fail eagerly * Fix double _Adapter * First pass at simplifying adapter names * Inline names to options property, life into class and rm companion * Differentiate between absent and null, use nullSafe() as needed * Group together compile and test dependencies * Remove incorrect comment * Revert formatting * Set, not mutable set * Collapse else-if nesting to one when * Cleaner formatting test code * Collapse more to locals * Collapse more * Return a nonnullable type in fromJson * Remove redundant out variance * Use KClass where appropriate * End comment in period * Remove redundant comment * Throw on unrecognized type in simplified name * Use illegalargumentexception instead * Emit a nullcheck at the beginning of toJson instead * Remove extra newline * Simplify processing to be less abusive * Skip using asClassName() when possible * Use addComment() * Switch to declared constructors Technically more correct since we're defining these * Unmodifiable set * return adapter(type, annotationTypes[0]) * Slight optimization - check if the type is parameterized first If the type is a parameterized type, then we know they'll have the two-arg constructor. This way we don't always try and fail the single arg constructor on parameterized types * Add test for type aliases, optimize to reuse adapters if possible This is a tiny optimization to make type aliases (which did already work) reuse adapter properties if they already exist for the backing type. What this means is that if you have: typealias Foo = String and properties foo: Foo bar: String you'll only get one adapter property field for String, and both will use it * Use string templating where possible * Remove all the kotshi tests
This commit is contained in:
153
kotlin-codegen/integration-test/pom.xml
Normal file
153
kotlin-codegen/integration-test/pom.xml
Normal file
@@ -0,0 +1,153 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.squareup.moshi</groupId>
|
||||
<artifactId>moshi-parent</artifactId>
|
||||
<version>1.6.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>moshi-kotlin-codegen-integration</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.squareup.moshi</groupId>
|
||||
<artifactId>moshi</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.moshi</groupId>
|
||||
<artifactId>moshi-kotlin-codegen-runtime</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-reflect</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<version>${kotlin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>kapt</id>
|
||||
<goals>
|
||||
<goal>kapt</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sourceDirs>
|
||||
<sourceDir>src/main/kotlin</sourceDir>
|
||||
<sourceDir>src/main/java</sourceDir>
|
||||
</sourceDirs>
|
||||
<annotationProcessorPaths>
|
||||
<annotationProcessorPath>
|
||||
<groupId>com.squareup.moshi</groupId>
|
||||
<artifactId>moshi-kotlin-codegen-compiler</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</annotationProcessorPath>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>compile</id>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sourceDirs>
|
||||
<sourceDir>src/main/kotlin</sourceDir>
|
||||
<sourceDir>src/main/java</sourceDir>
|
||||
</sourceDirs>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>test-kapt</id>
|
||||
<goals>
|
||||
<goal>test-kapt</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sourceDirs>
|
||||
<sourceDir>src/test/kotlin</sourceDir>
|
||||
<sourceDir>src/test/java</sourceDir>
|
||||
</sourceDirs>
|
||||
<annotationProcessorPaths>
|
||||
<annotationProcessorPath>
|
||||
<groupId>com.squareup.moshi</groupId>
|
||||
<artifactId>moshi-kotlin-codegen-compiler</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</annotationProcessorPath>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>test-compile</id>
|
||||
<goals>
|
||||
<goal>test-compile</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sourceDirs>
|
||||
<sourceDir>src/test/kotlin</sourceDir>
|
||||
<sourceDir>src/test/java</sourceDir>
|
||||
<sourceDir>target/generated-sources/kapt/test</sourceDir>
|
||||
</sourceDirs>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.5.1</version>
|
||||
<configuration>
|
||||
<proc>none</proc>
|
||||
<source>1.6</source>
|
||||
<target>1.6</target>
|
||||
</configuration>
|
||||
<executions>
|
||||
<!-- Replacing default-compile as it is treated specially by maven -->
|
||||
<execution>
|
||||
<id>default-compile</id>
|
||||
<phase>none</phase>
|
||||
</execution>
|
||||
<!-- Replacing default-testCompile as it is treated specially by maven -->
|
||||
<execution>
|
||||
<id>default-testCompile</id>
|
||||
<phase>none</phase>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>java-compile</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>java-test-compile</id>
|
||||
<phase>test-compile</phase>
|
||||
<goals> <goal>testCompile</goal> </goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
@@ -0,0 +1,280 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Square, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
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.Test
|
||||
|
||||
class DataClassesTest {
|
||||
|
||||
private val moshi = Moshi.Builder().add(MoshiSerializableFactory()).build()
|
||||
|
||||
@Test
|
||||
fun jsonAnnotation() {
|
||||
val adapter = moshi.adapter(JsonAnnotation::class.java)
|
||||
|
||||
// Read
|
||||
@Language("JSON")
|
||||
val json = """{"foo": "bar"}"""
|
||||
|
||||
val instance = adapter.fromJson(json)!!
|
||||
assertThat(instance.bar).isEqualTo("bar")
|
||||
|
||||
// Write
|
||||
@Language("JSON")
|
||||
val expectedJson = """{"foo":"baz"}"""
|
||||
|
||||
assertThat(adapter.toJson(JsonAnnotation("baz"))).isEqualTo(expectedJson)
|
||||
}
|
||||
|
||||
@MoshiSerializable
|
||||
data class JsonAnnotation(@Json(name = "foo") val bar: String)
|
||||
|
||||
@Test
|
||||
fun defaultValues() {
|
||||
val adapter = moshi.adapter(DefaultValues::class.java)
|
||||
|
||||
// Read/write with default values
|
||||
@Language("JSON")
|
||||
val json = """{"foo":"fooString"}"""
|
||||
|
||||
val instance = adapter.fromJson(json)!!
|
||||
assertThat(instance.foo).isEqualTo("fooString")
|
||||
assertThat(instance.bar).isEqualTo("")
|
||||
assertThat(instance.nullableBar).isNull()
|
||||
assertThat(instance.bazList).apply {
|
||||
isNotNull()
|
||||
isEmpty()
|
||||
}
|
||||
|
||||
@Language("JSON") val expected = """{"foo":"fooString","bar":"","bazList":[]}"""
|
||||
assertThat(adapter.toJson(DefaultValues("fooString"))).isEqualTo(expected)
|
||||
|
||||
// Read/write with real values
|
||||
@Language("JSON")
|
||||
val json2 = """
|
||||
{"foo":"fooString","bar":"barString","nullableBar":"bar","bazList":["baz"]}
|
||||
""".trimIndent()
|
||||
|
||||
val instance2 = adapter.fromJson(json2)!!
|
||||
assertThat(instance2.foo).isEqualTo("fooString")
|
||||
assertThat(instance2.bar).isEqualTo("barString")
|
||||
assertThat(instance2.nullableBar).isEqualTo("bar")
|
||||
assertThat(instance2.bazList).containsExactly("baz")
|
||||
assertThat(adapter.toJson(instance2)).isEqualTo(json2)
|
||||
}
|
||||
|
||||
@MoshiSerializable
|
||||
data class DefaultValues(val foo: String,
|
||||
val bar: String = "",
|
||||
val nullableBar: String? = null,
|
||||
val bazList: List<String> = emptyList())
|
||||
|
||||
@Test
|
||||
fun nullableArray() {
|
||||
val adapter = moshi.adapter(NullableArray::class.java)
|
||||
|
||||
@Language("JSON")
|
||||
val json = """{"data":[null,"why"]}"""
|
||||
|
||||
val instance = adapter.fromJson(json)!!
|
||||
assertThat(instance.data).containsExactly(null, "why")
|
||||
assertThat(adapter.toJson(instance)).isEqualTo(json)
|
||||
}
|
||||
|
||||
@MoshiSerializable
|
||||
data class NullableArray(val data: Array<String?>)
|
||||
|
||||
@Test
|
||||
fun primitiveArray() {
|
||||
val adapter = moshi.adapter(PrimitiveArray::class.java)
|
||||
|
||||
@Language("JSON")
|
||||
val json = """{"ints":[0,1]}"""
|
||||
|
||||
val instance = adapter.fromJson(json)!!
|
||||
assertThat(instance.ints).containsExactly(0, 1)
|
||||
assertThat(adapter.toJson(instance)).isEqualTo(json)
|
||||
}
|
||||
|
||||
@MoshiSerializable
|
||||
data class PrimitiveArray(val ints: IntArray)
|
||||
|
||||
@Test
|
||||
fun nullableTypes() {
|
||||
val adapter = moshi.adapter(NullabeTypes::class.java)
|
||||
|
||||
@Language("JSON")
|
||||
val json = """{"foo":"foo","nullableString":null}"""
|
||||
@Language("JSON")
|
||||
val invalidJson = """{"foo":null,"nullableString":null}"""
|
||||
|
||||
val instance = adapter.fromJson(json)!!
|
||||
assertThat(instance.foo).isEqualTo("foo")
|
||||
assertThat(instance.nullableString).isNull()
|
||||
|
||||
try {
|
||||
adapter.fromJson(invalidJson)
|
||||
fail("The invalid json should have failed!")
|
||||
} catch (e: JsonDataException) {
|
||||
assertThat(e).hasMessageContaining("foo")
|
||||
}
|
||||
}
|
||||
|
||||
@MoshiSerializable
|
||||
data class NullabeTypes(
|
||||
val foo: String,
|
||||
val nullableString: String?
|
||||
)
|
||||
|
||||
@Test
|
||||
fun collections() {
|
||||
val adapter = moshi.adapter(SpecialCollections::class.java)
|
||||
|
||||
val specialCollections = SpecialCollections(
|
||||
mutableListOf(),
|
||||
mutableSetOf(),
|
||||
mutableMapOf(),
|
||||
emptyList(),
|
||||
emptySet(),
|
||||
emptyMap()
|
||||
)
|
||||
|
||||
val json = adapter.toJson(specialCollections)
|
||||
val newCollections = adapter.fromJson(json)
|
||||
assertThat(newCollections).isEqualTo(specialCollections)
|
||||
}
|
||||
|
||||
@MoshiSerializable
|
||||
data class SpecialCollections(
|
||||
val mutableList: MutableList<String>,
|
||||
val mutableSet: MutableSet<String>,
|
||||
val mutableMap: MutableMap<String, String>,
|
||||
val immutableList: List<String>,
|
||||
val immutableSet: Set<String>,
|
||||
val immutableMap: Map<String, String>
|
||||
)
|
||||
|
||||
@Test
|
||||
fun mutableProperties() {
|
||||
val adapter = moshi.adapter(MutableProperties::class.java)
|
||||
|
||||
val mutableProperties = MutableProperties(
|
||||
"immutableProperty",
|
||||
"mutableProperty",
|
||||
mutableListOf("immutableMutableList"),
|
||||
mutableListOf("immutableImmutableList"),
|
||||
mutableListOf("mutableMutableList"),
|
||||
mutableListOf("mutableImmutableList"),
|
||||
"immutableProperty",
|
||||
"mutableProperty",
|
||||
mutableListOf("immutableMutableList"),
|
||||
mutableListOf("immutableImmutableList"),
|
||||
mutableListOf("mutableMutableList"),
|
||||
mutableListOf("mutableImmutableList")
|
||||
)
|
||||
|
||||
val json = adapter.toJson(mutableProperties)
|
||||
val newMutableProperties = adapter.fromJson(json)
|
||||
assertThat(newMutableProperties).isEqualTo(mutableProperties)
|
||||
}
|
||||
|
||||
@MoshiSerializable
|
||||
data class MutableProperties(
|
||||
val immutableProperty: String,
|
||||
var mutableProperty: String,
|
||||
val immutableMutableList: MutableList<String>,
|
||||
val immutableImmutableList: List<String>,
|
||||
var mutableMutableList: MutableList<String>,
|
||||
var mutableImmutableList: List<String>,
|
||||
val nullableImmutableProperty: String?,
|
||||
var nullableMutableProperty: String?,
|
||||
val nullableImmutableMutableList: MutableList<String>?,
|
||||
val nullableImmutableImmutableList: List<String>?,
|
||||
var nullableMutableMutableList: MutableList<String>?,
|
||||
var nullableMutableImmutableList: List<String>
|
||||
)
|
||||
|
||||
@Test
|
||||
fun nullableTypeParams() {
|
||||
val adapter = moshi.adapter<NullableTypeParams<Int>>(
|
||||
Types.newParameterizedType(NullableTypeParams::class.java, Int::class.javaObjectType))
|
||||
val nullSerializing = adapter.serializeNulls()
|
||||
|
||||
val nullableTypeParams = NullableTypeParams<Int>(
|
||||
listOf("foo", null, "bar"),
|
||||
setOf("foo", null, "bar"),
|
||||
mapOf("foo" to "bar", "baz" to null),
|
||||
null
|
||||
)
|
||||
|
||||
val noNullsTypeParams = NullableTypeParams<Int>(
|
||||
nullableTypeParams.nullableList,
|
||||
nullableTypeParams.nullableSet,
|
||||
nullableTypeParams.nullableMap.filterValues { it != null },
|
||||
null
|
||||
)
|
||||
|
||||
val json = adapter.toJson(nullableTypeParams)
|
||||
val newNullableTypeParams = adapter.fromJson(json)
|
||||
assertThat(newNullableTypeParams).isEqualTo(noNullsTypeParams)
|
||||
|
||||
val nullSerializedJson = nullSerializing.toJson(nullableTypeParams)
|
||||
val nullSerializedNullableTypeParams = adapter.fromJson(nullSerializedJson)
|
||||
assertThat(nullSerializedNullableTypeParams).isEqualTo(nullableTypeParams)
|
||||
}
|
||||
}
|
||||
|
||||
// Has to be outside to avoid Types seeing an owning class
|
||||
@MoshiSerializable
|
||||
data class NullableTypeParams<T>(
|
||||
val nullableList: List<String?>,
|
||||
val nullableSet: Set<String?>,
|
||||
val nullableMap: Map<String, String?>,
|
||||
val nullableT: T?
|
||||
)
|
||||
|
||||
typealias TypeAliasName = String
|
||||
|
||||
/**
|
||||
* This is here mostly just to ensure it still compiles. Covers variance, @Json, default values,
|
||||
* nullability, primitive arrays, and some wacky generics.
|
||||
*/
|
||||
@MoshiSerializable
|
||||
data class SmokeTestType(
|
||||
@Json(name = "first_name") val firstName: String,
|
||||
@Json(name = "last_name") val lastName: String,
|
||||
val age: Int,
|
||||
val nationalities: List<String> = emptyList(),
|
||||
val weight: Float,
|
||||
val tattoos: Boolean = false,
|
||||
val race: String?,
|
||||
val hasChildren: Boolean = false,
|
||||
val favoriteFood: String? = null,
|
||||
val favoriteDrink: String? = "Water",
|
||||
val wildcardOut: List<out String> = emptyList(),
|
||||
val wildcardIn: Array<in String>,
|
||||
val any: List<*>,
|
||||
val anyTwo: List<Any>,
|
||||
val anyOut: List<out Any>,
|
||||
val favoriteThreeNumbers: IntArray,
|
||||
val favoriteArrayValues: Array<String>,
|
||||
val favoriteNullableArrayValues: Array<String?>,
|
||||
val nullableSetListMapArrayNullableIntWithDefault: Set<List<Map<String, Array<IntArray?>>>>? = null,
|
||||
val aliasedName: TypeAliasName = "Woah"
|
||||
)
|
@@ -0,0 +1,760 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Square, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.squareup.moshi
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.Assert.fail
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.util.Locale
|
||||
import java.util.SimpleTimeZone
|
||||
import kotlin.annotation.AnnotationRetention.RUNTIME
|
||||
|
||||
class KotlinCodeGenTest {
|
||||
@Ignore @Test fun constructorParameters() {
|
||||
val moshi = Moshi.Builder().add(MoshiSerializableFactory()).build()
|
||||
val jsonAdapter = moshi.adapter(ConstructorParameters::class.java)
|
||||
|
||||
val encoded = ConstructorParameters(3, 5)
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("""{"a":3,"b":5}""")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("""{"a":4,"b":6}""")!!
|
||||
assertThat(decoded.a).isEqualTo(4)
|
||||
assertThat(decoded.b).isEqualTo(6)
|
||||
}
|
||||
|
||||
class ConstructorParameters(var a: Int, var b: Int)
|
||||
|
||||
@Ignore @Test fun properties() {
|
||||
|
||||
val moshi = Moshi.Builder().add(MoshiSerializableFactory()).build()
|
||||
val jsonAdapter = moshi.adapter(Properties::class.java)
|
||||
|
||||
val encoded = Properties()
|
||||
encoded.a = 3
|
||||
encoded.b = 5
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("""{"a":3,"b":5}""")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("""{"a":3,"b":5}""")!!
|
||||
assertThat(decoded.a).isEqualTo(3)
|
||||
assertThat(decoded.b).isEqualTo(5)
|
||||
}
|
||||
|
||||
class Properties {
|
||||
var a: Int = -1
|
||||
var b: Int = -1
|
||||
}
|
||||
|
||||
@Ignore @Test fun constructorParametersAndProperties() {
|
||||
val moshi = Moshi.Builder().add(MoshiSerializableFactory()).build()
|
||||
val jsonAdapter = moshi.adapter(ConstructorParametersAndProperties::class.java)
|
||||
|
||||
val encoded = ConstructorParametersAndProperties(3)
|
||||
encoded.b = 5
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("""{"a":3,"b":5}""")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("""{"a":4,"b":6}""")!!
|
||||
assertThat(decoded.a).isEqualTo(4)
|
||||
assertThat(decoded.b).isEqualTo(6)
|
||||
}
|
||||
|
||||
class ConstructorParametersAndProperties(var a: Int) {
|
||||
var b: Int = -1
|
||||
}
|
||||
|
||||
@Ignore @Test fun immutableConstructorParameters() {
|
||||
val moshi = Moshi.Builder().add(MoshiSerializableFactory()).build()
|
||||
val jsonAdapter = moshi.adapter(ImmutableConstructorParameters::class.java)
|
||||
|
||||
val encoded = ImmutableConstructorParameters(3, 5)
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("""{"a":3,"b":5}""")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("""{"a":4,"b":6}""")!!
|
||||
assertThat(decoded.a).isEqualTo(4)
|
||||
assertThat(decoded.b).isEqualTo(6)
|
||||
}
|
||||
|
||||
class ImmutableConstructorParameters(val a: Int, val b: Int)
|
||||
|
||||
@Ignore @Test fun immutableProperties() {
|
||||
val moshi = Moshi.Builder().add(MoshiSerializableFactory()).build()
|
||||
val jsonAdapter = moshi.adapter(ImmutableProperties::class.java)
|
||||
|
||||
val encoded = ImmutableProperties(3, 5)
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("""{"a":3,"b":5}""")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("""{"a":3,"b":5}""")!!
|
||||
assertThat(decoded.a).isEqualTo(3)
|
||||
assertThat(decoded.b).isEqualTo(5)
|
||||
}
|
||||
|
||||
class ImmutableProperties(a: Int, b: Int) {
|
||||
val a = a
|
||||
val b = b
|
||||
}
|
||||
|
||||
@Ignore @Test fun constructorDefaults() {
|
||||
val moshi = Moshi.Builder().add(MoshiSerializableFactory()).build()
|
||||
val jsonAdapter = moshi.adapter(ConstructorDefaultValues::class.java)
|
||||
|
||||
val encoded = ConstructorDefaultValues(3, 5)
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("""{"a":3,"b":5}""")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("""{"b":6}""")!!
|
||||
assertThat(decoded.a).isEqualTo(-1)
|
||||
assertThat(decoded.b).isEqualTo(6)
|
||||
}
|
||||
|
||||
class ConstructorDefaultValues(var a: Int = -1, var b: Int = -2)
|
||||
|
||||
@Ignore @Test fun requiredValueAbsent() {
|
||||
val moshi = Moshi.Builder().add(MoshiSerializableFactory()).build()
|
||||
val jsonAdapter = moshi.adapter(RequiredValueAbsent::class.java)
|
||||
|
||||
try {
|
||||
jsonAdapter.fromJson("""{"a":4}""")
|
||||
fail()
|
||||
} catch(expected: JsonDataException) {
|
||||
assertThat(expected).hasMessage("Required value b missing at $")
|
||||
}
|
||||
}
|
||||
|
||||
class RequiredValueAbsent(var a: Int = 3, var b: Int)
|
||||
|
||||
@Ignore @Test fun nonNullConstructorParameterCalledWithNullFailsWithJsonDataException() {
|
||||
val moshi = Moshi.Builder().add(MoshiSerializableFactory()).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)
|
||||
|
||||
@Ignore @Test fun nonNullPropertySetToNullFailsWithJsonDataException() {
|
||||
val moshi = Moshi.Builder().add(MoshiSerializableFactory()).build()
|
||||
val jsonAdapter = moshi.adapter(HasNonNullProperty::class.java)
|
||||
|
||||
try {
|
||||
jsonAdapter.fromJson("{\"a\":null}")
|
||||
fail()
|
||||
} catch (expected: JsonDataException) {
|
||||
assertThat(expected).hasMessage("Non-null value a was null at \$")
|
||||
}
|
||||
}
|
||||
|
||||
class HasNonNullProperty {
|
||||
var a: String = ""
|
||||
}
|
||||
|
||||
@Ignore @Test fun duplicatedValue() {
|
||||
val moshi = Moshi.Builder().add(MoshiSerializableFactory()).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().add(MoshiSerializableFactory()).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().add(MoshiSerializableFactory()).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().add(MoshiSerializableFactory()).build()
|
||||
val jsonAdapter = moshi.adapter(RepeatedValue::class.java)
|
||||
|
||||
try {
|
||||
jsonAdapter.fromJson("""{"a":4,"b":null,"b":6}""")
|
||||
fail()
|
||||
} catch(expected: JsonDataException) {
|
||||
assertThat(expected).hasMessage("Multiple values for b at $.b")
|
||||
}
|
||||
}
|
||||
|
||||
class RepeatedValue(var a: Int, var b: Int?)
|
||||
|
||||
@Ignore @Test fun constructorParameterWithQualifier() {
|
||||
val moshi = Moshi.Builder()
|
||||
.add(MoshiSerializableFactory())
|
||||
.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(MoshiSerializableFactory())
|
||||
.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().add(MoshiSerializableFactory()).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().add(MoshiSerializableFactory()).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().add(MoshiSerializableFactory()).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().add(MoshiSerializableFactory()).build()
|
||||
try {
|
||||
moshi.adapter(RequiredTransientConstructorParameter::class.java)
|
||||
fail()
|
||||
} catch (expected: IllegalArgumentException) {
|
||||
assertThat(expected).hasMessage("No default value for transient constructor parameter #0 " +
|
||||
"a of fun <init>(kotlin.Int): " +
|
||||
"com.squareup.moshi.KotlinJsonAdapterTest.RequiredTransientConstructorParameter")
|
||||
}
|
||||
}
|
||||
|
||||
class RequiredTransientConstructorParameter(@Transient var a: Int)
|
||||
|
||||
@Ignore @Test fun transientProperty() {
|
||||
val moshi = Moshi.Builder().add(MoshiSerializableFactory()).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().add(MoshiSerializableFactory()).build()
|
||||
val jsonAdapter = moshi.adapter(SubtypeConstructorParameters::class.java)
|
||||
|
||||
val encoded = SubtypeConstructorParameters(3, 5)
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("""{"a":3,"b":5}""")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("""{"a":4,"b":6}""")!!
|
||||
assertThat(decoded.a).isEqualTo(4)
|
||||
assertThat(decoded.b).isEqualTo(6)
|
||||
}
|
||||
|
||||
open class SupertypeConstructorParameters(var a: Int)
|
||||
|
||||
class SubtypeConstructorParameters(a: Int, var b: Int) : SupertypeConstructorParameters(a)
|
||||
|
||||
@Ignore @Test fun supertypeProperties() {
|
||||
val moshi = Moshi.Builder().add(MoshiSerializableFactory()).build()
|
||||
val jsonAdapter = moshi.adapter(SubtypeProperties::class.java)
|
||||
|
||||
val encoded = SubtypeProperties()
|
||||
encoded.a = 3
|
||||
encoded.b = 5
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("""{"b":5,"a":3}""")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("""{"a":4,"b":6}""")!!
|
||||
assertThat(decoded.a).isEqualTo(4)
|
||||
assertThat(decoded.b).isEqualTo(6)
|
||||
}
|
||||
|
||||
open class SupertypeProperties {
|
||||
var a: Int = -1
|
||||
}
|
||||
|
||||
class SubtypeProperties : SupertypeProperties() {
|
||||
var b: Int = -1
|
||||
}
|
||||
|
||||
@Ignore @Test fun extendsPlatformClassWithPrivateField() {
|
||||
val moshi = Moshi.Builder().add(MoshiSerializableFactory()).build()
|
||||
val jsonAdapter = moshi.adapter(ExtendsPlatformClassWithPrivateField::class.java)
|
||||
|
||||
val encoded = ExtendsPlatformClassWithPrivateField(3)
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("""{"a":3}""")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("""{"a":4,"id":"B"}""")!!
|
||||
assertThat(decoded.a).isEqualTo(4)
|
||||
assertThat(decoded.id).isEqualTo("C")
|
||||
}
|
||||
|
||||
internal class ExtendsPlatformClassWithPrivateField(var a: Int) : SimpleTimeZone(0, "C")
|
||||
|
||||
@Ignore @Test fun extendsPlatformClassWithProtectedField() {
|
||||
val moshi = Moshi.Builder().add(MoshiSerializableFactory()).build()
|
||||
val jsonAdapter = moshi.adapter(ExtendsPlatformClassWithProtectedField::class.java)
|
||||
|
||||
val encoded = ExtendsPlatformClassWithProtectedField(3)
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("""{"a":3,"buf":[0,0],"count":0}""")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("""{"a":4,"buf":[0,0],"size":0}""")!!
|
||||
assertThat(decoded.a).isEqualTo(4)
|
||||
assertThat(decoded.buf()).isEqualTo(ByteArray(2, { 0 }))
|
||||
assertThat(decoded.count()).isEqualTo(0)
|
||||
}
|
||||
|
||||
internal class ExtendsPlatformClassWithProtectedField(var a: Int) : ByteArrayOutputStream(2) {
|
||||
fun buf() = buf
|
||||
fun count() = count
|
||||
}
|
||||
|
||||
@Ignore @Test fun platformTypeThrows() {
|
||||
val moshi = Moshi.Builder().add(MoshiSerializableFactory()).build()
|
||||
try {
|
||||
moshi.adapter(Triple::class.java)
|
||||
fail()
|
||||
} catch (e: IllegalArgumentException) {
|
||||
assertThat(e).hasMessage("Platform class kotlin.Triple annotated [] "
|
||||
+ "requires explicit JsonAdapter to be registered")
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore @Test fun privateConstructorParameters() {
|
||||
val moshi = Moshi.Builder().add(MoshiSerializableFactory()).build()
|
||||
val jsonAdapter = moshi.adapter(PrivateConstructorParameters::class.java)
|
||||
|
||||
val encoded = PrivateConstructorParameters(3, 5)
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("""{"a":3,"b":5}""")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("""{"a":4,"b":6}""")!!
|
||||
assertThat(decoded.a()).isEqualTo(4)
|
||||
assertThat(decoded.b()).isEqualTo(6)
|
||||
}
|
||||
|
||||
class PrivateConstructorParameters(private var a: Int, private var b: Int) {
|
||||
fun a() = a
|
||||
fun b() = b
|
||||
}
|
||||
|
||||
@Ignore @Test fun privateConstructor() {
|
||||
val moshi = Moshi.Builder().add(MoshiSerializableFactory()).build()
|
||||
val jsonAdapter = moshi.adapter(PrivateConstructor::class.java)
|
||||
|
||||
val encoded = PrivateConstructor.newInstance(3, 5)
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("""{"a":3,"b":5}""")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("""{"a":4,"b":6}""")!!
|
||||
assertThat(decoded.a()).isEqualTo(4)
|
||||
assertThat(decoded.b()).isEqualTo(6)
|
||||
}
|
||||
|
||||
class PrivateConstructor private constructor(var a: Int, var b: Int) {
|
||||
fun a() = a
|
||||
fun b() = b
|
||||
companion object {
|
||||
fun newInstance(a: Int, b: Int) = PrivateConstructor(a, b)
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore @Test fun privateProperties() {
|
||||
val moshi = Moshi.Builder().add(MoshiSerializableFactory()).build()
|
||||
val jsonAdapter = moshi.adapter(PrivateProperties::class.java)
|
||||
|
||||
val encoded = PrivateProperties()
|
||||
encoded.a(3)
|
||||
encoded.b(5)
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("""{"a":3,"b":5}""")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("""{"a":4,"b":6}""")!!
|
||||
assertThat(decoded.a()).isEqualTo(4)
|
||||
assertThat(decoded.b()).isEqualTo(6)
|
||||
}
|
||||
|
||||
class PrivateProperties {
|
||||
var a: Int = -1
|
||||
var b: Int = -1
|
||||
|
||||
fun a() = a
|
||||
|
||||
fun a(a: Int) {
|
||||
this.a = a
|
||||
}
|
||||
|
||||
fun b() = b
|
||||
|
||||
fun b(b: Int) {
|
||||
this.b = b
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore @Test fun unsettablePropertyIgnored() {
|
||||
val moshi = Moshi.Builder().add(MoshiSerializableFactory()).build()
|
||||
val jsonAdapter = moshi.adapter(UnsettableProperty::class.java)
|
||||
|
||||
val encoded = UnsettableProperty()
|
||||
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 UnsettableProperty {
|
||||
val a: Int = -1
|
||||
var b: Int = -1
|
||||
}
|
||||
|
||||
@Ignore @Test fun getterOnlyNoBackingField() {
|
||||
val moshi = Moshi.Builder().add(MoshiSerializableFactory()).build()
|
||||
val jsonAdapter = moshi.adapter(GetterOnly::class.java)
|
||||
|
||||
val encoded = GetterOnly(3, 5)
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("""{"a":3,"b":5}""")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("""{"a":4,"b":6}""")!!
|
||||
assertThat(decoded.a).isEqualTo(4)
|
||||
assertThat(decoded.b).isEqualTo(6)
|
||||
assertThat(decoded.total).isEqualTo(10)
|
||||
}
|
||||
|
||||
class GetterOnly(var a: Int, var b: Int) {
|
||||
val total : Int
|
||||
get() = a + b
|
||||
}
|
||||
|
||||
@Ignore @Test fun getterAndSetterNoBackingField() {
|
||||
val moshi = Moshi.Builder().add(MoshiSerializableFactory()).build()
|
||||
val jsonAdapter = moshi.adapter(GetterAndSetter::class.java)
|
||||
|
||||
val encoded = GetterAndSetter(3, 5)
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("""{"a":3,"b":5,"total":8}""")
|
||||
|
||||
// Whether b is 6 or 7 is an implementation detail. Currently we call constructors then setters.
|
||||
val decoded1 = jsonAdapter.fromJson("""{"a":4,"b":6,"total":11}""")!!
|
||||
assertThat(decoded1.a).isEqualTo(4)
|
||||
assertThat(decoded1.b).isEqualTo(7)
|
||||
assertThat(decoded1.total).isEqualTo(11)
|
||||
|
||||
// Whether b is 6 or 7 is an implementation detail. Currently we call constructors then setters.
|
||||
val decoded2 = jsonAdapter.fromJson("""{"a":4,"total":11,"b":6}""")!!
|
||||
assertThat(decoded2.a).isEqualTo(4)
|
||||
assertThat(decoded2.b).isEqualTo(7)
|
||||
assertThat(decoded2.total).isEqualTo(11)
|
||||
}
|
||||
|
||||
class GetterAndSetter(var a: Int, var b: Int) {
|
||||
var total : Int
|
||||
get() = a + b
|
||||
set(value) {
|
||||
b = value - a
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore @Test fun nonPropertyConstructorParameter() {
|
||||
val moshi = Moshi.Builder().add(MoshiSerializableFactory()).build()
|
||||
try {
|
||||
moshi.adapter(NonPropertyConstructorParameter::class.java)
|
||||
fail()
|
||||
} catch(expected: IllegalArgumentException) {
|
||||
assertThat(expected).hasMessage(
|
||||
"No property for required constructor parameter #0 a of fun <init>(" +
|
||||
"kotlin.Int, kotlin.Int): ${NonPropertyConstructorParameter::class.qualifiedName}")
|
||||
}
|
||||
}
|
||||
|
||||
class NonPropertyConstructorParameter(a: Int, val b: Int)
|
||||
|
||||
@Ignore @Test fun kotlinEnumsAreNotCovered() {
|
||||
val moshi = Moshi.Builder().add(MoshiSerializableFactory()).build()
|
||||
val adapter = moshi.adapter(UsingEnum::class.java)
|
||||
|
||||
assertThat(adapter.fromJson("""{"e": "A"}""")).isEqualTo(UsingEnum(KotlinEnum.A))
|
||||
}
|
||||
|
||||
data class UsingEnum(val e: KotlinEnum)
|
||||
|
||||
enum class KotlinEnum {
|
||||
A, B
|
||||
}
|
||||
|
||||
@Ignore @Test fun interfacesNotSupported() {
|
||||
val moshi = Moshi.Builder().add(MoshiSerializableFactory()).build()
|
||||
try {
|
||||
moshi.adapter(Interface::class.java)
|
||||
fail()
|
||||
} catch (e: IllegalArgumentException) {
|
||||
assertThat(e).hasMessage("No JsonAdapter for interface " +
|
||||
"com.squareup.moshi.KotlinJsonAdapterTest\$Interface annotated []")
|
||||
}
|
||||
}
|
||||
|
||||
interface Interface
|
||||
|
||||
@Ignore @Test fun abstractClassesNotSupported() {
|
||||
val moshi = Moshi.Builder().add(MoshiSerializableFactory()).build()
|
||||
try {
|
||||
moshi.adapter(AbstractClass::class.java)
|
||||
fail()
|
||||
} catch (e: IllegalArgumentException) {
|
||||
assertThat(e).hasMessage(
|
||||
"Cannot serialize abstract class com.squareup.moshi.KotlinJsonAdapterTest\$AbstractClass")
|
||||
}
|
||||
}
|
||||
|
||||
abstract class AbstractClass(val a: Int)
|
||||
|
||||
@Ignore @Test fun innerClassesNotSupported() {
|
||||
val moshi = Moshi.Builder().add(MoshiSerializableFactory()).build()
|
||||
try {
|
||||
moshi.adapter(InnerClass::class.java)
|
||||
fail()
|
||||
} catch (e: IllegalArgumentException) {
|
||||
assertThat(e).hasMessage(
|
||||
"Cannot serialize non-static nested class com.squareup.moshi.KotlinCodeGenTest\$InnerClass")
|
||||
}
|
||||
}
|
||||
|
||||
inner class InnerClass(val a: Int)
|
||||
|
||||
@Ignore @Test fun localClassesNotSupported() {
|
||||
class LocalClass(val a: Int)
|
||||
val moshi = Moshi.Builder().add(MoshiSerializableFactory()).build()
|
||||
try {
|
||||
moshi.adapter(LocalClass::class.java)
|
||||
fail()
|
||||
} catch (e: IllegalArgumentException) {
|
||||
assertThat(e).hasMessage("Cannot serialize local class or object expression " +
|
||||
"com.squareup.moshi.KotlinJsonAdapterTest\$localClassesNotSupported\$LocalClass")
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore @Test fun objectDeclarationsNotSupported() {
|
||||
val moshi = Moshi.Builder().add(MoshiSerializableFactory()).build()
|
||||
try {
|
||||
moshi.adapter(ObjectDeclaration.javaClass)
|
||||
fail()
|
||||
} catch (e: IllegalArgumentException) {
|
||||
assertThat(e).hasMessage("Cannot serialize object declaration " +
|
||||
"com.squareup.moshi.KotlinJsonAdapterTest\$ObjectDeclaration")
|
||||
}
|
||||
}
|
||||
|
||||
object ObjectDeclaration {
|
||||
var a = 5
|
||||
}
|
||||
|
||||
@Ignore @Test fun objectExpressionsNotSupported() {
|
||||
val expression = object : Any() {
|
||||
var a = 5
|
||||
}
|
||||
val moshi = Moshi.Builder().add(MoshiSerializableFactory()).build()
|
||||
try {
|
||||
moshi.adapter(expression.javaClass)
|
||||
fail()
|
||||
} catch (e: IllegalArgumentException) {
|
||||
assertThat(e).hasMessage("Cannot serialize local class or object expression " +
|
||||
"com.squareup.moshi.KotlinJsonAdapterTest\$objectExpressionsNotSupported\$expression$1")
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore @Test fun manyProperties32() {
|
||||
val moshi = Moshi.Builder().add(MoshiSerializableFactory()).build()
|
||||
val jsonAdapter = moshi.adapter(ManyProperties32::class.java)
|
||||
|
||||
val encoded = ManyProperties32(
|
||||
101, 102, 103, 104, 105,
|
||||
106, 107, 108, 109, 110,
|
||||
111, 112, 113, 114, 115,
|
||||
116, 117, 118, 119, 120,
|
||||
121, 122, 123, 124, 125,
|
||||
126, 127, 128, 129, 130,
|
||||
131, 132)
|
||||
val json = ("""
|
||||
|{
|
||||
|"v01":101,"v02":102,"v03":103,"v04":104,"v05":105,
|
||||
|"v06":106,"v07":107,"v08":108,"v09":109,"v10":110,
|
||||
|"v11":111,"v12":112,"v13":113,"v14":114,"v15":115,
|
||||
|"v16":116,"v17":117,"v18":118,"v19":119,"v20":120,
|
||||
|"v21":121,"v22":122,"v23":123,"v24":124,"v25":125,
|
||||
|"v26":126,"v27":127,"v28":128,"v29":129,"v30":130,
|
||||
|"v31":131,"v32":132
|
||||
|}
|
||||
|""").trimMargin().replace("\n", "")
|
||||
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo(json)
|
||||
|
||||
val decoded = jsonAdapter.fromJson(json)!!
|
||||
assertThat(decoded.v01).isEqualTo(101)
|
||||
assertThat(decoded.v32).isEqualTo(132)
|
||||
}
|
||||
|
||||
class ManyProperties32(
|
||||
var v01: Int, var v02: Int, var v03: Int, var v04: Int, var v05: Int,
|
||||
var v06: Int, var v07: Int, var v08: Int, var v09: Int, var v10: Int,
|
||||
var v11: Int, var v12: Int, var v13: Int, var v14: Int, var v15: Int,
|
||||
var v16: Int, var v17: Int, var v18: Int, var v19: Int, var v20: Int,
|
||||
var v21: Int, var v22: Int, var v23: Int, var v24: Int, var v25: Int,
|
||||
var v26: Int, var v27: Int, var v28: Int, var v29: Int, var v30: Int,
|
||||
var v31: Int, var v32: Int)
|
||||
|
||||
@Ignore @Test fun manyProperties33() {
|
||||
val moshi = Moshi.Builder().add(MoshiSerializableFactory()).build()
|
||||
val jsonAdapter = moshi.adapter(ManyProperties33::class.java)
|
||||
|
||||
val encoded = ManyProperties33(
|
||||
101, 102, 103, 104, 105,
|
||||
106, 107, 108, 109, 110,
|
||||
111, 112, 113, 114, 115,
|
||||
116, 117, 118, 119, 120,
|
||||
121, 122, 123, 124, 125,
|
||||
126, 127, 128, 129, 130,
|
||||
131, 132, 133)
|
||||
val json = ("""
|
||||
|{
|
||||
|"v01":101,"v02":102,"v03":103,"v04":104,"v05":105,
|
||||
|"v06":106,"v07":107,"v08":108,"v09":109,"v10":110,
|
||||
|"v11":111,"v12":112,"v13":113,"v14":114,"v15":115,
|
||||
|"v16":116,"v17":117,"v18":118,"v19":119,"v20":120,
|
||||
|"v21":121,"v22":122,"v23":123,"v24":124,"v25":125,
|
||||
|"v26":126,"v27":127,"v28":128,"v29":129,"v30":130,
|
||||
|"v31":131,"v32":132,"v33":133
|
||||
|}
|
||||
|""").trimMargin().replace("\n", "")
|
||||
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo(json)
|
||||
|
||||
val decoded = jsonAdapter.fromJson(json)!!
|
||||
assertThat(decoded.v01).isEqualTo(101)
|
||||
assertThat(decoded.v32).isEqualTo(132)
|
||||
assertThat(decoded.v33).isEqualTo(133)
|
||||
}
|
||||
|
||||
class ManyProperties33(
|
||||
var v01: Int, var v02: Int, var v03: Int, var v04: Int, var v05: Int,
|
||||
var v06: Int, var v07: Int, var v08: Int, var v09: Int, var v10: Int,
|
||||
var v11: Int, var v12: Int, var v13: Int, var v14: Int, var v15: Int,
|
||||
var v16: Int, var v17: Int, var v18: Int, var v19: Int, var v20: Int,
|
||||
var v21: Int, var v22: Int, var v23: Int, var v24: Int, var v25: Int,
|
||||
var v26: Int, var v27: Int, var v28: Int, var v29: Int, var v30: Int,
|
||||
var v31: Int, var v32: Int, var v33: Int)
|
||||
|
||||
// TODO(jwilson): resolve generic types?
|
||||
|
||||
@Retention(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)
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user