Skip to content

Commit

Permalink
expose runInScreenScope job. fix/cleanup tests
Browse files Browse the repository at this point in the history
  • Loading branch information
luca992 committed Sep 13, 2023
1 parent 8a32936 commit dfea391
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 66 deletions.
1 change: 1 addition & 0 deletions shared/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ kotlin {
val commonTest by getting {
dependencies {
implementation(kotlin("test"))
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3")
implementation("com.russhwolf:multiplatform-settings-test:"+extra["multiplatformSettings.version"])
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,11 @@
package eu.baroncelli.dkmpsample.shared

import app.cash.sqldelight.driver.jdbc.sqlite.JdbcSqliteDriver
import com.russhwolf.settings.MapSettings
import app.cash.sqldelight.sqlite.driver.JdbcSqliteDriver
import eu.baroncelli.dkmpsample.shared.datalayer.Repository
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.runBlocking
import mylocal.db.LocalDb
import java.util.concurrent.Executors
import kotlin.coroutines.CoroutineContext

actual val testCoroutineContext: CoroutineContext =
Executors.newSingleThreadExecutor().asCoroutineDispatcher()
actual fun runBlockingTest(block: suspend CoroutineScope.() -> Unit) =
runBlocking(testCoroutineContext) { this.block() }

actual fun getTestRepository() : Repository {
actual suspend fun getTestRepository(): Repository {
val sqlDriver = JdbcSqliteDriver(JdbcSqliteDriver.IN_MEMORY)
LocalDb.Schema.create(sqlDriver)
return Repository(sqlDriver, MapSettings(), false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package eu.baroncelli.dkmpsample.shared.viewmodel

import eu.baroncelli.dkmpsample.shared.viewmodel.screens.CallOnInitValues
import eu.baroncelli.dkmpsample.shared.viewmodel.screens.navigationSettings
import kotlinx.coroutines.Job

data class NavigationState (
val currentLevel1ScreenIdentifier : ScreenIdentifier,
Expand Down Expand Up @@ -143,11 +144,11 @@ class Navigation(val stateManager : StateManager) {

// ADD SCREEN TO BACKSTACK

fun addScreenToBackstack(screenIdentifier: ScreenIdentifier) {
fun addScreenToBackstack(screenIdentifier: ScreenIdentifier): Job? {
debugLogger.log("addScreenToBackstack: "+screenIdentifier.URI)
stateManager.currentVerticalBackstack.add(screenIdentifier)
stateManager.currentVerticalNavigationLevelsMap[screenIdentifier.screen.navigationLevel] = screenIdentifier
stateManager.initScreen(screenIdentifier)
return stateManager.initScreen(screenIdentifier)
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class StateManager(repo: Repository) {

// INIT SCREEN

fun initScreen(screenIdentifier: ScreenIdentifier) {
fun initScreen(screenIdentifier: ScreenIdentifier): Job? {
debugLogger.log("initScreen: "+screenIdentifier.URI)
val screenInitSettings = screenIdentifier.getScreenInitSettings(this)
if (screenScopesMap[screenIdentifier.URI] == null || !screenScopesMap[screenIdentifier.URI]!!.isActive) {
Expand All @@ -43,22 +43,23 @@ class StateManager(repo: Repository) {
firstInit = true
screenStatesMap[screenIdentifier.URI] = MutableStateFlow(screenInitSettings.initState(screenIdentifier))
} else if (screenInitSettings.callOnInitAtEachNavigation == CallOnInitValues.DONT_CALL) {
return // in case: the state is already in the map
return null // in case: the state is already in the map
// AND "callOnInitAtEachNavigation" is set to DONT_CALL
// => we don't need to run the "callOnInit" function
}
runCallOnInit(screenIdentifier, screenInitSettings, firstInit)
return runCallOnInit(screenIdentifier, screenInitSettings, firstInit)
}

fun isInTheStatesMap(screenIdentifier: ScreenIdentifier) : Boolean {
return screenStatesMap.containsKey(screenIdentifier.URI)
}

fun runCallOnInit(screenIdentifier: ScreenIdentifier, screenInitSettings: ScreenInitSettings, firstInit : Boolean = false) {
if (!firstInit && screenInitSettings.callOnInitAtEachNavigation == CallOnInitValues.CALL_BEFORE_SHOWING_SCREEN) {
fun runCallOnInit(screenIdentifier: ScreenIdentifier, screenInitSettings: ScreenInitSettings, firstInit : Boolean = false) : Job? {
return if (!firstInit && screenInitSettings.callOnInitAtEachNavigation == CallOnInitValues.CALL_BEFORE_SHOWING_SCREEN) {
runBlocking {
screenInitSettings.callOnInit(this@StateManager)
}
null
} else {
runInScreenScope(screenIdentifier) {
screenInitSettings.callOnInit(this@StateManager)
Expand Down Expand Up @@ -122,10 +123,10 @@ class StateManager(repo: Repository) {
}

// we run each event function on a Dispatchers.Main coroutine
fun runInScreenScope (screenIdentifier: ScreenIdentifier? = null, block: suspend () -> Unit) {
fun runInScreenScope (screenIdentifier: ScreenIdentifier? = null, block: suspend () -> Unit): Job? {
val URI = screenIdentifier?.URI ?: currentScreenIdentifier.URI
val screenScope = screenScopesMap[URI]
screenScope?.launch {
return screenScope?.launch {
block()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,4 @@ import eu.baroncelli.dkmpsample.shared.datalayer.Repository
import kotlinx.coroutines.CoroutineScope
import kotlin.coroutines.CoroutineContext

expect fun runBlockingTest(block: suspend CoroutineScope.()-> Unit)
expect val testCoroutineContext: CoroutineContext

expect fun getTestRepository() : Repository
expect suspend fun getTestRepository() : Repository
Original file line number Diff line number Diff line change
@@ -1,44 +1,62 @@
package eu.baroncelli.dkmpsample.shared.viewmodel

import eu.baroncelli.dkmpsample.shared.datalayer.objects.CountryExtraData
import eu.baroncelli.dkmpsample.shared.datalayer.objects.CountryListData
import eu.baroncelli.dkmpsample.shared.datalayer.sources.localdb.countries.setCountriesList
import eu.baroncelli.dkmpsample.shared.getTestRepository
import eu.baroncelli.dkmpsample.shared.viewmodel.screens.Screen.*
import eu.baroncelli.dkmpsample.shared.viewmodel.screens.countrydetail.CountryDetailState
import eu.baroncelli.dkmpsample.shared.viewmodel.screens.countrieslist.*
import eu.baroncelli.dkmpsample.shared.viewmodel.screens.Screen.CountriesList
import eu.baroncelli.dkmpsample.shared.viewmodel.screens.Screen.CountryDetail
import eu.baroncelli.dkmpsample.shared.viewmodel.screens.countrieslist.CountriesListParams
import eu.baroncelli.dkmpsample.shared.viewmodel.screens.countrieslist.CountriesListState
import eu.baroncelli.dkmpsample.shared.viewmodel.screens.countrieslist.CountriesListType
import eu.baroncelli.dkmpsample.shared.viewmodel.screens.countrydetail.CountryDetailParams
import eu.baroncelli.dkmpsample.shared.viewmodel.screens.countrydetail.CountryDetailState
import eu.baroncelli.dkmpsample.shared.viewmodel.screens.countrydetail.CountryInfo
import kotlinx.coroutines.test.runTest
import kotlin.test.BeforeTest
import kotlin.test.Test
import kotlin.test.assertTrue

class ViewModelTests {

val vm = DKMPViewModel(getTestRepository())
val navigation = vm.navigation
val stateProvider = navigation.stateProvider
val stateManager = navigation.stateManager
lateinit var vm: DKMPViewModel
val navigation: Navigation
get() = vm.navigation
val stateProvider: StateProvider
get() = navigation.stateProvider
val stateManager: StateManager
get() = navigation.stateManager


@BeforeTest
fun setUp() = runTest {
vm = DKMPViewModel(getTestRepository())
}

@Test
fun testCountriesListStateUpdate() {
val screenIdentifier = ScreenIdentifier.get(CountriesList,CountriesListParams(CountriesListType.ALL))
val screenInitSettings = screenIdentifier.getScreenInitSettings(navigation)
stateManager.addScreen(screenIdentifier, screenInitSettings)
fun testCountriesListStateUpdate() = runTest {
val screenIdentifier = ScreenIdentifier.get(CountriesList, CountriesListParams(CountriesListType.ALL))
navigation.addScreenToBackstack(screenIdentifier)!!.join()
stateManager.updateScreen(CountriesListState::class) {
it.copy(favoriteCountries = mapOf("Italy" to true))
}
val screenState = stateProvider.get(screenIdentifier) as CountriesListState
val screenState = stateProvider.getScreenState<CountriesListState>(screenIdentifier).value
assertTrue(screenState.favoriteCountries.containsKey("Italy"))
}

@Test
fun testCountryDetailStateUpdate() {
fun testCountryDetailStateUpdate() = runTest {
stateManager.dataRepository.localDb.setCountriesList(
listOf(
CountryListData(name = "Germany")
)
)
val screenIdentifier = ScreenIdentifier.get(CountryDetail, CountryDetailParams("Germany"))
val screenInitSettings = screenIdentifier.getScreenInitSettings(navigation)
stateManager.addScreen(screenIdentifier, screenInitSettings)
navigation.addScreenToBackstack(screenIdentifier)!!.join()
stateManager.updateScreen(CountryDetailState::class) {
it.copy(countryInfo = CountryInfo(_extraData = CountryExtraData(vaccines = "Pfizer, Moderna, AstraZeneca")))
}
val screenState = stateProvider.get(screenIdentifier) as CountryDetailState
val screenState = stateProvider.getScreenState<CountryDetailState>(screenIdentifier).value
assertTrue(screenState.countryInfo.vaccinesList!!.contains("Pfizer"))
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,12 @@
package eu.baroncelli.dkmpsample.shared

import app.cash.sqldelight.driver.jdbc.sqlite.JdbcSqliteDriver
import com.russhwolf.settings.MapSettings
import eu.baroncelli.dkmpsample.shared.datalayer.Repository
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.newSingleThreadContext
import kotlinx.coroutines.runBlocking
import kotlin.coroutines.CoroutineContext
import app.cash.sqldelight.sqlite.driver.JdbcSqliteDriver
import mylocal.db.LocalDb

actual val testCoroutineContext: CoroutineContext =
newSingleThreadContext("testRunner")

actual fun runBlockingTest(block: suspend CoroutineScope.() -> Unit) =
runBlocking(testCoroutineContext) { this.block() }

actual fun getTestRepository() : Repository {
actual suspend fun getTestRepository(): Repository {
val sqlDriver = JdbcSqliteDriver(JdbcSqliteDriver.IN_MEMORY)
LocalDb.Schema.create(sqlDriver)
LocalDb.Schema.create(sqlDriver).await()
return Repository(sqlDriver, MapSettings(), false)
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,11 @@
package eu.baroncelli.dkmpsample.shared

import app.cash.sqldelight.driver.native.NativeSqliteDriver
import com.russhwolf.settings.MapSettings
import eu.baroncelli.dkmpsample.shared.datalayer.Repository
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.newSingleThreadContext
import kotlinx.coroutines.runBlocking
import kotlin.coroutines.CoroutineContext
import app.cash.sqldelight.drivers.native.NativeSqliteDriver
import mylocal.db.LocalDb

actual val testCoroutineContext: CoroutineContext =
newSingleThreadContext("testRunner")

actual fun runBlockingTest(block: suspend CoroutineScope.() -> Unit) =
runBlocking(testCoroutineContext) { this.block() }

actual fun getTestRepository() : Repository {
actual suspend fun getTestRepository(): Repository {
val sqlDriver = NativeSqliteDriver(LocalDb.Schema, "test.db")
return Repository(sqlDriver, MapSettings(), false)
}

0 comments on commit dfea391

Please sign in to comment.