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.OverscrollSpec
20 import com.android.compose.animation.scene.SceneKey
21 import com.android.compose.animation.scene.TransitionState
22 import com.google.common.truth.Fact.simpleFact
23 import com.google.common.truth.FailureMetadata
24 import com.google.common.truth.Subject
25 import com.google.common.truth.Subject.Factory
26 import com.google.common.truth.Truth
27 
28 /** Assert on a [TransitionState]. */
29 fun assertThat(state: TransitionState): TransitionStateSubject {
30     return Truth.assertAbout(TransitionStateSubject.transitionStates()).that(state)
31 }
32 
33 /** Assert on a [TransitionState.Transition]. */
assertThatnull34 fun assertThat(transitions: TransitionState.Transition): TransitionSubject {
35     return Truth.assertAbout(TransitionSubject.transitions()).that(transitions)
36 }
37 
38 class TransitionStateSubject
39 private constructor(
40     metadata: FailureMetadata,
41     private val actual: TransitionState,
42 ) : Subject(metadata, actual) {
hasCurrentScenenull43     fun hasCurrentScene(sceneKey: SceneKey) {
44         check("currentScene").that(actual.currentScene).isEqualTo(sceneKey)
45     }
46 
isIdlenull47     fun isIdle(): TransitionState.Idle {
48         if (actual !is TransitionState.Idle) {
49             failWithActual(simpleFact("expected to be TransitionState.Idle"))
50         }
51 
52         return actual as TransitionState.Idle
53     }
54 
isTransitionnull55     fun isTransition(): TransitionState.Transition {
56         if (actual !is TransitionState.Transition) {
57             failWithActual(simpleFact("expected to be TransitionState.Transition"))
58         }
59 
60         return actual as TransitionState.Transition
61     }
62 
63     companion object {
actualnull64         fun transitionStates() = Factory { metadata, actual: TransitionState ->
65             TransitionStateSubject(metadata, actual)
66         }
67     }
68 }
69 
70 class TransitionSubject
71 private constructor(
72     metadata: FailureMetadata,
73     private val actual: TransitionState.Transition,
74 ) : Subject(metadata, actual) {
hasCurrentScenenull75     fun hasCurrentScene(sceneKey: SceneKey) {
76         check("currentScene").that(actual.currentScene).isEqualTo(sceneKey)
77     }
78 
hasFromScenenull79     fun hasFromScene(sceneKey: SceneKey) {
80         check("fromScene").that(actual.fromScene).isEqualTo(sceneKey)
81     }
82 
hasToScenenull83     fun hasToScene(sceneKey: SceneKey) {
84         check("toScene").that(actual.toScene).isEqualTo(sceneKey)
85     }
86 
hasProgressnull87     fun hasProgress(progress: Float, tolerance: Float = 0f) {
88         check("progress").that(actual.progress).isWithin(tolerance).of(progress)
89     }
90 
hasProgressVelocitynull91     fun hasProgressVelocity(progressVelocity: Float, tolerance: Float = 0f) {
92         check("progressVelocity")
93             .that(actual.progressVelocity)
94             .isWithin(tolerance)
95             .of(progressVelocity)
96     }
97 
isInitiatedByUserInputnull98     fun isInitiatedByUserInput() {
99         check("isInitiatedByUserInput").that(actual.isInitiatedByUserInput).isTrue()
100     }
101 
hasIsUserInputOngoingnull102     fun hasIsUserInputOngoing(isUserInputOngoing: Boolean) {
103         check("isUserInputOngoing").that(actual.isUserInputOngoing).isEqualTo(isUserInputOngoing)
104     }
105 
hasOverscrollSpecnull106     fun hasOverscrollSpec(): OverscrollSpec {
107         check("currentOverscrollSpec").that(actual.currentOverscrollSpec).isNotNull()
108         return actual.currentOverscrollSpec!!
109     }
110 
hasNoOverscrollSpecnull111     fun hasNoOverscrollSpec() {
112         check("currentOverscrollSpec").that(actual.currentOverscrollSpec).isNull()
113     }
114 
hasBouncingScenenull115     fun hasBouncingScene(scene: SceneKey) {
116         if (actual !is TransitionState.HasOverscrollProperties) {
117             failWithActual(simpleFact("expected to be TransitionState.HasOverscrollProperties"))
118         }
119 
120         check("bouncingScene")
121             .that((actual as TransitionState.HasOverscrollProperties).bouncingScene)
122             .isEqualTo(scene)
123     }
124 
125     companion object {
actualnull126         fun transitions() = Factory { metadata, actual: TransitionState.Transition ->
127             TransitionSubject(metadata, actual)
128         }
129     }
130 }
131