diff options
| author | 2023-11-01 16:06:08 -0400 | |
|---|---|---|
| committer | 2023-11-06 13:44:10 -0500 | |
| commit | 50444c2a50f34725a8f33af5c55f9b498910b51f (patch) | |
| tree | 818f9957e7f10c81c1cccf3505dea6faf30e292d | |
| parent | 896c5c42c7a2dd9271957872fc1b29d96c1884ea (diff) | |
Initial use of Kosmos in SceneTestUtils and associated tests.
This shows how we can begin to bring in Kosmos incrementally, but does not take
any particular class to the final "this is fixed" state.
Bug: 303103876
Test: ./gradlew :SystemUILib:testAospDebugUnitTest
Flag: NONE
Change-Id: If65b86ae7a02e23589a81acb4cdd0d28428201f2
9 files changed, 113 insertions, 26 deletions
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt index d669006c68d3..ddeb05b39e53 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt @@ -23,6 +23,7 @@ import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.scene.SceneTestUtils +import com.android.systemui.scene.sceneKeys import com.android.systemui.scene.shared.model.ObservableTransitionState import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.shared.model.SceneModel @@ -70,10 +71,8 @@ class SceneContainerRepositoryTest : SysuiTestCase() { @Test(expected = IllegalStateException::class) fun setDesiredScene_noSuchSceneInContainer_throws() { - val underTest = - utils.fakeSceneContainerRepository( - utils.fakeSceneContainerConfig(listOf(SceneKey.QuickSettings, SceneKey.Lockscreen)), - ) + utils.kosmos.sceneKeys = listOf(SceneKey.QuickSettings, SceneKey.Lockscreen) + val underTest = utils.fakeSceneContainerRepository(utils.fakeSceneContainerConfig()) underTest.setDesiredScene(SceneModel(SceneKey.Shade)) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt index c0b586195eca..f6362fe528ed 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt @@ -27,6 +27,7 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.authentication.domain.model.AuthenticationMethodModel import com.android.systemui.classifier.FalsingCollector import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.kosmos.testScope import com.android.systemui.model.SysUiState import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java index 8e0cf7d7f695..55a44ae34ac6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java @@ -172,7 +172,7 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase { mTestScope.getBackgroundScope(), new SceneContainerRepository( mTestScope.getBackgroundScope(), - mUtils.fakeSceneContainerConfig(mUtils.fakeSceneKeys())), + mUtils.fakeSceneContainerConfig()), powerRepository, mock(SceneLogger.class)); diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java index 2f45b1260dc2..d4b35a9b1515 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java @@ -207,7 +207,7 @@ public class QuickSettingsControllerBaseTest extends SysuiTestCase { mTestScope.getBackgroundScope(), new SceneContainerRepository( mTestScope.getBackgroundScope(), - mUtils.fakeSceneContainerConfig(mUtils.fakeSceneKeys())), + mUtils.fakeSceneContainerConfig()), powerRepository, mock(SceneLogger.class)); diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java index 8309b85620bd..2e191b140e10 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java @@ -395,7 +395,7 @@ public class BubblesTest extends SysuiTestCase { mTestScope.getBackgroundScope(), new SceneContainerRepository( mTestScope.getBackgroundScope(), - mUtils.fakeSceneContainerConfig(mUtils.fakeSceneKeys())), + mUtils.fakeSceneContainerConfig()), powerRepository, mock(SceneLogger.class)); diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt new file mode 100644 index 000000000000..cc843b536756 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt @@ -0,0 +1,8 @@ +package com.android.systemui.kosmos + +import com.android.systemui.kosmos.Kosmos.Fixture +import kotlinx.coroutines.test.StandardTestDispatcher +import kotlinx.coroutines.test.TestScope + +val Kosmos.testDispatcher by Fixture { StandardTestDispatcher() } +val Kosmos.testScope by Fixture { TestScope(testDispatcher) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/Kosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/Kosmos.kt new file mode 100644 index 000000000000..c74cdd4ca4c4 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/Kosmos.kt @@ -0,0 +1,69 @@ +package com.android.systemui.kosmos + +import kotlin.reflect.KProperty + +// (Historical note: The name Kosmos is meant to invoke "Kotlin", the "Object Mother" pattern +// (https://martinfowler.com/bliki/ObjectMother.html), and of course the Greek word "kosmos" for +// the "order of the world" (https://en.wiktionary.org/wiki/%CE%BA%CF%8C%CF%83%CE%BC%CE%BF%CF%82) +/** + * Each Kosmos is its own self-contained set of fixtures, which may reference each other. Fixtures + * can be defined through extension properties in any file: + * ``` + * // fixture that must be set: + * var Kosmos.context by Fixture<Context>() + * + * // fixture with overrideable default. + * var Kosmos.landscapeMode by Fixture { false } + * + * // fixture forbidding override (note `val`, and referencing context fixture from above) + * val Kosmos.lifecycleScope by Fixture { context.lifecycleScope } + * ``` + * + * To use the fixtures, create an instance of Kosmos and retrieve the values you need: + * ``` + * val k = Kosmos() + * k.context = mContext + * val underTest = YourInteractor( + * context = k.context, + * landscapeMode = k.landscapeMode, + * ) + * ``` + */ +class Kosmos { + private val map: MutableMap<String, Any?> = mutableMapOf() + private val gotten: MutableSet<String> = mutableSetOf() + + /** + * A value in the kosmos that has a single value once it's read. It can be overridden before + * first use only; all objects that are dependent on this fixture will get the same value. + * + * Example classic uses would be a clock, filesystem, or singleton controller. + * + * If no [creator] parameter is provided, the fixture must be set before use. + */ + class Fixture<T>(private val creator: (Kosmos.() -> T)? = null) { + operator fun getValue(thisRef: Kosmos, property: KProperty<*>): T { + thisRef.gotten.add(property.name) + @Suppress("UNCHECKED_CAST") + if (!thisRef.map.contains(property.name)) { + if (creator == null) { + throw IllegalStateException( + "Fixture ${property.name} has no default, and is read before set." + ) + } else { + val nonNullCreator = creator + // The Kotlin compiler seems to need this odd workaround + thisRef.map[property.name] = thisRef.nonNullCreator() + } + } + return thisRef.map[property.name] as T + } + + operator fun setValue(thisRef: Kosmos, property: KProperty<*>, value: T) { + check(!thisRef.gotten.contains(property.name)) { + "Tried to set fixture '${property.name}' after it's already been read." + } + thisRef.map[property.name] = value + } + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneKosmos.kt new file mode 100644 index 000000000000..8fc419cadb21 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneKosmos.kt @@ -0,0 +1,20 @@ +package com.android.systemui.scene + +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.Kosmos.Fixture +import com.android.systemui.scene.shared.model.SceneContainerConfig +import com.android.systemui.scene.shared.model.SceneKey + +var Kosmos.sceneKeys by Fixture { + listOf( + SceneKey.QuickSettings, + SceneKey.Shade, + SceneKey.Lockscreen, + SceneKey.Bouncer, + SceneKey.Gone, + SceneKey.Communal, + ) +} + +val Kosmos.initialSceneKey by Fixture { SceneKey.Lockscreen } +val Kosmos.sceneContainerConfig by Fixture { SceneContainerConfig(sceneKeys, initialSceneKey) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt index 7c113e823bbc..217067b307bc 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt @@ -51,6 +51,9 @@ import com.android.systemui.keyguard.data.repository.FakeTrustRepository import com.android.systemui.keyguard.data.repository.KeyguardRepository import com.android.systemui.keyguard.data.repository.TrustRepository import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.testDispatcher +import com.android.systemui.kosmos.testScope import com.android.systemui.power.data.repository.FakePowerRepository import com.android.systemui.power.domain.interactor.PowerInteractorFactory import com.android.systemui.scene.data.repository.SceneContainerRepository @@ -71,8 +74,6 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.runBlocking -import kotlinx.coroutines.test.StandardTestDispatcher -import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.currentTime /** @@ -83,8 +84,9 @@ import kotlinx.coroutines.test.currentTime class SceneTestUtils( test: SysuiTestCase, ) { - val testDispatcher = StandardTestDispatcher() - val testScope = TestScope(testDispatcher) + val kosmos = Kosmos() + val testDispatcher = kosmos.testDispatcher + val testScope = kosmos.testScope val featureFlags = FakeFeatureFlagsClassic().apply { set(Flags.FACE_AUTH_REFACTOR, false) @@ -129,23 +131,11 @@ class SceneTestUtils( } fun fakeSceneKeys(): List<SceneKey> { - return listOf( - SceneKey.QuickSettings, - SceneKey.Shade, - SceneKey.Lockscreen, - SceneKey.Bouncer, - SceneKey.Gone, - SceneKey.Communal, - ) + return kosmos.sceneKeys } - fun fakeSceneContainerConfig( - sceneKeys: List<SceneKey> = fakeSceneKeys(), - ): SceneContainerConfig { - return SceneContainerConfig( - sceneKeys = sceneKeys, - initialSceneKey = SceneKey.Lockscreen, - ) + fun fakeSceneContainerConfig(): SceneContainerConfig { + return kosmos.sceneContainerConfig } @JvmOverloads |