Skip to content

Commit 12e5e54

Browse files
committed
Change runOnIdle to execute on the UI thread, and to not waitForIdle afterward.
1 parent c973fff commit 12e5e54

File tree

6 files changed

+106
-99
lines changed

6 files changed

+106
-99
lines changed

compose/foundation/foundation/src/skikoTest/kotlin/androidx/compose/foundation/ToggleableTest.kt

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,7 @@ class ToggleableTest {
5252
).testTag("toggle"))
5353
}
5454

55-
runOnIdle {
56-
assertEquals(false, state)
57-
}
55+
assertEquals(false, state)
5856

5957
onRoot().apply {
6058
performKeyPress(KeyEvent(Key.Tab, KeyEventType.KeyDown))
@@ -66,17 +64,13 @@ class ToggleableTest {
6664
performKeyPress(KeyEvent(Key.Spacebar, KeyEventType.KeyUp))
6765
}
6866

69-
runOnIdle {
70-
assertEquals(true, state)
71-
}
67+
assertEquals(true, state)
7268

7369
onNodeWithTag("toggle").apply {
7470
performKeyPress(KeyEvent(Key.Spacebar, KeyEventType.KeyDown))
7571
performKeyPress(KeyEvent(Key.Spacebar, KeyEventType.KeyUp))
7672
}
7773

78-
runOnIdle {
79-
assertEquals(false, state)
80-
}
74+
assertEquals(false, state)
8175
}
8276
}

compose/foundation/foundation/src/skikoTest/kotlin/androidx/compose/foundation/copyPasteAndroidTests/ScrollableTest.kt

Lines changed: 35 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1701,23 +1701,19 @@ class ScrollableTest {
17011701
}
17021702
}
17031703

1704-
runOnIdle {
1705-
assertThat(isOuterInScrollableContainer).isFalse()
1706-
assertThat(isInnerInScrollableContainer).isTrue()
1707-
}
1704+
assertThat(isOuterInScrollableContainer).isFalse()
1705+
assertThat(isInnerInScrollableContainer).isTrue()
17081706
}
17091707

17101708
@Test
17111709
fun scrollable_scrollByWorksWithRepeatableAnimations() = runSkikoComposeUiTest {
17121710
mainClock.autoAdvance = false
17131711

17141712
var total = 0f
1715-
val controller = ScrollableState(
1716-
consumeScrollDelta = {
1717-
total += it
1718-
it
1719-
}
1720-
)
1713+
val controller = ScrollableState {
1714+
total += it
1715+
it
1716+
}
17211717
setContentAndGetScope {
17221718
Box(
17231719
modifier = Modifier
@@ -1729,62 +1725,48 @@ class ScrollableTest {
17291725
)
17301726
}
17311727

1732-
runOnIdle {
1733-
scope.launch {
1734-
controller.animateScrollBy(
1735-
100f,
1736-
keyframes {
1737-
durationMillis = 2500
1738-
// emulate a repeatable animation:
1739-
0f at 0
1740-
100f at 500
1741-
100f at 1000
1742-
0f at 1500
1743-
0f at 2000
1744-
100f at 2500
1745-
}
1746-
)
1747-
}
1728+
scope.launch {
1729+
controller.animateScrollBy(
1730+
value = 100f,
1731+
animationSpec = keyframes {
1732+
durationMillis = 2500
1733+
// emulate a repeatable animation:
1734+
0f at 0
1735+
100f at 500
1736+
100f at 1000
1737+
0f at 1500
1738+
0f at 2000
1739+
100f at 2500
1740+
}
1741+
)
17481742
}
17491743

17501744
mainClock.advanceTimeBy(250)
1751-
runOnIdle {
1752-
// in the middle of the first animation
1753-
assertThat(total).isGreaterThan(0f)
1754-
assertThat(total).isLessThan(100f)
1755-
}
1745+
// in the middle of the first animation
1746+
assertThat(total).isGreaterThan(0f)
1747+
assertThat(total).isLessThan(100f)
17561748

17571749
mainClock.advanceTimeBy(500) // 750 ms
1758-
runOnIdle {
1759-
// first animation finished
1760-
assertThat(total).isEqualTo(100f)
1761-
}
1750+
// first animation finished
1751+
assertThat(total).isEqualTo(100f)
17621752

17631753
mainClock.advanceTimeBy(250) // 1250 ms
1764-
runOnIdle {
1765-
// in the middle of the second animation
1766-
assertThat(total).isGreaterThan(0f)
1767-
assertThat(total).isLessThan(100f)
1768-
}
1754+
// in the middle of the second animation
1755+
assertThat(total).isGreaterThan(0f)
1756+
assertThat(total).isLessThan(100f)
17691757

17701758
mainClock.advanceTimeBy(500) // 1750 ms
1771-
runOnIdle {
1772-
// second animation finished
1773-
assertThat(total).isEqualTo(0f)
1774-
}
1759+
// second animation finished
1760+
assertThat(total).isEqualTo(0f)
17751761

17761762
mainClock.advanceTimeBy(500) // 2250 ms
1777-
runOnIdle {
1778-
// in the middle of the third animation
1779-
assertThat(total).isGreaterThan(0f)
1780-
assertThat(total).isLessThan(100f)
1781-
}
1763+
// in the middle of the third animation
1764+
assertThat(total).isGreaterThan(0f)
1765+
assertThat(total).isLessThan(100f)
17821766

17831767
mainClock.advanceTimeBy(500) // 2750 ms
1784-
runOnIdle {
1785-
// third animation finished
1786-
assertThat(total).isEqualTo(100f)
1787-
}
1768+
// third animation finished
1769+
assertThat(total).isEqualTo(100f)
17881770
}
17891771

17901772
@Test

compose/material/material/src/desktopTest/kotlin/androidx/compose/material/DesktopMenuTest.kt

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -223,19 +223,15 @@ class DesktopMenuTest {
223223
}
224224
}
225225

226-
fun performKeyDownAndUp(key: Key) {
227-
onNodeWithTag("dropDownMenu").apply {
228-
performKeyPress(KeyEvent(key, KeyEventType.KeyDown))
229-
performKeyPress(KeyEvent(key, KeyEventType.KeyUp))
230-
}
226+
fun performKeyDownAndUp(key: Key) = onNodeWithTag("dropDownMenu").apply {
227+
performKeyPress(KeyEvent(key, KeyEventType.KeyDown))
228+
performKeyPress(KeyEvent(key, KeyEventType.KeyUp))
231229
}
232230

233231
fun assertClicksCount(i1: Int, i2: Int, i3: Int) {
234-
runOnIdle {
235-
assertThat(item1Clicked).isEqualTo(i1)
236-
assertThat(item2Clicked).isEqualTo(i2)
237-
assertThat(item3Clicked).isEqualTo(i3)
238-
}
232+
assertThat(item1Clicked).isEqualTo(i1)
233+
assertThat(item2Clicked).isEqualTo(i2)
234+
assertThat(item3Clicked).isEqualTo(i3)
239235
}
240236

241237
performKeyDownAndUp(Key.DirectionDown)

compose/material3/material3/src/skikoTest/kotlin/androidx/compose/material3/ExposedDropdownMenuTest.kt

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import androidx.compose.foundation.lazy.LazyColumn
2828
import androidx.compose.foundation.rememberScrollState
2929
import androidx.compose.foundation.verticalScroll
3030
import androidx.compose.runtime.Composable
31-
import androidx.compose.runtime.SideEffect
3231
import androidx.compose.runtime.getValue
3332
import androidx.compose.runtime.mutableStateOf
3433
import androidx.compose.runtime.remember
@@ -65,6 +64,7 @@ import androidx.compose.ui.unit.IntSize
6564
import androidx.compose.ui.unit.dp
6665
import kotlin.test.Ignore
6766
import kotlin.test.Test
67+
import kotlin.test.assertTrue
6868
import kotlinx.coroutines.CoroutineScope
6969
import kotlinx.coroutines.Dispatchers
7070
import kotlinx.coroutines.launch
@@ -210,7 +210,7 @@ class ExposedDropdownMenuTest {
210210
) {
211211
TextField(
212212
modifier = Modifier
213-
.menuAnchor()
213+
.menuAnchor(MenuAnchorType.PrimaryEditable)
214214
.then(
215215
if (index == testIndex) Modifier
216216
.testTag(TFTag)
@@ -282,7 +282,11 @@ class ExposedDropdownMenuTest {
282282
setContent {
283283
scrollState = rememberScrollState()
284284
scope = rememberCoroutineScope()
285-
Column(Modifier.verticalScroll(scrollState)) {
285+
Column(
286+
modifier = Modifier
287+
.height(500.dp)
288+
.verticalScroll(scrollState)
289+
) {
286290
Spacer(Modifier.height(300.dp))
287291

288292
val expanded = false
@@ -291,7 +295,7 @@ class ExposedDropdownMenuTest {
291295
onExpandedChange = {},
292296
) {
293297
TextField(
294-
modifier = Modifier.menuAnchor(),
298+
modifier = Modifier.menuAnchor(MenuAnchorType.PrimaryNotEditable),
295299
readOnly = true,
296300
value = "",
297301
onValueChange = {},
@@ -302,9 +306,7 @@ class ExposedDropdownMenuTest {
302306
onDismissRequest = {},
303307
content = {},
304308
)
305-
SideEffect {
306-
compositionCount++
307-
}
309+
compositionCount++
308310
}
309311

310312
Spacer(Modifier.height(300.dp))
@@ -313,13 +315,13 @@ class ExposedDropdownMenuTest {
313315

314316
assertThat(compositionCount).isEqualTo(1)
315317

316-
runOnIdle {
317-
scope.launch {
318-
scrollState.animateScrollBy(500f)
319-
}
318+
scope.launch {
319+
scrollState.animateScrollBy(500f)
320320
}
321+
mainClock.advanceTimeBy(10_000)
321322
waitForIdle()
322323

324+
assertTrue(scrollState.value > 0) // Make sure we did scroll
323325
assertThat(compositionCount).isEqualTo(1)
324326
}
325327

@@ -344,9 +346,7 @@ class ExposedDropdownMenuTest {
344346
onNodeWithTag(TFTag).assertIsDisplayed()
345347
onNodeWithTag(MenuItemTag).assertIsDisplayed()
346348

347-
runOnIdle {
348-
assertThat(menuBounds.width).isEqualTo(textFieldBounds.width)
349-
}
349+
assertThat(menuBounds.width).isEqualTo(textFieldBounds.width)
350350
}
351351

352352
@Test
@@ -382,7 +382,7 @@ class ExposedDropdownMenuTest {
382382
) {
383383
scrollState = rememberScrollState()
384384
TextField(
385-
modifier = Modifier.menuAnchor(),
385+
modifier = Modifier.menuAnchor(MenuAnchorType.PrimaryNotEditable),
386386
value = "",
387387
onValueChange = { },
388388
label = { Text("Label") },
@@ -403,14 +403,10 @@ class ExposedDropdownMenuTest {
403403
}
404404
}
405405

406-
runOnIdle {
407-
CoroutineScope(Dispatchers.Unconfined).launch {
408-
scrollState.scrollTo(scrollState.maxValue)
409-
}
406+
CoroutineScope(Dispatchers.Unconfined).launch {
407+
scrollState.scrollTo(scrollState.maxValue)
410408
}
411409

412-
waitForIdle()
413-
414410
onNodeWithTag("MenuContent 1").assertIsNotDisplayed()
415411
onNodeWithTag("MenuContent 100").assertIsDisplayed()
416412
}
@@ -423,7 +419,7 @@ class ExposedDropdownMenuTest {
423419
onExpandedChange = { },
424420
) {
425421
TextField(
426-
modifier = Modifier.menuAnchor(),
422+
modifier = Modifier.menuAnchor(MenuAnchorType.PrimaryNotEditable),
427423
value = "",
428424
onValueChange = { },
429425
label = { Text("Label") },
@@ -458,7 +454,7 @@ class ExposedDropdownMenuTest {
458454
) {
459455
TextField(
460456
modifier = Modifier
461-
.menuAnchor()
457+
.menuAnchor(MenuAnchorType.PrimaryEditable)
462458
.testTag(TFTag)
463459
.onGloballyPositioned {
464460
onTextFieldBoundsChanged?.invoke(it.boundsInRoot())

compose/ui/ui-test-junit4/src/desktopTest/kotlin/androidx/compose/ui/test/TestBasicsTest.kt

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import androidx.compose.foundation.layout.size
2222
import androidx.compose.material.Text
2323
import androidx.compose.runtime.LaunchedEffect
2424
import androidx.compose.runtime.getValue
25+
import androidx.compose.runtime.mutableIntStateOf
2526
import androidx.compose.runtime.mutableStateOf
2627
import androidx.compose.runtime.remember
2728
import androidx.compose.runtime.setValue
@@ -239,4 +240,45 @@ class TestBasicsTest {
239240
waitForIdle()
240241
assertEquals(initialTime, mainClock.currentTime)
241242
}
243+
244+
@Test
245+
fun runOnIdleExecutesOnUiThread() = runComposeUiTest {
246+
lateinit var mainThread: Thread
247+
setContent {
248+
mainThread = Thread.currentThread()
249+
}
250+
runOnIdle {
251+
assertEquals(Thread.currentThread(), mainThread)
252+
}
253+
}
254+
255+
@Test
256+
fun runOnIdleExecutesWhenIdle() = runComposeUiTest {
257+
var sourceValue by mutableIntStateOf(0)
258+
var targetValue = 0
259+
setContent {
260+
LaunchedEffect(sourceValue) {
261+
targetValue = sourceValue
262+
}
263+
}
264+
sourceValue = 1
265+
runOnIdle {
266+
assertEquals(targetValue, 1)
267+
}
268+
}
269+
270+
@Test
271+
fun runOnIdleDoesNotWaitForIdleAfterward() = runComposeUiTest {
272+
var sourceValue by mutableIntStateOf(0)
273+
var targetValue = 0
274+
setContent {
275+
LaunchedEffect(sourceValue) {
276+
targetValue = sourceValue
277+
}
278+
}
279+
runOnIdle {
280+
sourceValue = 1
281+
}
282+
assertEquals(targetValue, 0)
283+
}
242284
}

compose/ui/ui-test/src/skikoMain/kotlin/androidx/compose/ui/test/ComposeUiTest.skikoMain.kt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -302,11 +302,8 @@ class SkikoComposeUiTest @InternalTestApi constructor(
302302
}
303303

304304
override fun <T> runOnIdle(action: () -> T): T {
305-
// We are waiting for idle before and AFTER `action` to guarantee that changes introduced
306-
// in `action` are propagated to components. In Android's version, it's executed in the
307-
// Main thread which has similar effects.
308305
waitForIdle()
309-
return action().also { waitForIdle() }
306+
return runOnUiThread(action)
310307
}
311308

312309
override fun waitUntil(

0 commit comments

Comments
 (0)