Skip to content

Instantly share code, notes, and snippets.

@tomoya0x00
Last active February 20, 2022 08:06
Show Gist options
  • Save tomoya0x00/0e758bb5a471f2d046391564a3898273 to your computer and use it in GitHub Desktop.
Save tomoya0x00/0e758bb5a471f2d046391564a3898273 to your computer and use it in GitHub Desktop.
Allow snapshotFlow to be used without Compose.
import androidx.compose.runtime.snapshots.Snapshot
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Job
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.isActive
import kotlinx.coroutines.newSingleThreadContext
import org.junit.rules.TestWatcher
import org.junit.runner.Description
/**
* To be able to use snapshotFlow in test without Compose, We have to take snapshots.
* So this rule takes snapshots regularly.
*
* What's about snapshotFlow:
* https://developer.android.com/jetpack/compose/side-effects#snapshotFlow
*/
class ComposeStateTestRule(
snapshotIntervalMilliSec: Long = 1L
) : TestWatcher() {
@OptIn(DelicateCoroutinesApi::class)
private val dispatcher = newSingleThreadContext(name = "snapshot")
private val scope = CoroutineScope(SupervisorJob() + dispatcher)
private var job: Job? = null
private val snapshotTaker = flow<Unit> {
coroutineScope {
while(isActive) {
delay(snapshotIntervalMilliSec)
Snapshot.takeSnapshot { }
}
}
}
override fun starting(description: Description?) {
job = snapshotTaker.launchIn(scope)
}
override fun finished(description: Description?) {
job?.cancel()
job = null
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment