• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.compose.animation.scene.subjects
18 
19 import com.android.compose.animation.scene.OverlayKey
20 import com.android.compose.animation.scene.SceneKey
21 import com.android.compose.animation.scene.content.state.TransitionState
22 import com.android.mechanics.GestureContext
23 import com.google.common.truth.Fact.simpleFact
24 import com.google.common.truth.FailureMetadata
25 import com.google.common.truth.Subject
26 import com.google.common.truth.Subject.Factory
27 import com.google.common.truth.Truth
28 
29 /** Assert on a [TransitionState]. */
30 fun assertThat(state: TransitionState): TransitionStateSubject {
31     return Truth.assertAbout(TransitionStateSubject.transitionStates()).that(state)
32 }
33 
34 /** Assert on a [TransitionState.Transition.ChangeScene]. */
assertThatnull35 fun assertThat(transition: TransitionState.Transition.ChangeScene): SceneTransitionSubject {
36     return Truth.assertAbout(SceneTransitionSubject.sceneTransitions()).that(transition)
37 }
38 
39 /** Assert on a [TransitionState.Transition.ShowOrHideOverlay]. */
assertThatnull40 fun assertThat(
41     transition: TransitionState.Transition.ShowOrHideOverlay
42 ): ShowOrHideOverlayTransitionSubject {
43     return Truth.assertAbout(ShowOrHideOverlayTransitionSubject.showOrHideOverlayTransitions())
44         .that(transition)
45 }
46 
47 /** Assert on a [TransitionState.Transition.ReplaceOverlay]. */
assertThatnull48 fun assertThat(
49     transition: TransitionState.Transition.ReplaceOverlay
50 ): ReplaceOverlayTransitionSubject {
51     return Truth.assertAbout(ReplaceOverlayTransitionSubject.replaceOverlayTransitions())
52         .that(transition)
53 }
54 
55 class TransitionStateSubject
56 private constructor(metadata: FailureMetadata, private val actual: TransitionState) :
57     Subject(metadata, actual) {
hasCurrentScenenull58     fun hasCurrentScene(sceneKey: SceneKey) {
59         check("currentScene").that(actual.currentScene).isEqualTo(sceneKey)
60     }
61 
hasCurrentOverlaysnull62     fun hasCurrentOverlays(vararg overlays: OverlayKey) {
63         check("currentOverlays").that(actual.currentOverlays).containsExactlyElementsIn(overlays)
64     }
65 
isIdlenull66     fun isIdle(): TransitionState.Idle {
67         if (actual !is TransitionState.Idle) {
68             failWithActual(simpleFact("expected to be TransitionState.Idle"))
69         }
70 
71         return actual as TransitionState.Idle
72     }
73 
isSceneTransitionnull74     fun isSceneTransition(): TransitionState.Transition.ChangeScene {
75         if (actual !is TransitionState.Transition.ChangeScene) {
76             failWithActual(
77                 simpleFact("expected to be TransitionState.Transition.ChangeCurrentScene")
78             )
79         }
80 
81         return actual as TransitionState.Transition.ChangeScene
82     }
83 
isShowOrHideOverlayTransitionnull84     fun isShowOrHideOverlayTransition(): TransitionState.Transition.ShowOrHideOverlay {
85         if (actual !is TransitionState.Transition.ShowOrHideOverlay) {
86             failWithActual(
87                 simpleFact("expected to be TransitionState.Transition.ShowOrHideOverlay")
88             )
89         }
90 
91         return actual as TransitionState.Transition.ShowOrHideOverlay
92     }
93 
isReplaceOverlayTransitionnull94     fun isReplaceOverlayTransition(): TransitionState.Transition.ReplaceOverlay {
95         if (actual !is TransitionState.Transition.ReplaceOverlay) {
96             failWithActual(simpleFact("expected to be TransitionState.Transition.ReplaceOverlay"))
97         }
98 
99         return actual as TransitionState.Transition.ReplaceOverlay
100     }
101 
hasGestureContextnull102     fun hasGestureContext(): GestureContext {
103         if (actual !is TransitionState.Transition) {
104             failWithActual(simpleFact("expected to be TransitionState.Transition"))
105         }
106 
107         val gestureContext = ((actual as TransitionState.Transition).gestureContext)
108         check("transition.gestureContext").that(gestureContext).isNotNull()
109 
110         return checkNotNull(gestureContext)
111     }
112 
113     companion object {
actualnull114         fun transitionStates() = Factory { metadata, actual: TransitionState? ->
115             TransitionStateSubject(metadata, actual!!)
116         }
117     }
118 }
119 
120 abstract class BaseTransitionSubject<T : TransitionState.Transition>(
121     metadata: FailureMetadata,
122     protected val actual: T,
123 ) : Subject(metadata, actual) {
hasCurrentScenenull124     fun hasCurrentScene(sceneKey: SceneKey) {
125         check("currentScene").that(actual.currentScene).isEqualTo(sceneKey)
126     }
127 
hasCurrentOverlaysnull128     fun hasCurrentOverlays(vararg overlays: OverlayKey) {
129         check("currentOverlays").that(actual.currentOverlays).containsExactlyElementsIn(overlays)
130     }
131 
hasProgressnull132     fun hasProgress(progress: Float, tolerance: Float = 0.01f) {
133         check("progress").that(actual.progress).isWithin(tolerance).of(progress)
134     }
135 
hasProgressVelocitynull136     fun hasProgressVelocity(progressVelocity: Float, tolerance: Float = 0.01f) {
137         check("progressVelocity")
138             .that(actual.progressVelocity)
139             .isWithin(tolerance)
140             .of(progressVelocity)
141     }
142 
hasPreviewProgressnull143     fun hasPreviewProgress(progress: Float, tolerance: Float = 0.01f) {
144         check("previewProgress").that(actual.previewProgress).isWithin(tolerance).of(progress)
145     }
146 
hasPreviewProgressVelocitynull147     fun hasPreviewProgressVelocity(progressVelocity: Float, tolerance: Float = 0.01f) {
148         check("previewProgressVelocity")
149             .that(actual.previewProgressVelocity)
150             .isWithin(tolerance)
151             .of(progressVelocity)
152     }
153 
isInPreviewStagenull154     fun isInPreviewStage() {
155         check("isInPreviewStage").that(actual.isInPreviewStage).isTrue()
156     }
157 
isNotInPreviewStagenull158     fun isNotInPreviewStage() {
159         check("isInPreviewStage").that(actual.isInPreviewStage).isFalse()
160     }
161 
isInitiatedByUserInputnull162     fun isInitiatedByUserInput() {
163         check("isInitiatedByUserInput").that(actual.isInitiatedByUserInput).isTrue()
164     }
165 
hasIsUserInputOngoingnull166     fun hasIsUserInputOngoing(isUserInputOngoing: Boolean) {
167         check("isUserInputOngoing").that(actual.isUserInputOngoing).isEqualTo(isUserInputOngoing)
168     }
169 }
170 
171 class SceneTransitionSubject
172 private constructor(metadata: FailureMetadata, actual: TransitionState.Transition.ChangeScene) :
173     BaseTransitionSubject<TransitionState.Transition.ChangeScene>(metadata, actual) {
hasFromScenenull174     fun hasFromScene(sceneKey: SceneKey) {
175         check("fromScene").that(actual.fromScene).isEqualTo(sceneKey)
176     }
177 
hasToScenenull178     fun hasToScene(sceneKey: SceneKey) {
179         check("toScene").that(actual.toScene).isEqualTo(sceneKey)
180     }
181 
182     companion object {
sceneTransitionsnull183         fun sceneTransitions() =
184             Factory { metadata, actual: TransitionState.Transition.ChangeScene? ->
185                 SceneTransitionSubject(metadata, actual!!)
186             }
187     }
188 }
189 
190 class ShowOrHideOverlayTransitionSubject
191 private constructor(
192     metadata: FailureMetadata,
193     actual: TransitionState.Transition.ShowOrHideOverlay,
194 ) : BaseTransitionSubject<TransitionState.Transition.ShowOrHideOverlay>(metadata, actual) {
hasFromOrToScenenull195     fun hasFromOrToScene(fromOrToScene: SceneKey) {
196         check("fromOrToScene").that(actual.fromOrToScene).isEqualTo(fromOrToScene)
197     }
198 
hasOverlaynull199     fun hasOverlay(overlay: OverlayKey) {
200         check("overlay").that(actual.overlay).isEqualTo(overlay)
201     }
202 
203     companion object {
showOrHideOverlayTransitionsnull204         fun showOrHideOverlayTransitions() =
205             Factory { metadata, actual: TransitionState.Transition.ShowOrHideOverlay? ->
206                 ShowOrHideOverlayTransitionSubject(metadata, actual!!)
207             }
208     }
209 }
210 
211 class ReplaceOverlayTransitionSubject
212 private constructor(metadata: FailureMetadata, actual: TransitionState.Transition.ReplaceOverlay) :
213     BaseTransitionSubject<TransitionState.Transition.ReplaceOverlay>(metadata, actual) {
hasFromOverlaynull214     fun hasFromOverlay(fromOverlay: OverlayKey) {
215         check("fromOverlay").that(actual.fromOverlay).isEqualTo(fromOverlay)
216     }
217 
hasToOverlaynull218     fun hasToOverlay(toOverlay: OverlayKey) {
219         check("toOverlay").that(actual.toOverlay).isEqualTo(toOverlay)
220     }
221 
222     companion object {
replaceOverlayTransitionsnull223         fun replaceOverlayTransitions() =
224             Factory { metadata, actual: TransitionState.Transition.ReplaceOverlay? ->
225                 ReplaceOverlayTransitionSubject(metadata, actual!!)
226             }
227     }
228 }
229