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(scope = this, Condition.START_EAGERLY) 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(scope = this, Condition.START_EAGERLY) runCurrent() assertThat(condition.isConditionSet).isFalse() condition.start() runCurrent() assertThat(condition.isConditionSet).isTrue() assertThat(condition.isConditionMet).isFalse() } @Test fun emptyFlowWithNoInitialValue() = testScope.runTest { val flow = emptyFlow() val condition = flow.toCondition(scope = this, Condition.START_EAGERLY) condition.start() runCurrent() assertThat(condition.isConditionSet).isFalse() assertThat(condition.isConditionMet).isFalse() } @Test fun emptyFlowWithInitialValueOfTrue() = testScope.runTest { val flow = emptyFlow() val condition = flow.toCondition( scope = this, strategy = Condition.START_EAGERLY, initialValue = true ) condition.start() runCurrent() assertThat(condition.isConditionSet).isTrue() assertThat(condition.isConditionMet).isTrue() } @Test fun emptyFlowWithInitialValueOfFalse() = testScope.runTest { val flow = emptyFlow() val condition = flow.toCondition( scope = this, strategy = Condition.START_EAGERLY, 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(scope = this, strategy = Condition.START_EAGERLY) 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() val condition = flow.toCondition(scope = this, strategy = Condition.START_EAGERLY) 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) } }