-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2 from f-lab-edu/feature/1
[#1] 지출내역 Database 구현
- Loading branch information
Showing
10 changed files
with
413 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
24 changes: 0 additions & 24 deletions
24
app/src/androidTest/java/kr/ksw/mybudget/ExampleInstrumentedTest.kt
This file was deleted.
Oops, something went wrong.
173 changes: 173 additions & 0 deletions
173
app/src/androidTest/java/kr/ksw/mybudget/data/local/SpendingDaoTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
package kr.ksw.mybudget.data.local | ||
|
||
import android.content.Context | ||
import androidx.room.Room | ||
import androidx.test.core.app.ApplicationProvider | ||
import androidx.test.ext.junit.runners.AndroidJUnit4 | ||
import kotlinx.coroutines.flow.first | ||
import kotlinx.coroutines.test.runTest | ||
import kr.ksw.mybudget.R | ||
import kr.ksw.mybudget.data.local.dao.SpendingDao | ||
import kr.ksw.mybudget.data.local.databases.MyBudgetDatabase | ||
import kr.ksw.mybudget.data.local.entity.SpendingEntity | ||
import kr.ksw.mybudget.data.local.mock.MAJOR_CATEGORY_FOOD | ||
import kr.ksw.mybudget.data.local.mock.MAJOR_CATEGORY_LIFE_STYLE | ||
import kr.ksw.mybudget.data.local.mock.spendingList | ||
import kr.ksw.mybudget.data.local.mock.spendingListForBetween | ||
import org.junit.After | ||
import org.junit.Before | ||
import org.junit.Test | ||
import org.junit.runner.RunWith | ||
import java.io.IOException | ||
import java.time.LocalDate | ||
|
||
@RunWith(AndroidJUnit4::class) | ||
class SpendingDaoTest { | ||
private lateinit var db: MyBudgetDatabase | ||
private lateinit var dao: SpendingDao | ||
|
||
@Before | ||
fun createDB() { | ||
val context = ApplicationProvider.getApplicationContext<Context>() | ||
db = Room.inMemoryDatabaseBuilder( | ||
context, | ||
MyBudgetDatabase::class.java | ||
).build() | ||
dao = db.spendingDao | ||
} | ||
|
||
@After | ||
@Throws(IOException::class) | ||
fun closeDB() { | ||
db.close() | ||
} | ||
|
||
@Test | ||
fun getAllSpendingEntitiesIsEmpty() = runTest { | ||
val result = dao.getAllSpendingEntities().first() | ||
assert(result.isEmpty()) | ||
} | ||
|
||
@Test | ||
fun upsertSpendingEntity() = runTest { | ||
val context = ApplicationProvider.getApplicationContext<Context>() | ||
dao.upsertSpendingEntity(SpendingEntity( | ||
title = "스타벅스", | ||
date = LocalDate.now(), | ||
majorCategory = context.resources.getInteger(R.integer.category_food), | ||
subCategory = context.resources.getInteger(R.integer.category_cafe), | ||
price = 5_000 | ||
)) | ||
val result = dao.getAllSpendingEntities().first() | ||
assert(result.isNotEmpty()) | ||
} | ||
|
||
@Test | ||
fun deleteSpendingEntity() = runTest { | ||
val context = ApplicationProvider.getApplicationContext<Context>() | ||
val spending = SpendingEntity( | ||
id = 1, | ||
title = "스타벅스", | ||
date = LocalDate.now(), | ||
majorCategory = context.resources.getInteger(R.integer.category_food), | ||
subCategory = context.resources.getInteger(R.integer.category_cafe), | ||
price = 5_000 | ||
) | ||
dao.upsertSpendingEntity(spending) | ||
assert(dao.getAllSpendingEntities().first().isNotEmpty()) | ||
dao.deleteSpendingEntity(spending) | ||
assert(dao.getAllSpendingEntities().first().isEmpty()) | ||
} | ||
|
||
@Test | ||
fun `getSpendingEntitiesByMajorCategory Test Food Result Count is 2`() = runTest { | ||
spendingList.forEach { spending -> | ||
dao.upsertSpendingEntity(spending) | ||
} | ||
assert(dao.getAllSpendingEntities().first().isNotEmpty()) | ||
|
||
val result = dao.getSpendingEntitiesByMajorCategory(MAJOR_CATEGORY_FOOD) | ||
assert(result.isNotEmpty()) | ||
assert(result.size == 2) | ||
} | ||
|
||
@Test | ||
fun `getSpendingEntitiesBySubCategory Test LifeStyle And Transportation Category`() = runTest { | ||
spendingList.forEach { spending -> | ||
dao.upsertSpendingEntity(spending) | ||
} | ||
assert(dao.getAllSpendingEntities().first().isNotEmpty()) | ||
|
||
val resultLifeStyle = dao.getSpendingEntitiesByMajorCategory(MAJOR_CATEGORY_LIFE_STYLE) | ||
assert(resultLifeStyle.size == 2) | ||
|
||
val categoryTransportation = 31 | ||
val resultTransportation = dao.getSpendingEntitiesBySubCategory(categoryTransportation) | ||
assert(resultTransportation.size == 1) | ||
} | ||
|
||
@Test | ||
fun `getSpendingEntitiesBetween Today`() = runTest { | ||
spendingList.forEach { spending -> | ||
dao.upsertSpendingEntity(spending) | ||
} | ||
val from = LocalDate.now() | ||
val to = LocalDate.now() | ||
val result = dao.getSpendingEntitiesBetween(from, to) | ||
assert(result.isNotEmpty()) | ||
assert(result.size == spendingList.size) | ||
} | ||
|
||
@Test | ||
fun `getSpendingEntitiesBetween Week`() = runTest { | ||
val now = LocalDate.now() | ||
val from = now.plusDays(-((now.dayOfWeek.value - 1).toLong())) | ||
val to = now.plusDays((7 - now.dayOfWeek.value).toLong()) | ||
spendingListForBetween.forEach { spending -> | ||
dao.upsertSpendingEntity(spending) | ||
} | ||
val result = dao.getSpendingEntitiesBetween(from, to) | ||
assert(result.isNotEmpty()) | ||
assert(result.size == 1) | ||
} | ||
|
||
@Test | ||
fun `getSpendingEntitiesBetween Month`() = runTest { | ||
val now = LocalDate.now() | ||
val from = now.withDayOfMonth(1) | ||
val to = now.withDayOfMonth(now.lengthOfMonth()) | ||
spendingListForBetween.forEach { spending -> | ||
dao.upsertSpendingEntity(spending) | ||
} | ||
val result = dao.getSpendingEntitiesBetween(from, to) | ||
assert(result.isNotEmpty()) | ||
assert(result.size == 2) | ||
} | ||
|
||
@Test | ||
fun `getSpendingEntitiesBetween One Month Before`() = runTest { | ||
val month = LocalDate.now().plusMonths(-1L) | ||
val from = month.withDayOfMonth(1) | ||
val to = month.withDayOfMonth(month.lengthOfMonth()) | ||
println("$from, $to") | ||
spendingListForBetween.forEach { spending -> | ||
dao.upsertSpendingEntity(spending) | ||
} | ||
val result = dao.getSpendingEntitiesBetween(from, to) | ||
assert(result.isNotEmpty()) | ||
assert(result.size == 1) | ||
} | ||
|
||
@Test | ||
fun `getSpendingEntitiesBetween Year`() = runTest { | ||
val now = LocalDate.now() | ||
val from = now.withDayOfYear(1) | ||
println("$from, $now") | ||
spendingListForBetween.forEach { spending -> | ||
dao.upsertSpendingEntity(spending) | ||
} | ||
val result = dao.getSpendingEntitiesBetween(from, now) | ||
assert(result.isNotEmpty()) | ||
assert(result.size == spendingListForBetween.size) | ||
} | ||
} |
78 changes: 78 additions & 0 deletions
78
app/src/androidTest/java/kr/ksw/mybudget/data/local/mock/SpendingMock.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package kr.ksw.mybudget.data.local.mock | ||
|
||
import kr.ksw.mybudget.data.local.entity.SpendingEntity | ||
import java.time.LocalDate | ||
|
||
const val MAJOR_CATEGORY_FOOD = 1 | ||
const val MAJOR_CATEGORY_CULTURE = 2 | ||
const val MAJOR_CATEGORY_LIFE_STYLE = 3 | ||
const val MAJOR_CATEGORY_CASH = 4 | ||
|
||
val spendingList = listOf( | ||
SpendingEntity( | ||
title = "스타벅스", | ||
date = LocalDate.now(), | ||
majorCategory = MAJOR_CATEGORY_FOOD, | ||
subCategory = 12, | ||
price = 6_000 | ||
), | ||
SpendingEntity( | ||
title = "할리스", | ||
date = LocalDate.now(), | ||
majorCategory = MAJOR_CATEGORY_FOOD, | ||
subCategory = 12, | ||
price = 5_000 | ||
), | ||
SpendingEntity( | ||
title = "영화", | ||
date = LocalDate.now(), | ||
majorCategory = MAJOR_CATEGORY_CULTURE, | ||
subCategory = 22, | ||
price = 15_000 | ||
), | ||
SpendingEntity( | ||
title = "교통비", | ||
date = LocalDate.now(), | ||
majorCategory = MAJOR_CATEGORY_LIFE_STYLE, | ||
subCategory = 31, | ||
price = 100_000 | ||
), | ||
SpendingEntity( | ||
title = "통신비", | ||
date = LocalDate.now(), | ||
majorCategory = MAJOR_CATEGORY_LIFE_STYLE, | ||
subCategory = 32, | ||
price = 50_000 | ||
), | ||
SpendingEntity( | ||
title = "송금", | ||
date = LocalDate.now(), | ||
majorCategory = MAJOR_CATEGORY_CASH, | ||
subCategory = 41, | ||
price = 200_000 | ||
), | ||
) | ||
|
||
val spendingListForBetween = listOf( | ||
SpendingEntity( | ||
title = "송금", | ||
date = LocalDate.now().plusWeeks(-1L), | ||
majorCategory = MAJOR_CATEGORY_CASH, | ||
subCategory = 41, | ||
price = 200_000 | ||
), | ||
SpendingEntity( | ||
title = "송금", | ||
date = LocalDate.now().plusMonths(-1L), | ||
majorCategory = MAJOR_CATEGORY_CASH, | ||
subCategory = 41, | ||
price = 200_000 | ||
), | ||
SpendingEntity( | ||
title = "송금", | ||
date = LocalDate.now(), | ||
majorCategory = MAJOR_CATEGORY_CASH, | ||
subCategory = 41, | ||
price = 200_000 | ||
), | ||
) |
16 changes: 16 additions & 0 deletions
16
app/src/main/java/kr/ksw/mybudget/data/local/converter/Converters.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package kr.ksw.mybudget.data.local.converter | ||
|
||
import androidx.room.TypeConverter | ||
import java.time.LocalDate | ||
|
||
class Converters { | ||
@TypeConverter | ||
fun fromTimestamp(value: Int?): LocalDate? { | ||
return value?.let { LocalDate.ofYearDay(LocalDate.now().year, value) } | ||
} | ||
|
||
@TypeConverter | ||
fun dateToTimestamp(date: LocalDate?): Int? { | ||
return date?.dayOfYear | ||
} | ||
} |
38 changes: 38 additions & 0 deletions
38
app/src/main/java/kr/ksw/mybudget/data/local/dao/SpendingDao.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package kr.ksw.mybudget.data.local.dao | ||
|
||
import androidx.room.Dao | ||
import androidx.room.Delete | ||
import androidx.room.Query | ||
import androidx.room.Upsert | ||
import kotlinx.coroutines.flow.Flow | ||
import kr.ksw.mybudget.data.local.entity.SpendingEntity | ||
import java.time.LocalDate | ||
import java.util.Date | ||
|
||
@Dao | ||
interface SpendingDao { | ||
@Upsert | ||
suspend fun upsertSpendingEntity(spendingEntity: SpendingEntity) | ||
|
||
@Delete | ||
suspend fun deleteSpendingEntity(spendingEntity: SpendingEntity) | ||
|
||
@Query("SELECT * FROM spending_table") | ||
fun getAllSpendingEntities(): Flow<List<SpendingEntity>> | ||
|
||
@Query("SELECT * FROM spending_table WHERE majorCategory = :majorCategory") | ||
suspend fun getSpendingEntitiesByMajorCategory( | ||
majorCategory: Int | ||
): List<SpendingEntity> | ||
|
||
@Query("SELECT * FROM spending_table WHERE subCategory = :subCategory") | ||
suspend fun getSpendingEntitiesBySubCategory( | ||
subCategory: Int | ||
): List<SpendingEntity> | ||
|
||
@Query("SELECT * FROM spending_table WHERE date BETWEEN :from AND :to") | ||
suspend fun getSpendingEntitiesBetween( | ||
from: LocalDate, | ||
to: LocalDate | ||
): List<SpendingEntity> | ||
} |
Oops, something went wrong.