Parameterize kotlin test infra on CI (#1407)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index afea037..745b810 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -4,15 +4,15 @@
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 @@
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 }}'
diff --git a/kotlin/reflect/src/main/java/com/squareup/moshi/kotlin/reflect/KotlinJsonAdapter.kt b/kotlin/reflect/src/main/java/com/squareup/moshi/kotlin/reflect/KotlinJsonAdapter.kt
index 0db237e..f4a01ac 100644
--- a/kotlin/reflect/src/main/java/com/squareup/moshi/kotlin/reflect/KotlinJsonAdapter.kt
+++ b/kotlin/reflect/src/main/java/com/squareup/moshi/kotlin/reflect/KotlinJsonAdapter.kt
@@ -21,16 +21,19 @@
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 @@
}
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()),
diff --git a/kotlin/tests/build.gradle.kts b/kotlin/tests/build.gradle.kts
index 4b808e2..e4e9fba 100644
--- a/kotlin/tests/build.gradle.kts
+++ b/kotlin/tests/build.gradle.kts
@@ -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,11 +25,24 @@
id("com.google.devtools.ksp") apply false
}
-val useKsp = hasProperty("useKsp")
-if (useKsp) {
- apply(plugin = "com.google.devtools.ksp")
-} else {
- apply(plugin = "org.jetbrains.kotlin.kapt")
+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 {
@@ -48,10 +64,16 @@
}
dependencies {
- if (useKsp) {
- "kspTest"(project(":kotlin:codegen"))
- } else {
- "kaptTest"(project(":kotlin:codegen"))
+ when (testMode) {
+ REFLECT -> {
+ // Do nothing
+ }
+ KAPT -> {
+ "kaptTest"(project(":kotlin:codegen"))
+ }
+ KSP -> {
+ "kspTest"(project(":kotlin:codegen"))
+ }
}
testImplementation(project(":moshi"))
testImplementation(project(":kotlin:reflect"))
diff --git a/kotlin/tests/codegen-only/build.gradle.kts b/kotlin/tests/codegen-only/build.gradle.kts
new file mode 100644
index 0000000..7c5acb2
--- /dev/null
+++ b/kotlin/tests/codegen-only/build.gradle.kts
@@ -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)
+}
diff --git a/kotlin/tests/codegen-only/src/test/kotlin/com/squareup/moshi/kotlin/codegen/CompileOnlyTests.kt b/kotlin/tests/codegen-only/src/test/kotlin/com/squareup/moshi/kotlin/codegen/CompileOnlyTests.kt
new file mode 100644
index 0000000..f231683
--- /dev/null
+++ b/kotlin/tests/codegen-only/src/test/kotlin/com/squareup/moshi/kotlin/codegen/CompileOnlyTests.kt
@@ -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>
diff --git a/kotlin/tests/src/test/kotlin/com/squareup/moshi/kotlin/codegen/ComplexGenericsInheritanceTest.kt b/kotlin/tests/codegen-only/src/test/kotlin/com/squareup/moshi/kotlin/codegen/ComplexGenericsInheritanceTest.kt
similarity index 100%
rename from kotlin/tests/src/test/kotlin/com/squareup/moshi/kotlin/codegen/ComplexGenericsInheritanceTest.kt
rename to kotlin/tests/codegen-only/src/test/kotlin/com/squareup/moshi/kotlin/codegen/ComplexGenericsInheritanceTest.kt
diff --git a/kotlin/tests/src/test/kotlin/com/squareup/moshi/kotlin/DefaultConstructorTest.kt b/kotlin/tests/codegen-only/src/test/kotlin/com/squareup/moshi/kotlin/codegen/DefaultConstructorTest.kt
similarity index 89%
rename from kotlin/tests/src/test/kotlin/com/squareup/moshi/kotlin/DefaultConstructorTest.kt
rename to kotlin/tests/codegen-only/src/test/kotlin/com/squareup/moshi/kotlin/codegen/DefaultConstructorTest.kt
index 4b21e85..a211c7a 100644
--- a/kotlin/tests/src/test/kotlin/com/squareup/moshi/kotlin/DefaultConstructorTest.kt
+++ b/kotlin/tests/codegen-only/src/test/kotlin/com/squareup/moshi/kotlin/codegen/DefaultConstructorTest.kt
@@ -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 @@
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
}
diff --git a/kotlin/tests/src/test/kotlin/com/squareup/moshi/kotlin/codegen/GeneratedAdaptersTest.kt b/kotlin/tests/codegen-only/src/test/kotlin/com/squareup/moshi/kotlin/codegen/GeneratedAdaptersTest.kt
similarity index 92%
rename from kotlin/tests/src/test/kotlin/com/squareup/moshi/kotlin/codegen/GeneratedAdaptersTest.kt
rename to kotlin/tests/codegen-only/src/test/kotlin/com/squareup/moshi/kotlin/codegen/GeneratedAdaptersTest.kt
index 8d3d183..86a4bb2 100644
--- a/kotlin/tests/src/test/kotlin/com/squareup/moshi/kotlin/codegen/GeneratedAdaptersTest.kt
+++ b/kotlin/tests/codegen-only/src/test/kotlin/com/squareup/moshi/kotlin/codegen/GeneratedAdaptersTest.kt
@@ -36,7 +36,6 @@
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 @@
@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 @@
)
}
-// 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 @@
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>
diff --git a/kotlin/tests/src/test/kotlin/com/squareup/moshi/kotlin/codegen/GeneratedAdaptersTest_CustomGeneratedClassJsonAdapter.kt b/kotlin/tests/codegen-only/src/test/kotlin/com/squareup/moshi/kotlin/codegen/GeneratedAdaptersTest_CustomGeneratedClassJsonAdapter.kt
similarity index 100%
rename from kotlin/tests/src/test/kotlin/com/squareup/moshi/kotlin/codegen/GeneratedAdaptersTest_CustomGeneratedClassJsonAdapter.kt
rename to kotlin/tests/codegen-only/src/test/kotlin/com/squareup/moshi/kotlin/codegen/GeneratedAdaptersTest_CustomGeneratedClassJsonAdapter.kt
diff --git a/kotlin/tests/src/test/kotlin/com/squareup/moshi/kotlin/codegen/LooksLikeAClass/ClassInPackageThatLooksLikeAClass.kt b/kotlin/tests/codegen-only/src/test/kotlin/com/squareup/moshi/kotlin/codegen/LooksLikeAClass/ClassInPackageThatLooksLikeAClass.kt
similarity index 100%
rename from kotlin/tests/src/test/kotlin/com/squareup/moshi/kotlin/codegen/LooksLikeAClass/ClassInPackageThatLooksLikeAClass.kt
rename to kotlin/tests/codegen-only/src/test/kotlin/com/squareup/moshi/kotlin/codegen/LooksLikeAClass/ClassInPackageThatLooksLikeAClass.kt
diff --git a/kotlin/tests/codegen-only/src/test/kotlin/com/squareup/moshi/kotlin/codegen/MixingReflectAndCodeGen.kt b/kotlin/tests/codegen-only/src/test/kotlin/com/squareup/moshi/kotlin/codegen/MixingReflectAndCodeGen.kt
new file mode 100644
index 0000000..29510c9
--- /dev/null
+++ b/kotlin/tests/codegen-only/src/test/kotlin/com/squareup/moshi/kotlin/codegen/MixingReflectAndCodeGen.kt
@@ -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)
+}
diff --git a/kotlin/tests/src/test/kotlin/com/squareup/moshi/kotlin/codegen/MoshiKspTest.kt b/kotlin/tests/codegen-only/src/test/kotlin/com/squareup/moshi/kotlin/codegen/MoshiKspTest.kt
similarity index 100%
rename from kotlin/tests/src/test/kotlin/com/squareup/moshi/kotlin/codegen/MoshiKspTest.kt
rename to kotlin/tests/codegen-only/src/test/kotlin/com/squareup/moshi/kotlin/codegen/MoshiKspTest.kt
diff --git a/kotlin/tests/src/test/kotlin/com/squareup/moshi/kotlin/codegen/MultipleMasksTest.kt b/kotlin/tests/codegen-only/src/test/kotlin/com/squareup/moshi/kotlin/codegen/MultipleMasksTest.kt
similarity index 100%
rename from kotlin/tests/src/test/kotlin/com/squareup/moshi/kotlin/codegen/MultipleMasksTest.kt
rename to kotlin/tests/codegen-only/src/test/kotlin/com/squareup/moshi/kotlin/codegen/MultipleMasksTest.kt
diff --git a/kotlin/tests/src/test/kotlin/com/squareup/moshi/kotlin/codegen/annotation/UppercaseInAnnotationPackage.kt b/kotlin/tests/codegen-only/src/test/kotlin/com/squareup/moshi/kotlin/codegen/annotation/UppercaseInAnnotationPackage.kt
similarity index 100%
rename from kotlin/tests/src/test/kotlin/com/squareup/moshi/kotlin/codegen/annotation/UppercaseInAnnotationPackage.kt
rename to kotlin/tests/codegen-only/src/test/kotlin/com/squareup/moshi/kotlin/codegen/annotation/UppercaseInAnnotationPackage.kt
diff --git a/kotlin/tests/src/test/kotlin/com/squareup/moshi/kotlin/DualKotlinTest.kt b/kotlin/tests/src/test/kotlin/com/squareup/moshi/kotlin/DualKotlinTest.kt
index 82d20a2..5a1ff64 100644
--- a/kotlin/tests/src/test/kotlin/com/squareup/moshi/kotlin/DualKotlinTest.kt
+++ b/kotlin/tests/src/test/kotlin/com/squareup/moshi/kotlin/DualKotlinTest.kt
@@ -18,8 +18,6 @@
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 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 @@
}
}
}
+
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)
diff --git a/kotlin/tests/src/test/kotlin/com/squareup/moshi/kotlin/reflect/KotlinJsonAdapterTest.kt b/kotlin/tests/src/test/kotlin/com/squareup/moshi/kotlin/reflect/KotlinJsonAdapterTest.kt
index 23d857c..3a0424b 100644
--- a/kotlin/tests/src/test/kotlin/com/squareup/moshi/kotlin/reflect/KotlinJsonAdapterTest.kt
+++ b/kotlin/tests/src/test/kotlin/com/squareup/moshi/kotlin/reflect/KotlinJsonAdapterTest.kt
@@ -886,28 +886,6 @@
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
diff --git a/settings.gradle.kts b/settings.gradle.kts
index f3a138f..d3ff693 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -31,6 +31,7 @@
include(":kotlin:reflect")
include(":kotlin:codegen")
include(":kotlin:tests")
+include(":kotlin:tests:codegen-only")
include(":kotlin:tests:extra-moshi-test-module")
enableFeaturePreview("VERSION_CATALOGS")