[go: nahoru, domu]

blob: 51b360e746becafceae339655872f6091c8773f0 [file] [log] [blame]
/*
* Copyright 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.ui.test.util
import androidx.ui.core.PointerEventPass
import androidx.ui.core.PointerId
import androidx.ui.core.PointerInputChange
import androidx.ui.core.PointerInputData
import androidx.ui.core.gesture.util.VelocityTracker
import androidx.ui.core.pointerinput.PointerInputFilter
import androidx.ui.core.pointerinput.PointerInputModifier
import androidx.ui.test.util.PointerInputRecorder.DataPoint
import androidx.ui.unit.Duration
import androidx.ui.unit.IntPxSize
import androidx.ui.unit.PxPosition
import androidx.ui.unit.Uptime
import com.google.common.truth.Truth.assertThat
class PointerInputRecorder : PointerInputModifier {
data class DataPoint(val id: PointerId, val data: PointerInputData) {
val timestamp get() = data.uptime!!
val position get() = data.position!!
val x get() = data.position!!.x
val y get() = data.position!!.y
val down get() = data.down
}
private val _events = mutableListOf<DataPoint>()
val events get() = _events as List<DataPoint>
private val velocityTracker = VelocityTracker()
val recordedVelocity get() = velocityTracker.calculateVelocity()
override val pointerInputFilter = RecordingFilter {
_events.add(DataPoint(it.id, it.current))
velocityTracker.addPosition(it.current.uptime!!, it.current.position!!)
}
}
class RecordingFilter(private val record: (PointerInputChange) -> Unit) : PointerInputFilter() {
override fun onPointerInput(
changes: List<PointerInputChange>,
pass: PointerEventPass,
bounds: IntPxSize
): List<PointerInputChange> {
if (pass == PointerEventPass.InitialDown) {
changes.forEach {
record(it)
}
}
return changes
}
override fun onCancel() {
// Do nothing
}
}
fun Uptime.inMilliseconds(): Long = nanoseconds / 1_000_000
val PointerInputRecorder.downEvents get() = events.filter { it.down }
val PointerInputRecorder.recordedDuration: Duration
get() {
check(events.isNotEmpty()) { "No events recorded" }
return events.last().timestamp - events.first().timestamp
}
fun PointerInputRecorder.assertTimestampsAreIncreasing() {
check(events.isNotEmpty()) { "No events recorded" }
events.reduce { prev, curr ->
assertThat(curr.timestamp).isAtLeast(prev.timestamp)
curr
}
}
fun PointerInputRecorder.assertOnlyLastEventIsUp() {
check(events.isNotEmpty()) { "No events recorded" }
assertThat(events.last().down).isFalse()
assertThat(events.count { !it.down }).isEqualTo(1)
}
/**
* Checks that the coordinates are progressing in a monotonous direction
*/
fun List<DataPoint>.isMonotonousBetween(start: PxPosition, end: PxPosition) {
map { it.x.value }.isMonotonousBetween(start.x.value, end.x.value, 1e-3f)
map { it.y.value }.isMonotonousBetween(start.y.value, end.y.value, 1e-3f)
}
/**
* Verifies that all [DataPoint]s in the list are equal to the given position, with a tolerance
* of 0.001
*/
fun List<DataPoint>.areAlmostEqualTo(position: PxPosition) {
forEach { it.position.isAlmostEqualTo(position, 1e-3f) }
}