Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ import kotlinx.coroutines.test.TestCoroutineScheduler
internal abstract class AbstractMainTestClock(
private val testScheduler: TestCoroutineScheduler,
private val frameDelayMillis: Long,
private val runOnUiThread: (action: () -> Unit) -> Unit
private val runOnUiThread: (action: () -> Unit) -> Unit,
private val onTimeAdvanced: ((currentTime: Long) -> Unit)? = null,
) : MainTestClock {

override val currentTime: Long
Expand Down Expand Up @@ -73,5 +74,7 @@ internal abstract class AbstractMainTestClock(
// Therefore we also call `runCurrent` as it's done in TestCoroutineDispatcher
testScheduler.runCurrent()
}

onTimeAdvanced?.invoke(currentTime)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,8 @@
package androidx.compose.ui.test

import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.platform.testTag
Expand All @@ -29,6 +27,7 @@ import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue
import kotlinx.atomicfu.atomic
import kotlinx.coroutines.delay
import org.junit.Rule


Expand Down Expand Up @@ -78,4 +77,25 @@ class BasicTestTest {
val clockAfter = rule.mainClock.currentTime
assertTrue(clockAfter > clockBefore, "performClick did not advance the test clock")
}

@Test
fun advancingClockRunsRecomposition() {
rule.mainClock.autoAdvance = false
Comment thread
eymar marked this conversation as resolved.

rule.setContent {
var text by remember { mutableStateOf("1") }
Text(text, modifier = Modifier.testTag("text"))

LaunchedEffect(Unit){
delay(1_000)
text = "2"
}
}

rule.onNodeWithTag("text").assertTextEquals("1")
rule.mainClock.advanceTimeBy(999, ignoreFrameDuration = true)
rule.onNodeWithTag("text").assertTextEquals("1")
rule.mainClock.advanceTimeBy(1, ignoreFrameDuration = true)
rule.onNodeWithTag("text").assertTextEquals("2")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,11 @@ class SkikoComposeUiTest(

private val coroutineDispatcher = UnconfinedTestDispatcher()
private val testScope = TestScope(coroutineDispatcher)
override val mainClock: MainTestClock =
MainTestClockImpl(coroutineDispatcher.scheduler, frameDelayMillis = 16L)
override val mainClock: MainTestClock = MainTestClockImpl(
testScheduler = coroutineDispatcher.scheduler,
frameDelayMillis = 16L,
onTimeAdvanced = ::render
)
private val uncaughtExceptionHandler = UncaughtExceptionHandler()
private val infiniteAnimationPolicy = object : InfiniteAnimationPolicy {
override suspend fun <R> onInfiniteOperation(block: suspend () -> R): R {
Expand Down Expand Up @@ -179,11 +182,15 @@ class SkikoComposeUiTest(
}
}

private fun renderNextFrame() = runOnUiThread {
private fun render(timeMillis: Long) {
scene.render(
surface.canvas,
mainClock.currentTime * NanoSecondsPerMilliSecond
timeMillis * NanoSecondsPerMilliSecond
)
}

private fun renderNextFrame() = runOnUiThread {
render(mainClock.currentTime)
if (mainClock.autoAdvance) {
mainClock.advanceTimeByFrame()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ import kotlinx.coroutines.test.TestCoroutineScheduler
@OptIn(ExperimentalCoroutinesApi::class)
internal class MainTestClockImpl(
testScheduler: TestCoroutineScheduler,
frameDelayMillis: Long
frameDelayMillis: Long,
onTimeAdvanced: (Long) -> Unit
) : AbstractMainTestClock(
testScheduler,
frameDelayMillis,
::runOnUiThread
testScheduler = testScheduler,
frameDelayMillis = frameDelayMillis,
runOnUiThread = ::runOnUiThread,
onTimeAdvanced = onTimeAdvanced
)