mirror of
https://github.com/fankes/moshi.git
synced 2025-10-18 23:49:21 +08:00
Parameterize kotlin test infra on CI (#1407)
This commit is contained in:
8
.github/workflows/build.yml
vendored
8
.github/workflows/build.yml
vendored
@@ -4,15 +4,15 @@ on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: 'Java ${{ matrix.java-version }} | Kotlin ${{ matrix.kotlin-version }} | KSP ${{ matrix.use-ksp }}'
|
||||
name: 'Kotlin ${{ matrix.kotlin-version }} | Test Mode ${{ matrix.kotlin-test-mode }}'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
use-ksp: [ true, false ]
|
||||
kotlin-version: [ '1.5.31', '1.6.0-RC' ]
|
||||
ksp-version: [ '1.5.31-1.0.0', '1.6.0-RC-1.0.0' ]
|
||||
kotlin-test-mode: [ 'REFLECT', 'KSP', 'KAPT' ]
|
||||
exclude:
|
||||
- kotlin-version: '1.5.31'
|
||||
ksp-version: '1.6.0-RC-1.0.0'
|
||||
@@ -47,10 +47,10 @@ jobs:
|
||||
java-version: '17'
|
||||
|
||||
- name: Test
|
||||
run: ./gradlew build check --stacktrace -PuseKsp=${{ matrix.use-ksp }} -PkotlinVersion=${{ matrix.kotlin-version }}
|
||||
run: ./gradlew build check --stacktrace -PkotlinTestMode=${{ matrix.kotlin-test-mode }} -PkotlinVersion=${{ matrix.kotlin-version }}
|
||||
|
||||
- name: Publish (default branch only)
|
||||
if: github.repository == 'square/moshi' && github.ref == 'refs/heads/master' && matrix.kotlin-version == '1.5.31' && matrix.use-ksp == 'false'
|
||||
if: github.repository == 'square/moshi' && github.ref == 'refs/heads/master' && matrix.kotlin-version == '1.5.31' && matrix.kotlin-test-mode == 'reflect'
|
||||
run: ./gradlew publish
|
||||
env:
|
||||
ORG_GRADLE_PROJECT_mavenCentralUsername: '${{ secrets.SONATYPE_NEXUS_USERNAME }}'
|
||||
|
@@ -21,16 +21,19 @@ import com.squareup.moshi.JsonDataException
|
||||
import com.squareup.moshi.JsonReader
|
||||
import com.squareup.moshi.JsonWriter
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.squareup.moshi.Types
|
||||
import com.squareup.moshi.internal.Util
|
||||
import com.squareup.moshi.internal.Util.generatedAdapter
|
||||
import com.squareup.moshi.internal.Util.resolve
|
||||
import com.squareup.moshi.rawType
|
||||
import java.lang.reflect.Modifier
|
||||
import java.lang.reflect.Type
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KFunction
|
||||
import kotlin.reflect.KMutableProperty1
|
||||
import kotlin.reflect.KParameter
|
||||
import kotlin.reflect.KProperty1
|
||||
import kotlin.reflect.KTypeParameter
|
||||
import kotlin.reflect.full.findAnnotation
|
||||
import kotlin.reflect.full.memberProperties
|
||||
import kotlin.reflect.full.primaryConstructor
|
||||
@@ -257,7 +260,31 @@ public class KotlinJsonAdapterFactory : JsonAdapter.Factory {
|
||||
}
|
||||
|
||||
val name = jsonAnnotation?.name ?: property.name
|
||||
val resolvedPropertyType = resolve(type, rawType, property.returnType.javaType)
|
||||
val propertyType = when (val propertyTypeClassifier = property.returnType.classifier) {
|
||||
is KClass<*> -> {
|
||||
if (propertyTypeClassifier.isValue) {
|
||||
// When it's a value class, we need to resolve the type ourselves because the javaType
|
||||
// function will return its inlined type
|
||||
val rawClassifierType = propertyTypeClassifier.java
|
||||
if (property.returnType.arguments.isEmpty()) {
|
||||
rawClassifierType
|
||||
} else {
|
||||
Types.newParameterizedType(
|
||||
rawClassifierType,
|
||||
*property.returnType.arguments.mapNotNull { it.type?.javaType }.toTypedArray()
|
||||
)
|
||||
}
|
||||
} else {
|
||||
// This is safe when it's not a value class!
|
||||
property.returnType.javaType
|
||||
}
|
||||
}
|
||||
is KTypeParameter -> {
|
||||
property.returnType.javaType
|
||||
}
|
||||
else -> error("Not possible!")
|
||||
}
|
||||
val resolvedPropertyType = resolve(type, rawType, propertyType)
|
||||
val adapter = moshi.adapter<Any>(
|
||||
resolvedPropertyType,
|
||||
Util.jsonAnnotations(allAnnotations.toTypedArray()),
|
||||
|
@@ -14,6 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Build_gradle.TestMode.KAPT
|
||||
import Build_gradle.TestMode.KSP
|
||||
import Build_gradle.TestMode.REFLECT
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
|
||||
plugins {
|
||||
@@ -22,12 +25,25 @@ plugins {
|
||||
id("com.google.devtools.ksp") apply false
|
||||
}
|
||||
|
||||
val useKsp = hasProperty("useKsp")
|
||||
if (useKsp) {
|
||||
apply(plugin = "com.google.devtools.ksp")
|
||||
} else {
|
||||
enum class TestMode {
|
||||
REFLECT, KAPT, KSP
|
||||
}
|
||||
|
||||
val testMode = findProperty("kotlinTestMode")?.toString()
|
||||
?.let(TestMode::valueOf)
|
||||
?: REFLECT
|
||||
|
||||
when (testMode) {
|
||||
REFLECT -> {
|
||||
// Do nothing!
|
||||
}
|
||||
KAPT -> {
|
||||
apply(plugin = "org.jetbrains.kotlin.kapt")
|
||||
}
|
||||
KSP -> {
|
||||
apply(plugin = "com.google.devtools.ksp")
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType<Test>().configureEach {
|
||||
// ExtendsPlatformClassWithProtectedField tests a case where we set a protected ByteArrayOutputStream.buf field
|
||||
@@ -48,11 +64,17 @@ tasks.withType<KotlinCompile>().configureEach {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
if (useKsp) {
|
||||
"kspTest"(project(":kotlin:codegen"))
|
||||
} else {
|
||||
when (testMode) {
|
||||
REFLECT -> {
|
||||
// Do nothing
|
||||
}
|
||||
KAPT -> {
|
||||
"kaptTest"(project(":kotlin:codegen"))
|
||||
}
|
||||
KSP -> {
|
||||
"kspTest"(project(":kotlin:codegen"))
|
||||
}
|
||||
}
|
||||
testImplementation(project(":moshi"))
|
||||
testImplementation(project(":kotlin:reflect"))
|
||||
testImplementation(project(":kotlin:tests:extra-moshi-test-module"))
|
||||
|
87
kotlin/tests/codegen-only/build.gradle.kts
Normal file
87
kotlin/tests/codegen-only/build.gradle.kts
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
import Build_gradle.TestMode.KAPT
|
||||
import Build_gradle.TestMode.KSP
|
||||
import Build_gradle.TestMode.REFLECT
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
kotlin("kapt") apply false
|
||||
id("com.google.devtools.ksp") apply false
|
||||
}
|
||||
|
||||
enum class TestMode {
|
||||
REFLECT, KAPT, KSP
|
||||
}
|
||||
|
||||
val testMode = findProperty("kotlinTestMode")?.toString()
|
||||
?.let(TestMode::valueOf)
|
||||
?: KSP
|
||||
|
||||
when (testMode) {
|
||||
REFLECT -> {
|
||||
// Default to KSP. This is a CI-only thing
|
||||
apply(plugin = "com.google.devtools.ksp")
|
||||
}
|
||||
KAPT -> {
|
||||
apply(plugin = "org.jetbrains.kotlin.kapt")
|
||||
}
|
||||
KSP -> {
|
||||
apply(plugin = "com.google.devtools.ksp")
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType<Test>().configureEach {
|
||||
// ExtendsPlatformClassWithProtectedField tests a case where we set a protected ByteArrayOutputStream.buf field
|
||||
jvmArgs("--add-opens=java.base/java.io=ALL-UNNAMED")
|
||||
}
|
||||
|
||||
val useWError = findProperty("kotlinLanguageVersion")?.toString()
|
||||
?.startsWith("1.5")
|
||||
?: false
|
||||
tasks.withType<KotlinCompile>().configureEach {
|
||||
kotlinOptions {
|
||||
allWarningsAsErrors = useWError
|
||||
@Suppress("SuspiciousCollectionReassignment")
|
||||
freeCompilerArgs += listOf(
|
||||
"-Xopt-in=kotlin.ExperimentalStdlibApi"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
when (testMode) {
|
||||
REFLECT -> {
|
||||
// Default to KSP in this case, this is a CI-only thing
|
||||
"kspTest"(project(":kotlin:codegen"))
|
||||
}
|
||||
KAPT -> {
|
||||
"kaptTest"(project(":kotlin:codegen"))
|
||||
}
|
||||
KSP -> {
|
||||
"kspTest"(project(":kotlin:codegen"))
|
||||
}
|
||||
}
|
||||
testImplementation(project(":moshi"))
|
||||
testImplementation(project(":kotlin:reflect"))
|
||||
testImplementation(project(":kotlin:tests:extra-moshi-test-module"))
|
||||
testImplementation(kotlin("reflect"))
|
||||
testImplementation(libs.junit)
|
||||
testImplementation(libs.assertj)
|
||||
testImplementation(libs.truth)
|
||||
}
|
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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
|
||||
*
|
||||
* https://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.kotlin.codegen
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import kotlin.annotation.AnnotationTarget.TYPE
|
||||
|
||||
/*
|
||||
* These are classes that need only compile.
|
||||
*/
|
||||
|
||||
// Regression test for https://github.com/square/moshi/issues/905
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class GenericTestClassWithDefaults<T>(
|
||||
val input: String = "",
|
||||
val genericInput: T
|
||||
)
|
||||
|
||||
@Target(TYPE)
|
||||
annotation class TypeAnnotation
|
||||
|
||||
/**
|
||||
* Compilation-only test to ensure we don't render types with their annotations.
|
||||
* Regression test for https://github.com/square/moshi/issues/1033
|
||||
*/
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class TypeAnnotationClass(
|
||||
val propertyWithAnnotatedType: @TypeAnnotation String = "",
|
||||
val generic: List<@TypeAnnotation String>
|
||||
)
|
||||
|
||||
// Regression test for https://github.com/square/moshi/issues/1277
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class OtherTestModel(val TestModel: TestModel? = null)
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class TestModel(
|
||||
val someVariable: Int,
|
||||
val anotherVariable: String
|
||||
)
|
||||
|
||||
// Regression test for https://github.com/square/moshi/issues/1022
|
||||
@JsonClass(generateAdapter = true)
|
||||
internal data class MismatchParentAndNestedClassVisibility(
|
||||
val type: Int,
|
||||
val name: String? = null
|
||||
) {
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class NestedClass(
|
||||
val nestedProperty: String
|
||||
)
|
||||
}
|
||||
|
||||
// Regression test for https://github.com/square/moshi/issues/1052
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class KeysWithSpaces(
|
||||
@Json(name = "1. Information") val information: String,
|
||||
@Json(name = "2. Symbol") val symbol: String,
|
||||
@Json(name = "3. Last Refreshed") val lastRefreshed: String,
|
||||
@Json(name = "4. Interval") val interval: String,
|
||||
@Json(name = "5. Output Size") val size: String,
|
||||
@Json(name = "6. Time Zone") val timeZone: String
|
||||
)
|
||||
|
||||
// Regression test for https://github.com/square/moshi/issues/848
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Hotwords(
|
||||
val `class`: List<String>?
|
||||
)
|
||||
|
||||
/**
|
||||
* This is here mostly just to ensure it still compiles. Covers variance, @Json, default values,
|
||||
* nullability, primitive arrays, and some wacky generics.
|
||||
*/
|
||||
@JsonClass(generateAdapter = true)
|
||||
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: MutableList<out String> = mutableListOf(),
|
||||
val nullableWildcardOut: MutableList<out String?> = mutableListOf(),
|
||||
val wildcardIn: Array<in String>,
|
||||
val any: List<*>,
|
||||
val anyTwo: List<Any>,
|
||||
val anyOut: MutableList<out Any>,
|
||||
val nullableAnyOut: MutableList<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",
|
||||
val genericAlias: GenericTypeAlias = listOf("Woah"),
|
||||
// Regression test for https://github.com/square/moshi/issues/1272
|
||||
val nestedArray: Array<Map<String, Any>>? = null
|
||||
)
|
||||
|
||||
typealias TypeAliasName = String
|
||||
typealias GenericTypeAlias = List<String>
|
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.squareup.moshi.kotlin
|
||||
package com.squareup.moshi.kotlin.codegen
|
||||
|
||||
import com.squareup.moshi.JsonClass
|
||||
import com.squareup.moshi.Moshi
|
||||
@@ -66,14 +66,6 @@ data class TestClass(
|
||||
val dynamicInlineOptional: Int = createInlineInt()
|
||||
)
|
||||
|
||||
// Regression test for https://github.com/square/moshi/issues/905
|
||||
// Just needs to compile
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class GenericTestClassWithDefaults<T>(
|
||||
val input: String = "",
|
||||
val genericInput: T
|
||||
)
|
||||
|
||||
private fun createInt(): Int {
|
||||
return 3
|
||||
}
|
@@ -36,7 +36,6 @@ import org.junit.Assert.fail
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
import java.util.Locale
|
||||
import kotlin.annotation.AnnotationTarget.TYPE
|
||||
import kotlin.properties.Delegates
|
||||
import kotlin.reflect.full.memberProperties
|
||||
|
||||
@@ -1342,19 +1341,6 @@ class GeneratedAdaptersTest {
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class DeprecatedProperty(@Deprecated("Deprecated for reasons") val foo: String)
|
||||
|
||||
@Target(TYPE)
|
||||
annotation class TypeAnnotation
|
||||
|
||||
/**
|
||||
* Compilation-only test to ensure we don't render types with their annotations.
|
||||
* Regression test for https://github.com/square/moshi/issues/1033
|
||||
*/
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class TypeAnnotationClass(
|
||||
val propertyWithAnnotatedType: @TypeAnnotation String = "",
|
||||
val generic: List<@TypeAnnotation String>
|
||||
)
|
||||
|
||||
@Test fun typesSizeCheckMessages_noArgs() {
|
||||
try {
|
||||
// Note: This is impossible to do if you use the reified adapter extension!
|
||||
@@ -1401,42 +1387,6 @@ class GeneratedAdaptersTest {
|
||||
)
|
||||
}
|
||||
|
||||
// Regression test for https://github.com/square/moshi/issues/1277
|
||||
// Compile-only test
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class OtherTestModel(val TestModel: TestModel? = null)
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class TestModel(
|
||||
val someVariable: Int,
|
||||
val anotherVariable: String
|
||||
)
|
||||
|
||||
// Regression test for https://github.com/square/moshi/issues/1022
|
||||
// Compile-only test
|
||||
@JsonClass(generateAdapter = true)
|
||||
internal data class MismatchParentAndNestedClassVisibility(
|
||||
val type: Int,
|
||||
val name: String? = null
|
||||
) {
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class NestedClass(
|
||||
val nestedProperty: String
|
||||
)
|
||||
}
|
||||
|
||||
// Regression test for https://github.com/square/moshi/issues/1052
|
||||
// Compile-only test
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class KeysWithSpaces(
|
||||
@Json(name = "1. Information") val information: String,
|
||||
@Json(name = "2. Symbol") val symbol: String,
|
||||
@Json(name = "3. Last Refreshed") val lastRefreshed: String,
|
||||
@Json(name = "4. Interval") val interval: String,
|
||||
@Json(name = "5. Output Size") val size: String,
|
||||
@Json(name = "6. Time Zone") val timeZone: String
|
||||
)
|
||||
|
||||
// Has to be outside to avoid Types seeing an owning class
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class NullableTypeParams<T>(
|
||||
@@ -1446,45 +1396,3 @@ data class NullableTypeParams<T>(
|
||||
val nullableT: T?,
|
||||
val nonNullT: T
|
||||
)
|
||||
|
||||
/**
|
||||
* This is here mostly just to ensure it still compiles. Covers variance, @Json, default values,
|
||||
* nullability, primitive arrays, and some wacky generics.
|
||||
*/
|
||||
@JsonClass(generateAdapter = true)
|
||||
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: MutableList<out String> = mutableListOf(),
|
||||
val nullableWildcardOut: MutableList<out String?> = mutableListOf(),
|
||||
val wildcardIn: Array<in String>,
|
||||
val any: List<*>,
|
||||
val anyTwo: List<Any>,
|
||||
val anyOut: MutableList<out Any>,
|
||||
val nullableAnyOut: MutableList<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",
|
||||
val genericAlias: GenericTypeAlias = listOf("Woah"),
|
||||
// Regression test for https://github.com/square/moshi/issues/1272
|
||||
val nestedArray: Array<Map<String, Any>>? = null
|
||||
)
|
||||
|
||||
// Compile only, regression test for https://github.com/square/moshi/issues/848
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Hotwords(
|
||||
val `class`: List<String>?
|
||||
)
|
||||
|
||||
typealias TypeAliasName = String
|
||||
typealias GenericTypeAlias = List<String>
|
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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
|
||||
*
|
||||
* https://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.kotlin.codegen
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import com.squareup.moshi.JsonClass
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.squareup.moshi.adapter
|
||||
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
|
||||
import org.junit.Test
|
||||
|
||||
class MixingReflectAndCodeGen {
|
||||
@Test
|
||||
fun mixingReflectionAndCodegen() {
|
||||
val moshi = Moshi.Builder()
|
||||
.add(KotlinJsonAdapterFactory())
|
||||
.build()
|
||||
val generatedAdapter = moshi.adapter<UsesGeneratedAdapter>()
|
||||
val reflectionAdapter = moshi.adapter<UsesReflectionAdapter>()
|
||||
|
||||
assertThat(generatedAdapter.toString())
|
||||
.isEqualTo("GeneratedJsonAdapter(MixingReflectAndCodeGen.UsesGeneratedAdapter).nullSafe()")
|
||||
assertThat(reflectionAdapter.toString())
|
||||
.isEqualTo(
|
||||
"KotlinJsonAdapter(com.squareup.moshi.kotlin.codegen.MixingReflectAndCodeGen" +
|
||||
".UsesReflectionAdapter).nullSafe()"
|
||||
)
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
class UsesGeneratedAdapter(var a: Int, var b: Int)
|
||||
|
||||
@JsonClass(generateAdapter = false)
|
||||
class UsesReflectionAdapter(var a: Int, var b: Int)
|
||||
}
|
@@ -18,8 +18,6 @@ package com.squareup.moshi.kotlin
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import com.squareup.moshi.FromJson
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonAdapter
|
||||
import com.squareup.moshi.JsonAdapter.Factory
|
||||
import com.squareup.moshi.JsonClass
|
||||
import com.squareup.moshi.JsonDataException
|
||||
import com.squareup.moshi.JsonQualifier
|
||||
@@ -32,53 +30,15 @@ import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
|
||||
import org.intellij.lang.annotations.Language
|
||||
import org.junit.Assert.fail
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.Parameterized
|
||||
import org.junit.runners.Parameterized.Parameters
|
||||
import java.lang.reflect.Type
|
||||
import kotlin.annotation.AnnotationRetention.RUNTIME
|
||||
|
||||
/**
|
||||
* Parameterized tests that test serialization with both [KotlinJsonAdapterFactory] and code gen.
|
||||
*/
|
||||
@RunWith(Parameterized::class)
|
||||
class DualKotlinTest(useReflection: Boolean) {
|
||||
|
||||
companion object {
|
||||
@Parameters(name = "reflective={0}")
|
||||
@JvmStatic
|
||||
fun parameters(): List<Array<*>> {
|
||||
return listOf(
|
||||
arrayOf(true),
|
||||
arrayOf(false)
|
||||
)
|
||||
}
|
||||
}
|
||||
class DualKotlinTest {
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private val moshi = Moshi.Builder()
|
||||
.apply {
|
||||
if (useReflection) {
|
||||
add(KotlinJsonAdapterFactory())
|
||||
add(
|
||||
object : Factory {
|
||||
override fun create(
|
||||
type: Type,
|
||||
annotations: MutableSet<out Annotation>,
|
||||
moshi: Moshi
|
||||
): JsonAdapter<*>? {
|
||||
// Prevent falling back to generated adapter lookup
|
||||
val rawType = Types.getRawType(type)
|
||||
val metadataClass = Class.forName("kotlin.Metadata") as Class<out Annotation>
|
||||
check(rawType.isEnum || !rawType.isAnnotationPresent(metadataClass)) {
|
||||
"Unhandled Kotlin type in reflective test! $rawType"
|
||||
}
|
||||
return moshi.nextAdapter<Any>(this, type, annotations)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
// If code gen ran, the generated adapter will be tried first. If it can't find it, it will
|
||||
// gracefully fall back to the KotlinJsonAdapter. This allows us to easily test both.
|
||||
.addLast(KotlinJsonAdapterFactory())
|
||||
.build()
|
||||
|
||||
@Test fun requiredValueAbsent() {
|
||||
@@ -366,19 +326,22 @@ class DualKotlinTest(useReflection: Boolean) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assertThat(adapter.toJson(data))
|
||||
//language=JSON
|
||||
.isEqualTo(
|
||||
"""
|
||||
{"text":"root","t":{"text":"child 1"},"r":{"number":0,"t":{"number":1},"r":{"text":"grand child 1"}}}
|
||||
{"text":"root","r":{"number":0,"r":{"text":"grand child 1"},"t":{"number":1}},"t":{"text":"child 1"}}
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
open class Node<T : Node<T, R>, R : Node<R, T>> {
|
||||
var t: T? = null
|
||||
// kotlin-reflect doesn't preserve ordering, so put these in alphabetical order so that
|
||||
// both reflective and code gen tests work the same
|
||||
var r: R? = null
|
||||
var t: T? = null
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
|
@@ -886,28 +886,6 @@ class KotlinJsonAdapterTest {
|
||||
assertThat(adapter.toJson(value)).isEqualTo(json)
|
||||
}
|
||||
|
||||
@Test fun mixingReflectionAndCodegen() {
|
||||
val moshi = Moshi.Builder()
|
||||
.add(KotlinJsonAdapterFactory())
|
||||
.build()
|
||||
val generatedAdapter = moshi.adapter<UsesGeneratedAdapter>()
|
||||
val reflectionAdapter = moshi.adapter<UsesReflectionAdapter>()
|
||||
|
||||
assertThat(generatedAdapter.toString())
|
||||
.isEqualTo("GeneratedJsonAdapter(KotlinJsonAdapterTest.UsesGeneratedAdapter).nullSafe()")
|
||||
assertThat(reflectionAdapter.toString())
|
||||
.isEqualTo(
|
||||
"KotlinJsonAdapter(com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterTest" +
|
||||
".UsesReflectionAdapter).nullSafe()"
|
||||
)
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
class UsesGeneratedAdapter(var a: Int, var b: Int)
|
||||
|
||||
@JsonClass(generateAdapter = false)
|
||||
class UsesReflectionAdapter(var a: Int, var b: Int)
|
||||
|
||||
@Retention(RUNTIME)
|
||||
@JsonQualifier
|
||||
annotation class Uppercase
|
||||
|
@@ -31,6 +31,7 @@ include(":examples")
|
||||
include(":kotlin:reflect")
|
||||
include(":kotlin:codegen")
|
||||
include(":kotlin:tests")
|
||||
include(":kotlin:tests:codegen-only")
|
||||
include(":kotlin:tests:extra-moshi-test-module")
|
||||
|
||||
enableFeaturePreview("VERSION_CATALOGS")
|
||||
|
Reference in New Issue
Block a user