Merge remote-tracking branch 'origin/feature/coroutines' into feature/coroutines
This commit is contained in:
commit
c072f1532b
16 changed files with 336 additions and 403 deletions
|
@ -1,40 +1,26 @@
|
|||
//package com.nytimes.android.external.store3.base.impl
|
||||
//
|
||||
//import com.nytimes.android.external.store3.util.KeyParser
|
||||
//import com.nytimes.android.external.store3.util.ParserException
|
||||
//
|
||||
//import java.util.ArrayList
|
||||
//
|
||||
//import io.reactivex.annotations.NonNull
|
||||
//
|
||||
//import com.nytimes.android.external.cache3.Preconditions.checkArgument
|
||||
//import com.nytimes.android.external.cache3.Preconditions.checkNotNull
|
||||
//
|
||||
//class MultiParser<Key, Raw, Parsed>(parsers: List<KeyParser<Key, Any, Any>>) : KeyParser<Key, Raw, Parsed> {
|
||||
//
|
||||
// private val parsers = ArrayList<KeyParser<*, *, *>>()
|
||||
//
|
||||
// init {
|
||||
// this.parsers.addAll(parsers)
|
||||
// }
|
||||
//
|
||||
// private fun createParserException(): ParserException {
|
||||
// return ParserException("One of the provided parsers has a wrong typing. " + "Make sure that parsers are passed in a correct order and the fromTypes match each other.")
|
||||
// }
|
||||
//
|
||||
// @NonNull
|
||||
// @Throws(ParserException::class)
|
||||
// override
|
||||
// suspend fun apply(@NonNull key: Key, @NonNull raw: Raw): Parsed {
|
||||
// var parsed: Any = raw!!
|
||||
// for (parser in parsers) {
|
||||
// try {
|
||||
// parsed = parser.apply(key, parsed)!!
|
||||
// } catch (exception: ClassCastException) {
|
||||
// throw createParserException()
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// return parsed as Parsed
|
||||
// }
|
||||
//}
|
||||
package com.nytimes.android.external.store3.base.impl
|
||||
|
||||
import com.nytimes.android.external.store3.util.KeyParser
|
||||
import com.nytimes.android.external.store3.util.ParserException
|
||||
import io.reactivex.annotations.NonNull
|
||||
|
||||
class MultiParser<Key, Raw, Parsed>(private val parsers: List<KeyParser<Any?, Any?, Any?>>) : KeyParser<Key, Raw, Parsed> {
|
||||
|
||||
private fun createParserException(): ParserException {
|
||||
return ParserException("One of the provided parsers has a wrong typing. " +
|
||||
"Make sure that parsers are passed in a correct order and the fromTypes match each other.")
|
||||
}
|
||||
|
||||
@NonNull
|
||||
override suspend fun apply(@NonNull key: Key, @NonNull raw: Raw): Parsed {
|
||||
var parsed: Any = raw!!
|
||||
for (parser in parsers) {
|
||||
try {
|
||||
parsed = parser.apply(key, parsed)!!
|
||||
} catch (exception: ClassCastException) {
|
||||
throw createParserException()
|
||||
}
|
||||
}
|
||||
return parsed as Parsed
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,9 +10,9 @@ import com.nytimes.android.external.store3.base.Parser
|
|||
*/
|
||||
class ParsingFetcher<Parsed, Raw, Key>
|
||||
(private val rawFetcher: Fetcher<Raw, Key>,
|
||||
private val parser: Parser<Raw, Parsed>) {
|
||||
private val parser: Parser<Raw, Parsed>) : Fetcher<Parsed, Key> {
|
||||
|
||||
suspend fun fetch(key: Key): Parsed {
|
||||
override suspend fun fetch(key: Key): Parsed {
|
||||
return rawFetcher.fetch(key).let { parser.apply(it) }
|
||||
}
|
||||
|
||||
|
|
|
@ -9,8 +9,6 @@ import com.nytimes.android.external.store3.util.KeyParser
|
|||
import com.nytimes.android.external.store3.util.NoKeyParser
|
||||
import com.nytimes.android.external.store3.util.NoopParserFunc
|
||||
import com.nytimes.android.external.store3.util.NoopPersister
|
||||
|
||||
import io.reactivex.Maybe
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.Single
|
||||
import kotlinx.coroutines.channels.ReceiveChannel
|
||||
|
@ -38,12 +36,12 @@ open class RealStore<Parsed, Key> : Store<Parsed, Key> {
|
|||
StalePolicy.UNSPECIFIED)
|
||||
}
|
||||
|
||||
constructor(fetcher: Fetcher<Any, Key>,
|
||||
persister: Persister<Any, Key>,
|
||||
parser: Parser<Any, Parsed>) {
|
||||
internalStore = RealInternalStore(fetcher,
|
||||
persister,
|
||||
NoKeyParser(parser),
|
||||
constructor(fetcher: Fetcher<*, Key>,
|
||||
persister: Persister<*, Key>,
|
||||
parser: Parser<*, Parsed>) {
|
||||
internalStore = RealInternalStore(fetcher as Fetcher<Any, Key>,
|
||||
persister as Persister<Any, Key>,
|
||||
NoKeyParser(parser as Parser<Any, Parsed>),
|
||||
StalePolicy.UNSPECIFIED)
|
||||
}
|
||||
|
||||
|
@ -72,7 +70,7 @@ open class RealStore<Parsed, Key> : Store<Parsed, Key> {
|
|||
}
|
||||
|
||||
fun getWithResult(key: Key): Single<Result<Parsed>> {
|
||||
TODO("not implemented")
|
||||
TODO("not implemented")
|
||||
}
|
||||
|
||||
fun getRefreshing(key: Key): Observable<Parsed> {
|
||||
|
|
|
@ -6,13 +6,14 @@ import com.nytimes.android.external.store3.util.KeyParser
|
|||
import com.nytimes.android.external.store3.util.NoKeyParser
|
||||
import com.nytimes.android.external.store3.util.NoopParserFunc
|
||||
import com.nytimes.android.external.store3.util.NoopPersister
|
||||
import java.util.*
|
||||
|
||||
|
||||
/**
|
||||
* Builder where there parser is used.
|
||||
*/
|
||||
class RealStoreBuilder<Raw, Parsed, Key> {
|
||||
private var parser: KeyParser<Key, Raw, Parsed>? = null
|
||||
private val parsers = ArrayList<KeyParser<Any?, Any?, Any?>>()
|
||||
private var persister: Persister<Raw, Key>? = null
|
||||
private var fetcher: Fetcher<Raw, Key>? = null
|
||||
private var memoryPolicy: MemoryPolicy? = null
|
||||
|
@ -20,27 +21,24 @@ class RealStoreBuilder<Raw, Parsed, Key> {
|
|||
private//remove when it is implemented...
|
||||
var stalePolicy = StalePolicy.UNSPECIFIED
|
||||
|
||||
fun fetcher(fetcher: Fetcher<Raw, Key>): RealStoreBuilder<Raw, Parsed, Key> {
|
||||
fun fetcher(fetcher: Fetcher<Raw, Key>): RealStoreBuilder<Raw, Parsed, Key> = apply {
|
||||
this.fetcher = fetcher
|
||||
return this
|
||||
}
|
||||
|
||||
fun fetcher(fetcher: suspend (Key) -> Raw): RealStoreBuilder<Raw, Parsed, Key> {
|
||||
fun fetcher(fetcher: suspend (Key) -> Raw): RealStoreBuilder<Raw, Parsed, Key> = apply {
|
||||
this.fetcher = object : Fetcher<Raw, Key> {
|
||||
override suspend fun fetch(key: Key): Raw {
|
||||
return fetcher(key)
|
||||
}
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
fun persister(persister: Persister<Raw, Key>): RealStoreBuilder<Raw, Parsed, Key> {
|
||||
fun persister(persister: Persister<Raw, Key>): RealStoreBuilder<Raw, Parsed, Key> = apply {
|
||||
this.persister = persister
|
||||
return this
|
||||
}
|
||||
|
||||
fun persister(diskRead: DiskRead<Raw, Key>,
|
||||
diskWrite: DiskWrite<Raw, Key>): RealStoreBuilder<Raw, Parsed, Key> {
|
||||
diskWrite: DiskWrite<Raw, Key>): RealStoreBuilder<Raw, Parsed, Key> = apply {
|
||||
persister = object : Persister<Raw, Key> {
|
||||
override suspend fun read(key: Key): Raw? =
|
||||
diskRead.read(key)
|
||||
|
@ -48,46 +46,44 @@ class RealStoreBuilder<Raw, Parsed, Key> {
|
|||
override suspend fun write(key: Key, raw: Raw): Boolean =
|
||||
diskWrite.write(key, raw)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
fun parser(parser: Parser<Raw, Parsed>): RealStoreBuilder<Raw, Parsed, Key> {
|
||||
this.parser = NoKeyParser(parser)
|
||||
return this
|
||||
fun parser(parser: Parser<Raw, Parsed>): RealStoreBuilder<Raw, Parsed, Key> = apply {
|
||||
this.parsers.clear()
|
||||
this.parsers.add(NoKeyParser(parser as Parser<Any?, Any?>))
|
||||
}
|
||||
|
||||
fun parser(parser: KeyParser<Key, Raw, Parsed>): RealStoreBuilder<Raw, Parsed, Key> {
|
||||
this.parser = parser
|
||||
fun parser(parser: suspend (Raw) -> Parsed): RealStoreBuilder<Raw, Parsed, Key> =
|
||||
parser(NoKeyParser(object : Parser<Raw, Parsed> {
|
||||
override suspend fun apply(raw: Raw): Parsed {
|
||||
return parser(raw)
|
||||
}
|
||||
}))
|
||||
|
||||
return this
|
||||
fun parser(parser: KeyParser<Key, Raw, Parsed>): RealStoreBuilder<Raw, Parsed, Key> = apply {
|
||||
this.parsers.clear()
|
||||
this.parsers.add(parser as KeyParser<Any?, Any?, Any?>)
|
||||
}
|
||||
|
||||
fun parsers(parsers: List<Parser<Raw, Parsed>>): RealStoreBuilder<Raw, Parsed, Key> {
|
||||
TODO("not implemented")
|
||||
// this.parsers.clear()
|
||||
// for (parser in parsers) {
|
||||
// this.parsers.add(NoKeyParser<Key,Raw, Parsed>(parser))
|
||||
// }
|
||||
// return this
|
||||
fun parsers(parsers: List<Parser<*, *>>): RealStoreBuilder<Raw, Parsed, Key> = apply {
|
||||
this.parsers.clear()
|
||||
this.parsers.addAll(parsers.map { NoKeyParser<Any?, Any?, Any?>(it as Parser<Any?, Any?>) })
|
||||
}
|
||||
|
||||
fun memoryPolicy(memoryPolicy: MemoryPolicy): RealStoreBuilder<Raw, Parsed, Key> {
|
||||
fun memoryPolicy(memoryPolicy: MemoryPolicy): RealStoreBuilder<Raw, Parsed, Key> = apply {
|
||||
this.memoryPolicy = memoryPolicy
|
||||
return this
|
||||
}
|
||||
|
||||
//Store will backfill the disk cache anytime a record is stale
|
||||
//User will still get the stale record returned to them
|
||||
fun refreshOnStale(): RealStoreBuilder<Raw, Parsed, Key> {
|
||||
fun refreshOnStale(): RealStoreBuilder<Raw, Parsed, Key> = apply {
|
||||
stalePolicy = StalePolicy.REFRESH_ON_STALE
|
||||
return this
|
||||
}
|
||||
|
||||
//Store will try to get network source when disk data is stale
|
||||
//if network source throws error or is empty, stale disk data will be returned
|
||||
fun networkBeforeStale(): RealStoreBuilder<Raw, Parsed, Key> {
|
||||
fun networkBeforeStale(): RealStoreBuilder<Raw, Parsed, Key> = apply {
|
||||
stalePolicy = StalePolicy.NETWORK_BEFORE_STALE
|
||||
return this
|
||||
}
|
||||
|
||||
fun open(): Store<Parsed, Key> {
|
||||
|
@ -95,15 +91,15 @@ class RealStoreBuilder<Raw, Parsed, Key> {
|
|||
persister = NoopPersister.create(memoryPolicy)
|
||||
}
|
||||
|
||||
if (parser == null) {
|
||||
if (parsers.isEmpty()) {
|
||||
parser(NoopParserFunc())
|
||||
}
|
||||
|
||||
// val multiParser = MultiParser<Key, Raw, Parsed>(parsers)
|
||||
val multiParser = MultiParser<Key, Raw, Parsed>(parsers)
|
||||
|
||||
val realInternalStore: InternalStore<Parsed, Key> = RealInternalStore(fetcher!!, persister!!, parser!!, memoryPolicy, stalePolicy)
|
||||
val realInternalStore: RealInternalStore<Raw, Parsed, Key> = RealInternalStore(fetcher!!, persister!!, multiParser, memoryPolicy, stalePolicy)
|
||||
|
||||
return RealStore(realInternalStore)
|
||||
return RealStore<Parsed, Key>(realInternalStore)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
package com.nytimes.android.external.store3.util
|
||||
|
||||
import io.reactivex.annotations.NonNull
|
||||
import io.reactivex.functions.BiFunction
|
||||
|
||||
interface KeyParser<Key, Raw, Parsed> {
|
||||
interface KeyParser<in Key, in Raw, out Parsed> {
|
||||
|
||||
@Throws(ParserException::class)
|
||||
suspend fun apply(@NonNull key: Key, @NonNull raw: Raw): Parsed
|
||||
|
|
|
@ -4,7 +4,7 @@ import com.nytimes.android.external.store3.base.Parser
|
|||
|
||||
import io.reactivex.annotations.NonNull
|
||||
|
||||
class NoKeyParser<Key, Raw, Parsed>(private val parser: Parser<Raw, Parsed>) : KeyParser<Key, Raw, Parsed> {
|
||||
class NoKeyParser<in Key, in Raw, out Parsed>(private val parser: Parser<Raw, out Parsed>) : KeyParser<Key, Raw, Parsed> {
|
||||
|
||||
@Throws(ParserException::class)
|
||||
override suspend fun apply(@NonNull key: Key, @NonNull raw: Raw): Parsed {
|
||||
|
|
|
@ -4,7 +4,7 @@ import com.nytimes.android.external.store3.base.Clearable
|
|||
import com.nytimes.android.external.store3.base.Persister
|
||||
import com.nytimes.android.external.store3.base.impl.BarCode
|
||||
|
||||
class ClearingPersister : Persister<Int, BarCode>, Clearable<BarCode> {
|
||||
open class ClearingPersister : Persister<Int, BarCode>, Clearable<BarCode> {
|
||||
override suspend fun read(key: BarCode): Int? {
|
||||
throw RuntimeException()
|
||||
}
|
||||
|
|
|
@ -36,7 +36,8 @@ class DontCacheErrorsTest {
|
|||
try {
|
||||
store.get(barcode)
|
||||
fail()
|
||||
} catch (e: Exception) {
|
||||
} catch (e: RuntimeException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
shouldThrow = false
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
package com.nytimes.android.external.store3;
|
||||
|
||||
|
||||
import com.nytimes.android.external.store3.base.Fetcher;
|
||||
import com.nytimes.android.external.store3.base.Persister;
|
||||
import com.nytimes.android.external.store3.base.impl.BarCode;
|
||||
import com.nytimes.android.external.store3.base.impl.Store;
|
||||
import com.nytimes.android.external.store3.base.impl.StoreBuilder;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import io.reactivex.Maybe;
|
||||
import io.reactivex.Single;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class StoreBuilderTest {
|
||||
|
||||
public static final Date DATE = new Date();
|
||||
|
||||
@Test
|
||||
public void testBuildersBuildWithCorrectTypes() {
|
||||
//test is checking whether types are correct in builders
|
||||
Store<Date, Integer> store = StoreBuilder.<Integer, String, Date>parsedWithKey()
|
||||
.fetcher(key -> Single.just(String.valueOf(key)))
|
||||
.persister(new Persister<String, Integer>() {
|
||||
@Nonnull
|
||||
@Override
|
||||
public Maybe<String> read(@Nonnull Integer key) {
|
||||
return Maybe.just(String.valueOf(key));
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Single<Boolean> write(@Nonnull Integer key, @Nonnull String s) {
|
||||
return Single.just(true);
|
||||
}
|
||||
})
|
||||
.parser(s -> DATE)
|
||||
.open();
|
||||
|
||||
|
||||
Store<Date, BarCode> barCodeStore = StoreBuilder.<Date>barcode().fetcher(new Fetcher<Date, BarCode>() {
|
||||
@Nonnull
|
||||
@Override
|
||||
public Single<Date> fetch(@Nonnull BarCode barCode) {
|
||||
return Single.just(DATE);
|
||||
}
|
||||
}).open();
|
||||
|
||||
|
||||
Store<Date, Integer> keyStore = StoreBuilder.<Integer, Date>key()
|
||||
.fetcher(new Fetcher<Date, Integer>() {
|
||||
@Nonnull
|
||||
@Override
|
||||
public Single<Date> fetch(@Nonnull Integer key) {
|
||||
return Single.just(DATE);
|
||||
}
|
||||
})
|
||||
.open();
|
||||
Date result = store.get(5).blockingGet();
|
||||
result = barCodeStore.get(new BarCode("test", "5")).blockingGet();
|
||||
result = keyStore.get(5).blockingGet();
|
||||
assertThat(result).isNotNull();
|
||||
|
||||
}
|
||||
}
|
47
store/src/test/java/com/nytimes/android/external/store3/StoreBuilderTest.kt
vendored
Normal file
47
store/src/test/java/com/nytimes/android/external/store3/StoreBuilderTest.kt
vendored
Normal file
|
@ -0,0 +1,47 @@
|
|||
package com.nytimes.android.external.store3
|
||||
|
||||
|
||||
import com.nytimes.android.external.store3.base.Persister
|
||||
import com.nytimes.android.external.store3.base.impl.BarCode
|
||||
import com.nytimes.android.external.store3.base.impl.StoreBuilder
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.Test
|
||||
import java.util.*
|
||||
|
||||
class StoreBuilderTest {
|
||||
|
||||
@Test
|
||||
fun testBuildersBuildWithCorrectTypes() = runBlocking<Unit> {
|
||||
//test is checking whether types are correct in builders
|
||||
val store = StoreBuilder.parsedWithKey<Int, String, Date>()
|
||||
.fetcher { key -> key.toString() }
|
||||
.persister(object : Persister<String, Int> {
|
||||
override suspend fun read(key: Int): String? {
|
||||
return key.toString()
|
||||
}
|
||||
|
||||
override suspend fun write(key: Int, raw: String) = true
|
||||
})
|
||||
.parser { DATE }
|
||||
.open()
|
||||
|
||||
|
||||
val barCodeStore = StoreBuilder.barcode<Date>().fetcher { DATE }.open()
|
||||
|
||||
|
||||
val keyStore = StoreBuilder.key<Int, Date>()
|
||||
.fetcher { DATE }
|
||||
.open()
|
||||
var result = store.get(5)
|
||||
result = barCodeStore.get(BarCode("test", "5"))
|
||||
result = keyStore.get(5)
|
||||
assertThat(result).isNotNull()
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
val DATE = Date()
|
||||
}
|
||||
}
|
|
@ -1,13 +1,13 @@
|
|||
package com.nytimes.android.external.store3
|
||||
|
||||
import com.nhaarman.mockitokotlin2.mock
|
||||
import com.nhaarman.mockitokotlin2.whenever
|
||||
import com.nytimes.android.external.cache3.CacheBuilder
|
||||
import com.nytimes.android.external.store3.base.Fetcher
|
||||
import com.nytimes.android.external.store3.base.Persister
|
||||
import com.nytimes.android.external.store3.base.impl.BarCode
|
||||
import com.nytimes.android.external.store3.base.impl.StoreBuilder
|
||||
import com.nytimes.android.external.store3.util.NoopPersister
|
||||
import io.reactivex.Maybe
|
||||
import io.reactivex.Single
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
@ -32,15 +32,15 @@ class StoreTest {
|
|||
.open()
|
||||
|
||||
|
||||
`when`<Any>(fetcher.fetch(barCode))
|
||||
.thenReturn(Single.just(NETWORK))
|
||||
whenever(fetcher.fetch(barCode))
|
||||
.thenReturn(NETWORK)
|
||||
|
||||
`when`<Any>(persister.read(barCode))
|
||||
.thenReturn(Maybe.empty<String>())
|
||||
.thenReturn(Maybe.just(DISK))
|
||||
whenever(persister.read(barCode))
|
||||
.thenReturn(null)
|
||||
.thenReturn(DISK)
|
||||
|
||||
`when`<Any>(persister.write(barCode, NETWORK))
|
||||
.thenReturn(Single.just(true))
|
||||
whenever(persister.write(barCode, NETWORK))
|
||||
.thenReturn(true)
|
||||
|
||||
var value = simpleStore.get(barCode)
|
||||
|
||||
|
@ -59,15 +59,15 @@ class StoreTest {
|
|||
// .open()
|
||||
//
|
||||
//
|
||||
// `when`<Any>(fetcher.fetch(barCode))
|
||||
// .thenReturn(Single.just(NETWORK))
|
||||
// whenever(fetcher.fetch(barCode))
|
||||
// .thenReturn(NETWORK)
|
||||
//
|
||||
// `when`<Any>(persister.read(barCode))
|
||||
// .thenReturn(Maybe.empty<String>())
|
||||
// .thenReturn(Maybe.just(DISK))
|
||||
// whenever(persister.read(barCode))
|
||||
// .thenReturn(null)
|
||||
// .thenReturn(DISK)
|
||||
//
|
||||
// `when`<Any>(persister.write(barCode, NETWORK))
|
||||
// .thenReturn(Single.just(true))
|
||||
// whenever(persister.write(barCode, NETWORK))
|
||||
// .thenReturn(true)
|
||||
//
|
||||
// var result = simpleStore.getWithResult(barCode)
|
||||
//
|
||||
|
@ -90,23 +90,24 @@ class StoreTest {
|
|||
.open()
|
||||
|
||||
val networkSingle = Single.create<String> { emitter ->
|
||||
if (counter.incrementAndGet() == 1) {
|
||||
emitter.onSuccess(NETWORK)
|
||||
} else {
|
||||
emitter.onError(RuntimeException("Yo Dawg your inflight is broken"))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
`when`<Any>(fetcher.fetch(barCode))
|
||||
.thenReturn(networkSingle)
|
||||
whenever(fetcher.fetch(barCode))
|
||||
.thenAnswer {
|
||||
if (counter.incrementAndGet() == 1) {
|
||||
NETWORK
|
||||
} else {
|
||||
throw RuntimeException("Yo Dawg your inflight is broken")
|
||||
}
|
||||
}
|
||||
|
||||
`when`<Any>(persister.read(barCode))
|
||||
.thenReturn(Maybe.empty<String>())
|
||||
.thenReturn(Maybe.just(DISK))
|
||||
whenever(persister.read(barCode))
|
||||
.thenReturn(null)
|
||||
.thenReturn(DISK)
|
||||
|
||||
`when`<Any>(persister.write(barCode, NETWORK))
|
||||
.thenReturn(Single.just(true))
|
||||
whenever(persister.write(barCode, NETWORK))
|
||||
.thenReturn(true)
|
||||
|
||||
|
||||
val deferred = async { simpleStore.get(barCode) }
|
||||
|
@ -133,15 +134,15 @@ class StoreTest {
|
|||
// }
|
||||
//
|
||||
//
|
||||
// `when`<Any>(fetcher.fetch(barCode))
|
||||
// whenever(fetcher.fetch(barCode))
|
||||
// .thenReturn(networkSingle)
|
||||
//
|
||||
// `when`<Any>(persister.read(barCode))
|
||||
// .thenReturn(Maybe.empty<String>())
|
||||
// .thenReturn(Maybe.just(DISK))
|
||||
// whenever(persister.read(barCode))
|
||||
// .thenReturn(null)
|
||||
// .thenReturn(DISK)
|
||||
//
|
||||
// `when`<Any>(persister.write(barCode, NETWORK))
|
||||
// .thenReturn(Single.just(true))
|
||||
// whenever(persister.write(barCode, NETWORK))
|
||||
// .thenReturn(true)
|
||||
//
|
||||
//
|
||||
// val response = simpleStore.getWithResult(barCode)
|
||||
|
@ -160,13 +161,13 @@ class StoreTest {
|
|||
val simpleStore = SampleStore(fetcher, persister)
|
||||
simpleStore.clear()
|
||||
|
||||
`when`<Any>(fetcher.fetch(barCode))
|
||||
.thenReturn(Single.just(NETWORK))
|
||||
whenever(fetcher.fetch(barCode))
|
||||
.thenReturn(NETWORK)
|
||||
|
||||
`when`<Any>(persister.read(barCode))
|
||||
.thenReturn(Maybe.empty<String>())
|
||||
.thenReturn(Maybe.just(DISK))
|
||||
`when`<Any>(persister.write(barCode, NETWORK)).thenReturn(Single.just(true))
|
||||
whenever(persister.read(barCode))
|
||||
.thenReturn(null)
|
||||
.thenReturn(DISK)
|
||||
whenever(persister.write(barCode, NETWORK)).thenReturn(true)
|
||||
|
||||
var value = simpleStore.get(barCode)
|
||||
assertThat(value).isEqualTo(DISK)
|
||||
|
@ -181,13 +182,13 @@ class StoreTest {
|
|||
// val simpleStore = SampleStore(fetcher, persister)
|
||||
// simpleStore.clear()
|
||||
//
|
||||
// `when`<Any>(fetcher.fetch(barCode))
|
||||
// .thenReturn(Single.just(NETWORK))
|
||||
// whenever(fetcher.fetch(barCode))
|
||||
// .thenReturn(NETWORK)
|
||||
//
|
||||
// `when`<Any>(persister.read(barCode))
|
||||
// .thenReturn(Maybe.empty<String>())
|
||||
// .thenReturn(Maybe.just(DISK))
|
||||
// `when`<Any>(persister.write(barCode, NETWORK)).thenReturn(Single.just(true))
|
||||
// whenever(persister.read(barCode))
|
||||
// .thenReturn(null)
|
||||
// .thenReturn(DISK)
|
||||
// whenever(persister.write(barCode, NETWORK)).thenReturn(true)
|
||||
//
|
||||
// var result = simpleStore.getWithResult(barCode)
|
||||
//
|
||||
|
@ -207,8 +208,8 @@ class StoreTest {
|
|||
val simpleStore = SampleStore(fetcher, persister)
|
||||
|
||||
|
||||
`when`<Any>(fetcher.fetch(barCode))
|
||||
.thenReturn(Single.just(NETWORK))
|
||||
whenever(fetcher.fetch(barCode))
|
||||
.thenReturn(NETWORK)
|
||||
|
||||
var value = simpleStore.get(barCode)
|
||||
verify<Fetcher<String, BarCode>>(fetcher, times(1)).fetch(barCode)
|
||||
|
@ -232,8 +233,8 @@ class StoreTest {
|
|||
// val simpleStore = SampleStore(fetcher, persister)
|
||||
//
|
||||
//
|
||||
// `when`<Any>(fetcher.fetch(barCode))
|
||||
// .thenReturn(Single.just(NETWORK))
|
||||
// whenever(fetcher.fetch(barCode))
|
||||
// .thenReturn(NETWORK)
|
||||
//
|
||||
// var value = simpleStore.getWithResult(barCode)
|
||||
// verify<Fetcher<String, BarCode>>(fetcher, times(1)).fetch(barCode)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.nytimes.android.external.store3
|
||||
|
||||
import com.nytimes.android.external.store.util.Result
|
||||
import com.nhaarman.mockitokotlin2.mock
|
||||
import com.nytimes.android.external.store3.base.Fetcher
|
||||
import com.nytimes.android.external.store3.base.Parser
|
||||
import com.nytimes.android.external.store3.base.Persister
|
||||
|
@ -8,141 +8,128 @@ import com.nytimes.android.external.store3.base.impl.BarCode
|
|||
import com.nytimes.android.external.store3.base.impl.ParsingStoreBuilder
|
||||
import io.reactivex.Maybe
|
||||
import io.reactivex.Single
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.Test
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.*
|
||||
import org.mockito.MockitoAnnotations
|
||||
|
||||
class StoreWithParserTest {
|
||||
@Mock
|
||||
internal var fetcher: Fetcher<String, BarCode>? = null
|
||||
@Mock
|
||||
internal var persister: Persister<String, BarCode>? = null
|
||||
@Mock
|
||||
internal var parser: Parser<String, String>? = null
|
||||
val fetcher: Fetcher<String, BarCode> = mock()
|
||||
val persister: Persister<String, BarCode> = mock()
|
||||
val parser: Parser<String, String> = mock()
|
||||
|
||||
private val barCode = BarCode("key", "value")
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testSimple() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
|
||||
|
||||
fun testSimple() = runBlocking<Unit> {
|
||||
val simpleStore = ParsingStoreBuilder.builder<String, String>()
|
||||
.persister(persister!!)
|
||||
.fetcher(fetcher!!)
|
||||
.parser(parser!!)
|
||||
.persister(persister)
|
||||
.fetcher(fetcher)
|
||||
.parser(parser)
|
||||
.open()
|
||||
|
||||
`when`<Any>(fetcher!!.fetch(barCode))
|
||||
`when`<Any>(fetcher.fetch(barCode))
|
||||
.thenReturn(Single.just(NETWORK))
|
||||
|
||||
`when`<Any>(persister!!.read(barCode))
|
||||
`when`<Any>(persister.read(barCode))
|
||||
.thenReturn(Maybe.empty<String>())
|
||||
.thenReturn(Maybe.just(DISK))
|
||||
|
||||
`when`<Any>(persister!!.write(barCode, NETWORK))
|
||||
`when`<Any>(persister.write(barCode, NETWORK))
|
||||
.thenReturn(Single.just(true))
|
||||
|
||||
`when`<Any>(parser!!.apply(DISK)).thenReturn(barCode.key)
|
||||
`when`<Any>(parser.apply(DISK)).thenReturn(barCode.key)
|
||||
|
||||
var value = simpleStore.get(barCode).blockingGet()
|
||||
var value = simpleStore.get(barCode)
|
||||
assertThat(value).isEqualTo(barCode.key)
|
||||
value = simpleStore.get(barCode).blockingGet()
|
||||
value = simpleStore.get(barCode)
|
||||
assertThat(value).isEqualTo(barCode.key)
|
||||
verify<Fetcher<String, BarCode>>(fetcher, times(1)).fetch(barCode)
|
||||
}
|
||||
|
||||
// @Test
|
||||
// fun testSimpleWithResult() = runBlocking<Unit> {
|
||||
// val simpleStore = ParsingStoreBuilder.builder<String, String>()
|
||||
// .persister(persister)
|
||||
// .fetcher(fetcher)
|
||||
// .parser(parser)
|
||||
// .open()
|
||||
//
|
||||
// `when`<Any>(fetcher.fetch(barCode))
|
||||
// .thenReturn(Single.just(NETWORK))
|
||||
//
|
||||
// `when`<Any>(persister.read(barCode))
|
||||
// .thenReturn(Maybe.empty<String>())
|
||||
// .thenReturn(Maybe.just(DISK))
|
||||
//
|
||||
// `when`<Any>(persister.write(barCode, NETWORK))
|
||||
// .thenReturn(Single.just(true))
|
||||
//
|
||||
// `when`<Any>(parser.apply(DISK)).thenReturn(barCode.key)
|
||||
//
|
||||
// var result = simpleStore.getWithResult(barCode)
|
||||
// assertThat(result.source()).isEqualTo(Result.Source.NETWORK)
|
||||
// assertThat(result.value()).isEqualTo(barCode.key)
|
||||
//
|
||||
// result = simpleStore.getWithResult(barCode)
|
||||
// assertThat(result.source()).isEqualTo(Result.Source.CACHE)
|
||||
// assertThat(result.value()).isEqualTo(barCode.key)
|
||||
// verify<Fetcher<String, BarCode>>(fetcher, times(1)).fetch(barCode)
|
||||
// }
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testSimpleWithResult() {
|
||||
fun testSubclass() = runBlocking<Unit> {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
|
||||
val simpleStore = SampleParsingStore(fetcher, persister, parser)
|
||||
|
||||
val simpleStore = ParsingStoreBuilder.builder<String, String>()
|
||||
.persister(persister!!)
|
||||
.fetcher(fetcher!!)
|
||||
.parser(parser!!)
|
||||
.open()
|
||||
|
||||
`when`<Any>(fetcher!!.fetch(barCode))
|
||||
`when`<Any>(fetcher.fetch(barCode))
|
||||
.thenReturn(Single.just(NETWORK))
|
||||
|
||||
`when`<Any>(persister!!.read(barCode))
|
||||
`when`<Any>(persister.read(barCode))
|
||||
.thenReturn(Maybe.empty<String>())
|
||||
.thenReturn(Maybe.just(DISK))
|
||||
|
||||
`when`<Any>(persister!!.write(barCode, NETWORK))
|
||||
`when`<Any>(persister.write(barCode, NETWORK))
|
||||
.thenReturn(Single.just(true))
|
||||
|
||||
`when`<Any>(parser!!.apply(DISK)).thenReturn(barCode.key)
|
||||
`when`<Any>(parser.apply(DISK)).thenReturn(barCode.key)
|
||||
|
||||
var result = simpleStore.getWithResult(barCode).blockingGet()
|
||||
assertThat<Source>(result.source()).isEqualTo(Result.Source.NETWORK)
|
||||
assertThat(result.value()).isEqualTo(barCode.key)
|
||||
|
||||
result = simpleStore.getWithResult(barCode).blockingGet()
|
||||
assertThat<Source>(result.source()).isEqualTo(Result.Source.CACHE)
|
||||
assertThat(result.value()).isEqualTo(barCode.key)
|
||||
verify<Fetcher<String, BarCode>>(fetcher, times(1)).fetch(barCode)
|
||||
}
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testSubclass() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
|
||||
val simpleStore = SampleParsingStore(fetcher!!, persister!!, parser!!)
|
||||
|
||||
`when`<Any>(fetcher!!.fetch(barCode))
|
||||
.thenReturn(Single.just(NETWORK))
|
||||
|
||||
`when`<Any>(persister!!.read(barCode))
|
||||
.thenReturn(Maybe.empty<String>())
|
||||
.thenReturn(Maybe.just(DISK))
|
||||
|
||||
`when`<Any>(persister!!.write(barCode, NETWORK))
|
||||
.thenReturn(Single.just(true))
|
||||
|
||||
`when`<Any>(parser!!.apply(DISK)).thenReturn(barCode.key)
|
||||
|
||||
var value = simpleStore.get(barCode).blockingGet()
|
||||
var value = simpleStore.get(barCode)
|
||||
assertThat(value).isEqualTo(barCode.key)
|
||||
value = simpleStore.get(barCode).blockingGet()
|
||||
value = simpleStore.get(barCode)
|
||||
assertThat(value).isEqualTo(barCode.key)
|
||||
verify<Fetcher<String, BarCode>>(fetcher, times(1)).fetch(barCode)
|
||||
}
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testSubclassWithResult() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
|
||||
val simpleStore = SampleParsingStore(fetcher!!, persister!!, parser!!)
|
||||
|
||||
`when`<Any>(fetcher!!.fetch(barCode))
|
||||
.thenReturn(Single.just(NETWORK))
|
||||
|
||||
`when`<Any>(persister!!.read(barCode))
|
||||
.thenReturn(Maybe.empty<String>())
|
||||
.thenReturn(Maybe.just(DISK))
|
||||
|
||||
`when`<Any>(persister!!.write(barCode, NETWORK))
|
||||
.thenReturn(Single.just(true))
|
||||
|
||||
`when`<Any>(parser!!.apply(DISK)).thenReturn(barCode.key)
|
||||
|
||||
var result = simpleStore.getWithResult(barCode).blockingGet()
|
||||
assertThat<Source>(result.source()).isEqualTo(Result.Source.NETWORK)
|
||||
assertThat(result.value()).isEqualTo(barCode.key)
|
||||
|
||||
result = simpleStore.getWithResult(barCode).blockingGet()
|
||||
assertThat<Source>(result.source()).isEqualTo(Result.Source.CACHE)
|
||||
assertThat(result.value()).isEqualTo(barCode.key)
|
||||
verify<Fetcher<String, BarCode>>(fetcher, times(1)).fetch(barCode)
|
||||
}
|
||||
// @Test
|
||||
// fun testSubclassWithResult() = runBlocking<Unit> {
|
||||
// MockitoAnnotations.initMocks(this)
|
||||
//
|
||||
// val simpleStore = SampleParsingStore(fetcher, persister, parser)
|
||||
//
|
||||
// `when`<Any>(fetcher.fetch(barCode))
|
||||
// .thenReturn(Single.just(NETWORK))
|
||||
//
|
||||
// `when`<Any>(persister.read(barCode))
|
||||
// .thenReturn(Maybe.empty<String>())
|
||||
// .thenReturn(Maybe.just(DISK))
|
||||
//
|
||||
// `when`<Any>(persister.write(barCode, NETWORK))
|
||||
// .thenReturn(Single.just(true))
|
||||
//
|
||||
// `when`<Any>(parser.apply(DISK)).thenReturn(barCode.key)
|
||||
//
|
||||
// var result = simpleStore.getWithResult(barCode)
|
||||
// assertThat(result.source()).isEqualTo(Result.Source.NETWORK)
|
||||
// assertThat(result.value()).isEqualTo(barCode.key)
|
||||
//
|
||||
// result = simpleStore.getWithResult(barCode)
|
||||
// assertThat(result.source()).isEqualTo(Result.Source.CACHE)
|
||||
// assertThat(result.value()).isEqualTo(barCode.key)
|
||||
// verify<Fetcher<String, BarCode>>(fetcher, times(1)).fetch(barCode)
|
||||
// }
|
||||
|
||||
companion object {
|
||||
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
package com.nytimes.android.external.store3;
|
||||
|
||||
import com.nytimes.android.external.store3.base.Fetcher;
|
||||
import com.nytimes.android.external.store3.base.Persister;
|
||||
import com.nytimes.android.external.store3.base.impl.BarCode;
|
||||
import com.nytimes.android.external.store3.base.impl.Store;
|
||||
import com.nytimes.android.external.store3.base.impl.StoreBuilder;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
import io.reactivex.Maybe;
|
||||
import io.reactivex.Single;
|
||||
import io.reactivex.observers.TestObserver;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class StreamOneKeyTest {
|
||||
|
||||
private static final String TEST_ITEM = "test";
|
||||
private static final String TEST_ITEM2 = "test2";
|
||||
|
||||
@Mock
|
||||
Fetcher<String, BarCode> fetcher;
|
||||
@Mock
|
||||
Persister<String, BarCode> persister;
|
||||
|
||||
private final BarCode barCode = new BarCode("key", "value");
|
||||
private final BarCode barCode2 = new BarCode("key2", "value2");
|
||||
|
||||
private Store<String, BarCode> store;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
store = StoreBuilder.<String>barcode()
|
||||
.persister(persister)
|
||||
.fetcher(fetcher)
|
||||
.open();
|
||||
|
||||
when(fetcher.fetch(barCode))
|
||||
.thenReturn(Single.just(TEST_ITEM))
|
||||
.thenReturn(Single.just(TEST_ITEM2));
|
||||
|
||||
when(persister.read(barCode))
|
||||
.thenReturn(Maybe.<String>empty())
|
||||
.thenReturn(Maybe.just(TEST_ITEM))
|
||||
.thenReturn(Maybe.just(TEST_ITEM2));
|
||||
|
||||
when(persister.write(barCode, TEST_ITEM))
|
||||
.thenReturn(Single.just(true));
|
||||
when(persister.write(barCode, TEST_ITEM2))
|
||||
.thenReturn(Single.just(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStream() {
|
||||
TestObserver<String> streamObservable = store.stream(barCode).test();
|
||||
//first time we subscribe to stream it will fail getting from memory & disk and instead
|
||||
//fresh from network, write to disk and notifiy subscribers
|
||||
streamObservable.assertValueCount(1);
|
||||
|
||||
store.clear();
|
||||
//fresh should notify subscribers again
|
||||
store.fresh(barCode).test().awaitCount(1);
|
||||
streamObservable.assertValues(TEST_ITEM, TEST_ITEM2);
|
||||
|
||||
//get for another barcode should not trigger a stream for barcode1
|
||||
when(fetcher.fetch(barCode2))
|
||||
.thenReturn(Single.just(TEST_ITEM));
|
||||
when(persister.read(barCode2))
|
||||
.thenReturn(Maybe.empty())
|
||||
.thenReturn(Maybe.just(TEST_ITEM));
|
||||
when(persister.write(barCode2, TEST_ITEM))
|
||||
.thenReturn(Single.just(true));
|
||||
store.get(barCode2).test().awaitCount(1);
|
||||
streamObservable.assertValueCount(2);
|
||||
}
|
||||
}
|
75
store/src/test/java/com/nytimes/android/external/store3/StreamOneKeyTest.kt
vendored
Normal file
75
store/src/test/java/com/nytimes/android/external/store3/StreamOneKeyTest.kt
vendored
Normal file
|
@ -0,0 +1,75 @@
|
|||
package com.nytimes.android.external.store3
|
||||
|
||||
import com.nhaarman.mockitokotlin2.mock
|
||||
import com.nytimes.android.external.store3.base.Fetcher
|
||||
import com.nytimes.android.external.store3.base.Persister
|
||||
import com.nytimes.android.external.store3.base.impl.BarCode
|
||||
import com.nytimes.android.external.store3.base.impl.Store
|
||||
import com.nytimes.android.external.store3.base.impl.StoreBuilder
|
||||
import io.reactivex.Maybe
|
||||
import io.reactivex.Single
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.mockito.Mockito.`when`
|
||||
|
||||
class StreamOneKeyTest {
|
||||
|
||||
val fetcher: Fetcher<String, BarCode> = mock()
|
||||
val persister: Persister<String, BarCode> = mock()
|
||||
|
||||
private val barCode = BarCode("key", "value")
|
||||
private val barCode2 = BarCode("key2", "value2")
|
||||
|
||||
private val store: Store<String, BarCode> = StoreBuilder.barcode<String>()
|
||||
.persister(persister)
|
||||
.fetcher(fetcher)
|
||||
.open()
|
||||
|
||||
@Before
|
||||
fun setUp() = runBlocking<Unit> {
|
||||
`when`<Any>(fetcher.fetch(barCode))
|
||||
.thenReturn(Single.just(TEST_ITEM))
|
||||
.thenReturn(Single.just(TEST_ITEM2))
|
||||
|
||||
`when`<Any>(persister.read(barCode))
|
||||
.thenReturn(Maybe.empty<String>())
|
||||
.thenReturn(Maybe.just(TEST_ITEM))
|
||||
.thenReturn(Maybe.just(TEST_ITEM2))
|
||||
|
||||
`when`<Any>(persister.write(barCode, TEST_ITEM))
|
||||
.thenReturn(Single.just(true))
|
||||
`when`<Any>(persister.write(barCode, TEST_ITEM2))
|
||||
.thenReturn(Single.just(true))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testStream() = runBlocking<Unit> {
|
||||
val streamObservable = store.stream(barCode).test()
|
||||
//first time we subscribe to stream it will fail getting from memory & disk and instead
|
||||
//fresh from network, write to disk and notifiy subscribers
|
||||
streamObservable.assertValueCount(1)
|
||||
|
||||
store.clear()
|
||||
//fresh should notify subscribers again
|
||||
store.fresh(barCode)
|
||||
streamObservable.assertValues(TEST_ITEM, TEST_ITEM2)
|
||||
|
||||
//get for another barcode should not trigger a stream for barcode1
|
||||
`when`<Any>(fetcher.fetch(barCode2))
|
||||
.thenReturn(Single.just(TEST_ITEM))
|
||||
`when`<Any>(persister.read(barCode2))
|
||||
.thenReturn(Maybe.empty<Any>())
|
||||
.thenReturn(Maybe.just(TEST_ITEM))
|
||||
`when`<Any>(persister.write(barCode2, TEST_ITEM))
|
||||
.thenReturn(Single.just(true))
|
||||
store.get(barCode2)
|
||||
streamObservable.assertValueCount(2)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private val TEST_ITEM = "test"
|
||||
private val TEST_ITEM2 = "test2"
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package com.nytimes.android.external.store3.room
|
||||
|
||||
import com.nhaarman.mockitokotlin2.mock
|
||||
import com.nytimes.android.external.store3.base.Clearable
|
||||
import com.nytimes.android.external.store3.base.impl.BarCode
|
||||
import com.nytimes.android.external.store3.base.impl.StalePolicy
|
||||
|
@ -8,16 +9,14 @@ import com.nytimes.android.external.store3.base.room.RoomPersister
|
|||
import io.reactivex.Observable
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.Test
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.`when`
|
||||
import org.mockito.Mockito.verify
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
|
||||
class ClearStoreRoomTest {
|
||||
@Mock
|
||||
internal var persister: RoomClearingPersister? = null
|
||||
private val persister: RoomClearingPersister = mock()
|
||||
private val networkCalls: AtomicInteger = AtomicInteger(0)
|
||||
private var store = StoreRoom.from({ Observable.fromCallable { networkCalls.incrementAndGet() } },
|
||||
private val store = StoreRoom.from({ Observable.fromCallable { networkCalls.incrementAndGet() } },
|
||||
persister,
|
||||
StalePolicy.UNSPECIFIED)
|
||||
|
||||
|
@ -26,18 +25,18 @@ class ClearStoreRoomTest {
|
|||
// one request should produce one call
|
||||
val barcode = BarCode("type", "key")
|
||||
|
||||
`when`(persister!!.read(barcode))
|
||||
`when`(persister.read(barcode))
|
||||
.thenReturn(Observable.empty()) //read from disk on get
|
||||
.thenReturn(Observable.just(1)) //read from disk after fetching from network
|
||||
.thenReturn(Observable.empty()) //read from disk after clearing
|
||||
.thenReturn(Observable.just(1)) //read from disk after making additional network call
|
||||
|
||||
store!!.get(barcode).test().awaitTerminalEvent()
|
||||
store.get(barcode).test().awaitTerminalEvent()
|
||||
assertThat(networkCalls.toInt()).isEqualTo(1)
|
||||
|
||||
// after clearing the memory another call should be made
|
||||
store!!.clear(barcode)
|
||||
store!!.get(barcode).test().awaitTerminalEvent()
|
||||
store.clear(barcode)
|
||||
store.get(barcode).test().awaitTerminalEvent()
|
||||
verify<RoomClearingPersister>(persister).clear(barcode)
|
||||
assertThat(networkCalls.toInt()).isEqualTo(2)
|
||||
}
|
||||
|
@ -47,13 +46,13 @@ class ClearStoreRoomTest {
|
|||
val barcode1 = BarCode("type1", "key1")
|
||||
val barcode2 = BarCode("type2", "key2")
|
||||
|
||||
`when`(persister!!.read(barcode1))
|
||||
`when`(persister.read(barcode1))
|
||||
.thenReturn(Observable.empty()) //read from disk
|
||||
.thenReturn(Observable.just(1)) //read from disk after fetching from network
|
||||
.thenReturn(Observable.empty()) //read from disk after clearing disk cache
|
||||
.thenReturn(Observable.just(1)) //read from disk after making additional network call
|
||||
|
||||
`when`(persister!!.read(barcode2))
|
||||
`when`(persister.read(barcode2))
|
||||
.thenReturn(Observable.empty()) //read from disk
|
||||
.thenReturn(Observable.just(1)) //read from disk after fetching from network
|
||||
.thenReturn(Observable.empty()) //read from disk after clearing disk cache
|
||||
|
@ -61,20 +60,20 @@ class ClearStoreRoomTest {
|
|||
|
||||
|
||||
// each request should produce one call
|
||||
store!!.get(barcode1).test().awaitTerminalEvent()
|
||||
store!!.get(barcode2).test().awaitTerminalEvent()
|
||||
store.get(barcode1).test().awaitTerminalEvent()
|
||||
store.get(barcode2).test().awaitTerminalEvent()
|
||||
assertThat(networkCalls.toInt()).isEqualTo(2)
|
||||
|
||||
store!!.clear()
|
||||
store.clear()
|
||||
|
||||
// after everything is cleared each request should produce another 2 calls
|
||||
store!!.get(barcode1).test().awaitTerminalEvent()
|
||||
store!!.get(barcode2).test().awaitTerminalEvent()
|
||||
store.get(barcode1).test().awaitTerminalEvent()
|
||||
store.get(barcode2).test().awaitTerminalEvent()
|
||||
assertThat(networkCalls.toInt()).isEqualTo(4)
|
||||
}
|
||||
|
||||
//everything will be mocked
|
||||
internal class RoomClearingPersister : RoomPersister<Int, Int, BarCode>, Clearable<BarCode> {
|
||||
internal open class RoomClearingPersister : RoomPersister<Int, Int, BarCode>, Clearable<BarCode> {
|
||||
override fun clear(key: BarCode) {
|
||||
throw RuntimeException()
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import java.util.concurrent.TimeUnit
|
|||
|
||||
class NoopPersisterTest {
|
||||
|
||||
@Rule
|
||||
@get:Rule
|
||||
var exception = ExpectedException.none()
|
||||
|
||||
@Test
|
||||
|
|
Loading…
Reference in a new issue