[go: nahoru, domu]

blob: 7cc62a7838a2dadaf9ff4dc20836bc8ab235b519 [file] [log] [blame]
Matvei Malkov2d37cbd2019-07-04 15:15:20 +01001/*
2 * Copyright 2019 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
17package androidx.ui.material
18
Jelle Fresen11fc7062020-01-13 16:53:55 +000019import android.os.SystemClock.sleep
Matvei Malkov7aa7fd22019-08-16 16:52:59 +010020import androidx.compose.Model
Matvei Malkov2d37cbd2019-07-04 15:15:20 +010021import androidx.test.filters.MediumTest
22import androidx.ui.core.OnPositioned
Matvei Malkov7aa7fd22019-08-16 16:52:59 +010023import androidx.ui.core.TestTag
Matvei Malkov7aa7fd22019-08-16 16:52:59 +010024import androidx.ui.foundation.Clickable
Matvei Malkov2d37cbd2019-07-04 15:15:20 +010025import androidx.ui.layout.Container
Matvei Malkov7aa7fd22019-08-16 16:52:59 +010026import androidx.ui.semantics.Semantics
Matvei Malkov2d37cbd2019-07-04 15:15:20 +010027import androidx.ui.test.createComposeRule
Jelle Fresen11fc7062020-01-13 16:53:55 +000028import androidx.ui.test.doGesture
Matvei Malkov7aa7fd22019-08-16 16:52:59 +010029import androidx.ui.test.findByTag
Jelle Fresen11fc7062020-01-13 16:53:55 +000030import androidx.ui.test.globalBounds
31import androidx.ui.test.sendClick
George Mount842c8c12020-01-08 16:03:42 -080032import androidx.ui.unit.PxPosition
33import androidx.ui.unit.PxSize
34import androidx.ui.unit.dp
Ryan Mentley7865a632019-08-20 20:10:29 -070035import androidx.ui.unit.height
Jelle Fresen11fc7062020-01-13 16:53:55 +000036import androidx.ui.unit.px
George Mount842c8c12020-01-08 16:03:42 -080037import androidx.ui.unit.round
Ryan Mentley7865a632019-08-20 20:10:29 -070038import androidx.ui.unit.width
Filip Pavlise63b30c2020-01-09 16:21:07 +000039import com.google.common.truth.Truth.assertThat
Matvei Malkov2d37cbd2019-07-04 15:15:20 +010040import org.junit.Rule
41import org.junit.Test
42import org.junit.runner.RunWith
43import org.junit.runners.JUnit4
44import kotlin.math.roundToInt
45
Matvei Malkov7aa7fd22019-08-16 16:52:59 +010046@Model
47data class DrawerStateHolder(var state: DrawerState)
48
Matvei Malkov2d37cbd2019-07-04 15:15:20 +010049@MediumTest
50@RunWith(JUnit4::class)
51class DrawerTest {
52
53 @get:Rule
Matvei Malkov7aa7fd22019-08-16 16:52:59 +010054 val composeTestRule = createComposeRule(disableTransitions = true)
Matvei Malkov2d37cbd2019-07-04 15:15:20 +010055
56 @Test
57 fun modalDrawer_testOffset_whenOpened() {
58 var position: PxPosition? = null
59 composeTestRule.setMaterialContent {
Matvei Malkov7aa7fd22019-08-16 16:52:59 +010060 ModalDrawerLayout(DrawerState.Opened, {}, drawerContent = {
Matvei Malkov2d37cbd2019-07-04 15:15:20 +010061 Container(expanded = true) {
62 OnPositioned { coords ->
63 position = coords.localToGlobal(PxPosition.Origin)
64 }
65 }
Matvei Malkov7aa7fd22019-08-16 16:52:59 +010066 }) {}
Matvei Malkov2d37cbd2019-07-04 15:15:20 +010067 }
Filip Pavlise63b30c2020-01-09 16:21:07 +000068 composeTestRule.runOnIdleCompose {
69 assertThat(position!!.x.value).isEqualTo(0f)
70 }
Matvei Malkov2d37cbd2019-07-04 15:15:20 +010071 }
72
73 @Test
74 fun modalDrawer_testOffset_whenClosed() {
75 var position: PxPosition? = null
76 composeTestRule.setMaterialContent {
Matvei Malkov7aa7fd22019-08-16 16:52:59 +010077 ModalDrawerLayout(DrawerState.Closed, {}, drawerContent = {
Matvei Malkov2d37cbd2019-07-04 15:15:20 +010078 Container(expanded = true) {
79 OnPositioned { coords ->
80 position = coords.localToGlobal(PxPosition.Origin)
81 }
82 }
Matvei Malkov7aa7fd22019-08-16 16:52:59 +010083 }) {}
Matvei Malkov2d37cbd2019-07-04 15:15:20 +010084 }
85 val width = composeTestRule.displayMetrics.widthPixels
Filip Pavlise63b30c2020-01-09 16:21:07 +000086 composeTestRule.runOnIdleCompose {
87 assertThat(position!!.x.round().value).isEqualTo(-width)
88 }
Matvei Malkov2d37cbd2019-07-04 15:15:20 +010089 }
90
91 @Test
92 fun modalDrawer_testEndPadding_whenOpened() {
93 var size: PxSize? = null
94 composeTestRule.setMaterialContent {
Matvei Malkov7aa7fd22019-08-16 16:52:59 +010095 ModalDrawerLayout(DrawerState.Opened, {}, drawerContent = {
Matvei Malkov2d37cbd2019-07-04 15:15:20 +010096 Container(expanded = true) {
97 OnPositioned { coords ->
98 size = coords.size
99 }
100 }
Matvei Malkov7aa7fd22019-08-16 16:52:59 +0100101 }) {}
Matvei Malkov2d37cbd2019-07-04 15:15:20 +0100102 }
103
104 val width = composeTestRule.displayMetrics.widthPixels
Filip Pavlise63b30c2020-01-09 16:21:07 +0000105 composeTestRule.runOnIdleComposeWithDensity {
106 assertThat(size!!.width.round().value)
Matvei Malkov2d37cbd2019-07-04 15:15:20 +0100107 .isEqualTo(width - 56.dp.toPx().round().value)
108 }
109 }
110
111 @Test
112 fun bottomDrawer_testOffset_whenOpened() {
113 var position: PxPosition? = null
114 composeTestRule.setMaterialContent {
Matvei Malkov7aa7fd22019-08-16 16:52:59 +0100115 BottomDrawerLayout(DrawerState.Opened, {}, drawerContent = {
Matvei Malkov2d37cbd2019-07-04 15:15:20 +0100116 Container(expanded = true) {
117 OnPositioned { coords ->
118 position = coords.localToGlobal(PxPosition.Origin)
119 }
120 }
Matvei Malkov7aa7fd22019-08-16 16:52:59 +0100121 }) {}
Matvei Malkov2d37cbd2019-07-04 15:15:20 +0100122 }
Filip Pavlise63b30c2020-01-09 16:21:07 +0000123
Matvei Malkov2270be12019-07-08 16:59:45 +0100124 val width = composeTestRule.displayMetrics.widthPixels
Matvei Malkov2d37cbd2019-07-04 15:15:20 +0100125 val height = composeTestRule.displayMetrics.heightPixels
Matvei Malkov2270be12019-07-08 16:59:45 +0100126 // temporary calculation of landscape screen
127 val expectedHeight = if (width > height) height else (height / 2f).roundToInt()
Filip Pavlise63b30c2020-01-09 16:21:07 +0000128 composeTestRule.runOnIdleCompose {
129 assertThat(position!!.y.round().value).isEqualTo(expectedHeight)
130 }
Matvei Malkov2d37cbd2019-07-04 15:15:20 +0100131 }
132
133 @Test
134 fun bottomDrawer_testOffset_whenClosed() {
135 var position: PxPosition? = null
136 composeTestRule.setMaterialContent {
Matvei Malkov7aa7fd22019-08-16 16:52:59 +0100137 BottomDrawerLayout(DrawerState.Closed, {}, drawerContent = {
Matvei Malkov2d37cbd2019-07-04 15:15:20 +0100138 Container(expanded = true) {
139 OnPositioned { coords ->
140 position = coords.localToGlobal(PxPosition.Origin)
141 }
142 }
Matvei Malkov7aa7fd22019-08-16 16:52:59 +0100143 }) {}
Matvei Malkov2d37cbd2019-07-04 15:15:20 +0100144 }
145 val height = composeTestRule.displayMetrics.heightPixels
Filip Pavlise63b30c2020-01-09 16:21:07 +0000146 composeTestRule.runOnIdleCompose {
147 assertThat(position!!.y.round().value).isEqualTo(height)
148 }
Matvei Malkov2d37cbd2019-07-04 15:15:20 +0100149 }
150
151 @Test
152 fun staticDrawer_testWidth_whenOpened() {
153 composeTestRule
Matvei Malkov804bee42019-07-16 16:24:06 +0100154 .setMaterialContentAndCollectSizes {
Matvei Malkov2d37cbd2019-07-04 15:15:20 +0100155 StaticDrawer {
156 Container(expanded = true) {}
157 }
158 }
159 .assertWidthEqualsTo(256.dp)
160 }
Matvei Malkov7aa7fd22019-08-16 16:52:59 +0100161
162 @Test
163 fun modalDrawer_bodyContent_clickable() {
164 var drawerClicks = 0
165 var bodyClicks = 0
166 val drawerState = DrawerStateHolder(DrawerState.Closed)
167 composeTestRule.setMaterialContent {
Aurimas Liutikas7a828d32019-10-07 17:16:05 -0700168 // emulate click on the screen
Matvei Malkov7aa7fd22019-08-16 16:52:59 +0100169 TestTag("Drawer") {
170 Semantics(container = true) {
171 ModalDrawerLayout(drawerState.state, { drawerState.state = it },
172 drawerContent = {
173 Clickable(onClick = { drawerClicks += 1 }) {
174 Container(expanded = true) {}
175 }
176 },
177 bodyContent = {
178 Clickable(onClick = { bodyClicks += 1 }) {
179 Container(expanded = true) {}
180 }
181 })
182 }
183 }
184 }
185
Jelle Fresen11fc7062020-01-13 16:53:55 +0000186 // Click in the middle of the drawer (which is the middle of the body)
187 findByTag("Drawer").doGesture { sendClick() }
Matvei Malkov7aa7fd22019-08-16 16:52:59 +0100188
Filip Pavlis2b161e42019-11-22 17:40:08 +0000189 composeTestRule.runOnIdleCompose {
Filip Pavlise63b30c2020-01-09 16:21:07 +0000190 assertThat(drawerClicks).isEqualTo(0)
191 assertThat(bodyClicks).isEqualTo(1)
Matvei Malkov7aa7fd22019-08-16 16:52:59 +0100192
Matvei Malkov7aa7fd22019-08-16 16:52:59 +0100193 drawerState.state = DrawerState.Opened
194 }
Jelle Fresen11fc7062020-01-13 16:53:55 +0000195 sleep(100) // TODO(147586311): remove this sleep when opening the drawer triggers a wait
Matvei Malkov7aa7fd22019-08-16 16:52:59 +0100196
Jelle Fresen11fc7062020-01-13 16:53:55 +0000197 // Click on the left-center pixel of the drawer
198 findByTag("Drawer").doGesture {
Ryan Mentley7865a632019-08-20 20:10:29 -0700199 val left = 1.px
Jelle Fresen11fc7062020-01-13 16:53:55 +0000200 val centerY = globalBounds.height / 2
Ryan Mentley7865a632019-08-20 20:10:29 -0700201 sendClick(PxPosition(left, centerY))
Jelle Fresen11fc7062020-01-13 16:53:55 +0000202 }
Matvei Malkov7aa7fd22019-08-16 16:52:59 +0100203
Filip Pavlis2b161e42019-11-22 17:40:08 +0000204 composeTestRule.runOnIdleCompose {
Filip Pavlise63b30c2020-01-09 16:21:07 +0000205 assertThat(drawerClicks).isEqualTo(1)
206 assertThat(bodyClicks).isEqualTo(1)
Filip Pavlis2b161e42019-11-22 17:40:08 +0000207 }
Matvei Malkov7aa7fd22019-08-16 16:52:59 +0100208 }
209
210 @Test
211 fun bottomDrawer_bodyContent_clickable() {
212 var drawerClicks = 0
213 var bodyClicks = 0
214 val drawerState = DrawerStateHolder(DrawerState.Closed)
215 composeTestRule.setMaterialContent {
Aurimas Liutikas7a828d32019-10-07 17:16:05 -0700216 // emulate click on the screen
Matvei Malkov7aa7fd22019-08-16 16:52:59 +0100217 TestTag("Drawer") {
218 Semantics(container = true) {
219 BottomDrawerLayout(drawerState.state, { drawerState.state = it },
220 drawerContent = {
221 Clickable(onClick = { drawerClicks += 1 }) {
222 Container(expanded = true) {}
223 }
224 },
225 bodyContent = {
226 Clickable(onClick = { bodyClicks += 1 }) {
227 Container(expanded = true) {}
228 }
229 })
230 }
231 }
232 }
233
Jelle Fresen11fc7062020-01-13 16:53:55 +0000234 // Click in the middle of the drawer (which is the middle of the body)
235 findByTag("Drawer").doGesture { sendClick() }
Matvei Malkov7aa7fd22019-08-16 16:52:59 +0100236
Filip Pavlise63b30c2020-01-09 16:21:07 +0000237 composeTestRule.runOnIdleCompose {
238 assertThat(drawerClicks).isEqualTo(0)
239 assertThat(bodyClicks).isEqualTo(1)
240 }
Matvei Malkov7aa7fd22019-08-16 16:52:59 +0100241
Jelle Fresen11fc7062020-01-13 16:53:55 +0000242 composeTestRule.runOnUiThread {
243 drawerState.state = DrawerState.Opened
244 }
245 sleep(100) // TODO(147586311): remove this sleep when opening the drawer triggers a wait
246
247 // Click on the bottom-center pixel of the drawer
248 findByTag("Drawer").doGesture {
249 val bounds = globalBounds
250 val centerX = bounds.width / 2
Ryan Mentley7865a632019-08-20 20:10:29 -0700251 val bottom = bounds.height - 1.px
252 sendClick(PxPosition(centerX, bottom))
Jelle Fresen11fc7062020-01-13 16:53:55 +0000253 }
254
255 assertThat(drawerClicks).isEqualTo(1)
256 assertThat(bodyClicks).isEqualTo(1)
Matvei Malkov7aa7fd22019-08-16 16:52:59 +0100257 }
Matvei Malkov2d37cbd2019-07-04 15:15:20 +0100258}