Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/explore viewmodel 테스트 #34

Merged
merged 16 commits into from
Jan 11, 2025
Merged
Show file tree
Hide file tree
Changes from 15 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
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import kr.co.convention.implementations
import kr.co.convention.libs
import kr.co.convention.testImplementations
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.dependencies
Expand All @@ -21,6 +22,10 @@ class SeeDocsFeatureConventionPlugin : Plugin<Project> {
project(":core:model"),
libs.koin.compose
)

testImplementations(
project(":core:testing")
)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ class SeeDocsLibraryConventionPlugin : Plugin<Project> {
libs.kotlinx.coroutines.android
)
testImplementations(
kotlin("test")
kotlin("test"),
)
androidTestImplementations(
kotlin("test")
kotlin("test"),
)
}
}
Expand Down
2 changes: 1 addition & 1 deletion core/data/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ android {
}

dependencies {
api(projects.core.model)
implementation(projects.core.common)
implementation(projects.core.model)
implementation(projects.core.database)
}
1 change: 1 addition & 0 deletions core/testing/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
17 changes: 17 additions & 0 deletions core/testing/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import kr.co.convention.setNamespace

plugins {
alias(libs.plugins.seedocs.library)
}

setNamespace("core.testing")

dependencies {
api(libs.mockk)
api(libs.kotlinx.coroutines.test)
api(libs.mockk.android)
api(libs.koin.test)
api(libs.koin.junit)
api(projects.core.data)
api(libs.turbine)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package kr.co.testing.repository

import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.update
import kr.co.data.repository.RecentRepository
import kr.co.model.FileInfo

class TestRecentRepository: RecentRepository {

private val recentFilesFlow: MutableStateFlow<List<FileInfo>> =
MutableStateFlow(emptyList())

override suspend fun insert(recentFile: FileInfo) {
recentFilesFlow.update { it + recentFile }
}

override fun get(): Flow<List<FileInfo>> =
recentFilesFlow

override suspend fun delete(recentFile: FileInfo) {
recentFilesFlow.update { it - recentFile }
}
}
19 changes: 19 additions & 0 deletions core/testing/src/main/java/kr/co/testing/rule/CoroutineTestRule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package kr.co.testing.rule

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.resetMain
import kotlinx.coroutines.test.setMain
import org.junit.rules.TestWatcher
import org.junit.runner.Description

class CoroutineTestRule : TestWatcher() {
override fun starting(description: Description?) {
super.starting(description)
Dispatchers.setMain(UnconfinedTestDispatcher())
}

override fun finished(description: Description?) {
Dispatchers.resetMain()
}
}
5 changes: 4 additions & 1 deletion feature/explore/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@ plugins {
alias(libs.plugins.seedocs.library.compose)
}

setNamespace("feature.explore")
setNamespace("feature.explore")
dependencies {
implementation(libs.firebase.crashlytics.buildtools)
}
9 changes: 8 additions & 1 deletion feature/explore/src/main/java/kr/co/di/ExploreModule.kt
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
package kr.co.di

import kr.co.explore.ExploreViewModel
import kr.co.util.FileManagerImpl
import kr.co.util.FileManager
import org.koin.core.module.dsl.viewModel
import org.koin.dsl.module

val exploreModule =
module {
viewModel {
ExploreViewModel(
get()
get(),
get<FileManagerImpl>(),
)
}

single<FileManager> {
FileManagerImpl()
}
}
3 changes: 1 addition & 2 deletions feature/explore/src/main/java/kr/co/explore/ExploreScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,13 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import kr.co.model.ExploreSideEffect
import kr.co.model.ExploreUiIntent
import kr.co.model.ExploreUiState
import kr.co.model.FileInfo
import kr.co.seedocs.feature.explore.R
import kr.co.ui.theme.SeeDocsTheme
import kr.co.ui.theme.Theme
import kr.co.ui.util.LaunchIntentHandler
import kr.co.ui.util.LaunchSideEffect
import kr.co.ui.widget.FileBox
import kr.co.util.DEFAULT_STORAGE
import kr.co.util.FileManagerImpl.Companion.DEFAULT_STORAGE
import kr.co.widget.FolderBox
import org.koin.androidx.compose.koinViewModel

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ import kr.co.model.ExploreUiIntent
import kr.co.model.ExploreUiState
import kr.co.model.FileInfo
import kr.co.ui.base.BaseMviViewModel
import kr.co.util.readPDFOrDirectory
import kr.co.util.FileManagerImpl

internal class ExploreViewModel(
private val recentRepository: RecentRepository,
private val fileManagerImpl: FileManagerImpl,

Choose a reason for hiding this comment

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

ViewModel의 의존성은 FileManager 인터페이스로 두고, 주입되는 클래스를 구체클래스인 FileManagerImpl로 하는 것이 의존성 주입 목적에 맞을 것 같습니다.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

아 이름 바꾸면서 바꼇네요 수정하겠습니다

) :
BaseMviViewModel<ExploreUiState, ExploreUiIntent, ExploreSideEffect>(ExploreUiState.INIT) {

Expand All @@ -26,7 +27,7 @@ internal class ExploreViewModel(
copy(path = path)
}

readPDFOrDirectory(path).partition { it.isDirectory }.let { (folders, files) ->
fileManagerImpl.readPDFOrDirectory(path).partition { it.isDirectory }.let { (folders, files) ->
reduce {
copy(
folders = folders,
Expand Down
7 changes: 7 additions & 0 deletions feature/explore/src/main/java/kr/co/util/FileManager.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package kr.co.util

import kr.co.model.FileInfo

internal fun interface FileManager {
suspend fun readPDFOrDirectory(path: String): List<FileInfo>
}
44 changes: 44 additions & 0 deletions feature/explore/src/main/java/kr/co/util/FileManagerImpl.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package kr.co.util

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import kr.co.model.FileInfo
import java.io.File
import java.nio.file.Files
import java.nio.file.attribute.BasicFileAttributes
import java.nio.file.attribute.FileTime
import java.time.LocalDateTime
import java.time.ZoneId

internal class FileManagerImpl: FileManager {
override suspend fun readPDFOrDirectory(
path: String,
): List<FileInfo> = withContext(Dispatchers.IO) {
File(path).listFiles()?.filter { !it.isHidden && (it.isDirectory || it.extension == PDF) }
?.map {
val attributes = getFileAttributes(it)
FileInfo(
name = it.name,
path = it.path,
type = FileInfo.Type.from(it.extension),
isDirectory = it.isDirectory,
size = it.length(),
isHidden = it.isHidden,
createdAt = attributes.creationTime().toLocalDateTime(),
lastModified = attributes.lastModifiedTime().toLocalDateTime(),
)
} ?: emptyList()
}

private fun getFileAttributes(file: File): BasicFileAttributes =
Files.readAttributes(file.toPath(), BasicFileAttributes::class.java)

private fun FileTime.toLocalDateTime(): LocalDateTime =
LocalDateTime.ofInstant(this.toInstant(), ZoneId.systemDefault())

companion object {
internal const val DEFAULT_STORAGE = "/storage/emulated/0"

private const val PDF = "pdf"
}
}
40 changes: 0 additions & 40 deletions feature/explore/src/main/java/kr/co/util/FileUtil.kt

This file was deleted.

Loading
Loading