[go: nahoru, domu]

blob: cd4a7fc4f2f706a21ce3dbe7f870e50836aa7708 [file] [log] [blame]
shepshapard648840f2019-07-17 14:28:50 -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 */
16
17package androidx.ui.core.gesture
18
19import androidx.ui.core.Direction
shepshapard648840f2019-07-17 14:28:50 -070020import androidx.ui.core.PointerEventPass
21import androidx.ui.core.consumeDownChange
shepshapard648840f2019-07-17 14:28:50 -070022import androidx.ui.testutils.consume
23import androidx.ui.testutils.down
24import androidx.ui.testutils.invokeOverAllPasses
25import androidx.ui.testutils.invokeOverPasses
26import androidx.ui.testutils.moveBy
27import androidx.ui.testutils.moveTo
28import androidx.ui.testutils.up
George Mount842c8c12020-01-08 16:03:42 -080029import androidx.ui.unit.Duration
George Mount842c8c12020-01-08 16:03:42 -080030import androidx.ui.unit.milliseconds
shepshapard648840f2019-07-17 14:28:50 -070031import com.google.common.truth.Truth.assertThat
32import org.junit.Before
33import org.junit.Test
34import org.junit.runner.RunWith
35import org.junit.runners.JUnit4
36
37// TODO(shepshapard): Write the following tests.
38// Verify correct shape of slop area (should it be a square or circle)?
39// Test for cases with more than one pointer
40// Test for cases where things are reset when last pointer goes up
41// Verify all methods called during onPostUp
Shep Shapardad4e8152020-04-03 13:22:08 -070042// Verify default behavior when no callback provided for filter or canDrag
shepshapard648840f2019-07-17 14:28:50 -070043
44// Changing this value will break tests that expect the value to be 10.
45private const val TestTouchSlop = 10
46
47@RunWith(JUnit4::class)
Shep Shaparddd9e2bc2020-05-19 15:25:36 -070048class DragSlopExceededGestureFilterTest {
shepshapard648840f2019-07-17 14:28:50 -070049
Shep Shaparddd9e2bc2020-05-19 15:25:36 -070050 private val onDragSlopExceeded: () -> Unit = { onDragSlopExceededCallCount++ }
shepshapard648840f2019-07-17 14:28:50 -070051 private val canDrag: (Direction) -> Boolean = { direction ->
52 canDragDirections.add(direction)
53 canDragReturn
54 }
Shep Shaparddd9e2bc2020-05-19 15:25:36 -070055 private var onDragSlopExceededCallCount: Int = 0
shepshapard648840f2019-07-17 14:28:50 -070056 private var canDragReturn = false
57 private var canDragDirections: MutableList<Direction> = mutableListOf()
Shep Shaparddd9e2bc2020-05-19 15:25:36 -070058 private lateinit var filter: DragSlopExceededGestureFilter
shepshapard648840f2019-07-17 14:28:50 -070059
Shep Shapard4babf792020-02-13 16:37:14 -080060 private val TinyNum = .01f
61
shepshapard648840f2019-07-17 14:28:50 -070062 @Before
63 fun setup() {
Shep Shaparddd9e2bc2020-05-19 15:25:36 -070064 onDragSlopExceededCallCount = 0
shepshapard648840f2019-07-17 14:28:50 -070065 canDragReturn = true
66 canDragDirections.clear()
Shep Shapardad4e8152020-04-03 13:22:08 -070067 filter =
Nader Jawadfeb99f82020-05-21 13:07:36 -070068 DragSlopExceededGestureFilter(TestTouchSlop.toFloat())
Shep Shapardad4e8152020-04-03 13:22:08 -070069 filter.canDrag = canDrag
Shep Shaparddd9e2bc2020-05-19 15:25:36 -070070 filter.onDragSlopExceeded = onDragSlopExceeded
shepshapard648840f2019-07-17 14:28:50 -070071 }
72
73 // Verify the circumstances under which canDrag should not be called.
74
75 @Test
76 fun onPointerInputChanges_down_canDragNotCalled() {
Shep Shapardad4e8152020-04-03 13:22:08 -070077 filter::onPointerInput.invokeOverAllPasses(down(0))
shepshapard648840f2019-07-17 14:28:50 -070078 assertThat(canDragDirections).isEmpty()
79 }
80
81 @Test
82 fun onPointerInputChanges_downUp_canDragNotCalled() {
Shep Shapard091fd692020-01-29 16:35:47 -080083 val down = down(0, duration = 0.milliseconds)
Shep Shapardad4e8152020-04-03 13:22:08 -070084 filter::onPointerInput.invokeOverAllPasses(down)
Shep Shaparde261df92019-11-15 11:24:31 -080085 val up = down.up(10.milliseconds)
Shep Shapardad4e8152020-04-03 13:22:08 -070086 filter::onPointerInput.invokeOverAllPasses(up)
shepshapard648840f2019-07-17 14:28:50 -070087
88 assertThat(canDragDirections).isEmpty()
89 }
90
91 @Test
92 fun onPointerInputChanges_downMoveFullyConsumed_canDragNotCalled() {
Shep Shapard091fd692020-01-29 16:35:47 -080093 val down = down(0)
Shep Shapardad4e8152020-04-03 13:22:08 -070094 filter::onPointerInput.invokeOverAllPasses(down)
shepshapard648840f2019-07-17 14:28:50 -070095 val move = down.moveBy(Duration(milliseconds = 10), 3f, 5f).consume(3f, 5f)
Shep Shapardad4e8152020-04-03 13:22:08 -070096 filter::onPointerInput.invokeOverAllPasses(move)
shepshapard648840f2019-07-17 14:28:50 -070097
98 assertThat(canDragDirections).isEmpty()
99 }
100
101 // Verify the circumstances under which canDrag should be called.
102
103 @Test
104 fun onPointerInputChanges_downMove1Dimension_canDragCalledOnce() {
Shep Shapard091fd692020-01-29 16:35:47 -0800105 val down = down(0)
Shep Shapardad4e8152020-04-03 13:22:08 -0700106 filter::onPointerInput.invokeOverAllPasses(down)
shepshapard648840f2019-07-17 14:28:50 -0700107 val move = down.moveBy(Duration(milliseconds = 10), 3f, 0f)
Shep Shapardad4e8152020-04-03 13:22:08 -0700108 filter::onPointerInput.invokeOverAllPasses(move)
shepshapard648840f2019-07-17 14:28:50 -0700109
110 // Twice because while under touch slop, TouchSlopExceededGestureDetector checks during PostUp and PostDown
111 assertThat(canDragDirections).hasSize(2)
112 }
113
114 @Test
115 fun onPointerInputChanges_downMove2Dimensions_canDragCalledTwice() {
Shep Shapard091fd692020-01-29 16:35:47 -0800116 val down = down(0)
Shep Shapardad4e8152020-04-03 13:22:08 -0700117 filter::onPointerInput.invokeOverAllPasses(down)
shepshapard648840f2019-07-17 14:28:50 -0700118 val move = down.moveBy(Duration(milliseconds = 10), 3f, 5f)
Shep Shapardad4e8152020-04-03 13:22:08 -0700119 filter::onPointerInput.invokeOverAllPasses(move)
shepshapard648840f2019-07-17 14:28:50 -0700120
121 // 4 times because while under touch slop, TouchSlopExceededGestureDetector checks during PostUp and
122 // PostDown
123 assertThat(canDragDirections).hasSize(4)
124 }
125
126 @Test
127 fun onPointerInputChanges_downMoveOneDimensionPartiallyConsumed_canDragCalledOnce() {
Shep Shapard091fd692020-01-29 16:35:47 -0800128 val down = down(0)
Shep Shapardad4e8152020-04-03 13:22:08 -0700129 filter::onPointerInput.invokeOverAllPasses(down)
shepshapard648840f2019-07-17 14:28:50 -0700130 val move = down.moveBy(Duration(milliseconds = 10), 0f, 5f).consume(0f, 4f)
Shep Shapardad4e8152020-04-03 13:22:08 -0700131 filter::onPointerInput.invokeOverAllPasses(move)
shepshapard648840f2019-07-17 14:28:50 -0700132
133 // Twice because while under touch slop, DragGestureDetector checks during PostUp and
134 // PostDown
135 assertThat(canDragDirections).hasSize(2)
136 }
137
138 @Test
139 fun onPointerInputChanges_downMoveTwoDimensionPartiallyConsumed_canDragCalledTwice() {
Shep Shapard091fd692020-01-29 16:35:47 -0800140 val down = down(0)
Shep Shapardad4e8152020-04-03 13:22:08 -0700141 filter::onPointerInput.invokeOverAllPasses(down)
shepshapard648840f2019-07-17 14:28:50 -0700142 val move = down.moveBy(Duration(milliseconds = 10), 3f, 5f).consume(2f, 4f)
Shep Shapardad4e8152020-04-03 13:22:08 -0700143 filter::onPointerInput.invokeOverAllPasses(move)
shepshapard648840f2019-07-17 14:28:50 -0700144
145 // 4 times because while under touch slop, DragGestureDetector checks during PostUp and
146 // PostDown
147 assertThat(canDragDirections).hasSize(4)
148 }
149
150 @Test
151 fun onPointerInputChanges_dragPastTouchSlopOneDimensionAndDrag3MoreTimes_canDragCalledOnce() {
Shep Shapard4babf792020-02-13 16:37:14 -0800152 val beyondSlop = TestTouchSlop + TinyNum
shepshapard648840f2019-07-17 14:28:50 -0700153
Shep Shapard091fd692020-01-29 16:35:47 -0800154 val down = down(0)
Shep Shapardad4e8152020-04-03 13:22:08 -0700155 filter::onPointerInput.invokeOverAllPasses(down)
Shep Shapard4babf792020-02-13 16:37:14 -0800156 var move = down.moveTo(10.milliseconds, 0f, beyondSlop)
Shep Shapardad4e8152020-04-03 13:22:08 -0700157 filter::onPointerInput.invokeOverAllPasses(move)
shepshapard648840f2019-07-17 14:28:50 -0700158 repeat(3) {
159 move = move.moveBy(Duration(milliseconds = 10), 0f, 1f)
Shep Shapardad4e8152020-04-03 13:22:08 -0700160 filter::onPointerInput.invokeOverAllPasses(move)
shepshapard648840f2019-07-17 14:28:50 -0700161 }
162
163 // Once because although DragGestureDetector checks during PostUp and PostDown, slop is
164 // surpassed during PostUp, and thus isn't checked again.
165 assertThat(canDragDirections).hasSize(1)
166 }
167
168 @Test
169 fun onPointerInputChanges_downMoveUnderSlop3Times_canDragCalled3Times() {
Shep Shapard4babf792020-02-13 16:37:14 -0800170 val thirdSlop = TestTouchSlop / 3
shepshapard648840f2019-07-17 14:28:50 -0700171
Shep Shapard091fd692020-01-29 16:35:47 -0800172 val down = down(0)
Shep Shapardad4e8152020-04-03 13:22:08 -0700173 filter::onPointerInput.invokeOverAllPasses(down)
shepshapard648840f2019-07-17 14:28:50 -0700174 var move = down
175 repeat(3) {
Shep Shapard4babf792020-02-13 16:37:14 -0800176 move = move.moveBy(Duration(milliseconds = 10), 0f, thirdSlop.toFloat())
Shep Shapardad4e8152020-04-03 13:22:08 -0700177 filter::onPointerInput.invokeOverAllPasses(move)
shepshapard648840f2019-07-17 14:28:50 -0700178 }
179
180 // 6 times because while under touch slop, DragGestureDetector checks during PostUp and
181 // PostDown
182 assertThat(canDragDirections).hasSize(6)
183 }
184
185 @Test
186 fun onPointerInputChanges_moveBeyondSlopThenIntoTouchSlopAreaAndOutAgain_canDragCalledOnce() {
Shep Shapard4babf792020-02-13 16:37:14 -0800187 val beyondSlop = TestTouchSlop + TinyNum
shepshapard648840f2019-07-17 14:28:50 -0700188
Shep Shapard091fd692020-01-29 16:35:47 -0800189 var event = down(0)
Shep Shapardad4e8152020-04-03 13:22:08 -0700190 filter::onPointerInput.invokeOverAllPasses(event)
shepshapard648840f2019-07-17 14:28:50 -0700191 // Out of touch slop region
Shep Shapard4babf792020-02-13 16:37:14 -0800192 event = event.moveBy(Duration(milliseconds = 10), 0f, beyondSlop)
Shep Shapardad4e8152020-04-03 13:22:08 -0700193 filter::onPointerInput.invokeOverAllPasses(event)
shepshapard648840f2019-07-17 14:28:50 -0700194 // Back into touch slop region
Shep Shapard4babf792020-02-13 16:37:14 -0800195 event = event.moveBy(Duration(milliseconds = 10), 0f, -beyondSlop)
Shep Shapardad4e8152020-04-03 13:22:08 -0700196 filter::onPointerInput.invokeOverAllPasses(event)
shepshapard648840f2019-07-17 14:28:50 -0700197 // Out of touch slop region again
Shep Shapard4babf792020-02-13 16:37:14 -0800198 event = event.moveBy(Duration(milliseconds = 10), 0f, beyondSlop)
Shep Shapardad4e8152020-04-03 13:22:08 -0700199 filter::onPointerInput.invokeOverAllPasses(event)
shepshapard648840f2019-07-17 14:28:50 -0700200
201 // Once because although DragGestureDetector checks during PostUp and PostDown, slop is
202 // surpassed during PostUp, and thus isn't checked again.
203 assertThat(canDragDirections).hasSize(1)
204 }
205
206 // Verification of correctness of values passed to canDrag.
207
208 @Test
209 fun onPointerInputChanges_canDragCalledWithCorrectDirection() {
210 onPointerInputChanges_canDragCalledWithCorrectDirection(
211 -1f, 0f, arrayOf(Direction.LEFT)
212 )
213 onPointerInputChanges_canDragCalledWithCorrectDirection(
214 0f, -1f, arrayOf(Direction.UP)
215 )
216 onPointerInputChanges_canDragCalledWithCorrectDirection(
217 1f, 0f, arrayOf(Direction.RIGHT)
218 )
219 onPointerInputChanges_canDragCalledWithCorrectDirection(
220 0f, 1f, arrayOf(Direction.DOWN)
221 )
222 onPointerInputChanges_canDragCalledWithCorrectDirection(
223 -1f, -1f, arrayOf(Direction.LEFT, Direction.UP)
224 )
225 onPointerInputChanges_canDragCalledWithCorrectDirection(
226 -1f, 1f, arrayOf(Direction.LEFT, Direction.DOWN)
227 )
228 onPointerInputChanges_canDragCalledWithCorrectDirection(
229 1f, -1f, arrayOf(Direction.RIGHT, Direction.UP)
230 )
231 onPointerInputChanges_canDragCalledWithCorrectDirection(
232 1f, 1f, arrayOf(Direction.RIGHT, Direction.DOWN)
233 )
234 }
235
236 private fun onPointerInputChanges_canDragCalledWithCorrectDirection(
237 dx: Float,
238 dy: Float,
239 expectedDirections: Array<Direction>
240 ) {
241 canDragDirections.clear()
Shep Shapard091fd692020-01-29 16:35:47 -0800242 val down = down(0)
Shep Shapardad4e8152020-04-03 13:22:08 -0700243 filter::onPointerInput.invokeOverAllPasses(down)
shepshapard648840f2019-07-17 14:28:50 -0700244 val move = down.moveBy(Duration(milliseconds = 10), dx, dy)
Shep Shapardad4e8152020-04-03 13:22:08 -0700245 filter::onPointerInput.invokeOverAllPasses(move)
shepshapard648840f2019-07-17 14:28:50 -0700246
247 // Everything here is twice because DragGestureDetector checks during PostUp and PostDown.
248 assertThat(canDragDirections).hasSize(expectedDirections.size * 2)
249 expectedDirections.forEach { direction ->
250 assertThat(canDragDirections.count { it == direction })
251 .isEqualTo(2)
252 }
253 }
254
255 // Verify the circumstances under which onTouchSlopExceeded should not be called.
256
257 // TODO(b/129701831): This test assumes that if a pointer moves by slop in both x and y, we are
258 // still under slop even though sqrt(slop^2 + slop^2) > slop. This may be inaccurate and this
259 // test may therefore need to be updated.
260 @Test
261 fun onPointerInputChanges_downMoveWithinSlop_onTouchSlopExceededNotCalled() {
Shep Shapard091fd692020-01-29 16:35:47 -0800262 val down = down(0)
Shep Shapardad4e8152020-04-03 13:22:08 -0700263 filter::onPointerInput.invokeOverAllPasses(down)
shepshapard648840f2019-07-17 14:28:50 -0700264 val move = down.moveBy(
265 Duration(milliseconds = 10),
266 TestTouchSlop.toFloat(),
267 TestTouchSlop.toFloat()
268 )
Shep Shapardad4e8152020-04-03 13:22:08 -0700269 filter::onPointerInput.invokeOverAllPasses(move)
shepshapard648840f2019-07-17 14:28:50 -0700270
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700271 assertThat(onDragSlopExceededCallCount).isEqualTo(0)
shepshapard648840f2019-07-17 14:28:50 -0700272 }
273
274 @Test
275 fun onPointerInputChanges_moveBeyondSlopInUnsupportedDirection_onTouchSlopExceededNotCalled() {
Shep Shapard4babf792020-02-13 16:37:14 -0800276 val beyondSlop = TestTouchSlop + TinyNum
shepshapard648840f2019-07-17 14:28:50 -0700277 canDragReturn = false
278
Shep Shapard091fd692020-01-29 16:35:47 -0800279 val down = down(0)
Shep Shapardad4e8152020-04-03 13:22:08 -0700280 filter::onPointerInput.invokeOverAllPasses(down)
shepshapard648840f2019-07-17 14:28:50 -0700281 val move = down.moveBy(
282 Duration(milliseconds = 10),
283 beyondSlop,
284 beyondSlop
285 )
Shep Shapardad4e8152020-04-03 13:22:08 -0700286 filter::onPointerInput.invokeOverAllPasses(move)
shepshapard648840f2019-07-17 14:28:50 -0700287
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700288 assertThat(onDragSlopExceededCallCount).isEqualTo(0)
shepshapard648840f2019-07-17 14:28:50 -0700289 }
290
291 @Test
292 fun onPointerInputChanges_moveBeyondSlopButConsumeUnder_onTouchSlopExceededNotCalled() {
293
Shep Shapard091fd692020-01-29 16:35:47 -0800294 val down = down(0)
Shep Shapardad4e8152020-04-03 13:22:08 -0700295 filter::onPointerInput.invokeOverAllPasses(down)
shepshapard648840f2019-07-17 14:28:50 -0700296
Shep Shapard4babf792020-02-13 16:37:14 -0800297 val move = down.moveBy(10.milliseconds, TestTouchSlop + TinyNum, 0f).consume(dx = 1f)
Shep Shapardad4e8152020-04-03 13:22:08 -0700298 filter::onPointerInput.invokeOverAllPasses(move)
shepshapard648840f2019-07-17 14:28:50 -0700299
300 // Assert
301
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700302 assertThat(onDragSlopExceededCallCount).isEqualTo(0)
shepshapard648840f2019-07-17 14:28:50 -0700303 }
304
305 @Test
306 fun onPointerInputChanges_moveUnderToPostUpThenModOverInOppDir_onTouchSlopExceededNotCalled() {
307
Shep Shapard091fd692020-01-29 16:35:47 -0800308 val down = down(0)
Shep Shapardad4e8152020-04-03 13:22:08 -0700309 filter::onPointerInput.invokeOverAllPasses(down)
shepshapard648840f2019-07-17 14:28:50 -0700310
Shep Shapard091fd692020-01-29 16:35:47 -0800311 val move = down.moveBy(10.milliseconds, TestTouchSlop.toFloat(), 0f)
Shep Shapardad4e8152020-04-03 13:22:08 -0700312 filter::onPointerInput.invokeOverPasses(
shepshapard648840f2019-07-17 14:28:50 -0700313 listOf(move),
Shep Shapardbf513c52019-12-16 17:06:51 -0800314 listOf(
315 PointerEventPass.InitialDown,
316 PointerEventPass.PreUp,
317 PointerEventPass.PreDown,
318 PointerEventPass.PostUp
319 )
shepshapard648840f2019-07-17 14:28:50 -0700320 )
Shep Shapard4babf792020-02-13 16:37:14 -0800321 val move2 = move.consume(dx = (TestTouchSlop * 2f + TinyNum))
Shep Shapardad4e8152020-04-03 13:22:08 -0700322 filter::onPointerInput.invokeOverPasses(
Shep Shapardbf513c52019-12-16 17:06:51 -0800323 move2,
shepshapard648840f2019-07-17 14:28:50 -0700324 PointerEventPass.PostDown
325 )
326
327 // Assert
328
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700329 assertThat(onDragSlopExceededCallCount).isEqualTo(1)
shepshapard648840f2019-07-17 14:28:50 -0700330 }
331
332 // TODO(b/129701831): This test assumes that if a pointer moves by slop in both x and y, we are
333 // still under slop even though sqrt(slop^2 + slop^2) > slop. This may be inaccurate and this
334 // test may therefore need to be updated.
335 @Test
336 fun onPointerInputChanges_moveAroundWithinSlop_onTouchSlopExceededNotCalled() {
337 val slop = TestTouchSlop.toFloat()
338
Shep Shapard091fd692020-01-29 16:35:47 -0800339 var change = down(0)
Shep Shapardad4e8152020-04-03 13:22:08 -0700340 filter::onPointerInput.invokeOverAllPasses(change)
shepshapard648840f2019-07-17 14:28:50 -0700341
342 // Go around the border of the touch slop area
343
344 // To top left
Shep Shaparde261df92019-11-15 11:24:31 -0800345 change = change.moveTo(10.milliseconds, -slop, -slop)
Shep Shapardad4e8152020-04-03 13:22:08 -0700346 filter::onPointerInput.invokeOverAllPasses(change)
shepshapard648840f2019-07-17 14:28:50 -0700347 // To bottom left
Shep Shaparde261df92019-11-15 11:24:31 -0800348 change = change.moveTo(20.milliseconds, -slop, slop)
Shep Shapardad4e8152020-04-03 13:22:08 -0700349 filter::onPointerInput.invokeOverAllPasses(change)
shepshapard648840f2019-07-17 14:28:50 -0700350 // To bottom right
Shep Shaparde261df92019-11-15 11:24:31 -0800351 change = change.moveTo(30.milliseconds, slop, slop)
Shep Shapardad4e8152020-04-03 13:22:08 -0700352 filter::onPointerInput.invokeOverAllPasses(change)
shepshapard648840f2019-07-17 14:28:50 -0700353 // To top right
Shep Shaparde261df92019-11-15 11:24:31 -0800354 change = change.moveTo(40.milliseconds, slop, -slop)
Shep Shapardad4e8152020-04-03 13:22:08 -0700355 filter::onPointerInput.invokeOverAllPasses(change)
shepshapard648840f2019-07-17 14:28:50 -0700356
357 // Jump from corner to opposite corner and back
358
359 // To bottom left
Shep Shaparde261df92019-11-15 11:24:31 -0800360 change = change.moveTo(50.milliseconds, -slop, slop)
Shep Shapardad4e8152020-04-03 13:22:08 -0700361 filter::onPointerInput.invokeOverAllPasses(change)
shepshapard648840f2019-07-17 14:28:50 -0700362 // To top right
Shep Shaparde261df92019-11-15 11:24:31 -0800363 change = change.moveTo(60.milliseconds, slop, -slop)
Shep Shapardad4e8152020-04-03 13:22:08 -0700364 filter::onPointerInput.invokeOverAllPasses(change)
shepshapard648840f2019-07-17 14:28:50 -0700365
366 // Move the other diagonal
367
368 // To top left
Shep Shaparde261df92019-11-15 11:24:31 -0800369 change = change.moveTo(70.milliseconds, -slop, -slop)
Shep Shapardad4e8152020-04-03 13:22:08 -0700370 filter::onPointerInput.invokeOverAllPasses(change)
shepshapard648840f2019-07-17 14:28:50 -0700371
372 // Jump from corner to opposite corner and back
373
374 // To bottom right
Shep Shaparde261df92019-11-15 11:24:31 -0800375 change = change.moveTo(80.milliseconds, slop, slop)
Shep Shapardad4e8152020-04-03 13:22:08 -0700376 filter::onPointerInput.invokeOverAllPasses(change)
shepshapard648840f2019-07-17 14:28:50 -0700377 // To top left
Shep Shaparde261df92019-11-15 11:24:31 -0800378 change = change.moveTo(90.milliseconds, -slop, -slop)
Shep Shapardad4e8152020-04-03 13:22:08 -0700379 filter::onPointerInput.invokeOverAllPasses(change)
shepshapard648840f2019-07-17 14:28:50 -0700380
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700381 assertThat(onDragSlopExceededCallCount).isEqualTo(0)
shepshapard648840f2019-07-17 14:28:50 -0700382 }
383
384 // Verify the circumstances under which onTouchSlopExceeded should be called.
385
386 @Test
387 fun onPointerInputChanges_movePassedSlop_onTouchSlopExceededCallOnce() {
Shep Shapard4babf792020-02-13 16:37:14 -0800388 val beyondSlop = TestTouchSlop + TinyNum
shepshapard648840f2019-07-17 14:28:50 -0700389
Shep Shapard091fd692020-01-29 16:35:47 -0800390 val down = down(0)
Shep Shapardad4e8152020-04-03 13:22:08 -0700391 filter::onPointerInput.invokeOverAllPasses(down)
shepshapard648840f2019-07-17 14:28:50 -0700392 val move = down.moveBy(
393 Duration(milliseconds = 100),
Shep Shapard4babf792020-02-13 16:37:14 -0800394 beyondSlop,
shepshapard648840f2019-07-17 14:28:50 -0700395 0f
396 )
Shep Shapardad4e8152020-04-03 13:22:08 -0700397 filter::onPointerInput.invokeOverAllPasses(move)
shepshapard648840f2019-07-17 14:28:50 -0700398
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700399 assertThat(onDragSlopExceededCallCount).isEqualTo(1)
shepshapard648840f2019-07-17 14:28:50 -0700400 }
401
402 @Test
403 fun onPointerInputChanges_movePassedSlopIn2Events_onTouchSlopExceededCallOnce() {
404
Shep Shapard091fd692020-01-29 16:35:47 -0800405 val down = down(0)
Shep Shapardad4e8152020-04-03 13:22:08 -0700406 filter::onPointerInput.invokeOverAllPasses(down)
shepshapard648840f2019-07-17 14:28:50 -0700407 val move = down.moveBy(
408 Duration(milliseconds = 100),
409 TestTouchSlop.toFloat(),
410 0f
411 )
Shep Shapardad4e8152020-04-03 13:22:08 -0700412 filter::onPointerInput.invokeOverAllPasses(move)
shepshapard648840f2019-07-17 14:28:50 -0700413 val move2 = down.moveBy(
414 Duration(milliseconds = 100),
415 1f,
416 0f
417 )
Shep Shapardad4e8152020-04-03 13:22:08 -0700418 filter::onPointerInput.invokeOverAllPasses(move2)
shepshapard648840f2019-07-17 14:28:50 -0700419
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700420 assertThat(onDragSlopExceededCallCount).isEqualTo(1)
shepshapard648840f2019-07-17 14:28:50 -0700421 }
422
423 @Test
424 fun onPointerInputChanges_passSlopThenInSlopAreaThenOut_onTouchSlopExceededCallOnce() {
Shep Shapard4babf792020-02-13 16:37:14 -0800425 val beyondSlop = TestTouchSlop + TinyNum
shepshapard648840f2019-07-17 14:28:50 -0700426
Shep Shapard091fd692020-01-29 16:35:47 -0800427 var event = down(0)
Shep Shapardad4e8152020-04-03 13:22:08 -0700428 filter::onPointerInput.invokeOverAllPasses(event)
shepshapard648840f2019-07-17 14:28:50 -0700429 // Out of touch slop region
Shep Shapard4babf792020-02-13 16:37:14 -0800430 event = event.moveBy(Duration(milliseconds = 10), 0f, beyondSlop)
Shep Shapardad4e8152020-04-03 13:22:08 -0700431 filter::onPointerInput.invokeOverAllPasses(event)
shepshapard648840f2019-07-17 14:28:50 -0700432 // Back into touch slop region
Shep Shapard4babf792020-02-13 16:37:14 -0800433 event = event.moveBy(Duration(milliseconds = 10), 0f, -beyondSlop)
Shep Shapardad4e8152020-04-03 13:22:08 -0700434 filter::onPointerInput.invokeOverAllPasses(event)
shepshapard648840f2019-07-17 14:28:50 -0700435 // Out of touch slop region again
Shep Shapard4babf792020-02-13 16:37:14 -0800436 event = event.moveBy(Duration(milliseconds = 10), 0f, beyondSlop)
Shep Shapardad4e8152020-04-03 13:22:08 -0700437 filter::onPointerInput.invokeOverAllPasses(event)
shepshapard648840f2019-07-17 14:28:50 -0700438
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700439 assertThat(onDragSlopExceededCallCount).isEqualTo(1)
shepshapard648840f2019-07-17 14:28:50 -0700440 }
441
442 @Test
443 fun onPointerInputChanges_downConsumedMovePassedSlop_onTouchSlopExceededCallOnce() {
Shep Shapard4babf792020-02-13 16:37:14 -0800444 val beyondSlop = TestTouchSlop + TinyNum
shepshapard648840f2019-07-17 14:28:50 -0700445
Shep Shapard091fd692020-01-29 16:35:47 -0800446 val down = down(0).consumeDownChange()
Shep Shapardad4e8152020-04-03 13:22:08 -0700447 filter::onPointerInput.invokeOverAllPasses(down)
Shep Shapard4babf792020-02-13 16:37:14 -0800448 val move = down.moveBy(Duration(milliseconds = 100), beyondSlop, 0f)
Shep Shapardad4e8152020-04-03 13:22:08 -0700449 filter::onPointerInput.invokeOverAllPasses(move)
shepshapard648840f2019-07-17 14:28:50 -0700450
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700451 assertThat(onDragSlopExceededCallCount).isEqualTo(1)
shepshapard648840f2019-07-17 14:28:50 -0700452 }
453
454 @Test
455 fun onPointerInputChanges_beyondInUnsupportThenBeyondInSupport_onTouchSlopExceededCallOnce() {
Shep Shapard4babf792020-02-13 16:37:14 -0800456 val beyondSlop = TestTouchSlop + TinyNum
shepshapard648840f2019-07-17 14:28:50 -0700457
Shep Shapard091fd692020-01-29 16:35:47 -0800458 var change = down(0)
Shep Shapardad4e8152020-04-03 13:22:08 -0700459 filter::onPointerInput.invokeOverAllPasses(change)
shepshapard648840f2019-07-17 14:28:50 -0700460 canDragReturn = false
461 change = change.moveBy(
462 Duration(milliseconds = 10),
463 0f,
Shep Shapard4babf792020-02-13 16:37:14 -0800464 beyondSlop
shepshapard648840f2019-07-17 14:28:50 -0700465 )
466 // Sanity check that onTouchSlopExceeded has not been called.
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700467 assertThat(onDragSlopExceededCallCount).isEqualTo(0)
shepshapard648840f2019-07-17 14:28:50 -0700468
469 canDragReturn = true
Shep Shapardad4e8152020-04-03 13:22:08 -0700470 filter::onPointerInput.invokeOverAllPasses(change)
shepshapard648840f2019-07-17 14:28:50 -0700471 change = change.moveBy(
472 Duration(milliseconds = 10),
473 0f,
Shep Shapard4babf792020-02-13 16:37:14 -0800474 -beyondSlop
shepshapard648840f2019-07-17 14:28:50 -0700475 )
Shep Shapardad4e8152020-04-03 13:22:08 -0700476 filter::onPointerInput.invokeOverAllPasses(change)
shepshapard648840f2019-07-17 14:28:50 -0700477
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700478 assertThat(onDragSlopExceededCallCount).isEqualTo(1)
shepshapard648840f2019-07-17 14:28:50 -0700479 }
480
481 @Test
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700482 fun onPointerInputChanges_2PointsMoveInOpposite_onTouchSlopExceededNotCalled() {
shepshapard648840f2019-07-17 14:28:50 -0700483
484 // Arrange
485
Shep Shapard4babf792020-02-13 16:37:14 -0800486 val beyondSlop = TestTouchSlop + TinyNum
shepshapard648840f2019-07-17 14:28:50 -0700487
488 var pointer1 = down(1)
489 var pointer2 = down(2)
Shep Shapardad4e8152020-04-03 13:22:08 -0700490 filter::onPointerInput.invokeOverAllPasses(pointer1, pointer2)
shepshapard648840f2019-07-17 14:28:50 -0700491
492 // Act
493
494 pointer1 = pointer1.moveBy(
495 Duration(milliseconds = 100),
Shep Shapard4babf792020-02-13 16:37:14 -0800496 beyondSlop,
shepshapard648840f2019-07-17 14:28:50 -0700497 0f
498 )
499 pointer2 = pointer2.moveBy(
500 Duration(milliseconds = 100),
Shep Shapard4babf792020-02-13 16:37:14 -0800501 -beyondSlop,
shepshapard648840f2019-07-17 14:28:50 -0700502 0f
503 )
Shep Shapardad4e8152020-04-03 13:22:08 -0700504 filter::onPointerInput.invokeOverAllPasses(pointer1, pointer2)
shepshapard648840f2019-07-17 14:28:50 -0700505
506 // Assert
507
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700508 assertThat(onDragSlopExceededCallCount).isEqualTo(0)
shepshapard648840f2019-07-17 14:28:50 -0700509 }
510
511 @Test
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700512 fun onPointerInputChanges_3PointsMoveAverage0_onDragSlopExceededNotCalled() {
shepshapard648840f2019-07-17 14:28:50 -0700513
514 // Arrange
515
Shep Shapard4babf792020-02-13 16:37:14 -0800516 val beyondSlop = TestTouchSlop + TinyNum
shepshapard648840f2019-07-17 14:28:50 -0700517
Shep Shapardbf513c52019-12-16 17:06:51 -0800518 val pointers = arrayOf(down(0), down(1), down(2))
Shep Shapardad4e8152020-04-03 13:22:08 -0700519 filter::onPointerInput.invokeOverAllPasses(*pointers)
shepshapard648840f2019-07-17 14:28:50 -0700520
521 // Act
522
523 // These movements average to no movement.
524 pointers[0] =
525 pointers[0].moveBy(
526 Duration(milliseconds = 100),
Shep Shapard4babf792020-02-13 16:37:14 -0800527 beyondSlop * -1,
528 beyondSlop * -1
shepshapard648840f2019-07-17 14:28:50 -0700529 )
530 pointers[1] =
531 pointers[1].moveBy(
532 Duration(milliseconds = 100),
Shep Shapard4babf792020-02-13 16:37:14 -0800533 beyondSlop * 1,
534 beyondSlop * -1
shepshapard648840f2019-07-17 14:28:50 -0700535 )
536 pointers[2] =
537 pointers[2].moveBy(
538 Duration(milliseconds = 100),
539 0f,
Shep Shapard4babf792020-02-13 16:37:14 -0800540 beyondSlop * 2
shepshapard648840f2019-07-17 14:28:50 -0700541 )
Shep Shapardad4e8152020-04-03 13:22:08 -0700542 filter::onPointerInput.invokeOverAllPasses(*pointers)
shepshapard648840f2019-07-17 14:28:50 -0700543
544 // Assert
545
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700546 assertThat(onDragSlopExceededCallCount).isEqualTo(0)
shepshapard648840f2019-07-17 14:28:50 -0700547 }
548
549 @Test
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700550 fun onPointerInputChanges_2Points1MoveJustBeyondSlop_onDragSlopExceededNotCalled() {
shepshapard648840f2019-07-17 14:28:50 -0700551
552 // Arrange
553
Shep Shapard4babf792020-02-13 16:37:14 -0800554 val beyondSlop = TestTouchSlop + TinyNum
shepshapard648840f2019-07-17 14:28:50 -0700555
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700556 var pointer1 = down(0)
557 var pointer2 = down(1)
558 filter::onPointerInput.invokeOverAllPasses(pointer1, pointer2)
shepshapard648840f2019-07-17 14:28:50 -0700559
560 // Act
561
562 // These movements average to no movement.
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700563
564 pointer1 =
565 pointer1.moveBy(
shepshapard648840f2019-07-17 14:28:50 -0700566 Duration(milliseconds = 100),
567 0f,
568 0f
569 )
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700570 pointer2 =
571 pointer2.moveBy(
shepshapard648840f2019-07-17 14:28:50 -0700572 Duration(milliseconds = 100),
Shep Shapard4babf792020-02-13 16:37:14 -0800573 beyondSlop * -1,
shepshapard648840f2019-07-17 14:28:50 -0700574 0f
575 )
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700576 filter::onPointerInput.invokeOverAllPasses(pointer1, pointer2)
shepshapard648840f2019-07-17 14:28:50 -0700577
578 // Assert
579
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700580 assertThat(onDragSlopExceededCallCount).isEqualTo(0)
shepshapard648840f2019-07-17 14:28:50 -0700581 }
582
583 @Test
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700584 fun onPointerInputChanges_2Points1MoveJustUnderTwiceSlop_onDragSlopExceededNotCalled() {
585
586 // Arrange
587
588 val beyondSlop = TestTouchSlop + TinyNum
589
590 var pointer1 = down(0)
591 var pointer2 = down(1)
592 filter::onPointerInput.invokeOverAllPasses(pointer1, pointer2)
593
594 // Act
595
596 // These movements average to no movement.
597
598 pointer1 =
599 pointer1.moveBy(
600 Duration(milliseconds = 100),
601 0f,
602 0f
603 )
604 pointer2 =
605 pointer2.moveBy(
606 Duration(milliseconds = 100),
607 beyondSlop * 2 - 1,
608 0f
609 )
610 filter::onPointerInput.invokeOverAllPasses(pointer1, pointer2)
611
612 // Assert
613
614 assertThat(onDragSlopExceededCallCount).isEqualTo(0)
615 }
616
617 @Test
618 fun onPointerInputChanges_2Points1MoveToTwiceSlop_onDragSlopExceededNotCalled() {
619
620 // Arrange
621
622 val beyondSlop = TestTouchSlop + TinyNum
623
624 var pointer1 = down(0)
625 var pointer2 = down(1)
626 filter::onPointerInput.invokeOverAllPasses(pointer1, pointer2)
627
628 // Act
629
630 // These movements average to no movement.
631
632 pointer1 =
633 pointer1.moveBy(
634 Duration(milliseconds = 100),
635 0f,
636 0f
637 )
638 pointer2 =
639 pointer2.moveBy(
640 Duration(milliseconds = 100),
641 beyondSlop * 2,
642 0f
643 )
644 filter::onPointerInput.invokeOverAllPasses(pointer1, pointer2)
645
646 // Assert
647
648 assertThat(onDragSlopExceededCallCount).isEqualTo(1)
649 }
650
651 @Test
652 fun onPointerInputChanges_1PointMovesBeyondSlopAndThenManyTimes_onDragSlopExceededCallOnce() {
shepshapard648840f2019-07-17 14:28:50 -0700653
654 // Arrange
655
Shep Shapard4babf792020-02-13 16:37:14 -0800656 val beyondSlop = TestTouchSlop + TinyNum
shepshapard648840f2019-07-17 14:28:50 -0700657
658 var pointer = down(0)
Shep Shapardad4e8152020-04-03 13:22:08 -0700659 filter::onPointerInput.invokeOverAllPasses(pointer)
shepshapard648840f2019-07-17 14:28:50 -0700660
661 // Act
662
663 repeat(5) {
Shep Shapard4babf792020-02-13 16:37:14 -0800664 pointer = pointer.moveBy(100.milliseconds, beyondSlop, beyondSlop)
Shep Shapardad4e8152020-04-03 13:22:08 -0700665 filter::onPointerInput.invokeOverAllPasses(pointer)
shepshapard648840f2019-07-17 14:28:50 -0700666 }
667
668 // Assert
669
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700670 assertThat(onDragSlopExceededCallCount).isEqualTo(1)
shepshapard648840f2019-07-17 14:28:50 -0700671 }
672
673 @Test
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700674 fun onPointerInputChanges_1ModifiedToMoveBeyondSlopBeforePostUp_onDragSlopExceededCallOnce() {
Shep Shapard4babf792020-02-13 16:37:14 -0800675 val beyondSlop = TestTouchSlop + TinyNum
shepshapard648840f2019-07-17 14:28:50 -0700676
Shep Shapard091fd692020-01-29 16:35:47 -0800677 val down = down(0)
Shep Shapardad4e8152020-04-03 13:22:08 -0700678 filter::onPointerInput.invokeOverAllPasses(down)
shepshapard648840f2019-07-17 14:28:50 -0700679
Shep Shapard4babf792020-02-13 16:37:14 -0800680 val move = down.moveBy(10.milliseconds, 0f, 0f).consume(dx = beyondSlop)
Shep Shapardad4e8152020-04-03 13:22:08 -0700681 filter::onPointerInput.invokeOverPasses(
shepshapard648840f2019-07-17 14:28:50 -0700682 listOf(move),
Shep Shapardbf513c52019-12-16 17:06:51 -0800683 listOf(
684 PointerEventPass.InitialDown,
685 PointerEventPass.PreUp,
686 PointerEventPass.PreDown,
687 PointerEventPass.PostUp
688 )
shepshapard648840f2019-07-17 14:28:50 -0700689 )
690
691 // Assert
692
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700693 assertThat(onDragSlopExceededCallCount).isEqualTo(1)
shepshapard648840f2019-07-17 14:28:50 -0700694 }
695
696 @Test
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700697 fun onPointerInputChanges_1ModedToMoveBeyondSlopBeforePostDown_onDragSlopExceededCallOnce() {
Shep Shapard4babf792020-02-13 16:37:14 -0800698 val beyondSlop = TestTouchSlop + TinyNum
shepshapard648840f2019-07-17 14:28:50 -0700699
Shep Shapard091fd692020-01-29 16:35:47 -0800700 val down = down(0)
Shep Shapardad4e8152020-04-03 13:22:08 -0700701 filter::onPointerInput.invokeOverAllPasses(down)
shepshapard648840f2019-07-17 14:28:50 -0700702
Shep Shapard091fd692020-01-29 16:35:47 -0800703 val move = down.moveBy(10.milliseconds, 0f, 0f)
Shep Shapardad4e8152020-04-03 13:22:08 -0700704 filter::onPointerInput.invokeOverPasses(
shepshapard648840f2019-07-17 14:28:50 -0700705 listOf(move),
Shep Shapardbf513c52019-12-16 17:06:51 -0800706 listOf(
707 PointerEventPass.InitialDown,
708 PointerEventPass.PreUp,
709 PointerEventPass.PreDown,
710 PointerEventPass.PostUp
711 )
shepshapard648840f2019-07-17 14:28:50 -0700712 )
713
Shep Shapard4babf792020-02-13 16:37:14 -0800714 val moveConsumed = move.consume(dx = beyondSlop)
Shep Shapardad4e8152020-04-03 13:22:08 -0700715 filter::onPointerInput.invokeOverPasses(
Shep Shapardbf513c52019-12-16 17:06:51 -0800716 moveConsumed,
shepshapard648840f2019-07-17 14:28:50 -0700717 PointerEventPass.PostDown
718 )
719
720 // Assert
721
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700722 assertThat(onDragSlopExceededCallCount).isEqualTo(1)
shepshapard648840f2019-07-17 14:28:50 -0700723 }
724
725 @Test
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700726 fun onPointerInputChanges_moveUnderToPostUpThenModOverToPostDown_onDragSlopExceededCallOnce() {
shepshapard648840f2019-07-17 14:28:50 -0700727 val halfSlop = TestTouchSlop / 2
Shep Shapard4babf792020-02-13 16:37:14 -0800728 val restOfSlopAndBeyond = TestTouchSlop - halfSlop + TinyNum
shepshapard648840f2019-07-17 14:28:50 -0700729
Shep Shapard091fd692020-01-29 16:35:47 -0800730 val down = down(0)
Shep Shapardad4e8152020-04-03 13:22:08 -0700731 filter::onPointerInput.invokeOverAllPasses(down)
shepshapard648840f2019-07-17 14:28:50 -0700732
Shep Shapard091fd692020-01-29 16:35:47 -0800733 val move = down.moveBy(10.milliseconds, halfSlop.toFloat(), 0f)
Shep Shapardad4e8152020-04-03 13:22:08 -0700734 filter::onPointerInput.invokeOverPasses(
shepshapard648840f2019-07-17 14:28:50 -0700735 listOf(move),
Shep Shapardbf513c52019-12-16 17:06:51 -0800736 listOf(
737 PointerEventPass.InitialDown,
738 PointerEventPass.PreUp,
739 PointerEventPass.PreDown,
740 PointerEventPass.PostUp
741 )
shepshapard648840f2019-07-17 14:28:50 -0700742 )
743
Shep Shapard4babf792020-02-13 16:37:14 -0800744 val moveConsumed = move.consume(dx = -restOfSlopAndBeyond)
Shep Shapardad4e8152020-04-03 13:22:08 -0700745 filter::onPointerInput.invokeOverPasses(
Shep Shapardbf513c52019-12-16 17:06:51 -0800746 moveConsumed,
shepshapard648840f2019-07-17 14:28:50 -0700747 PointerEventPass.PostDown
748 )
749
750 // Assert
751
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700752 assertThat(onDragSlopExceededCallCount).isEqualTo(1)
shepshapard648840f2019-07-17 14:28:50 -0700753 }
754
755 @Test
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700756 fun onPointerInputChanges_moveBeyondSlopAllPassesUpToPostUp_onDragSlopExceededCallOnce() {
Shep Shapard4babf792020-02-13 16:37:14 -0800757 val beyondSlop = TestTouchSlop + TinyNum
shepshapard648840f2019-07-17 14:28:50 -0700758
Shep Shapard091fd692020-01-29 16:35:47 -0800759 val down = down(0)
Shep Shapardad4e8152020-04-03 13:22:08 -0700760 filter::onPointerInput.invokeOverAllPasses(down)
shepshapard648840f2019-07-17 14:28:50 -0700761
Shep Shapard4babf792020-02-13 16:37:14 -0800762 val move = down.moveBy(10.milliseconds, beyondSlop, 0f)
Shep Shapardad4e8152020-04-03 13:22:08 -0700763 filter::onPointerInput.invokeOverPasses(
shepshapard648840f2019-07-17 14:28:50 -0700764 listOf(move),
Shep Shapardbf513c52019-12-16 17:06:51 -0800765 listOf(
766 PointerEventPass.InitialDown,
767 PointerEventPass.PreUp,
768 PointerEventPass.PreDown,
769 PointerEventPass.PostUp
770 )
shepshapard648840f2019-07-17 14:28:50 -0700771 )
772
773 // Assert
774
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700775 assertThat(onDragSlopExceededCallCount).isEqualTo(1)
shepshapard648840f2019-07-17 14:28:50 -0700776 }
777
778 // Verification that TouchSlopExceededGestureDetector does not consume any changes.
779
780 @Test
781 fun onPointerInputChanges_1Down_nothingConsumed() {
782
Shep Shapardad4e8152020-04-03 13:22:08 -0700783 val result = filter::onPointerInput.invokeOverAllPasses(down(0))
shepshapard648840f2019-07-17 14:28:50 -0700784
785 // Assert
786
Shep Shapardbf513c52019-12-16 17:06:51 -0800787 assertThat(result.consumed.downChange).isFalse()
Nader Jawade6a9b332020-05-21 13:49:20 -0700788 assertThat(result.consumed.positionChange.x).isEqualTo(0f)
789 assertThat(result.consumed.positionChange.y).isEqualTo(0f)
shepshapard648840f2019-07-17 14:28:50 -0700790 }
791
792 @Test
793 fun onPointerInputChanges_1MoveUnderSlop_nothingConsumed() {
794
Shep Shapard091fd692020-01-29 16:35:47 -0800795 val down = down(0)
Shep Shapardad4e8152020-04-03 13:22:08 -0700796 filter::onPointerInput.invokeOverAllPasses(down)
shepshapard648840f2019-07-17 14:28:50 -0700797
Shep Shapard091fd692020-01-29 16:35:47 -0800798 val move = down.moveBy(10.milliseconds, TestTouchSlop.toFloat(), TestTouchSlop.toFloat())
Shep Shapardad4e8152020-04-03 13:22:08 -0700799 val result = filter::onPointerInput.invokeOverAllPasses(move)
shepshapard648840f2019-07-17 14:28:50 -0700800
801 // Assert
802
Shep Shapardbf513c52019-12-16 17:06:51 -0800803 assertThat(result.consumed.downChange).isFalse()
Nader Jawade6a9b332020-05-21 13:49:20 -0700804 assertThat(result.consumed.positionChange.x).isEqualTo(0f)
805 assertThat(result.consumed.positionChange.y).isEqualTo(0f)
shepshapard648840f2019-07-17 14:28:50 -0700806 }
807
808 @Test
809 fun onPointerInputChanges_1MoveUnderSlopThenUp_nothingConsumed() {
810
Shep Shapard091fd692020-01-29 16:35:47 -0800811 val down = down(0)
Shep Shapardad4e8152020-04-03 13:22:08 -0700812 filter::onPointerInput.invokeOverAllPasses(down)
shepshapard648840f2019-07-17 14:28:50 -0700813
Shep Shapard091fd692020-01-29 16:35:47 -0800814 val move = down.moveBy(10.milliseconds, TestTouchSlop.toFloat(), TestTouchSlop.toFloat())
Shep Shapardad4e8152020-04-03 13:22:08 -0700815 filter::onPointerInput.invokeOverAllPasses(move)
shepshapard648840f2019-07-17 14:28:50 -0700816
Shep Shaparde261df92019-11-15 11:24:31 -0800817 val up = move.up(20.milliseconds)
Shep Shapardad4e8152020-04-03 13:22:08 -0700818 val result = filter::onPointerInput.invokeOverAllPasses(up)
shepshapard648840f2019-07-17 14:28:50 -0700819
820 // Assert
821
Shep Shapardbf513c52019-12-16 17:06:51 -0800822 assertThat(result.consumed.downChange).isFalse()
Nader Jawade6a9b332020-05-21 13:49:20 -0700823 assertThat(result.consumed.positionChange.x).isEqualTo(0f)
824 assertThat(result.consumed.positionChange.y).isEqualTo(0f)
shepshapard648840f2019-07-17 14:28:50 -0700825 }
826
827 @Test
828 fun onPointerInputChanges_1MoveOverSlop_nothingConsumed() {
Shep Shapard4babf792020-02-13 16:37:14 -0800829 val beyondSlop = TestTouchSlop + TinyNum
shepshapard648840f2019-07-17 14:28:50 -0700830
Shep Shapard091fd692020-01-29 16:35:47 -0800831 val down = down(0)
Shep Shapardad4e8152020-04-03 13:22:08 -0700832 filter::onPointerInput.invokeOverAllPasses(down)
shepshapard648840f2019-07-17 14:28:50 -0700833
Shep Shapard4babf792020-02-13 16:37:14 -0800834 val move = down.moveBy(10.milliseconds, beyondSlop, beyondSlop)
Shep Shapardad4e8152020-04-03 13:22:08 -0700835 val result = filter::onPointerInput.invokeOverAllPasses(move)
shepshapard648840f2019-07-17 14:28:50 -0700836
837 // Assert
838
Shep Shapardbf513c52019-12-16 17:06:51 -0800839 assertThat(result.consumed.downChange).isFalse()
Nader Jawade6a9b332020-05-21 13:49:20 -0700840 assertThat(result.consumed.positionChange.x).isEqualTo(0f)
841 assertThat(result.consumed.positionChange.y).isEqualTo(0f)
shepshapard648840f2019-07-17 14:28:50 -0700842 }
843
844 @Test
845 fun onPointerInputChanges_1MoveOverSlopThenUp_nothingConsumed() {
Shep Shapard4babf792020-02-13 16:37:14 -0800846 val beyondSlop = TestTouchSlop + TinyNum
shepshapard648840f2019-07-17 14:28:50 -0700847
Shep Shapard091fd692020-01-29 16:35:47 -0800848 val down = down(0)
Shep Shapardad4e8152020-04-03 13:22:08 -0700849 filter::onPointerInput.invokeOverAllPasses(down)
shepshapard648840f2019-07-17 14:28:50 -0700850
Shep Shapard4babf792020-02-13 16:37:14 -0800851 val move = down.moveBy(10.milliseconds, beyondSlop, beyondSlop)
Shep Shapardad4e8152020-04-03 13:22:08 -0700852 filter::onPointerInput.invokeOverAllPasses(move)
shepshapard648840f2019-07-17 14:28:50 -0700853
Shep Shaparde261df92019-11-15 11:24:31 -0800854 val up = move.up(20.milliseconds)
Shep Shapardad4e8152020-04-03 13:22:08 -0700855 val result = filter::onPointerInput.invokeOverAllPasses(up)
shepshapard648840f2019-07-17 14:28:50 -0700856
857 // Assert
858
Shep Shapardbf513c52019-12-16 17:06:51 -0800859 assertThat(result.consumed.downChange).isFalse()
Nader Jawade6a9b332020-05-21 13:49:20 -0700860 assertThat(result.consumed.positionChange.x).isEqualTo(0f)
861 assertThat(result.consumed.positionChange.y).isEqualTo(0f)
shepshapard648840f2019-07-17 14:28:50 -0700862 }
863
864 // Verification that TouchSlopExceededGestureDetector resets after up correctly.
865
866 @Test
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700867 fun onPointerInputChanges_MoveBeyondUpDownMoveBeyond_onDragSlopExceededCalledTwice() {
Shep Shapard4babf792020-02-13 16:37:14 -0800868 val beyondSlop = TestTouchSlop + TinyNum
shepshapard648840f2019-07-17 14:28:50 -0700869
870 repeat(2) {
Shep Shapard091fd692020-01-29 16:35:47 -0800871 val down = down(0)
Shep Shapardad4e8152020-04-03 13:22:08 -0700872 filter::onPointerInput.invokeOverAllPasses(down)
shepshapard648840f2019-07-17 14:28:50 -0700873
Shep Shapard4babf792020-02-13 16:37:14 -0800874 val move = down.moveBy(10.milliseconds, beyondSlop, 0f)
Shep Shapardad4e8152020-04-03 13:22:08 -0700875 filter::onPointerInput.invokeOverAllPasses(move)
shepshapard648840f2019-07-17 14:28:50 -0700876
Shep Shaparde261df92019-11-15 11:24:31 -0800877 val up = move.up(20.milliseconds)
Shep Shapardad4e8152020-04-03 13:22:08 -0700878 filter::onPointerInput.invokeOverAllPasses(up)
shepshapard648840f2019-07-17 14:28:50 -0700879 }
880
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700881 assertThat(onDragSlopExceededCallCount).isEqualTo(2)
shepshapard648840f2019-07-17 14:28:50 -0700882 }
Shep Shapardbf513c52019-12-16 17:06:51 -0800883
884 // Verification that cancellation behavior is correct.
885
886 @Test
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700887 fun onCancel_underSlopCancelUnderSlop_onDragSlopExceededNotCalled() {
Shep Shapard4babf792020-02-13 16:37:14 -0800888 val underSlop = TestTouchSlop - TinyNum
Shep Shapardbf513c52019-12-16 17:06:51 -0800889
890 // Arrange
891
892 var pointer = down(0, 0.milliseconds, 0f, 0f)
Shep Shapardad4e8152020-04-03 13:22:08 -0700893 filter::onPointerInput.invokeOverAllPasses(pointer)
Shep Shapardbf513c52019-12-16 17:06:51 -0800894
895 pointer = pointer.moveTo(
896 10.milliseconds,
Shep Shapard4babf792020-02-13 16:37:14 -0800897 underSlop,
Shep Shapardbf513c52019-12-16 17:06:51 -0800898 0f
899 )
Shep Shapardad4e8152020-04-03 13:22:08 -0700900 filter::onPointerInput.invokeOverAllPasses(pointer)
Shep Shapardbf513c52019-12-16 17:06:51 -0800901
902 // Act
903
Shep Shapardad4e8152020-04-03 13:22:08 -0700904 filter.onCancel()
Shep Shapardbf513c52019-12-16 17:06:51 -0800905
906 pointer = down(0, 0.milliseconds, 0f, 0f)
Shep Shapardad4e8152020-04-03 13:22:08 -0700907 filter::onPointerInput.invokeOverAllPasses(pointer)
Shep Shapardbf513c52019-12-16 17:06:51 -0800908
909 pointer = pointer.moveTo(
910 10.milliseconds,
Shep Shapard4babf792020-02-13 16:37:14 -0800911 underSlop,
Shep Shapardbf513c52019-12-16 17:06:51 -0800912 0f
913 )
Shep Shapardad4e8152020-04-03 13:22:08 -0700914 filter::onPointerInput.invokeOverAllPasses(pointer)
Shep Shapardbf513c52019-12-16 17:06:51 -0800915
916 // Assert
917
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700918 assertThat(onDragSlopExceededCallCount).isEqualTo(0)
Shep Shapardbf513c52019-12-16 17:06:51 -0800919 }
920
921 @Test
Shep Shapard6c9f1da2020-03-24 14:12:35 -0700922 fun onCancel_pastSlopCancelPastSlop_onScaleSlopExceededCalledTwice() {
Shep Shapard4babf792020-02-13 16:37:14 -0800923 val overSlop = TestTouchSlop + TinyNum
Shep Shapardbf513c52019-12-16 17:06:51 -0800924
925 // Arrange
926
927 var pointer = down(0, 0.milliseconds, 0f, 0f)
Shep Shapardad4e8152020-04-03 13:22:08 -0700928 filter::onPointerInput.invokeOverAllPasses(pointer)
Shep Shapardbf513c52019-12-16 17:06:51 -0800929
930 pointer = pointer.moveTo(
931 10.milliseconds,
Shep Shapard4babf792020-02-13 16:37:14 -0800932 overSlop,
Shep Shapardbf513c52019-12-16 17:06:51 -0800933 0f
934 )
Shep Shapardad4e8152020-04-03 13:22:08 -0700935 filter::onPointerInput.invokeOverAllPasses(pointer)
Shep Shapardbf513c52019-12-16 17:06:51 -0800936
937 // Act
938
Shep Shapardad4e8152020-04-03 13:22:08 -0700939 filter.onCancel()
Shep Shapardbf513c52019-12-16 17:06:51 -0800940
941 pointer = down(0, 0.milliseconds, 0f, 0f)
Shep Shapardad4e8152020-04-03 13:22:08 -0700942 filter::onPointerInput.invokeOverAllPasses(pointer)
Shep Shapardbf513c52019-12-16 17:06:51 -0800943
944 pointer = pointer.moveTo(
945 10.milliseconds,
Shep Shapard4babf792020-02-13 16:37:14 -0800946 overSlop,
Shep Shapardbf513c52019-12-16 17:06:51 -0800947 0f
948 )
Shep Shapardad4e8152020-04-03 13:22:08 -0700949 filter::onPointerInput.invokeOverAllPasses(pointer)
Shep Shapardbf513c52019-12-16 17:06:51 -0800950
951 // Assert
952
Shep Shaparddd9e2bc2020-05-19 15:25:36 -0700953 assertThat(onDragSlopExceededCallCount).isEqualTo(2)
Shep Shapardbf513c52019-12-16 17:06:51 -0800954 }
shepshapard648840f2019-07-17 14:28:50 -0700955}