Loading packages/SystemUI/multivalentTests/src/com/android/systemui/kosmos/GeneralKosmosTest.kt 0 → 100644 +74 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.kosmos import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.test.runTest import org.junit.Test import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class GeneralKosmosTest : SysuiTestCase() { @Test fun stateCurrentValueMutableStateFlow() = runTest { val source = MutableStateFlow(1) val mapped = source .map { it * 2 } .stateIn( scope = backgroundScope, started = SharingStarted.WhileSubscribed(), initialValue = source.value * 2, ) assertThat(currentValue(mapped)).isEqualTo(2) source.value = 3 assertThat(currentValue(mapped)).isEqualTo(6) } @Test fun stateCurrentValueOnEmittedFlow() = runTest { val source = flow { emit(1) emit(2) } val mapped = source .map { it * 2 } .stateIn( scope = backgroundScope, started = SharingStarted.WhileSubscribed(), initialValue = 2, ) assertThat(currentValue(mapped)).isEqualTo(4) } @Test fun currentValueIsNull() = runTest { val source = MutableStateFlow<Int?>(null) assertThat(currentValue(source)).isEqualTo(null) } } packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt +3 −2 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ import com.android.systemui.keyguard.KeyguardViewMediator import com.android.systemui.keyguard.ui.viewmodel.lockscreenUserActionsViewModel import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.collectLastValue import com.android.systemui.kosmos.currentValue import com.android.systemui.kosmos.runCurrent import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.testScope Loading Loading @@ -77,6 +78,7 @@ import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.launch import kotlinx.coroutines.test.advanceTimeBy import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import org.junit.runner.RunWith Loading Loading @@ -399,9 +401,8 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() { * Note that this doesn't assert what the current scene is in the UI. */ private fun Kosmos.assertCurrentScene(expected: SceneKey) { testScope.runCurrent() assertWithMessage("Current scene mismatch!") .that(sceneContainerViewModel.currentScene.value) .that(currentValue(sceneContainerViewModel.currentScene)) .isEqualTo(expected) } Loading packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt +27 −0 Original line number Diff line number Diff line Loading @@ -8,7 +8,10 @@ import com.android.systemui.kosmos.Kosmos.Fixture import com.android.systemui.settings.brightness.ui.BrightnessWarningToast import com.android.systemui.util.mockito.mock import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch import kotlinx.coroutines.test.StandardTestDispatcher import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.UnconfinedTestDispatcher Loading Loading @@ -58,3 +61,27 @@ fun Kosmos.runCurrent() = testScope.runCurrent() fun <T> Kosmos.collectLastValue(flow: Flow<T>) = testScope.collectLastValue(flow) fun <T> Kosmos.collectValues(flow: Flow<T>): FlowValue<List<T>> = testScope.collectValues(flow) /** * Retrieve the current value of this [StateFlow] safely. Needs a [TestScope] in order to make sure * that all pending tasks have run before returning a value. Tests that directly access * [StateFlow.value] may be incorrect, since the value returned may be stale if the current test * dispatcher is a [StandardTestDispatcher]. * * If you want to assert on a [Flow] that is not a [StateFlow], please use * [TestScope.collectLastValue], to make sure that the desired value is captured when emitted. */ @OptIn(ExperimentalCoroutinesApi::class) fun <T> TestScope.currentValue(stateFlow: StateFlow<T>): T { val values = mutableListOf<T>() val job = backgroundScope.launch { stateFlow.collect(values::add) } runCurrent() job.cancel() // StateFlow should always have at least one value return values.last() } /** Retrieve the current value of this [StateFlow] safely. See `currentValue(TestScope)`. */ fun <T> Kosmos.currentValue(stateFlow: StateFlow<T>): T { return testScope.currentValue(stateFlow) } Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/kosmos/GeneralKosmosTest.kt 0 → 100644 +74 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.kosmos import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.test.runTest import org.junit.Test import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class GeneralKosmosTest : SysuiTestCase() { @Test fun stateCurrentValueMutableStateFlow() = runTest { val source = MutableStateFlow(1) val mapped = source .map { it * 2 } .stateIn( scope = backgroundScope, started = SharingStarted.WhileSubscribed(), initialValue = source.value * 2, ) assertThat(currentValue(mapped)).isEqualTo(2) source.value = 3 assertThat(currentValue(mapped)).isEqualTo(6) } @Test fun stateCurrentValueOnEmittedFlow() = runTest { val source = flow { emit(1) emit(2) } val mapped = source .map { it * 2 } .stateIn( scope = backgroundScope, started = SharingStarted.WhileSubscribed(), initialValue = 2, ) assertThat(currentValue(mapped)).isEqualTo(4) } @Test fun currentValueIsNull() = runTest { val source = MutableStateFlow<Int?>(null) assertThat(currentValue(source)).isEqualTo(null) } }
packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt +3 −2 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ import com.android.systemui.keyguard.KeyguardViewMediator import com.android.systemui.keyguard.ui.viewmodel.lockscreenUserActionsViewModel import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.collectLastValue import com.android.systemui.kosmos.currentValue import com.android.systemui.kosmos.runCurrent import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.testScope Loading Loading @@ -77,6 +78,7 @@ import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.launch import kotlinx.coroutines.test.advanceTimeBy import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import org.junit.runner.RunWith Loading Loading @@ -399,9 +401,8 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() { * Note that this doesn't assert what the current scene is in the UI. */ private fun Kosmos.assertCurrentScene(expected: SceneKey) { testScope.runCurrent() assertWithMessage("Current scene mismatch!") .that(sceneContainerViewModel.currentScene.value) .that(currentValue(sceneContainerViewModel.currentScene)) .isEqualTo(expected) } Loading
packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt +27 −0 Original line number Diff line number Diff line Loading @@ -8,7 +8,10 @@ import com.android.systemui.kosmos.Kosmos.Fixture import com.android.systemui.settings.brightness.ui.BrightnessWarningToast import com.android.systemui.util.mockito.mock import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch import kotlinx.coroutines.test.StandardTestDispatcher import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.UnconfinedTestDispatcher Loading Loading @@ -58,3 +61,27 @@ fun Kosmos.runCurrent() = testScope.runCurrent() fun <T> Kosmos.collectLastValue(flow: Flow<T>) = testScope.collectLastValue(flow) fun <T> Kosmos.collectValues(flow: Flow<T>): FlowValue<List<T>> = testScope.collectValues(flow) /** * Retrieve the current value of this [StateFlow] safely. Needs a [TestScope] in order to make sure * that all pending tasks have run before returning a value. Tests that directly access * [StateFlow.value] may be incorrect, since the value returned may be stale if the current test * dispatcher is a [StandardTestDispatcher]. * * If you want to assert on a [Flow] that is not a [StateFlow], please use * [TestScope.collectLastValue], to make sure that the desired value is captured when emitted. */ @OptIn(ExperimentalCoroutinesApi::class) fun <T> TestScope.currentValue(stateFlow: StateFlow<T>): T { val values = mutableListOf<T>() val job = backgroundScope.launch { stateFlow.collect(values::add) } runCurrent() job.cancel() // StateFlow should always have at least one value return values.last() } /** Retrieve the current value of this [StateFlow] safely. See `currentValue(TestScope)`. */ fun <T> Kosmos.currentValue(stateFlow: StateFlow<T>): T { return testScope.currentValue(stateFlow) }