Merge "Add helper to convert a kotlin flow to a Condition" into udc-dev

This commit is contained in:
Lucas Silva
2023-04-15 21:39:19 +00:00
committed by Android (Google) Code Review
2 changed files with 158 additions and 0 deletions

View File

@@ -0,0 +1,23 @@
package com.android.systemui.shared.condition
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.launch
/** Converts a boolean flow to a [Condition] object which can be used with a [Monitor] */
@JvmOverloads
fun Flow<Boolean>.toCondition(scope: CoroutineScope, initialValue: Boolean? = null): Condition {
return object : Condition(initialValue, false) {
var job: Job? = null
override fun start() {
job = scope.launch { collect { updateCondition(it) } }
}
override fun stop() {
job?.cancel()
job = null
}
}
}

View File

@@ -0,0 +1,135 @@
package com.android.systemui.shared.condition
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(AndroidTestingRunner::class)
class ConditionExtensionsTest : SysuiTestCase() {
private lateinit var testScope: TestScope
@Before
fun setUp() {
testScope = TestScope(StandardTestDispatcher())
}
@Test
fun flowInitiallyTrue() =
testScope.runTest {
val flow = flowOf(true)
val condition = flow.toCondition(this)
runCurrent()
assertThat(condition.isConditionSet).isFalse()
condition.start()
runCurrent()
assertThat(condition.isConditionSet).isTrue()
assertThat(condition.isConditionMet).isTrue()
}
@Test
fun flowInitiallyFalse() =
testScope.runTest {
val flow = flowOf(false)
val condition = flow.toCondition(this)
runCurrent()
assertThat(condition.isConditionSet).isFalse()
condition.start()
runCurrent()
assertThat(condition.isConditionSet).isTrue()
assertThat(condition.isConditionMet).isFalse()
}
@Test
fun emptyFlowWithNoInitialValue() =
testScope.runTest {
val flow = emptyFlow<Boolean>()
val condition = flow.toCondition(this)
condition.start()
runCurrent()
assertThat(condition.isConditionSet).isFalse()
assertThat(condition.isConditionMet).isFalse()
}
@Test
fun emptyFlowWithInitialValueOfTrue() =
testScope.runTest {
val flow = emptyFlow<Boolean>()
val condition = flow.toCondition(scope = this, initialValue = true)
condition.start()
runCurrent()
assertThat(condition.isConditionSet).isTrue()
assertThat(condition.isConditionMet).isTrue()
}
@Test
fun emptyFlowWithInitialValueOfFalse() =
testScope.runTest {
val flow = emptyFlow<Boolean>()
val condition = flow.toCondition(scope = this, initialValue = false)
condition.start()
runCurrent()
assertThat(condition.isConditionSet).isTrue()
assertThat(condition.isConditionMet).isFalse()
}
@Test
fun conditionUpdatesWhenFlowEmitsNewValue() =
testScope.runTest {
val flow = MutableStateFlow(false)
val condition = flow.toCondition(this)
condition.start()
runCurrent()
assertThat(condition.isConditionSet).isTrue()
assertThat(condition.isConditionMet).isFalse()
flow.value = true
runCurrent()
assertThat(condition.isConditionMet).isTrue()
flow.value = false
runCurrent()
assertThat(condition.isConditionMet).isFalse()
condition.stop()
}
@Test
fun stoppingConditionUnsubscribesFromFlow() =
testScope.runTest {
val flow = MutableSharedFlow<Boolean>()
val condition = flow.toCondition(this)
runCurrent()
assertThat(flow.subscriptionCount.value).isEqualTo(0)
condition.start()
runCurrent()
assertThat(flow.subscriptionCount.value).isEqualTo(1)
condition.stop()
runCurrent()
assertThat(flow.subscriptionCount.value).isEqualTo(0)
}
}