diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index 6b04ece..3746213 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -14,6 +14,7 @@
+
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 37a7509..7bfef59 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/build.gradle b/build.gradle
index 9239b7c..bf1a973 100644
--- a/build.gradle
+++ b/build.gradle
@@ -10,6 +10,7 @@ buildscript {
classpath Deps.Gradle.gradle
classpath Deps.Gradle.kotlinGradlePlugin
classpath Deps.Gradle.androidMavenGradlePlugin
+ classpath Deps.Gradle.hiltAndroidGradlePlugin
}
}
diff --git a/buildSrc/src/main/java/dependencies/Deps.kt b/buildSrc/src/main/java/dependencies/Deps.kt
index 77b7563..89c8031 100644
--- a/buildSrc/src/main/java/dependencies/Deps.kt
+++ b/buildSrc/src/main/java/dependencies/Deps.kt
@@ -9,6 +9,7 @@ object Deps {
const val gradle = "com.android.tools.build:gradle:3.6.3"
const val kotlinGradlePlugin = "org.jetbrains.kotlin:kotlin-gradle-plugin:${Kotlin.version}"
const val androidMavenGradlePlugin = "com.github.dcendents:android-maven-gradle-plugin:2.1"
+ const val hiltAndroidGradlePlugin = "com.google.dagger:hilt-android-gradle-plugin:${Hilt.version}"
}
object Kotlin {
@@ -20,6 +21,7 @@ object Deps {
}
object AndroidX {
+ const val activityKtx = "androidx.activity:activity-ktx:1.1.0"
const val appCompat = "androidx.appcompat:appcompat:1.1.0"
const val constraintLayout = "androidx.constraintlayout:constraintlayout:2.0.0-beta4"
const val recyclerView = "androidx.recyclerview:recyclerview:1.1.0"
@@ -28,6 +30,18 @@ object Deps {
const val viewModelKtx = "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"
const val liveDataKtx = "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0"
}
+
+ object Hilt {
+ const val version = "1.0.0-alpha02"
+ const val lifecycleViewModel = "androidx.hilt:hilt-lifecycle-viewmodel:$version"
+ const val compiler = "androidx.hilt:hilt-compiler:$version"
+ }
+ }
+
+ object Hilt {
+ const val version = "2.28.3-alpha"
+ const val android = "com.google.dagger:hilt-android:$version"
+ const val compiler = "com.google.dagger:hilt-android-compiler:$version"
}
object Glide {
@@ -39,8 +53,13 @@ object Deps {
const val gson = "com.squareup.retrofit2:converter-gson:2.8.1"
}
+ object OkHttp {
+ const val logging = "com.squareup.okhttp3:logging-interceptor:4.9.0"
+ }
+
object Test {
const val junit4 = "junit:junit:4.13"
const val coreTesting = "androidx.arch.core:core-testing:2.1.0"
+ const val mockitoCore = "org.mockito:mockito-core:3.5.13"
}
}
\ No newline at end of file
diff --git a/example/androidwithdsl/src/main/java/dohun/kim/kinda/androidwithdsl/CountViewModel.kt b/example/androidwithdsl/src/main/java/dohun/kim/kinda/androidwithdsl/CountViewModel.kt
index 5b33803..979ce76 100644
--- a/example/androidwithdsl/src/main/java/dohun/kim/kinda/androidwithdsl/CountViewModel.kt
+++ b/example/androidwithdsl/src/main/java/dohun/kim/kinda/androidwithdsl/CountViewModel.kt
@@ -9,24 +9,24 @@ import kotlinx.coroutines.delay
class CountViewModel : KindaViewModel(
initialState = CountState(),
reducer = buildReducer {
- whenEvent(CountEvent.AttemptMagic) {
+ whenEvent {
dispatch(CountSideEffect.Magic)
}
- whenEvent(CountEvent.Decrease) {
+ whenEvent {
next(copy(count = count - 1))
}
- whenEvent(CountEvent.Increase) {
+ whenEvent {
next(copy(count = count + 1))
}
- whenEvent(CountEvent.Increase1000) {
+ whenEvent {
next(copy(count = count + 1000))
}
},
sideEffectHandler = buildSideEffectHandler {
- whenSideEffect(CountSideEffect.Magic) {
+ whenSideEffect {
delay(1000)
CountEvent.Increase1000
}
diff --git a/example/hilt-retrofit-test/.gitignore b/example/hilt-retrofit-test/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/example/hilt-retrofit-test/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/example/hilt-retrofit-test/build.gradle b/example/hilt-retrofit-test/build.gradle
new file mode 100644
index 0000000..037c690
--- /dev/null
+++ b/example/hilt-retrofit-test/build.gradle
@@ -0,0 +1,66 @@
+import dependencies.Deps
+
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+apply plugin: 'kotlin-android-extensions'
+apply plugin: 'kotlin-kapt'
+apply plugin: 'dagger.hilt.android.plugin'
+
+android {
+ compileSdkVersion 30
+ buildToolsVersion "30.0.2"
+
+ defaultConfig {
+ applicationId "dohun.kim.kinda.hilt_retrofit_test"
+ minSdkVersion 16
+ targetSdkVersion 30
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+
+ kotlinOptions {
+ jvmTarget = JavaVersion.VERSION_1_8.toString()
+ }
+}
+
+dependencies {
+ implementation project(path: ':kinda-core')
+ implementation project(path: ':kinda-dsl')
+ implementation project(path: ':kinda-android')
+
+ implementation Deps.Glide.glide
+
+ implementation Deps.Kotlin.kotlin
+
+ implementation Deps.AndroidX.activityKtx
+ implementation Deps.AndroidX.appCompat
+ implementation Deps.AndroidX.constraintLayout
+ implementation Deps.AndroidX.recyclerView
+
+ implementation Deps.AndroidX.Hilt.lifecycleViewModel
+ kapt Deps.AndroidX.Hilt.compiler
+
+ implementation Deps.Hilt.android
+ kapt Deps.Hilt.compiler
+
+ implementation Deps.Retrofit.retrofit
+ implementation Deps.Retrofit.gson
+
+ testImplementation project(path: ':kinda-android-test')
+ testImplementation Deps.Test.junit4
+ testImplementation Deps.Test.mockitoCore
+}
diff --git a/example/hilt-retrofit-test/proguard-rules.pro b/example/hilt-retrofit-test/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/example/hilt-retrofit-test/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/example/hilt-retrofit-test/src/main/AndroidManifest.xml b/example/hilt-retrofit-test/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..2fedd4c
--- /dev/null
+++ b/example/hilt-retrofit-test/src/main/AndroidManifest.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/ExampleApplication.kt b/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/ExampleApplication.kt
new file mode 100644
index 0000000..fe6380d
--- /dev/null
+++ b/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/ExampleApplication.kt
@@ -0,0 +1,7 @@
+package dohun.kim.kinda.hilt_retrofit_test
+
+import android.app.Application
+import dagger.hilt.android.HiltAndroidApp
+
+@HiltAndroidApp
+class ExampleApplication : Application()
\ No newline at end of file
diff --git a/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/data/GithubApi.kt b/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/data/GithubApi.kt
new file mode 100644
index 0000000..1a6925b
--- /dev/null
+++ b/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/data/GithubApi.kt
@@ -0,0 +1,10 @@
+package dohun.kim.kinda.hilt_retrofit_test.data
+
+import dohun.kim.kinda.hilt_retrofit_test.model.UserModel
+import retrofit2.http.GET
+
+interface GithubApi {
+
+ @GET("users")
+ suspend fun getUsers(): List
+}
\ No newline at end of file
diff --git a/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/data/GithubRepository.kt b/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/data/GithubRepository.kt
new file mode 100644
index 0000000..3a97e27
--- /dev/null
+++ b/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/data/GithubRepository.kt
@@ -0,0 +1,22 @@
+package dohun.kim.kinda.hilt_retrofit_test.data
+
+import dohun.kim.kinda.hilt_retrofit_test.data.exception.getCustomHttpException
+import dohun.kim.kinda.hilt_retrofit_test.model.UserModel
+import javax.inject.Inject
+
+interface GithubRepository {
+
+ suspend fun getUsers(): List
+}
+
+class DefaultGithubRepository @Inject constructor(
+ private val githubApi: GithubApi
+) : GithubRepository {
+
+ override suspend fun getUsers(): List =
+ try {
+ githubApi.getUsers()
+ } catch (e: Exception) {
+ throw e.getCustomHttpException()
+ }
+}
\ No newline at end of file
diff --git a/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/data/exception/CustomExceptionExtensions.kt b/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/data/exception/CustomExceptionExtensions.kt
new file mode 100644
index 0000000..50bf897
--- /dev/null
+++ b/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/data/exception/CustomExceptionExtensions.kt
@@ -0,0 +1,15 @@
+package dohun.kim.kinda.hilt_retrofit_test.data.exception
+
+import retrofit2.HttpException
+
+fun Exception.getCustomHttpException(): Exception =
+ when (this) {
+ is HttpException -> {
+ when (code()) {
+ 403 -> ForbiddenException()
+ 500 -> InternalErrorException()
+ else -> InternalErrorException()
+ }
+ }
+ else -> InternalErrorException()
+ }
\ No newline at end of file
diff --git a/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/data/exception/ForbiddenException.kt b/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/data/exception/ForbiddenException.kt
new file mode 100644
index 0000000..7df4620
--- /dev/null
+++ b/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/data/exception/ForbiddenException.kt
@@ -0,0 +1,3 @@
+package dohun.kim.kinda.hilt_retrofit_test.data.exception
+
+class ForbiddenException : RuntimeException()
\ No newline at end of file
diff --git a/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/data/exception/InternalErrorException.kt b/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/data/exception/InternalErrorException.kt
new file mode 100644
index 0000000..2122da9
--- /dev/null
+++ b/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/data/exception/InternalErrorException.kt
@@ -0,0 +1,3 @@
+package dohun.kim.kinda.hilt_retrofit_test.data.exception
+
+class InternalErrorException : RuntimeException()
\ No newline at end of file
diff --git a/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/di/NetworkModule.kt b/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/di/NetworkModule.kt
new file mode 100644
index 0000000..7f5d45d
--- /dev/null
+++ b/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/di/NetworkModule.kt
@@ -0,0 +1,24 @@
+package dohun.kim.kinda.hilt_retrofit_test.di
+
+import dagger.Module
+import dagger.Provides
+import dagger.hilt.InstallIn
+import dagger.hilt.android.components.ApplicationComponent
+import dohun.kim.kinda.hilt_retrofit_test.data.GithubApi
+import retrofit2.Retrofit
+import retrofit2.converter.gson.GsonConverterFactory
+import javax.inject.Singleton
+
+@Module
+@InstallIn(ApplicationComponent::class)
+class NetworkModule {
+
+ @Provides
+ @Singleton
+ fun provideGithubApi(): GithubApi =
+ Retrofit.Builder()
+ .addConverterFactory(GsonConverterFactory.create())
+ .baseUrl("https://api.github.com/")
+ .build()
+ .create(GithubApi::class.java)
+}
\ No newline at end of file
diff --git a/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/di/RepositoryModule.kt b/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/di/RepositoryModule.kt
new file mode 100644
index 0000000..0aefe8b
--- /dev/null
+++ b/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/di/RepositoryModule.kt
@@ -0,0 +1,18 @@
+package dohun.kim.kinda.hilt_retrofit_test.di
+
+import dagger.Binds
+import dagger.Module
+import dagger.hilt.InstallIn
+import dagger.hilt.android.components.ActivityRetainedComponent
+import dagger.hilt.android.scopes.ActivityRetainedScoped
+import dohun.kim.kinda.hilt_retrofit_test.data.DefaultGithubRepository
+import dohun.kim.kinda.hilt_retrofit_test.data.GithubRepository
+
+@Module
+@InstallIn(ActivityRetainedComponent::class)
+abstract class RepositoryModule {
+
+ @Binds
+ @ActivityRetainedScoped
+ abstract fun bindGithubRepository(githubRepository: DefaultGithubRepository): GithubRepository
+}
\ No newline at end of file
diff --git a/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/github/GithubActivity.kt b/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/github/GithubActivity.kt
new file mode 100644
index 0000000..a41dd26
--- /dev/null
+++ b/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/github/GithubActivity.kt
@@ -0,0 +1,35 @@
+package dohun.kim.kinda.hilt_retrofit_test.github
+
+import android.os.Bundle
+import android.view.View
+import android.widget.Toast
+import androidx.activity.viewModels
+import dagger.hilt.android.AndroidEntryPoint
+import dohun.kim.kinda.hilt_retrofit_test.R
+import dohun.kim.kinda.kinda_android.KindaActivity
+import kotlinx.android.synthetic.main.activity_github.*
+
+@AndroidEntryPoint
+class GithubActivity : KindaActivity() {
+
+ override val viewModel: GithubViewModel by viewModels()
+
+ private val userListAdapter = UserListAdapter()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_github)
+
+ rv_user.adapter = userListAdapter
+ }
+
+ override fun render(state: GithubState) {
+ pb_loading.visibility = if (state.isLoading) View.VISIBLE else View.INVISIBLE
+
+ userListAdapter.submitList(state.users)
+
+ state.toastEvent.getData()?.let { strRes ->
+ Toast.makeText(this, strRes, Toast.LENGTH_SHORT).show()
+ }
+ }
+}
diff --git a/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/github/GithubState.kt b/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/github/GithubState.kt
new file mode 100644
index 0000000..3e1675f
--- /dev/null
+++ b/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/github/GithubState.kt
@@ -0,0 +1,24 @@
+package dohun.kim.kinda.hilt_retrofit_test.github
+
+import dohun.kim.kinda.hilt_retrofit_test.model.UserModel
+import dohun.kim.kinda.kinda_core.Event
+import dohun.kim.kinda.kinda_core.KindaEvent
+import dohun.kim.kinda.kinda_core.KindaSideEffect
+import dohun.kim.kinda.kinda_core.KindaState
+
+data class GithubState(
+ val isLoading: Boolean = false,
+ val users: List = emptyList(),
+
+ val toastEvent: Event = Event()
+) : KindaState
+
+sealed class GithubEvent : KindaEvent {
+ object AttemptGetUsers : GithubEvent()
+ data class GetUsersSucceed(val users: List) : GithubEvent()
+ data class ToastEvent(val message: String) : GithubEvent()
+}
+
+sealed class GithubSideEffect : KindaSideEffect {
+ object GetUsers : GithubSideEffect()
+}
\ No newline at end of file
diff --git a/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/github/GithubViewModel.kt b/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/github/GithubViewModel.kt
new file mode 100644
index 0000000..c448ce1
--- /dev/null
+++ b/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/github/GithubViewModel.kt
@@ -0,0 +1,47 @@
+package dohun.kim.kinda.hilt_retrofit_test.github
+
+import androidx.hilt.lifecycle.ViewModelInject
+import dohun.kim.kinda.hilt_retrofit_test.data.GithubRepository
+import dohun.kim.kinda.hilt_retrofit_test.data.exception.ForbiddenException
+import dohun.kim.kinda.hilt_retrofit_test.data.exception.InternalErrorException
+import dohun.kim.kinda.kinda_android.KindaViewModel
+import dohun.kim.kinda.kinda_core.Event
+import dohun.kim.kinda.kinda_core.interceptor.LoggingInterceptor
+import dohun.kim.kinda.kinda_dsl.buildReducer
+import dohun.kim.kinda.kinda_dsl.buildSideEffectHandler
+
+class GithubViewModel @ViewModelInject constructor(
+ private val githubRepository: GithubRepository
+) : KindaViewModel(
+ initialState = GithubState(),
+ reducer = buildReducer {
+ whenEvent {
+ next(copy(isLoading = true), GithubSideEffect.GetUsers)
+ }
+
+ whenEvent {
+ next(copy(users = it.users, isLoading = false))
+ }
+
+ whenEvent {
+ next(copy(toastEvent = Event(it.message), isLoading = false))
+ }
+ },
+ sideEffectHandler = buildSideEffectHandler {
+ whenSideEffect {
+ try {
+ val users = githubRepository.getUsers()
+ GithubEvent.GetUsersSucceed(users)
+ } catch (e: InternalErrorException) {
+ GithubEvent.ToastEvent("서버 문제가 발생했습니다.")
+ } catch (e: ForbiddenException) {
+ GithubEvent.ToastEvent("잠시 후 다시 시도해주세요.")
+ }
+ }
+ },
+ interceptors = setOf(LoggingInterceptor())
+) {
+ init {
+ intent(GithubEvent.AttemptGetUsers)
+ }
+}
\ No newline at end of file
diff --git a/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/github/UserListAdapter.kt b/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/github/UserListAdapter.kt
new file mode 100644
index 0000000..c649f17
--- /dev/null
+++ b/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/github/UserListAdapter.kt
@@ -0,0 +1,27 @@
+package dohun.kim.kinda.hilt_retrofit_test.github
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import com.bumptech.glide.Glide
+import dohun.kim.kinda.hilt_retrofit_test.R
+import dohun.kim.kinda.hilt_retrofit_test.model.UserModel
+import kotlinx.android.synthetic.main.item_user.view.*
+
+class UserListAdapter : ListAdapter(UserModel.DIFF_CALLBACK) {
+
+ inner class UserHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+ fun bind(position: Int) {
+ val item = getItem(position)
+ Glide.with(itemView).load(item.avatarUrl).into(itemView.iv_avatar)
+ itemView.tv_login.text = item.login
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserHolder =
+ UserHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_user, parent, false))
+
+ override fun onBindViewHolder(holder: UserHolder, position: Int) = holder.bind(position)
+}
\ No newline at end of file
diff --git a/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/model/UserModel.kt b/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/model/UserModel.kt
new file mode 100644
index 0000000..a1f4af9
--- /dev/null
+++ b/example/hilt-retrofit-test/src/main/java/dohun/kim/kinda/hilt_retrofit_test/model/UserModel.kt
@@ -0,0 +1,24 @@
+package dohun.kim.kinda.hilt_retrofit_test.model
+
+import androidx.recyclerview.widget.DiffUtil
+import com.google.gson.annotations.SerializedName
+
+data class UserModel(
+
+ val login: String,
+
+ val id: Int,
+
+ @SerializedName("avatar_url")
+ val avatarUrl: String
+) {
+ companion object {
+ val DIFF_CALLBACK = object : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(oldItem: UserModel, newItem: UserModel): Boolean =
+ oldItem.id == newItem.id
+
+ override fun areContentsTheSame(oldItem: UserModel, newItem: UserModel): Boolean =
+ oldItem.login == newItem.login && oldItem.avatarUrl == newItem.avatarUrl
+ }
+ }
+}
\ No newline at end of file
diff --git a/example/hilt-retrofit-test/src/main/res/drawable-v24/ic_launcher_foreground.xml b/example/hilt-retrofit-test/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 0000000..2b068d1
--- /dev/null
+++ b/example/hilt-retrofit-test/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/example/hilt-retrofit-test/src/main/res/drawable/ic_launcher_background.xml b/example/hilt-retrofit-test/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..07d5da9
--- /dev/null
+++ b/example/hilt-retrofit-test/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/example/hilt-retrofit-test/src/main/res/layout/activity_github.xml b/example/hilt-retrofit-test/src/main/res/layout/activity_github.xml
new file mode 100644
index 0000000..cc8f307
--- /dev/null
+++ b/example/hilt-retrofit-test/src/main/res/layout/activity_github.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/example/hilt-retrofit-test/src/main/res/layout/item_user.xml b/example/hilt-retrofit-test/src/main/res/layout/item_user.xml
new file mode 100644
index 0000000..3d591ea
--- /dev/null
+++ b/example/hilt-retrofit-test/src/main/res/layout/item_user.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/example/hilt-retrofit-test/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/example/hilt-retrofit-test/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/example/hilt-retrofit-test/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/example/hilt-retrofit-test/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/example/hilt-retrofit-test/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/example/hilt-retrofit-test/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/example/hilt-retrofit-test/src/main/res/mipmap-hdpi/ic_launcher.png b/example/hilt-retrofit-test/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..a571e60
Binary files /dev/null and b/example/hilt-retrofit-test/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/example/hilt-retrofit-test/src/main/res/mipmap-hdpi/ic_launcher_round.png b/example/hilt-retrofit-test/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..61da551
Binary files /dev/null and b/example/hilt-retrofit-test/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/example/hilt-retrofit-test/src/main/res/mipmap-mdpi/ic_launcher.png b/example/hilt-retrofit-test/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..c41dd28
Binary files /dev/null and b/example/hilt-retrofit-test/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/example/hilt-retrofit-test/src/main/res/mipmap-mdpi/ic_launcher_round.png b/example/hilt-retrofit-test/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..db5080a
Binary files /dev/null and b/example/hilt-retrofit-test/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/example/hilt-retrofit-test/src/main/res/mipmap-xhdpi/ic_launcher.png b/example/hilt-retrofit-test/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..6dba46d
Binary files /dev/null and b/example/hilt-retrofit-test/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/example/hilt-retrofit-test/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/example/hilt-retrofit-test/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..da31a87
Binary files /dev/null and b/example/hilt-retrofit-test/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/example/hilt-retrofit-test/src/main/res/mipmap-xxhdpi/ic_launcher.png b/example/hilt-retrofit-test/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..15ac681
Binary files /dev/null and b/example/hilt-retrofit-test/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/example/hilt-retrofit-test/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/example/hilt-retrofit-test/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..b216f2d
Binary files /dev/null and b/example/hilt-retrofit-test/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/example/hilt-retrofit-test/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/example/hilt-retrofit-test/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..f25a419
Binary files /dev/null and b/example/hilt-retrofit-test/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/example/hilt-retrofit-test/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/example/hilt-retrofit-test/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..e96783c
Binary files /dev/null and b/example/hilt-retrofit-test/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/example/hilt-retrofit-test/src/main/res/values/colors.xml b/example/hilt-retrofit-test/src/main/res/values/colors.xml
new file mode 100644
index 0000000..4faecfa
--- /dev/null
+++ b/example/hilt-retrofit-test/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ #6200EE
+ #3700B3
+ #03DAC5
+
\ No newline at end of file
diff --git a/example/hilt-retrofit-test/src/main/res/values/strings.xml b/example/hilt-retrofit-test/src/main/res/values/strings.xml
new file mode 100644
index 0000000..7156113
--- /dev/null
+++ b/example/hilt-retrofit-test/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ HiltRetrofitTest
+
\ No newline at end of file
diff --git a/example/hilt-retrofit-test/src/main/res/values/styles.xml b/example/hilt-retrofit-test/src/main/res/values/styles.xml
new file mode 100644
index 0000000..fac9291
--- /dev/null
+++ b/example/hilt-retrofit-test/src/main/res/values/styles.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/example/hilt-retrofit-test/src/test/java/dohun/kim/kinda/hilt_retrofit_test/GithubViewModelTest.kt b/example/hilt-retrofit-test/src/test/java/dohun/kim/kinda/hilt_retrofit_test/GithubViewModelTest.kt
new file mode 100644
index 0000000..4eec24a
--- /dev/null
+++ b/example/hilt-retrofit-test/src/test/java/dohun/kim/kinda/hilt_retrofit_test/GithubViewModelTest.kt
@@ -0,0 +1,53 @@
+package dohun.kim.kinda.hilt_retrofit_test
+
+import dohun.kim.kinda.hilt_retrofit_test.data.GithubRepository
+import dohun.kim.kinda.hilt_retrofit_test.data.exception.InternalErrorException
+import dohun.kim.kinda.hilt_retrofit_test.github.GithubEvent
+import dohun.kim.kinda.hilt_retrofit_test.github.GithubSideEffect
+import dohun.kim.kinda.hilt_retrofit_test.github.GithubState
+import dohun.kim.kinda.hilt_retrofit_test.github.GithubViewModel
+import dohun.kim.kinda.hilt_retrofit_test.model.UserModel
+import dohun.kim.kinda.kinda_android.KindaViewModel
+import dohun.kim.kinda.kinda_android_test.KindaViewModelTest
+import kotlinx.coroutines.runBlocking
+import org.junit.Assert.assertEquals
+import org.junit.Test
+import org.mockito.Mock
+import org.mockito.Mockito.`when`
+
+class GithubViewModelTest : KindaViewModelTest() {
+
+ @Mock
+ private lateinit var githubRepository: GithubRepository
+
+ override fun buildViewModel(): KindaViewModel =
+ GithubViewModel(githubRepository)
+
+ @Test
+ fun `AttemptGetUsers GettingUsersSucceed SetUsersState`() = runBlocking {
+ `when`(githubRepository.getUsers()).thenReturn(users)
+
+ GithubEvent.AttemptGetUsers expectState {
+ assertEquals(users, it.users)
+ assertEquals(users[0].id, it.users[0].id)
+ assertEquals(users.size, it.users.size)
+ }
+ }
+
+ @Test
+ fun `AttemptGetUsers ThrowInternalErrorException ShowErrorMessage`() = runBlocking {
+ `when`(githubRepository.getUsers())
+ .thenThrow(InternalErrorException())
+
+ GithubEvent.AttemptGetUsers expectState {
+ assertEquals("서버 문제가 발생했습니다.", it.toastEvent.peekData())
+ }
+ }
+
+ companion object TestData {
+ private val users = listOf(
+ UserModel("kimdohun0104", 0, "https://kimdohunimage.jpg"),
+ UserModel("hello", 1, "https://helloworld.jpg")
+ )
+ }
+}
\ No newline at end of file
diff --git a/kinda-android-test/build.gradle b/kinda-android-test/build.gradle
index f210fe1..706b0ff 100644
--- a/kinda-android-test/build.gradle
+++ b/kinda-android-test/build.gradle
@@ -37,4 +37,5 @@ dependencies {
implementation Deps.Test.junit4
implementation Deps.Test.coreTesting
+ implementation Deps.Test.mockitoCore
}
\ No newline at end of file
diff --git a/kinda-android-test/src/main/java/dohun/kim/kinda/kinda_android_test/KindaViewModelTest.kt b/kinda-android-test/src/main/java/dohun/kim/kinda/kinda_android_test/KindaViewModelTest.kt
index c89c105..b135df2 100644
--- a/kinda-android-test/src/main/java/dohun/kim/kinda/kinda_android_test/KindaViewModelTest.kt
+++ b/kinda-android-test/src/main/java/dohun/kim/kinda/kinda_android_test/KindaViewModelTest.kt
@@ -7,6 +7,7 @@ import dohun.kim.kinda.kinda_core.KindaSideEffect
import dohun.kim.kinda.kinda_core.KindaState
import org.junit.Before
import org.junit.Rule
+import org.mockito.MockitoAnnotations
abstract class KindaViewModelTest {
@@ -22,7 +23,8 @@ abstract class KindaViewModelTest
@Before
- fun initViewModel() {
+ fun initKindaViewModelTest() {
+ MockitoAnnotations.openMocks(this)
viewModel = buildViewModel()
}
@@ -32,6 +34,7 @@ abstract class KindaViewModelTest Unit) {
viewModel.intent(this)
+ Thread.sleep(50) // Waiting for the side effect result
assertion.invoke(currentState)
}
@@ -39,6 +42,7 @@ abstract class KindaViewModelTest
viewModel.intent(event)
}
+ Thread.sleep(100) // Waiting for the side effect result
assertion.invoke(currentState)
}
}
\ No newline at end of file
diff --git a/kinda-core/src/main/java/dohun/kim/kinda/kinda_core/Event.kt b/kinda-core/src/main/java/dohun/kim/kinda/kinda_core/Event.kt
index a2a2987..81ca957 100644
--- a/kinda-core/src/main/java/dohun/kim/kinda/kinda_core/Event.kt
+++ b/kinda-core/src/main/java/dohun/kim/kinda/kinda_core/Event.kt
@@ -1,5 +1,6 @@
package dohun.kim.kinda.kinda_core
+import org.jetbrains.annotations.TestOnly
import java.util.concurrent.atomic.AtomicBoolean
class Event(
@@ -13,4 +14,9 @@ class Event(
}
return null
}
+
+ @TestOnly
+ fun peekData(): T? {
+ return data
+ }
}
\ No newline at end of file
diff --git a/kinda-dsl/src/main/java/dohun/kim/kinda/kinda_dsl/ReducerDslBuilder.kt b/kinda-dsl/src/main/java/dohun/kim/kinda/kinda_dsl/ReducerDslBuilder.kt
index ba15b30..d35e22a 100644
--- a/kinda-dsl/src/main/java/dohun/kim/kinda/kinda_dsl/ReducerDslBuilder.kt
+++ b/kinda-dsl/src/main/java/dohun/kim/kinda/kinda_dsl/ReducerDslBuilder.kt
@@ -4,13 +4,12 @@ import dohun.kim.kinda.kinda_core.*
class ReducerDslBuilder {
- val reduceMap = HashMap Next>()
+ val reduceMap = HashMap, S.(E) -> Next>()
- fun whenEvent(
- event: E,
- next: S.(E) -> Next
+ inline fun whenEvent(
+ noinline next: S.(EVENT) -> Next
) {
- reduceMap[event] = next
+ reduceMap[EVENT::class.java as Class] = next as S.(E) -> Next
}
fun next(state: S, sideEffect: SE? = null) = Next(state, sideEffect)
@@ -22,7 +21,7 @@ class ReducerDslBuilder {
fun build() = object : KindaReducer {
override fun reduce(state: S, event: E): Next {
reduceMap.keys.forEach { key ->
- if (key::class.isInstance(event)) {
+ if (key.isInstance(event)) {
return reduceMap[key]!!.invoke(state, event)
}
}
diff --git a/kinda-dsl/src/main/java/dohun/kim/kinda/kinda_dsl/SideEffectHandlerDslBuilder.kt b/kinda-dsl/src/main/java/dohun/kim/kinda/kinda_dsl/SideEffectHandlerDslBuilder.kt
index 527e928..3ab5c65 100644
--- a/kinda-dsl/src/main/java/dohun/kim/kinda/kinda_dsl/SideEffectHandlerDslBuilder.kt
+++ b/kinda-dsl/src/main/java/dohun/kim/kinda/kinda_dsl/SideEffectHandlerDslBuilder.kt
@@ -7,19 +7,19 @@ import dohun.kim.kinda.kinda_core.KindaState
class SideEffectHandlerDslBuilder {
- val sideEffectHandleMap = HashMap E>()
+ val sideEffectHandleMap = HashMap, suspend S.() -> E>()
- fun whenSideEffect(
- sideEffect: SE,
- next: suspend S.() -> E
+ inline fun whenSideEffect(
+ noinline next: suspend S.() -> E
) {
- sideEffectHandleMap[sideEffect] = next
+ sideEffectHandleMap[SIDE_EFFECT::class.java as Class] = next
}
fun build() = object : KindaSideEffectHandler {
override suspend fun handle(state: S, sideEffect: SE): E {
+ println("handle side Effect")
sideEffectHandleMap.keys.forEach { key ->
- if (key::class.isInstance(sideEffect)) {
+ if (key.isInstance(sideEffect)) {
return sideEffectHandleMap[key]!!.invoke(state)
}
}
diff --git a/settings.gradle b/settings.gradle
index 6c3a918..51de999 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,3 +1,4 @@
+include ':example:hilt-retrofit-test'
include ':kinda-android-test'
include ':example:androidwithdsl'
include ':example:android'