[go: nahoru, domu]

blob: 13db79181d1d3198bf703ffabde4c40e5d19aa45 [file] [log] [blame]
Jelle Fresenae8fbfc2020-06-02 17:54:26 +01001/*
2 * Copyright 2020 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.test.inputdispatcher
18
19import android.view.MotionEvent.ACTION_DOWN
20import android.view.MotionEvent.ACTION_MOVE
21import android.view.MotionEvent.ACTION_UP
22import androidx.test.filters.SmallTest
Jelle Fresen4c25bda2020-06-15 19:29:59 +010023import androidx.ui.test.InputDispatcher.InputDispatcherTestRule
Jelle Fresenae8fbfc2020-06-02 17:54:26 +010024import androidx.ui.test.android.AndroidInputDispatcher
25import androidx.ui.test.util.MotionEventRecorder
26import androidx.ui.test.util.assertHasValidEventTimes
27import androidx.ui.test.util.verify
28import androidx.ui.unit.Duration
Jelle Fresenae8fbfc2020-06-02 17:54:26 +010029import androidx.ui.unit.inMilliseconds
30import androidx.ui.unit.milliseconds
31import com.google.common.truth.Truth.assertThat
32import org.junit.After
33import org.junit.Before
34import org.junit.Rule
35import org.junit.Test
36import org.junit.rules.TestRule
37import org.junit.runner.RunWith
38import org.junit.runners.Parameterized
39
40/**
41 * Tests if the [AndroidInputDispatcher.sendSwipe] gesture works when specifying the gesture as a
42 * function between two positions. Verifies if the generated MotionEvents for a gesture with a
43 * given duration and a set of keyTimes have the expected timestamps. The timestamps should
44 * include all keyTimes, and divide the duration between those keyTimes as equally as possible
45 * with as close to [AndroidInputDispatcher.eventPeriod] between each successive event as possible.
46 */
47@SmallTest
48@RunWith(Parameterized::class)
49class SendSwipeWithKeyTimesTest(private val config: TestConfig) {
50 data class TestConfig(
51 val duration: Duration,
52 val keyTimes: List<Long>,
53 val expectedTimestamps: List<Long>
54 )
55
56 companion object {
57 private val curve = { t: Long ->
Nader Jawad6df06122020-06-03 15:27:08 -070058 androidx.ui.geometry.Offset(t.toFloat(), (-t).toFloat())
Jelle Fresenae8fbfc2020-06-02 17:54:26 +010059 }
60
61 @JvmStatic
62 @Parameterized.Parameters(name = "{0}")
63 fun createTestSet(): List<TestConfig> {
64 return listOf(
65 // 10.ms normally splits into 1 event, but here we add a keyTime that must yield
66 // an event at that time
67 TestConfig(10.milliseconds, listOf(1), listOf(1, 10)),
68 TestConfig(10.milliseconds, listOf(2), listOf(2, 10)),
69 TestConfig(10.milliseconds, listOf(3), listOf(3, 10)),
70 TestConfig(10.milliseconds, listOf(4), listOf(4, 10)),
71 TestConfig(10.milliseconds, listOf(5), listOf(5, 10)),
72 TestConfig(10.milliseconds, listOf(6), listOf(6, 10)),
73 TestConfig(10.milliseconds, listOf(7), listOf(7, 10)),
74 TestConfig(10.milliseconds, listOf(8), listOf(8, 10)),
75 TestConfig(10.milliseconds, listOf(9), listOf(9, 10)),
76 // With 2 keyTimes we expect to see both those keyTimes in the generated events
77 TestConfig(10.milliseconds, listOf(1, 9), listOf(1, 9, 10)),
78 // Same for 3 keyTimes
79 TestConfig(10.milliseconds, listOf(1, 5, 9), listOf(1, 5, 9, 10)),
80 // If two keyTimes are longer than eventPeriod apart from each other, that period
81 // must be split as usual (here: between 10 and 28)
82 TestConfig(30.milliseconds, listOf(5, 10, 28), listOf(5, 10, 19, 28, 30))
83 )
84 }
85 }
86
87 @get:Rule
Jelle Fresen4c25bda2020-06-15 19:29:59 +010088 val inputDispatcherRule: TestRule = InputDispatcherTestRule(disableDispatchInRealTime = true)
Jelle Fresenae8fbfc2020-06-02 17:54:26 +010089
90 private val recorder = MotionEventRecorder()
91 private val subject = AndroidInputDispatcher(recorder::recordEvent)
92
93 @Before
94 fun setUp() {
95 require(config.keyTimes.distinct() == config.keyTimes.distinct().sorted()) {
96 "keyTimes needs to be sorted, not ${config.keyTimes}"
97 }
98 }
99
100 @After
101 fun tearDown() {
102 recorder.disposeEvents()
103 }
104
105 @Test
106 fun swipeWithKeyTimes() {
107 // Given a swipe with a given duration and set of keyTimes
108 subject.sendSwipe(curve = curve, duration = config.duration, keyTimes = config.keyTimes)
109
110 // then
111 val expectedNumberOfMoveEvents = config.expectedTimestamps.size
112 recorder.assertHasValidEventTimes()
113 recorder.events.apply {
114 // down + up + #move
115 assertThat(size).isEqualTo(2 + expectedNumberOfMoveEvents)
116
117 val durationMs = config.duration.inMilliseconds()
118 // First is down, last is up
119 first().verify(curve, ACTION_DOWN, expectedRelativeTime = 0)
120 last().verify(curve, ACTION_UP, expectedRelativeTime = durationMs)
121 // In between are all move events with the expected timestamps
122 drop(1).zip(config.expectedTimestamps).forEach { (event, expectedTimestamp) ->
123 event.verify(curve, ACTION_MOVE, expectedRelativeTime = expectedTimestamp)
124 }
125 }
126 }
127}