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

Add GetDayLogList Usecase and it's viewModel Impelementation. #48

Merged
merged 1 commit into from Jan 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 9 additions & 8 deletions app/build.gradle
Expand Up @@ -56,12 +56,13 @@ android {
dependencies {

implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.4.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.5.0'
implementation "androidx.compose.ui:ui:$compose_version"
implementation "androidx.compose.material:material:$compose_version"
implementation "androidx.compose.material:material-icons-extended:$compose_version"
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
implementation 'androidx.test:core-ktx:1.4.0'
debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.0'
implementation 'androidx.activity:activity-compose:1.4.0'
Expand All @@ -71,16 +72,17 @@ dependencies {
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.2")
testImplementation("org.junit.jupiter:junit-jupiter-params:5.8.2")
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.0'
testImplementation("de.mannodermaus.junit5:android-test-core:1.3.0")
testImplementation "com.google.truth:truth:1.1.2"

androidTestImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.0'
androidTestImplementation("androidx.test:runner:1.4.0")
androidTestImplementation("org.junit.jupiter:junit-jupiter-api:5.8.2")
androidTestImplementation("de.mannodermaus.junit5:android-test-core:1.3.0")
androidTestRuntimeOnly("de.mannodermaus.junit5:android-test-runner:1.3.0")
// androidTestImplementation("de.mannodermaus.junit5:android-test-compose:0.1.0-SNAPSHOT")
debugImplementation "com.google.truth:truth:1.1.2"
testImplementation "com.google.truth:truth:1.1.2"
androidTestImplementation "com.google.truth:truth:1.1.2"
androidTestImplementation 'androidx.test:core:1.0.0'
androidTestImplementation 'androidx.test:core:1.4.0'
// to wait flow
androidTestImplementation("app.cash.turbine:turbine:0.6.1")

Expand All @@ -94,16 +96,15 @@ dependencies {
kapt "com.google.dagger:hilt-android-compiler:2.37"
implementation "androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03"
kapt "androidx.hilt:hilt-compiler:1.0.0"
implementation 'androidx.hilt:hilt-navigation-compose:1.0.0-beta01'
implementation 'androidx.hilt:hilt-navigation-compose:1.0.0'

// Datetime better than util Date
implementation "org.jetbrains.kotlinx:kotlinx-datetime:0.3.1"

// Room
def room_version = "2.4.0-alpha03"
def room_version = "2.4.1"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"

// Kotlin Extensions and Coroutines support for Room
implementation "androidx.room:room-ktx:$room_version"
}
Expand Up @@ -3,13 +3,13 @@ package com.wangmir.calliope
import android.content.Context
import androidx.test.core.app.ApplicationProvider
import com.google.common.truth.Truth.assertThat
import com.wangmir.calliope.model.DataRepository
import com.wangmir.calliope.model.adapters.data.DataRepositoryImpl
import com.wangmir.calliope.model.adapters.data.LocalDatabase
import com.wangmir.calliope.model.entities.Date
import com.wangmir.calliope.model.entities.DayLog
import com.wangmir.calliope.model.entities.EmotionLog
import com.wangmir.calliope.model.entities.TextLog
import com.wangmir.calliope.domain.repositories.DataRepository
import com.wangmir.calliope.adapters.data.DataRepositoryImpl
import com.wangmir.calliope.adapters.data.LocalDatabase
import com.wangmir.calliope.domain.entities.Date
import com.wangmir.calliope.domain.entities.DayLog
import com.wangmir.calliope.domain.entities.EmotionLog
import com.wangmir.calliope.domain.entities.TextLog
import com.wangmir.calliope.testutils.getOrAwaitValue
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
Expand Down
39 changes: 39 additions & 0 deletions app/src/androidTest/java/com/wangmir/calliope/UseCasesTest.kt
@@ -0,0 +1,39 @@
package com.wangmir.calliope

import com.google.common.truth.Truth.assertThat
import com.wangmir.calliope.adapters.data.FakeDataRepository
import com.wangmir.calliope.domain.usecases.GetDayLogList
import com.wangmir.calliope.domain.util.DayLogFilter
import com.wangmir.calliope.domain.util.OrderType
import com.wangmir.calliope.testutils.getOrAwaitValue
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.runBlocking
import org.junit.jupiter.api.Test

@ExperimentalCoroutinesApi
class UseCasesTest {

private val getDayLogList get() = GetDayLogList(FakeDataRepository())

@Test
fun testGetDayLogListByYear() = runBlocking {
val uc = getDayLogList
var filter = DayLogFilter.Year(OrderType.Ascending, 2021)
var result = uc(filter).getOrAwaitValue(this, dispatcher = Dispatchers.IO)
assertThat(result).isNotNull()
result.forEach {
assertThat(it.date.year).isEqualTo(2021)
}

assertThat(result[0].date.toInt()).isLessThan(result[1].date.toInt())

filter = DayLogFilter.Year(OrderType.Descending, 2021)
result = uc(filter).getOrAwaitValue(this, dispatcher = Dispatchers.IO)
result.forEach {
assertThat(it.date.year).isEqualTo(2021)
}

assertThat(result[0].date.toInt()).isGreaterThan(result[1].date.toInt())
}
}
2 changes: 2 additions & 0 deletions app/src/main/java/com/wangmir/calliope/MainActivity.kt
Expand Up @@ -8,8 +8,10 @@ import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import com.wangmir.calliope.ui.theme.CalliopeTheme
import com.wangmir.calliope.ui.view.Home
import dagger.hilt.android.AndroidEntryPoint

@ExperimentalMaterialApi
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Expand Down
@@ -1,4 +1,4 @@
package com.wangmir.calliope.model.adapters.data
package com.wangmir.calliope.adapters.data

import androidx.room.Delete
import androidx.room.Insert
Expand Down
@@ -1,8 +1,8 @@
package com.wangmir.calliope.model.adapters.data
package com.wangmir.calliope.adapters.data

import com.wangmir.calliope.model.DataRepository
import com.wangmir.calliope.model.entities.DayLog
import com.wangmir.calliope.model.entities.EmotionLog
import com.wangmir.calliope.domain.repositories.DataRepository
import com.wangmir.calliope.domain.entities.DayLog
import com.wangmir.calliope.domain.entities.EmotionLog
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.datetime.LocalDate
Expand Down
@@ -1,10 +1,10 @@
package com.wangmir.calliope.model.adapters.data
package com.wangmir.calliope.adapters.data

import androidx.room.Dao
import androidx.room.Query
import com.wangmir.calliope.model.entities.Date
import com.wangmir.calliope.model.entities.DayLog
import com.wangmir.calliope.model.entities.EmotionLog
import com.wangmir.calliope.domain.entities.Date
import com.wangmir.calliope.domain.entities.DayLog
import com.wangmir.calliope.domain.entities.EmotionLog
import kotlinx.coroutines.flow.Flow
import kotlinx.datetime.LocalDate

Expand Down
@@ -0,0 +1,61 @@
package com.wangmir.calliope.adapters.data

import com.wangmir.calliope.domain.entities.Date
import com.wangmir.calliope.domain.entities.DayLog
import com.wangmir.calliope.domain.entities.EmotionLog
import com.wangmir.calliope.domain.entities.TextLog
import com.wangmir.calliope.domain.repositories.DataRepository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
import kotlinx.datetime.LocalDate

class FakeDataRepository : DataRepository {

companion object {
const val MOCK_KEYWORD = "MOCK_KEYWORD"
}

val list = mutableListOf<DayLog>()
val mockData = DayLog.getMockDayLog()

init {
// year 2021
list.add(mockData.copy(date = Date(2021, 10, 30)))
list.add(mockData.copy(date = Date(2021, 9, 28)))

// year 2022
list.add(mockData.copy(date = Date(2022, 1, 21)))
list.add(mockData.copy(date = Date(2022, 2, 28)))

// keyword has "MOCK_KEYWORD"
list.add(mockData.copy(textLog = TextLog(MOCK_KEYWORD)))
list.add(mockData.copy(textLog = TextLog(MOCK_KEYWORD + "tail misc text")))

// emotion is Fear
list.add(mockData.copy(emotionLog = EmotionLog.Fear))
}

override suspend fun insertDayLog(dayLog: DayLog) {
list.add(dayLog)
}

override suspend fun getDayLog(date: LocalDate): DayLog {
return list.find { it.date == Date(date) }!!
}

override suspend fun deleteDayLog(date: LocalDate) {
list.removeIf { it.date == Date(date) }
}

override fun getDayLogsByYear(year: Int): Flow<List<DayLog>> {
return flowOf(list.filter { it.date.year == year })
}

override fun getDayLogsByKeyword(keyword: String): Flow<List<DayLog>> {
return flowOf(list.filter { it.textLog.text.contains(keyword) })
}

override fun getDayLogsByEmotion(emotionLog: EmotionLog): Flow<List<DayLog>> {
return flowOf(list.filter { it.emotionLog == emotionLog })
}
}
@@ -1,10 +1,10 @@
package com.wangmir.calliope.model.adapters.data
package com.wangmir.calliope.adapters.data

import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import com.wangmir.calliope.model.entities.DayLog
import com.wangmir.calliope.domain.entities.DayLog

@Database(
entities = [DayLog::class],
Expand Down
16 changes: 12 additions & 4 deletions app/src/main/java/com/wangmir/calliope/di/AppModule.kt
@@ -1,9 +1,10 @@
package com.wangmir.calliope.di

import android.app.Application
import com.wangmir.calliope.model.DataRepository
import com.wangmir.calliope.model.adapters.data.DataRepositoryImpl
import com.wangmir.calliope.model.adapters.data.LocalDatabase
import com.wangmir.calliope.adapters.data.FakeDataRepository
import com.wangmir.calliope.adapters.data.LocalDatabase
import com.wangmir.calliope.domain.repositories.DataRepository
import com.wangmir.calliope.domain.usecases.GetDayLogList
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
Expand All @@ -20,5 +21,12 @@ object AppModule {

@Provides
@Singleton
fun provideDataRepository(db: LocalDatabase): DataRepository = DataRepositoryImpl(db.dayLogDao)
fun provideDataRepository(db: LocalDatabase): DataRepository = FakeDataRepository()
// TODO: until make create dayLog view, fake repository will be used as list of view.
// fun provideDataRepository(db: LocalDatabase): DataRepository = DataRepositoryImpl(db.dayLogDao)

@Provides
@Singleton
fun provideGetDayLogList(dataRepository: DataRepository): GetDayLogList =
GetDayLogList(dataRepository)
}
@@ -1,4 +1,4 @@
package com.wangmir.calliope.model.entities
package com.wangmir.calliope.domain.entities

import androidx.room.Embedded
import androidx.room.Entity
Expand Down Expand Up @@ -44,4 +44,8 @@ data class Date (
override fun toString(): String {
return "$year.$month.$dayOfMonth."
}

fun toInt(): Int {
return "$year$month$dayOfMonth".toInt()
}
}
@@ -1,4 +1,4 @@
package com.wangmir.calliope.model.entities
package com.wangmir.calliope.domain.entities

enum class EmotionLog (val value: String) {
NotSet("none"),
Expand Down
@@ -1,4 +1,4 @@
package com.wangmir.calliope.model.entities
package com.wangmir.calliope.domain.entities

data class SttLog(
val sttText: String
Expand Down
@@ -1,4 +1,4 @@
package com.wangmir.calliope.model.entities
package com.wangmir.calliope.domain.entities

data class TextLog(
val text: String
Expand Down
@@ -1,4 +1,4 @@
package com.wangmir.calliope.model.entities
package com.wangmir.calliope.domain.entities

data class VoiceLog(
val audioFilePath: String
Expand Down
@@ -1,7 +1,7 @@
package com.wangmir.calliope.model
package com.wangmir.calliope.domain.repositories

import com.wangmir.calliope.model.entities.DayLog
import com.wangmir.calliope.model.entities.EmotionLog
import com.wangmir.calliope.domain.entities.DayLog
import com.wangmir.calliope.domain.entities.EmotionLog
import kotlinx.coroutines.flow.Flow
import kotlinx.datetime.LocalDate

Expand Down
@@ -0,0 +1,26 @@
package com.wangmir.calliope.domain.usecases

import com.wangmir.calliope.domain.entities.DayLog
import com.wangmir.calliope.domain.repositories.DataRepository
import com.wangmir.calliope.domain.util.DayLogFilter
import com.wangmir.calliope.domain.util.OrderType
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map

class GetDayLogList(
private val dataRepository: DataRepository
) {
operator fun invoke(filter: DayLogFilter): Flow<List<DayLog>> {
val logs = when (filter) {
is DayLogFilter.Year -> dataRepository.getDayLogsByYear(filter.year)
is DayLogFilter.Keyword -> dataRepository.getDayLogsByKeyword(filter.keyword)
is DayLogFilter.Emotion -> dataRepository.getDayLogsByEmotion(filter.emotion)
}
return logs.map { dayLogs ->
when (filter.orderType) {
is OrderType.Ascending -> dayLogs.sortedBy { it.date.toInt() }
is OrderType.Descending -> dayLogs.sortedByDescending { it.date.toInt() }
}
}
}
}
@@ -0,0 +1,9 @@
package com.wangmir.calliope.domain.util

import com.wangmir.calliope.domain.entities.EmotionLog

sealed class DayLogFilter(val orderType: OrderType) {
class Year(orderType: OrderType, val year: Int): DayLogFilter(orderType)
class Keyword(orderType: OrderType, val keyword: String): DayLogFilter(orderType)
class Emotion(orderType: OrderType, val emotion: EmotionLog): DayLogFilter(orderType)
}
@@ -0,0 +1,6 @@
package com.wangmir.calliope.domain.util

sealed class OrderType {
object Ascending: OrderType()
object Descending: OrderType()
}

This file was deleted.

@@ -1,4 +1,4 @@
package com.wangmir.calliope.viewmodels
package com.wangmir.calliope.presentation

import androidx.lifecycle.ViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
Expand Down
@@ -0,0 +1,11 @@
package com.wangmir.calliope.presentation.list

import com.wangmir.calliope.domain.entities.DayLog
import com.wangmir.calliope.domain.util.DayLogFilter

sealed class DayLogListEvent {
data class Filter(val dayLogFilter: DayLogFilter): DayLogListEvent()
data class DeleteNote(val dayLog: DayLog): DayLogListEvent()
object RestoreNote: DayLogListEvent()
object ToggleOrderSection: DayLogListEvent()
}