xref: /aosp_15_r20/platform_testing/libraries/motion/tests/src/platform/test/motion/filmstrip/FilmstripTest.kt (revision dd0948b35e70be4c0246aabd6c72554a5eb8b22a)
1 /*
2  * 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 platform.test.motion.filmstrip
18 
19 import android.graphics.Bitmap
20 import android.graphics.Canvas
21 import android.graphics.Color
22 import androidx.test.ext.junit.runners.AndroidJUnit4
23 import com.google.common.truth.Truth.assertThat
24 import org.junit.Rule
25 import org.junit.Test
26 import org.junit.rules.TestName
27 import org.junit.runner.RunWith
28 import platform.test.motion.golden.SupplementalFrameId
29 import platform.test.motion.golden.TimestampFrameId
30 import platform.test.motion.testing.createGoldenPathManager
31 import platform.test.screenshot.ScreenshotAsserterConfig
32 import platform.test.screenshot.ScreenshotTestRule
33 
34 @RunWith(AndroidJUnit4::class)
35 class FilmstripTest {
36 
37     private val goldenPathManager =
38         createGoldenPathManager("platform_testing/libraries/motion/tests/assets")
39 
40     @get:Rule val screenshotTestRule = ScreenshotTestRule(goldenPathManager)
41     @get:Rule val testName = TestName()
42 
assertFilmstripRenderingnull43     private fun assertFilmstripRendering(filmstrip: Filmstrip) {
44         screenshotTestRule
45             .createScreenshotAsserter(
46                 ScreenshotAsserterConfig(captureStrategy = { filmstrip.renderFilmstrip() })
47             )
48             .assertGoldenImage(testName.methodName)
49     }
50 
51     @Test
horizontalSingleFramenull52     fun horizontalSingleFrame() {
53         assertFilmstripRendering(
54             Filmstrip(listOf(MotionScreenshot(TimestampFrameId(10), mockScreenshot(Color.RED))))
55                 .apply { orientation = FilmstripOrientation.HORIZONTAL }
56         )
57     }
58 
59     @Test
verticalSingleFramenull60     fun verticalSingleFrame() {
61         assertFilmstripRendering(
62             Filmstrip(listOf(MotionScreenshot(TimestampFrameId(10), mockScreenshot(Color.RED))))
63                 .apply { orientation = FilmstripOrientation.VERTICAL }
64         )
65     }
66 
67     @Test
horizontalFilmstripnull68     fun horizontalFilmstrip() {
69         val w = 100
70         val h = 200
71 
72         val screenshots =
73             listOf(
74                 MotionScreenshot(TimestampFrameId(10), mockScreenshot(Color.RED, w, h)),
75                 MotionScreenshot(TimestampFrameId(20), mockScreenshot(Color.GREEN, w, h)),
76                 MotionScreenshot(SupplementalFrameId("after"), mockScreenshot(Color.BLUE, w, h)),
77             )
78 
79         assertFilmstripRendering(
80             Filmstrip(screenshots).apply { orientation = FilmstripOrientation.HORIZONTAL }
81         )
82     }
83 
84     @Test
horizontalFilmstrip_labelsWiderThanScreenshotnull85     fun horizontalFilmstrip_labelsWiderThanScreenshot() {
86         val w = 100
87         val h = 20
88 
89         val screenshots =
90             listOf(
91                 MotionScreenshot(
92                     SupplementalFrameId("wide_before"),
93                     mockScreenshot(Color.RED, w, h),
94                 ),
95                 MotionScreenshot(
96                     SupplementalFrameId("wide_after"),
97                     mockScreenshot(Color.BLUE, w, h),
98                 ),
99             )
100 
101         assertFilmstripRendering(
102             Filmstrip(screenshots).apply { orientation = FilmstripOrientation.HORIZONTAL }
103         )
104     }
105 
106     @Test
horizontalFilmstrip_variableSize_tileMatchesLargestDimensionsnull107     fun horizontalFilmstrip_variableSize_tileMatchesLargestDimensions() {
108         val screenshots =
109             listOf(
110                 MotionScreenshot(TimestampFrameId(1), mockScreenshot(Color.RED, 100, 200)),
111                 MotionScreenshot(TimestampFrameId(2), mockScreenshot(Color.GREEN, 150, 75)),
112                 MotionScreenshot(TimestampFrameId(3), mockScreenshot(Color.BLUE, 50, 50)),
113             )
114 
115         assertFilmstripRendering(
116             Filmstrip(screenshots).apply { orientation = FilmstripOrientation.HORIZONTAL }
117         )
118     }
119 
120     @Test
verticalFilmstripnull121     fun verticalFilmstrip() {
122         val w = 200
123         val h = 100
124 
125         val screenshots =
126             listOf(
127                 MotionScreenshot(TimestampFrameId(10), mockScreenshot(Color.RED, w, h)),
128                 MotionScreenshot(TimestampFrameId(20), mockScreenshot(Color.GREEN, w, h)),
129                 MotionScreenshot(SupplementalFrameId("after"), mockScreenshot(Color.BLUE, w, h)),
130             )
131 
132         assertFilmstripRendering(
133             Filmstrip(screenshots).apply { orientation = FilmstripOrientation.VERTICAL }
134         )
135     }
136 
137     @Test
verticalFilmstrip_labelsTallerThanScreenshotnull138     fun verticalFilmstrip_labelsTallerThanScreenshot() {
139         val w = 100
140         val h = 5
141 
142         val screenshots =
143             listOf(
144                 MotionScreenshot(SupplementalFrameId("before"), mockScreenshot(Color.RED, w, h)),
145                 MotionScreenshot(SupplementalFrameId("after"), mockScreenshot(Color.BLUE, w, h)),
146             )
147 
148         assertFilmstripRendering(
149             Filmstrip(screenshots).apply { orientation = FilmstripOrientation.VERTICAL }
150         )
151     }
152 
153     @Test
verticalFilmstrip_variableSize_tileMatchesLargestDimensionsnull154     fun verticalFilmstrip_variableSize_tileMatchesLargestDimensions() {
155         val screenshots =
156             listOf(
157                 MotionScreenshot(TimestampFrameId(1), mockScreenshot(Color.RED, 100, 200)),
158                 MotionScreenshot(TimestampFrameId(2), mockScreenshot(Color.GREEN, 150, 75)),
159                 MotionScreenshot(TimestampFrameId(3), mockScreenshot(Color.BLUE, 50, 50)),
160             )
161 
162         assertFilmstripRendering(
163             Filmstrip(screenshots).apply { orientation = FilmstripOrientation.VERTICAL }
164         )
165     }
166 
167     @Test
automaticOrientation_tallScreenshots_filmstripIsHorizontalnull168     fun automaticOrientation_tallScreenshots_filmstripIsHorizontal() {
169         val w = 100
170         val h = 200
171 
172         val screenshots =
173             listOf(
174                 MotionScreenshot(TimestampFrameId(10), mockScreenshot(Color.RED, w, h)),
175                 MotionScreenshot(TimestampFrameId(20), mockScreenshot(Color.GREEN, w, h)),
176                 MotionScreenshot(SupplementalFrameId("after"), mockScreenshot(Color.BLUE, w, h)),
177             )
178 
179         val bitmap =
180             Filmstrip(screenshots)
181                 .apply { orientation = FilmstripOrientation.AUTOMATIC }
182                 .renderFilmstrip()
183 
184         assertThat(bitmap.width).isEqualTo(w * 3)
185         assertThat(bitmap.height).isLessThan(h * 3)
186     }
187 
188     @Test
automaticOrientation_wideScreenshots_filmstripIsVerticalnull189     fun automaticOrientation_wideScreenshots_filmstripIsVertical() {
190         val w = 200
191         val h = 100
192 
193         val screenshots =
194             listOf(
195                 MotionScreenshot(TimestampFrameId(10), mockScreenshot(Color.RED, w, h)),
196                 MotionScreenshot(TimestampFrameId(20), mockScreenshot(Color.GREEN, w, h)),
197                 MotionScreenshot(SupplementalFrameId("after"), mockScreenshot(Color.BLUE, w, h)),
198             )
199 
200         val bitmap =
201             Filmstrip(screenshots)
202                 .apply { orientation = FilmstripOrientation.AUTOMATIC }
203                 .renderFilmstrip()
204 
205         assertThat(bitmap.width).isLessThan(w * 3)
206         assertThat(bitmap.height).isEqualTo(h * 3)
207     }
208 
209     @Test
limitLongestSide_scalesBasedOnLongerHeightnull210     fun limitLongestSide_scalesBasedOnLongerHeight() {
211         val screenshots =
212             listOf(
213                 MotionScreenshot(TimestampFrameId(1), mockScreenshot(Color.RED, 100, 200)),
214                 MotionScreenshot(TimestampFrameId(2), mockScreenshot(Color.GREEN, 150, 75)),
215                 MotionScreenshot(TimestampFrameId(3), mockScreenshot(Color.BLUE, 50, 50)),
216             )
217 
218         assertFilmstripRendering(
219             Filmstrip(screenshots).apply {
220                 limitLongestSide(100)
221                 orientation = FilmstripOrientation.HORIZONTAL
222             }
223         )
224     }
225 
226     @Test
limitLongestSide_scalesBasedOnLongerWidthnull227     fun limitLongestSide_scalesBasedOnLongerWidth() {
228         val screenshots =
229             listOf(
230                 MotionScreenshot(TimestampFrameId(1), mockScreenshot(Color.RED, 200, 100)),
231                 MotionScreenshot(TimestampFrameId(2), mockScreenshot(Color.GREEN, 150, 75)),
232                 MotionScreenshot(TimestampFrameId(3), mockScreenshot(Color.BLUE, 50, 50)),
233             )
234 
235         assertFilmstripRendering(
236             Filmstrip(screenshots).apply {
237                 limitLongestSide(100)
238                 orientation = FilmstripOrientation.HORIZONTAL
239             }
240         )
241     }
242 
243     @Test
limitLongestSide_doesNotScaleUpnull244     fun limitLongestSide_doesNotScaleUp() {
245         val screenshots =
246             listOf(
247                 MotionScreenshot(TimestampFrameId(1), mockScreenshot(Color.RED, 200, 100)),
248                 MotionScreenshot(TimestampFrameId(2), mockScreenshot(Color.GREEN, 150, 75)),
249                 MotionScreenshot(TimestampFrameId(3), mockScreenshot(Color.BLUE, 50, 50)),
250             )
251 
252         assertFilmstripRendering(
253             Filmstrip(screenshots).apply {
254                 limitLongestSide(300)
255                 orientation = FilmstripOrientation.HORIZONTAL
256             }
257         )
258     }
259 
mockScreenshotnull260     private fun mockScreenshot(
261         color: Int,
262         width: Int = 400,
263         height: Int = 200,
264         bitmapConfig: Bitmap.Config = Bitmap.Config.ARGB_8888,
265     ) = Bitmap.createBitmap(width, height, bitmapConfig).also { Canvas(it).drawColor(color) }
266 }
267