Skip to content

Commit

Permalink
Rename to InsertionStrategy
Browse files Browse the repository at this point in the history
Signed-off-by: mramotar_dbx <[email protected]>
  • Loading branch information
matt-ramotar committed Oct 18, 2023
1 parent eb8a10a commit 514cc74
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 104 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package org.mobilenativefoundation.store.paging5

enum class InsertionStrategy {
APPEND,
PREPEND
}
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ private fun <Id : Any, Key : StoreKey.Collection<Id>, Output : StoreData<Id>> jo

val currentData = currentResponse.value as StoreData.Collection<Id, StoreData.Single<Id>>

val joinedOutput = (lastOutput?.insertItems(key.loadType, currentData.items) ?: currentData) as Output
val joinedOutput = (lastOutput?.insertItems(key.insertionStrategy, currentData.items) ?: currentData) as Output
return StoreReadResponse.Data(joinedOutput, currentResponse.origin)
}

Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,6 @@ interface StoreData<out Id : Any> {
/**
* Inserts items to the existing collection and returns the updated collection.
*/
fun insertItems(type: StoreKey.LoadType, items: List<S>): Collection<Id, S>
fun insertItems(strategy: InsertionStrategy, items: List<S>): Collection<Id, S>
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ interface StoreKey<out Id : Any> {
* Represents a key for fetching collections of items.
*/
interface Collection<out Id : Any> : StoreKey<Id> {
val loadType: LoadType
val insertionStrategy: InsertionStrategy

/**
* Represents a key for page-based fetching.
Expand Down Expand Up @@ -58,9 +58,4 @@ interface StoreKey<out Id : Any> {
interface Filter<Value : Any> {
operator fun invoke(items: List<Value>): List<Value>
}

enum class LoadType {
APPEND,
PREPEND
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
package org.mobilenativefoundation.store.paging5

import app.cash.turbine.test
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.mobilenativefoundation.store.paging5.util.*
import org.mobilenativefoundation.store.store5.ExperimentalStoreApi
import org.mobilenativefoundation.store.store5.MutableStore
import org.mobilenativefoundation.store.store5.StoreReadResponse
import org.mobilenativefoundation.store.store5.*
import kotlin.test.assertEquals
import kotlin.test.assertIs

Expand All @@ -31,7 +30,7 @@ class LaunchPagingStoreTests {
}

@Test
fun `state transitions from Loading to Loaded Collection for valid Cursor key`() = testScope.runTest {
fun transitionFromInitialToData() = testScope.runTest {
val key = PostKey.Cursor("1", 10)
val keys = flowOf(key)
val stateFlow = store.launchPagingStore(this, keys)
Expand All @@ -48,7 +47,7 @@ class LaunchPagingStoreTests {
}

@Test
fun `state transitions appropriately for multiple valid keys emitted in succession`() = testScope.runTest {
fun multipleValidKeysEmittedInSuccession() = testScope.runTest {
val key1 = PostKey.Cursor("1", 10)
val key2 = PostKey.Cursor("11", 10)
val keys = flowOf(key1, key2)
Expand All @@ -74,7 +73,7 @@ class LaunchPagingStoreTests {
}

@Test
fun `state remains consistent if the same key is emitted multiple times`() = testScope.runTest {
fun sameKeyEmittedMultipleTimes() = testScope.runTest {
val key = PostKey.Cursor("1", 10)
val keys = flowOf(key, key)
val stateFlow = store.launchPagingStore(this, keys)
Expand All @@ -89,4 +88,68 @@ class LaunchPagingStoreTests {
expectNoEvents()
}
}

@Test
fun multipleKeysWithReadsAndWrites() = testScope.runTest {
val api = FakePostApi()
val db = FakePostDatabase(userId)
val factory = PostStoreFactory(api = api, db = db)
val store = factory.create()

val key1 = PostKey.Cursor("1", 10)
val key2 = PostKey.Cursor("11", 10)
val keys = flowOf(key1, key2)

val stateFlow = store.launchPagingStore(this, keys)
stateFlow.test {
val initialState = awaitItem()
assertIs<StoreReadResponse.Initial>(initialState)
val loadingState = awaitItem()
assertIs<StoreReadResponse.Loading>(loadingState)
val loadedState1 = awaitItem()
assertIs<StoreReadResponse.Data<PostData.Feed>>(loadedState1)
val data1 = loadedState1.value
assertEquals(10, data1.posts.size)
val loadedState2 = awaitItem()
assertIs<StoreReadResponse.Data<PostData.Feed>>(loadedState2)
val data2 = loadedState2.value
assertEquals(20, data2.posts.size)
}

val cached = store.stream<PostPutRequestResult>(StoreReadRequest.cached(key1, refresh = false))
.first { it.dataOrNull() != null }
assertIs<StoreReadResponse.Data<PostData>>(cached)
assertEquals(StoreReadResponseOrigin.Cache, cached.origin)
val data = cached.requireData()
assertIs<PostData.Feed>(data)
assertEquals(10, data.posts.size)

val cached2 = store.stream<PostPutRequestResult>(StoreReadRequest.cached(PostKey.Single("2"), refresh = false))
.first { it.dataOrNull() != null }
assertIs<StoreReadResponse.Data<PostData>>(cached2)
assertEquals(StoreReadResponseOrigin.Cache, cached2.origin)
val data2 = cached2.requireData()
assertIs<PostData.Post>(data2)
assertEquals("2", data2.title)


store.write(StoreWriteRequest.of(PostKey.Single("2"), PostData.Post("2", "2-modified")))

val cached3 = store.stream<PostPutRequestResult>(StoreReadRequest.cached(PostKey.Single("2"), refresh = false))
.first { it.dataOrNull() != null }
assertIs<StoreReadResponse.Data<PostData>>(cached3)
assertEquals(StoreReadResponseOrigin.Cache, cached3.origin)
val data3 = cached3.requireData()
assertIs<PostData.Post>(data3)
assertEquals("2-modified", data3.title)

val cached4 =
store.stream<PostPutRequestResult>(StoreReadRequest.cached(PostKey.Cursor("1", 10), refresh = false))
.first { it.dataOrNull() != null }
assertIs<StoreReadResponse.Data<PostData>>(cached4)
assertEquals(StoreReadResponseOrigin.Cache, cached4.origin)
val data4 = cached4.requireData()
assertIs<PostData.Feed>(data4)
assertEquals("2-modified", data4.posts[1].title)
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.mobilenativefoundation.store.paging5.util

import org.mobilenativefoundation.store.paging5.InsertionStrategy
import org.mobilenativefoundation.store.paging5.StoreData
import org.mobilenativefoundation.store.paging5.StoreKey

sealed class PostData : StoreData<String> {
data class Post(val postId: String, val title: String) : StoreData.Single<String>, PostData() {
Expand All @@ -11,16 +11,16 @@ sealed class PostData : StoreData<String> {
data class Feed(val posts: List<Post>) : StoreData.Collection<String, Post>, PostData() {
override val items: List<Post> get() = posts
override fun copyWith(items: List<Post>): StoreData.Collection<String, Post> = copy(posts = items)
override fun insertItems(type: StoreKey.LoadType, items: List<Post>): StoreData.Collection<String, Post> {
override fun insertItems(strategy: InsertionStrategy, items: List<Post>): StoreData.Collection<String, Post> {

return when (type) {
StoreKey.LoadType.APPEND -> {
return when (strategy) {
InsertionStrategy.APPEND -> {
val updatedItems = items.toMutableList()
updatedItems.addAll(posts)
copyWith(items = updatedItems)
}

StoreKey.LoadType.PREPEND -> {
InsertionStrategy.PREPEND -> {
val updatedItems = posts.toMutableList()
updatedItems.addAll(items)
copyWith(items = updatedItems)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.mobilenativefoundation.store.paging5.util

import org.mobilenativefoundation.store.paging5.InsertionStrategy
import org.mobilenativefoundation.store.paging5.StoreKey

sealed class PostKey : StoreKey<String> {
Expand All @@ -8,7 +9,7 @@ sealed class PostKey : StoreKey<String> {
override val size: Int,
override val sort: StoreKey.Sort? = null,
override val filters: List<StoreKey.Filter<*>>? = null,
override val loadType: StoreKey.LoadType = StoreKey.LoadType.PREPEND
override val insertionStrategy: InsertionStrategy = InsertionStrategy.APPEND
) : StoreKey.Collection.Cursor<String>, PostKey()

data class Single(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ import org.mobilenativefoundation.store.paging5.StoreKey
import org.mobilenativefoundation.store.store5.*
import kotlin.math.floor

typealias PostStore = MutableStore<PostKey, PostData>

class PostStoreFactory(private val api: PostApi, private val db: PostDatabase) {

private fun createFetcher(): Fetcher<PostKey, PostData> = Fetcher.of { key ->
Expand Down

0 comments on commit 514cc74

Please sign in to comment.