You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
 
 

91 lines
3.1 KiB

package cash.z.ecc.android.sdk.test
import android.content.Context
import androidx.test.platform.app.InstrumentationRegistry
import cash.z.ecc.android.sdk.internal.TroubleshootingTwig
import cash.z.ecc.android.sdk.internal.Twig
import cash.z.ecc.android.sdk.internal.twig
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.newFixedThreadPoolContext
import kotlinx.coroutines.runBlocking
import org.junit.After
import org.junit.AfterClass
import org.junit.Before
import org.junit.BeforeClass
import java.util.concurrent.TimeoutException
open class ScopedTest(val defaultTimeout: Long = 2000L) {
protected lateinit var testScope: CoroutineScope
// if an androidTest doesn't need a context, then maybe it should be a unit test instead?!
val context: Context = InstrumentationRegistry.getInstrumentation().context
@Before
fun start() {
twig("===================== TEST STARTED ==================================")
testScope = CoroutineScope(
Job(classScope.coroutineContext[Job]!!) + newFixedThreadPoolContext(
5,
this.javaClass.simpleName
)
)
}
@After
fun end() = runBlocking<Unit> {
twig("======================= TEST CANCELLING =============================")
testScope.cancel()
testScope.coroutineContext[Job]?.join()
twig("======================= TEST ENDED ==================================")
}
fun timeout(duration: Long, block: suspend () -> Unit) = timeoutWith(testScope, duration, block)
companion object {
@JvmStatic
lateinit var classScope: CoroutineScope
init {
Twig.plant(TroubleshootingTwig())
twig("================================================================ INIT")
}
@BeforeClass
@JvmStatic
fun createScope() {
twig("======================= CLASS STARTED ===============================")
classScope = CoroutineScope(
SupervisorJob() + newFixedThreadPoolContext(2, this.javaClass.simpleName)
)
}
@AfterClass
@JvmStatic
fun destroyScope() = runBlocking<Unit> {
twig("======================= CLASS CANCELLING ============================")
classScope.cancel()
classScope.coroutineContext[Job]?.join()
twig("======================= CLASS ENDED =================================")
}
@JvmStatic
fun timeoutWith(scope: CoroutineScope, duration: Long, block: suspend () -> Unit) {
scope.launch {
delay(duration)
val message = "ERROR: Test timed out after ${duration}ms"
twig(message)
throw TimeoutException(message)
}.let { selfDestruction ->
scope.launch {
block()
selfDestruction.cancel()
}
}
}
}
}