1
0
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:
Allan Wang 2021-04-18 17:58:23 -07:00
parent 6abaf596e4
commit 41b6765da8
No known key found for this signature in database
GPG Key ID: 69D90B885D405BDB
5 changed files with 47 additions and 54 deletions

View File

@ -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

View File

@ -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
}
}
}
}

View File

@ -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
}

View File

@ -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)

View File

@ -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)
}