Skip to content
This repository has been archived by the owner on Jul 16, 2024. It is now read-only.

Adopt PublishedApi #36

Merged
merged 11 commits into from
Feb 28, 2022
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ jobs:
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/**.gradle', '**/**.gradle.kts', '**/gradle/wrapper/gradle-wrapper.properties', '**/buildSrc/src/main/kotlin/**.kt') }}
- name: Unit tests
run: ./gradlew testDebugUnitTest
run: ./gradlew test

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test events were not received

instrumentation-tests:
name: Instrumentation tests
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import okhttp3.OkHttpClient
import retrofit2.Converter
import retrofit2.Retrofit

@Suppress("unused")
abstract class BaseRetrofitHelper {

private val retrofit by lazy {
@PublishedApi
internal val retrofit by lazy {
Retrofit.Builder()
.baseUrl(baseUrl)
.client(buildOkHttpClient())
Expand All @@ -32,9 +32,7 @@ abstract class BaseRetrofitHelper {
}
}

fun <T : Any> create(service: Class<T>): T = retrofit.create(service)

inline fun <reified T : Any> create(): T = create(T::class.java)
inline fun <reified T : Any> create(): T = retrofit.create(T::class.java)

protected abstract fun OkHttpClient.Builder.addInterceptors(): OkHttpClient.Builder

Expand Down
3 changes: 3 additions & 0 deletions buildSrc/src/main/kotlin/Extensions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ fun DependencyHandler.androidTestImplementations(vararg names: Any): Array<Depen
fun DependencyHandler.testImplementations(vararg names: Any): Array<Dependency?> =
config("testImplementation", *names)

fun DependencyHandler.kaptTests(vararg names: Any): Array<Dependency?> =
config("kaptTest", *names)

fun PluginAware.applyPlugins(vararg names: String) {
apply { names.forEach(::plugin) }
}
Expand Down
2 changes: 2 additions & 0 deletions common/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,6 @@ dependencies {
implementations(*Libs.coil)
debugImplementations(Libs.chuckerDebug)
releaseImplementations(Libs.chuckerRelease)

kaptTests(Libs.moshiCompiler)
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

java.lang.RuntimeException: Failed to find the generated JsonAdapter class for class io.goooler.demoapp.common.JsonUtilTest$Repo
	at com.squareup.moshi.internal.Util.generatedAdapter(Util.java:590)
	at com.squareup.moshi.StandardJsonAdapters$1.create(StandardJsonAdapters.java:61)
	at com.squareup.moshi.Moshi.adapter(Moshi.java:146)
	at com.squareup.moshi.Moshi.adapter(Moshi.java:106)
	at com.squareup.moshi.Moshi.adapter(Moshi.java:80)
	at io.goooler.demoapp.common.JsonUtilTest.JsonUtil fromJson(String)(JsonUtilTest.kt:95)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:110)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38)
	at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62)
	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
	at jdk.proxy1/jdk.proxy1.$Proxy2.processTestClass(Unknown Source)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker$2.run(TestWorker.java:176)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
	at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:133)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:71)
	at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
	at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
Caused by: java.lang.ClassNotFoundException: io.goooler.demoapp.common.JsonUtilTest_RepoJsonAdapter
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Class.java:467)
	at com.squareup.moshi.internal.Util.generatedAdapter(Util.java:564)
	... 48 more

}
32 changes: 14 additions & 18 deletions common/src/main/kotlin/io/goooler/demoapp/common/util/JsonUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,47 +4,43 @@ package io.goooler.demoapp.common.util

import com.squareup.moshi.Moshi
import com.squareup.moshi.Types
import java.lang.reflect.Type
import org.intellij.lang.annotations.Language

object JsonUtil {
@PublishedApi
internal val moshi: Moshi = Moshi.Builder().build()

fun <T> fromJson(json: String, clazz: Class<T>): T? = try {
moshi.adapter(clazz).fromJson(json)
inline fun <reified T> fromJson(@Language("JSON") string: String): T? = try {
moshi.adapter(T::class.java).fromJson(string)
} catch (e: Exception) {
e.printStackTrace()
null
}

fun <T> fromJson(json: String, typeOfT: Type): T? = try {
moshi.adapter<T>(typeOfT).fromJson(json)
fun <T> fromJson(
@Language("JSON") string: String,
rawType: Class<*>,
vararg typeArguments: Class<*>
): T? = try {
moshi.adapter<T>(Types.newParameterizedType(rawType, *typeArguments)).fromJson(string)
} catch (e: Exception) {
e.printStackTrace()
null
}

fun <T> fromJson(json: String, rawType: Class<*>, vararg typeArguments: Class<*>): T? = try {
fromJson(json, Types.newParameterizedType(rawType, *typeArguments))
@Language("JSON")
inline fun <reified T> toJson(value: T?): String? = try {
moshi.adapter(T::class.java).toJson(value)
} catch (e: Exception) {
e.printStackTrace()
null
}

fun <T> toJson(o: T?, clazz: Class<T>): String? = try {
moshi.adapter(clazz).toJson(o)
} catch (e: Exception) {
e.printStackTrace()
null
}

inline fun <reified T> toJson(o: T?): String? = toJson(o, T::class.java)
}

inline fun <reified T> String.fromJson(): T? = JsonUtil.fromJson(this, T::class.java)

inline fun <reified T> String.fromJson(typeOfT: Type): T? = JsonUtil.fromJson(this, typeOfT)

inline fun <reified T> String.fromJson(rawType: Class<*>, vararg typeArguments: Class<*>): T? =
JsonUtil.fromJson(this, rawType, *typeArguments)

@Language("JSON")
fun Any?.toJson(): String? = JsonUtil.toJson(this)
96 changes: 96 additions & 0 deletions common/src/test/kotlin/io/goooler/demoapp/common/JsonUtilTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package io.goooler.demoapp.common

import com.squareup.moshi.JsonClass
import io.goooler.demoapp.common.util.JsonUtil
import io.goooler.demoapp.common.util.fromJson
import io.goooler.demoapp.common.util.toJson
import org.intellij.lang.annotations.Language
import org.junit.Assert.assertTrue
import org.junit.Test

class JsonUtilTest {
@Test
fun `JsonUtil fromJson(String)`() {
assertTrue(JsonUtil.fromJson<Repo>(firstStr) == firstBean)
assertTrue(JsonUtil.fromJson<Repo>(secondStr) == secondBean)
}

@Test
fun `JsonUtil fromJson(String, Class, Class)`() {
val array: Array<Repo> = JsonUtil.fromJson(strArray, Array::class.java, Repo::class.java)
?: throw Exception("Parse json error")
assertTrue(array.first() == firstBean)
assertTrue(array[1] == secondBean)
}

@Test
fun `JsonUtil toJson(T)`() {
assertTrue(JsonUtil.toJson(firstBean) == firstStr)
assertTrue(JsonUtil.toJson(secondBean) == secondStr)
}

@Test
fun `String fromJson()`() {
assertTrue(firstStr.fromJson<Repo>() == firstBean)
assertTrue(secondStr.fromJson<Repo>() == secondBean)
}

@Test
fun `String fromJson(Class, Class)`() {
val array: Array<Repo> = strArray.fromJson(Array::class.java, Repo::class.java)
?: throw Exception("Parse json error")
assertTrue(array.first() == firstBean)
assertTrue(array[1] == secondBean)
}

@Test
fun `Any? toJson(T)`() {
assertTrue(firstBean.toJson() == firstStr)
assertTrue(secondBean.toJson() == secondStr)
}

@JsonClass(generateAdapter = true)
internal data class Repo(val id: Long, val name: String, val owner: Owner) {
@JsonClass(generateAdapter = true)
data class Owner(val login: String)

override fun equals(other: Any?): Boolean = if (other is Repo) {
this.id == other.id && this.name == other.name && this.owner.login == other.owner.login
} else {
false
}

override fun hashCode(): Int = id.hashCode()
}

companion object {
@Language("JSON")
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private val firstStr = """
{
"id": 126987864,
"name": "1024_hosts",
"owner": {
"login": "Goooler"
}
}
""".trimIndent()

@Language("JSON")
private val secondStr = """
{
"id": 374913489,
"name": "AndroidUiDemo",
"owner": {
"login": "Goooler"
}
}
""".trimIndent()

// https://api.github.com/users/goooler/repos?&page=1&per_page=2
@Language("JSON")
private val strArray = "[$firstStr,$secondStr]"

private val firstBean = Repo(126987864, "1024_hosts", Repo.Owner("Goooler"))
private val secondBean = Repo(374913489, "AndroidUiDemo", Repo.Owner("Goooler"))
}
}