[go: nahoru, domu]

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