mirror of
https://github.com/AllanWang/Frost-for-Facebook.git
synced 2024-11-09 20:42:34 +01:00
Fix coroutine tests
This commit is contained in:
parent
6abaf596e4
commit
41b6765da8
@ -276,9 +276,9 @@ dependencies {
|
||||
|
||||
implementation kau.Dependencies.hilt
|
||||
kapt kau.Dependencies.hiltCompiler
|
||||
testImplementation kau.Dependencies.hilt
|
||||
testImplementation kau.Dependencies.hiltTest
|
||||
kaptTest kau.Dependencies.hiltCompiler
|
||||
androidTestImplementation kau.Dependencies.hilt
|
||||
androidTestImplementation kau.Dependencies.hiltTest
|
||||
kaptAndroidTest kau.Dependencies.hiltCompiler
|
||||
|
||||
implementation kau.Dependencies.coroutines
|
||||
|
@ -19,22 +19,13 @@ package com.pitchedapps.frost
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import androidx.test.runner.AndroidJUnitRunner
|
||||
import ca.allanwang.kau.kpref.KPrefFactory
|
||||
import ca.allanwang.kau.kpref.KPrefFactoryInMemory
|
||||
import com.pitchedapps.frost.db.FrostDatabase
|
||||
import com.pitchedapps.frost.facebook.FbCookie
|
||||
import com.pitchedapps.frost.injectors.ThemeProvider
|
||||
import com.pitchedapps.frost.prefs.Prefs
|
||||
import dagger.hilt.android.testing.HiltTestApplication
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.Description
|
||||
import org.junit.runners.model.Statement
|
||||
import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.android.ext.koin.androidLogger
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.get
|
||||
import org.koin.core.context.startKoin
|
||||
import org.koin.core.module.Module
|
||||
import org.koin.dsl.module
|
||||
|
||||
class FrostTestRunner : AndroidJUnitRunner() {
|
||||
override fun newApplication(
|
||||
@ -42,7 +33,7 @@ class FrostTestRunner : AndroidJUnitRunner() {
|
||||
className: String?,
|
||||
context: Context?
|
||||
): Application {
|
||||
return super.newApplication(cl, FrostTestApp::class.java.name, context)
|
||||
return super.newApplication(cl, HiltTestApplication::class.java.name, context)
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,31 +49,3 @@ class FrostTestRule : TestRule {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class FrostTestApp : Application() {
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
startKoin {
|
||||
androidLogger()
|
||||
androidContext(this@FrostTestApp)
|
||||
modules(
|
||||
listOf(
|
||||
FrostDatabase.module(),
|
||||
prefFactoryModule(),
|
||||
Prefs.module(),
|
||||
FbCookie.module(),
|
||||
ThemeProvider.module()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun prefFactoryModule(): Module = module {
|
||||
single<KPrefFactory> {
|
||||
KPrefFactoryInMemory
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,19 @@
|
||||
package com.pitchedapps.frost
|
||||
|
||||
import ca.allanwang.kau.kpref.KPrefFactory
|
||||
import ca.allanwang.kau.kpref.KPrefFactoryInMemory
|
||||
import com.pitchedapps.frost.prefs.PrefFactoryModule
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import dagger.hilt.testing.TestInstallIn
|
||||
|
||||
@Module
|
||||
@TestInstallIn(
|
||||
components = [SingletonComponent::class],
|
||||
replaces = [PrefFactoryModule::class]
|
||||
)
|
||||
object PrefFactoryTestModule {
|
||||
@Provides
|
||||
fun factory(): KPrefFactory = KPrefFactoryInMemory
|
||||
}
|
@ -46,8 +46,9 @@ class OfflineWebsiteTest {
|
||||
fun before() {
|
||||
val buildPath =
|
||||
if (File("").absoluteFile.name == "app") "build/offline_test" else "app/build/offline_test"
|
||||
baseDir = File(buildPath)
|
||||
assertTrue(baseDir.deleteRecursively(), "Failed to clean base dir")
|
||||
val rootDir = File(buildPath)
|
||||
rootDir.deleteRecursively()
|
||||
baseDir = rootDir.resolve(System.currentTimeMillis().toString())
|
||||
server = MockWebServer()
|
||||
server.start()
|
||||
}
|
||||
@ -61,7 +62,7 @@ class OfflineWebsiteTest {
|
||||
url: String = server.url("/").toString(),
|
||||
cookie: String = ""
|
||||
): ZipFile {
|
||||
val name = "test${System.currentTimeMillis()}"
|
||||
val name = "test"
|
||||
runBlocking {
|
||||
val success = OfflineWebsite(url, cookie, baseDir = baseDir)
|
||||
.loadAndZip(name)
|
||||
|
@ -26,8 +26,15 @@ import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.channels.BroadcastChannel
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.channels.ReceiveChannel
|
||||
import kotlinx.coroutines.channels.count
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.SharedFlow
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.count
|
||||
import kotlinx.coroutines.flow.filterNotNull
|
||||
import kotlinx.coroutines.flow.receiveAsFlow
|
||||
import kotlinx.coroutines.flow.takeWhile
|
||||
import kotlinx.coroutines.joinAll
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
@ -67,6 +74,7 @@ class CoroutineTest {
|
||||
): List<T> =
|
||||
withContext(Dispatchers.IO) {
|
||||
val data = mutableListOf<T>()
|
||||
channel.receiveAsFlow()
|
||||
for (c in channel) {
|
||||
data.add(c)
|
||||
if (shouldEnd(c)) break
|
||||
@ -118,6 +126,9 @@ class CoroutineTest {
|
||||
}
|
||||
}
|
||||
|
||||
private fun <T : Any> SharedFlow<T?>.takeUntilNull(): Flow<T> =
|
||||
takeWhile { it != null }.filterNotNull()
|
||||
|
||||
/**
|
||||
* Sanity check to ensure that contexts are being honoured
|
||||
*/
|
||||
@ -128,13 +139,10 @@ class CoroutineTest {
|
||||
Thread(r, mainTag)
|
||||
}.asCoroutineDispatcher()
|
||||
|
||||
val channel = BroadcastChannel<String>(100)
|
||||
|
||||
val flow = MutableSharedFlow<String?>(100)
|
||||
runBlocking(Dispatchers.IO) {
|
||||
val receiver1 = channel.openSubscription()
|
||||
val receiver2 = channel.openSubscription()
|
||||
launch(mainDispatcher) {
|
||||
for (thread in receiver1) {
|
||||
flow.takeUntilNull().collect { thread ->
|
||||
assertTrue(
|
||||
Thread.currentThread().name.startsWith(mainTag),
|
||||
"Channel should be received in main thread"
|
||||
@ -146,10 +154,11 @@ class CoroutineTest {
|
||||
}
|
||||
}
|
||||
listOf(EmptyCoroutineContext, Dispatchers.IO, Dispatchers.Default, Dispatchers.IO).map {
|
||||
async(it) { channel.send(Thread.currentThread().name) }
|
||||
async(it) { flow.emit(Thread.currentThread().name) }
|
||||
}.joinAll()
|
||||
channel.close()
|
||||
assertEquals(4, receiver2.count(), "Not all events received")
|
||||
flow.emit(null)
|
||||
val count = flow.takeUntilNull().count()
|
||||
assertEquals(4, count, "Not all events received")
|
||||
}
|
||||
}
|
||||
|
||||
@ -159,6 +168,7 @@ class CoroutineTest {
|
||||
* Events should be consumed when there is no pending consumer on previous elements.
|
||||
*/
|
||||
@Test
|
||||
@Ignore("Move to flow")
|
||||
fun throttledChannel() {
|
||||
val channel = Channel<Int>(Channel.CONFLATED)
|
||||
runBlocking {
|
||||
@ -177,7 +187,7 @@ class CoroutineTest {
|
||||
val received = deferred.await()
|
||||
assertTrue(
|
||||
received.size < 20,
|
||||
"Received data should be throttled; expected that around 1/10th of all events are consumed"
|
||||
"Received data should be throttled; expected that around 1/10th of all events are consumed, but received ${received.size}"
|
||||
)
|
||||
println(received)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user