blob: 00c1945279aad8c7f513670a7e4d3e947b957c68 [file]
/*
* Copyright (C) 2024 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 com.android.mechanics.spec
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.mechanics.spring.SpringParameters
import com.android.mechanics.testing.BreakpointSubject.Companion.assertThat
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class MotionSpecTest {
@Test
fun containsSegment_unknownSegment_returnsFalse() {
val underTest = MotionSpec.builder(spring).complete()
assertThat(underTest.containsSegment(SegmentKey(b1, b2, InputDirection.Max))).isFalse()
}
@Test
fun containsSegment_symmetricSpec_knownSegment_returnsTrue() {
val underTest =
MotionSpec.builder(spring)
.toBreakpoint(10f, key = b1)
.continueWith(Mapping.One)
.toBreakpoint(20f, key = b2)
.completeWith(Mapping.Identity)
assertThat(underTest.containsSegment(SegmentKey(b1, b2, InputDirection.Max))).isTrue()
assertThat(underTest.containsSegment(SegmentKey(b1, b2, InputDirection.Min))).isTrue()
}
@Test
fun containsSegment_asymmetricSpec_knownMaxDirectionSegment_trueOnlyInMaxDirection() {
val forward =
DirectionalMotionSpec.builder(spring)
.toBreakpoint(10f, key = b1)
.continueWith(Mapping.One)
.toBreakpoint(20f, key = b2)
.completeWith(Mapping.Identity)
val reverse = DirectionalMotionSpec.builder(spring).complete()
val underTest = MotionSpec(forward, reverse)
assertThat(underTest.containsSegment(SegmentKey(b1, b2, InputDirection.Max))).isTrue()
assertThat(underTest.containsSegment(SegmentKey(b1, b2, InputDirection.Min))).isFalse()
}
@Test
fun containsSegment_asymmetricSpec_knownMinDirectionSegment_trueOnlyInMinDirection() {
val forward = DirectionalMotionSpec.builder(spring).complete()
val reverse =
DirectionalMotionSpec.builder(spring)
.toBreakpoint(10f, key = b1)
.continueWith(Mapping.One)
.toBreakpoint(20f, key = b2)
.completeWith(Mapping.Identity)
val underTest = MotionSpec(forward, reverse)
assertThat(underTest.containsSegment(SegmentKey(b1, b2, InputDirection.Max))).isFalse()
assertThat(underTest.containsSegment(SegmentKey(b1, b2, InputDirection.Min))).isTrue()
}
@Test
fun segmentAtInput_emptySpec_maxDirection_segmentDataIsCorrect() {
val underTest = MotionSpec.builder(spring).complete()
val segmentAtInput = underTest.segmentAtInput(0f, InputDirection.Max)
assertThat(segmentAtInput.spec).isSameInstanceAs(underTest)
assertThat(segmentAtInput.minBreakpoint).isSameInstanceAs(Breakpoint.minLimit)
assertThat(segmentAtInput.maxBreakpoint).isSameInstanceAs(Breakpoint.maxLimit)
assertThat(segmentAtInput.direction).isEqualTo(InputDirection.Max)
assertThat(segmentAtInput.mapping).isEqualTo(Mapping.Identity)
}
@Test
fun segmentAtInput_emptySpec_minDirection_segmentDataIsCorrect() {
val underTest = MotionSpec.builder(spring).complete()
val segmentAtInput = underTest.segmentAtInput(0f, InputDirection.Min)
assertThat(segmentAtInput.spec).isSameInstanceAs(underTest)
assertThat(segmentAtInput.minBreakpoint).isSameInstanceAs(Breakpoint.minLimit)
assertThat(segmentAtInput.maxBreakpoint).isSameInstanceAs(Breakpoint.maxLimit)
assertThat(segmentAtInput.direction).isEqualTo(InputDirection.Min)
assertThat(segmentAtInput.mapping).isEqualTo(Mapping.Identity)
}
@Test
fun segmentAtInput_atBreakpointPosition() {
val underTest =
MotionSpec.builder(spring)
.toBreakpoint(10f, key = b1)
.continueWith(Mapping.One)
.toBreakpoint(20f, key = b2)
.completeWith(Mapping.Identity)
val segmentAtInput = underTest.segmentAtInput(10f, InputDirection.Max)
assertThat(segmentAtInput.key).isEqualTo(SegmentKey(b1, b2, InputDirection.Max))
assertThat(segmentAtInput.minBreakpoint).isAt(10f)
assertThat(segmentAtInput.maxBreakpoint).isAt(20f)
assertThat(segmentAtInput.mapping).isEqualTo(Mapping.One)
}
@Test
fun segmentAtInput_reverse_atBreakpointPosition() {
val underTest =
MotionSpec.builder(spring)
.toBreakpoint(10f, key = b1)
.continueWith(Mapping.One)
.toBreakpoint(20f, key = b2)
.completeWith(Mapping.Identity)
val segmentAtInput = underTest.segmentAtInput(20f, InputDirection.Min)
assertThat(segmentAtInput.key).isEqualTo(SegmentKey(b1, b2, InputDirection.Min))
assertThat(segmentAtInput.minBreakpoint).isAt(10f)
assertThat(segmentAtInput.maxBreakpoint).isAt(20f)
assertThat(segmentAtInput.mapping).isEqualTo(Mapping.One)
}
@Test
fun containsSegment_asymmetricSpec_readsFromIndicatedDirection() {
val forward =
DirectionalMotionSpec.builder(spring)
.toBreakpoint(10f, key = b1)
.continueWith(Mapping.One)
.toBreakpoint(20f, key = b2)
.completeWith(Mapping.Identity)
val reverse =
DirectionalMotionSpec.builder(spring)
.toBreakpoint(5f, key = b1)
.continueWith(Mapping.Two)
.toBreakpoint(25f, key = b2)
.completeWith(Mapping.Identity)
val underTest = MotionSpec(forward, reverse)
val segmentAtInputMax = underTest.segmentAtInput(15f, InputDirection.Max)
assertThat(segmentAtInputMax.key).isEqualTo(SegmentKey(b1, b2, InputDirection.Max))
assertThat(segmentAtInputMax.minBreakpoint).isAt(10f)
assertThat(segmentAtInputMax.maxBreakpoint).isAt(20f)
assertThat(segmentAtInputMax.mapping).isEqualTo(Mapping.One)
val segmentAtInputMin = underTest.segmentAtInput(15f, InputDirection.Min)
assertThat(segmentAtInputMin.key).isEqualTo(SegmentKey(b1, b2, InputDirection.Min))
assertThat(segmentAtInputMin.minBreakpoint).isAt(5f)
assertThat(segmentAtInputMin.maxBreakpoint).isAt(25f)
assertThat(segmentAtInputMin.mapping).isEqualTo(Mapping.Two)
}
@Test
fun onSegmentChanged_noHandler_returnsEqualSegmentForSameInput() {
val underTest =
MotionSpec.builder(spring)
.toBreakpoint(10f, key = b1)
.continueWith(Mapping.One)
.toBreakpoint(20f, key = b2)
.completeWith(Mapping.Identity)
val segmentAtInput = underTest.segmentAtInput(15f, InputDirection.Max)
val onChangedResult = underTest.onChangeSegment(segmentAtInput, 15f, InputDirection.Max)
assertThat(segmentAtInput).isEqualTo(onChangedResult)
}
@Test
fun onSegmentChanged_noHandler_returnsNewSegmentForNewInput() {
val underTest =
MotionSpec.builder(spring)
.toBreakpoint(10f, key = b1)
.continueWith(Mapping.One)
.toBreakpoint(20f, key = b2)
.completeWith(Mapping.Identity)
val segmentAtInput = underTest.segmentAtInput(15f, InputDirection.Max)
val onChangedResult = underTest.onChangeSegment(segmentAtInput, 15f, InputDirection.Min)
assertThat(segmentAtInput).isNotEqualTo(onChangedResult)
assertThat(onChangedResult.key).isEqualTo(SegmentKey(b1, b2, InputDirection.Min))
}
@Test
fun onSegmentChanged_withHandlerReturningNull_returnsSegmentAtInput() {
val underTest =
MotionSpec.builder(spring)
.toBreakpoint(10f, key = b1)
.continueWith(Mapping.One)
.toBreakpoint(20f, key = b2)
.completeWith(Mapping.Identity)
.copy(
segmentHandlers =
mapOf(SegmentKey(b1, b2, InputDirection.Max) to { _, _, _ -> null })
)
val segmentAtInput = underTest.segmentAtInput(15f, InputDirection.Max)
val onChangedResult = underTest.onChangeSegment(segmentAtInput, 15f, InputDirection.Min)
assertThat(segmentAtInput).isNotEqualTo(onChangedResult)
assertThat(onChangedResult.key).isEqualTo(SegmentKey(b1, b2, InputDirection.Min))
}
@Test
fun onSegmentChanged_withHandlerReturningSegment_returnsHandlerResult() {
val underTest =
MotionSpec.builder(spring)
.toBreakpoint(10f, key = b1)
.continueWith(Mapping.One)
.toBreakpoint(20f, key = b2)
.completeWith(Mapping.Identity)
.copy(
segmentHandlers =
mapOf(
SegmentKey(b1, b2, InputDirection.Max) to
{ _, _, _ ->
segmentAtInput(0f, InputDirection.Min)
}
)
)
val segmentAtInput = underTest.segmentAtInput(15f, InputDirection.Max)
val onChangedResult = underTest.onChangeSegment(segmentAtInput, 15f, InputDirection.Min)
assertThat(segmentAtInput).isNotEqualTo(onChangedResult)
assertThat(onChangedResult.key)
.isEqualTo(SegmentKey(Breakpoint.minLimit.key, b1, InputDirection.Min))
}
companion object {
val b1 = BreakpointKey("one")
val b2 = BreakpointKey("two")
val b3 = BreakpointKey("three")
val spring = SpringParameters(stiffness = 100f, dampingRatio = 1f)
}
}