[go: nahoru, domu]

blob: 83359531616b95b985a808f3970b720aafd7bd95 [file] [log] [blame]
shepshapardd9f05232019-08-08 10:21:47 -07001/*
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 */
16package androidx.ui.core.gesture
17
18import android.view.MotionEvent
19import android.view.View
20import android.view.ViewGroup
21import androidx.test.rule.ActivityTestRule
22import androidx.ui.core.ipx
23import androidx.ui.core.setContent
24import androidx.ui.framework.test.TestActivity
25import com.nhaarman.mockitokotlin2.any
26import com.nhaarman.mockitokotlin2.verify
27import com.nhaarman.mockitokotlin2.verifyNoMoreInteractions
28import org.junit.Assert.assertTrue
29import org.junit.Before
30import org.junit.Rule
31import org.junit.Test
32import org.junit.runner.RunWith
33import org.junit.runners.JUnit4
34import java.util.concurrent.CountDownLatch
35import java.util.concurrent.TimeUnit
36import androidx.ui.core.PxPosition
37import com.nhaarman.mockitokotlin2.reset
38import com.nhaarman.mockitokotlin2.spy
39import com.nhaarman.mockitokotlin2.times
40import androidx.test.filters.LargeTest
41import androidx.ui.core.Layout
shepshapardd9f05232019-08-08 10:21:47 -070042
43@LargeTest
44@RunWith(JUnit4::class)
45class LongPressDragGestureDetectorTest {
46 @get:Rule
47 val activityTestRule = ActivityTestRule<TestActivity>(TestActivity::class.java)
48 private lateinit var longPressDragObserver: LongPressDragObserver
49 private lateinit var longPressCountDownLatch: CountDownLatch
50 private lateinit var view: View
51
52 @Before
53 fun setup() {
54 longPressDragObserver = spy(MyLongPressDragObserver {
55 longPressCountDownLatch.countDown()
56 })
57
58 val activity = activityTestRule.activity
59 assertTrue(activity.hasFocusLatch.await(5, TimeUnit.SECONDS))
60
61 val setupLatch = CountDownLatch(2)
62 activityTestRule.runOnUiThreadIR {
63 activity.setContent {
64 LongPressDragGestureDetector(longPressDragObserver) {
65 Layout(
66 measureBlock = { _, _ ->
67 layout(100.ipx, 100.ipx) {
68 setupLatch.countDown()
69 }
70 }, children = {}
71 )
72 }
73 }
74
75 view = activity.findViewById<ViewGroup>(android.R.id.content)
76 setupLatch.countDown()
77 }
78 assertTrue(setupLatch.await(1000, TimeUnit.SECONDS))
79 }
80
81 // Tests that verify conditions under which nothing will be called.
82
83 @Test
84 fun ui_downMoveUpBeforeLongPressTimeout_noCallbacksCalled() {
85
86 val down = MotionEvent(
87 0,
88 MotionEvent.ACTION_DOWN,
89 1,
90 0,
91 arrayOf(PointerProperties(0)),
92 arrayOf(PointerCoords(50f, 50f))
93 )
94 val move = MotionEvent(
95 0,
96 MotionEvent.ACTION_MOVE,
97 1,
98 0,
99 arrayOf(PointerProperties(0)),
100 arrayOf(PointerCoords(51f, 50f))
101 )
102 val up = MotionEvent(
103 0,
104 MotionEvent.ACTION_UP,
105 1,
106 0,
107 arrayOf(PointerProperties(0)),
108 arrayOf(PointerCoords(51f, 50f))
109 )
110 activityTestRule.runOnUiThreadIR {
111 view.dispatchTouchEvent(down)
112 view.dispatchTouchEvent(move)
113 view.dispatchTouchEvent(up)
114 }
115
116 verifyNoMoreInteractions(longPressDragObserver)
117 }
118
119 // Tests that verify conditions under which onLongPress will only be called.
120
121 @Test
122 fun ui_downWaitForLongPress_onLongPressCalled() {
123
124 val down = MotionEvent(
125 0,
126 MotionEvent.ACTION_DOWN,
127 1,
128 0,
129 arrayOf(PointerProperties(0)),
130 arrayOf(PointerCoords(50f, 50f))
131 )
132 waitForLongPress {
133 view.dispatchTouchEvent(down)
134 }
135
136 verify(longPressDragObserver).onLongPress(any())
137 verifyNoMoreInteractions(longPressDragObserver)
138 }
139
140 // Tests that verify conditions under which onDragStart and onDrag will be called.
141
142 @Test
143 fun ui_downWaitForLongPressMove_onDragStartAndOnDragCalled() {
144
145 // Arrange.
146 val down = MotionEvent(
147 0,
148 MotionEvent.ACTION_DOWN,
149 1,
150 0,
151 arrayOf(PointerProperties(0)),
152 arrayOf(PointerCoords(50f, 50f))
153 )
154 waitForLongPress {
155 view.dispatchTouchEvent(down)
156 }
157 reset(longPressDragObserver)
158
159 // Act.
160 val move = MotionEvent(
161 0,
162 MotionEvent.ACTION_MOVE,
163 1,
164 0,
165 arrayOf(PointerProperties(0)),
166 arrayOf(PointerCoords(51f, 50f))
167 )
168 view.dispatchTouchEvent(move)
169
170 // Assert.
171 verify(longPressDragObserver).onDragStart()
172 // Twice because DragGestureDetector dispatches onDrag during 2 passes.
173 verify(longPressDragObserver, times(2)).onDrag(any())
174 verifyNoMoreInteractions(longPressDragObserver)
175 }
176
177 // Tests that verify conditions under which onStop will be called.
178
179 @Test
180 fun ui_downWaitForLongPressMoveUp_onDragStopCalled() {
181
182 // Arrange.
183 val down = MotionEvent(
184 0,
185 MotionEvent.ACTION_DOWN,
186 1,
187 0,
188 arrayOf(PointerProperties(0)),
189 arrayOf(PointerCoords(50f, 50f))
190 )
191 waitForLongPress {
192 view.dispatchTouchEvent(down)
193 }
194 val move = MotionEvent(
195 0,
196 MotionEvent.ACTION_MOVE,
197 1,
198 0,
199 arrayOf(PointerProperties(0)),
200 arrayOf(PointerCoords(51f, 50f))
201 )
202 view.dispatchTouchEvent(move)
203 reset(longPressDragObserver)
204
205 // Act.
206 val up = MotionEvent(
207 0,
208 MotionEvent.ACTION_UP,
209 1,
210 0,
211 arrayOf(PointerProperties(0)),
212 arrayOf(PointerCoords(51f, 50f))
213 )
214 view.dispatchTouchEvent(up)
215
216 // Assert.
217 verify(longPressDragObserver).onStop(any())
218 verifyNoMoreInteractions(longPressDragObserver)
219 }
220
221 @Test
222 fun ui_downWaitForLongPressUp_onDragStopCalled() {
223
224 // Arrange.
225 val down = MotionEvent(
226 0,
227 MotionEvent.ACTION_DOWN,
228 1,
229 0,
230 arrayOf(PointerProperties(0)),
231 arrayOf(PointerCoords(50f, 50f))
232 )
233 waitForLongPress {
234 view.dispatchTouchEvent(down)
235 }
236 reset(longPressDragObserver)
237
238 // Act.
239 val up = MotionEvent(
240 0,
241 MotionEvent.ACTION_UP,
242 1,
243 0,
244 arrayOf(PointerProperties(0)),
245 arrayOf(PointerCoords(51f, 50f))
246 )
247 view.dispatchTouchEvent(up)
248
249 // Assert.
250 verify(longPressDragObserver).onStop(any())
251 verifyNoMoreInteractions(longPressDragObserver)
252 }
253
254 private fun waitForLongPress(block: () -> Unit) {
255 longPressCountDownLatch = CountDownLatch(1)
Louis Pullen-Freilich54b4c112019-10-23 19:05:56 +0100256 activityTestRule.runOnUiThreadIR(block)
shepshapardd9f05232019-08-08 10:21:47 -0700257 assertTrue(longPressCountDownLatch.await(750, TimeUnit.MILLISECONDS))
258 }
259}
260
261@Suppress("RedundantOverride")
262open class MyLongPressDragObserver(val onLongPress: () -> Unit) : LongPressDragObserver {
263 override fun onLongPress(pxPosition: PxPosition) {
264 onLongPress()
265 }
266
267 override fun onDragStart() { }
268
269 override fun onDrag(dragDistance: PxPosition): PxPosition {
270 return super.onDrag(dragDistance)
271 }
272
273 override fun onStop(velocity: PxPosition) { }
shepshapardb14d6432019-08-05 17:13:22 -0700274}