Skip to content

Commit

Permalink
Merge pull request #56 from stslex/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
stslex authored Sep 21, 2023
2 parents 1bdfdba + 4520524 commit 9b97fa9
Show file tree
Hide file tree
Showing 45 changed files with 482 additions and 159 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@
.cxx
local.properties
play_config.*
keystore.*
keystore.*
Gemfile.lock
1 change: 1 addition & 0 deletions core/database/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
14 changes: 14 additions & 0 deletions core/database/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
plugins {
id("csplashscreen.android.library")
}

android.namespace = "st.slex.csplashscreen.core.database"

dependencies {
implementation(project(":core:core"))
implementation(libs.bundles.room)
annotationProcessor(libs.androidx.room.compiler)
ksp(libs.androidx.room.compiler)
implementation(libs.androidx.paging.runtime)
androidTestApi(libs.androidx.room.testing)
}
Empty file.
21 changes: 21 additions & 0 deletions core/database/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package st.slex.csplashscreen.core.database

import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4

import org.junit.Test
import org.junit.runner.RunWith

import org.junit.Assert.*

/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("st.slex.csplashscreen.core.database.test", appContext.packageName)
}
}
4 changes: 4 additions & 0 deletions core/database/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package st.slex.csplashscreen.core.database

import androidx.room.Database
import androidx.room.RoomDatabase
import st.slex.csplashscreen.core.database.favourite.FavouriteDao
import st.slex.csplashscreen.core.database.favourite.FavouriteEntity
import st.slex.csplashscreen.core.database.search.SearchDao
import st.slex.csplashscreen.core.database.search.SearchEntity

@Database(
entities = [SearchEntity::class, FavouriteEntity::class],
version = 1,
exportSchema = false
)
abstract class AppDatabase : RoomDatabase() {

abstract val favouriteDao: FavouriteDao

abstract val searchDao: SearchDao

companion object {
val NAME = "app.db"
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package st.slex.csplashscreen.core.database.di

import st.slex.csplashscreen.core.database.favourite.FavouriteDao
import st.slex.csplashscreen.core.database.search.SearchDao

interface DatabaseApi {

val searchDao: SearchDao

val favouriteDao: FavouriteDao
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package st.slex.csplashscreen.core.database.di

import st.slex.csplashscreen.core.core.AppApi

object DatabaseApiBuilder {

fun build(appApi: AppApi): DatabaseApi = DaggerDatabaseComponent
.factory()
.create(
dependencies = DaggerDatabaseDependenciesComponent
.factory()
.create(appApi)
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package st.slex.csplashscreen.core.database.di

import dagger.Component
import javax.inject.Singleton

@Component(
dependencies = [DatabaseDependencies::class],
modules = [DatabaseModule::class]
)
@Singleton
interface DatabaseComponent : DatabaseApi {

@Component.Factory
interface Factory {
fun create(dependencies: DatabaseDependencies): DatabaseApi
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package st.slex.csplashscreen.core.database.di

import android.content.Context

interface DatabaseDependencies {

val context: Context
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package st.slex.csplashscreen.core.database.di

import dagger.Component
import st.slex.csplashscreen.core.core.AppApi
import javax.inject.Singleton

@Component(dependencies = [AppApi::class])
@Singleton
interface DatabaseDependenciesComponent : DatabaseDependencies {

@Component.Factory
interface Factory {
fun create(appApi: AppApi): DatabaseDependencies
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package st.slex.csplashscreen.core.database.di

import android.content.Context
import androidx.room.Room
import dagger.Module
import dagger.Provides
import st.slex.csplashscreen.core.database.AppDatabase
import st.slex.csplashscreen.core.database.favourite.FavouriteDao
import st.slex.csplashscreen.core.database.search.SearchDao
import javax.inject.Singleton

@Module
class DatabaseModule {

@Provides
@Singleton
fun provideDatabase(context: Context): AppDatabase = Room.databaseBuilder(
context,
AppDatabase::class.java,
AppDatabase.NAME
)
.build()

@Provides
@Singleton
fun provideSearchDao(database: AppDatabase): SearchDao = database.searchDao

@Provides
@Singleton
fun providesFavouriteDao(database: AppDatabase): FavouriteDao = database.favouriteDao
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package st.slex.csplashscreen.core.favourite.data.datasource
package st.slex.csplashscreen.core.database.favourite

import androidx.paging.PagingSource
import androidx.room.Dao
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package st.slex.csplashscreen.core.favourite.data.datasource
package st.slex.csplashscreen.core.database.favourite

import androidx.room.ColumnInfo
import androidx.room.Entity
Expand All @@ -19,4 +19,4 @@ data class FavouriteEntity(
val downloadUrl: String,
@ColumnInfo(name = "tags")
val tags: String,
)
)
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package st.slex.csplashscreen.feature.search.data.database
package st.slex.csplashscreen.core.database.search

import androidx.paging.PagingSource
import androidx.room.Dao
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package st.slex.csplashscreen.feature.search.data.database
package st.slex.csplashscreen.core.database.search

import androidx.room.ColumnInfo
import androidx.room.Entity
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package st.slex.csplashscreen.core.database

import android.content.Context
import androidx.paging.PagingSource
import androidx.room.Room
import androidx.test.core.app.ApplicationProvider
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.cancellable
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.runBlocking
import org.junit.AfterClass
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
import st.slex.csplashscreen.core.database.favourite.FavouriteDao
import st.slex.csplashscreen.core.database.favourite.FavouriteEntity
import java.util.UUID

@RunWith(RobolectricTestRunner::class)
@Config(manifest = Config.NONE)
class FavouriteDaoTest {

private val dao: FavouriteDao

init {
val context: Context = ApplicationProvider.getApplicationContext()
database = Room
.databaseBuilder(context, AppDatabase::class.java, AppDatabase.NAME)
.build()
dao = database.favouriteDao
}

@Test
fun `add single item to db`() = runBlocking(Dispatchers.IO) {
val expected = generateRandomItem()
dao.add(expected)
val actual = dao.getItem(expected.uuid)
Assert.assertEquals(expected, actual)
}

@Test
fun `remove item from db`() = runBlocking(Dispatchers.IO) {
val expected = generateRandomItem()
dao.add(expected)
val actual = dao.getItem(expected.uuid)
Assert.assertEquals(expected, actual)
dao.remove(expected.uuid)
val actualRemoved = dao.getItem(expected.uuid)
Assert.assertNull(actualRemoved)
}

@Test
fun `get flow items`() = runBlocking(Dispatchers.IO) {
val expected = generateRandomItem()
dao.add(expected)
val actual = dao.getFlow(expected.uuid)
.cancellable()
.firstOrNull()
Assert.assertEquals(expected, actual)
}

@Test
fun `get paging items`() = runBlocking(Dispatchers.IO) {
val insertItemSize = 10
val pageLoadSize = 15
repeat(insertItemSize) {
val expected = generateRandomItem()
dao.add(expected)
}
val loadResult = dao.getAll().load(
PagingSource.LoadParams.Refresh(
key = null,
loadSize = pageLoadSize,
placeholdersEnabled = false
)
)
val actual = (loadResult as? PagingSource.LoadResult.Page)?.data
Assert.assertNotNull(actual)
Assert.assertTrue(actual!!.size in insertItemSize..pageLoadSize)
}

private fun generateRandomItem(): FavouriteEntity = UUID.randomUUID().toString()
.let { uuid ->
FavouriteEntity(
uuid = uuid,
url = "url_$uuid",
username = "username_$uuid",
userUrl = "user_url_$uuid",
downloadUrl = "download_url_$uuid",
tags = "tags_$uuid",
)
}

companion object {
private lateinit var database: AppDatabase

@AfterClass
@JvmStatic
fun afterTestsEnd() {
database.close()
}
}
}
Loading

0 comments on commit 9b97fa9

Please sign in to comment.