Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (C) 2017 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 
     17 package androidx.dynamicanimation.tests;
     18 
     19 import static org.junit.Assert.assertEquals;
     20 import static org.junit.Assert.assertTrue;
     21 import static org.mockito.Matchers.eq;
     22 import static org.mockito.Matchers.floatThat;
     23 import static org.mockito.Mockito.mock;
     24 import static org.mockito.Mockito.timeout;
     25 import static org.mockito.Mockito.verify;
     26 
     27 import android.support.test.InstrumentationRegistry;
     28 import android.support.test.filters.MediumTest;
     29 import android.support.test.rule.ActivityTestRule;
     30 import android.support.test.runner.AndroidJUnit4;
     31 import android.view.View;
     32 
     33 import androidx.dynamicanimation.animation.DynamicAnimation;
     34 import androidx.dynamicanimation.animation.FlingAnimation;
     35 import androidx.dynamicanimation.animation.FloatPropertyCompat;
     36 import androidx.dynamicanimation.animation.FloatValueHolder;
     37 import androidx.dynamicanimation.test.R;
     38 
     39 import org.junit.Before;
     40 import org.junit.Rule;
     41 import org.junit.Test;
     42 import org.junit.rules.ExpectedException;
     43 import org.junit.runner.RunWith;
     44 import org.mockito.internal.matchers.GreaterThan;
     45 import org.mockito.internal.matchers.LessThan;
     46 
     47 @MediumTest
     48 @RunWith(AndroidJUnit4.class)
     49 public class FlingTests {
     50     @Rule
     51     public final ActivityTestRule<AnimationActivity> mActivityTestRule;
     52     public View mView1;
     53     public View mView2;
     54 
     55     @Rule
     56     public ExpectedException mExpectedException = ExpectedException.none();
     57 
     58     public FlingTests() {
     59         mActivityTestRule = new ActivityTestRule<>(AnimationActivity.class);
     60     }
     61 
     62     @Before
     63     public void setup() throws Exception {
     64         mView1 = mActivityTestRule.getActivity().findViewById(R.id.anim_view);
     65         mView2 = mActivityTestRule.getActivity().findViewById(R.id.anim_another_view);
     66     }
     67 
     68     /**
     69      * Test that custom properties are supported.
     70      */
     71     @Test
     72     public void testCustomProperties() {
     73         final Object animObj = new Object();
     74         FloatPropertyCompat property = new FloatPropertyCompat("") {
     75             private float mValue = 0f;
     76             @Override
     77             public float getValue(Object object) {
     78                 assertEquals(animObj, object);
     79                 return mValue;
     80             }
     81 
     82             @Override
     83             public void setValue(Object object, float value) {
     84                 assertEquals(animObj, object);
     85                 assertTrue(value > mValue);
     86                 assertTrue(value >= 100);
     87                 mValue = value;
     88             }
     89         };
     90         final FlingAnimation anim = new FlingAnimation(animObj, property);
     91         DynamicAnimation.OnAnimationEndListener listener = mock(
     92                 DynamicAnimation.OnAnimationEndListener.class);
     93         anim.addEndListener(listener);
     94         InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
     95             @Override
     96             public void run() {
     97                 anim.setStartValue(100).setStartVelocity(2000).start();
     98             }
     99         });
    100         verify(listener, timeout(1000)).onAnimationEnd(eq(anim), eq(false), floatThat(
    101                 new GreaterThan(110f)), eq(0f));
    102     }
    103 
    104     /**
    105      * Test that spring animation can work with a single property without an object.
    106      */
    107     @Test
    108     public void testFloatValueHolder() {
    109         FloatValueHolder floatValueHolder = new FloatValueHolder();
    110         assertEquals(0.0f, floatValueHolder.getValue(), 0.01f);
    111 
    112         final FlingAnimation anim = new FlingAnimation(floatValueHolder).setStartVelocity(-2500);
    113 
    114         DynamicAnimation.OnAnimationEndListener listener = mock(
    115                 DynamicAnimation.OnAnimationEndListener.class);
    116         anim.addEndListener(listener);
    117         InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
    118             @Override
    119             public void run() {
    120                 anim.start();
    121             }
    122         });
    123         verify(listener, timeout(1000)).onAnimationEnd(eq(anim), eq(false), floatThat(
    124                 new LessThan(-50f)), eq(0f));
    125     }
    126 
    127 
    128     /**
    129      * Test that friction does affect how fast the slow down happens. Fling animation with
    130      * higher friction should finish first.
    131      */
    132     @Test
    133     public void testFriction() {
    134         FloatValueHolder floatValueHolder = new FloatValueHolder();
    135         float lowFriction = 0.5f;
    136         float highFriction = 2f;
    137         final FlingAnimation animLowFriction = new FlingAnimation(floatValueHolder);
    138         final FlingAnimation animHighFriction = new FlingAnimation(floatValueHolder);
    139 
    140         animHighFriction.setFriction(highFriction);
    141         animLowFriction.setFriction(lowFriction);
    142 
    143         DynamicAnimation.OnAnimationEndListener listener = mock(
    144                 DynamicAnimation.OnAnimationEndListener.class);
    145         animHighFriction.addEndListener(listener);
    146         InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
    147             @Override
    148             public void run() {
    149                 animHighFriction.setStartVelocity(5000).setStartValue(0).start();
    150                 animLowFriction.setStartVelocity(5000).setStartValue(0).start();
    151             }
    152         });
    153 
    154         verify(listener, timeout(1000)).onAnimationEnd(eq(animHighFriction), eq(false), floatThat(
    155                 new GreaterThan(200f)), eq(0f));
    156         // By the time high scalar animation finishes, the lower friction animation should still be
    157         // running.
    158         assertTrue(animLowFriction.isRunning());
    159         InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
    160             @Override
    161             public void run() {
    162                 animLowFriction.cancel();
    163             }
    164         });
    165 
    166         assertEquals(lowFriction, animLowFriction.getFriction(), 0f);
    167         assertEquals(highFriction, animHighFriction.getFriction(), 0f);
    168 
    169     }
    170 
    171     /**
    172      * Test that velocity threshold does affect how early fling animation ends. An animation with
    173      * higher velocity threshold should finish first.
    174      */
    175     @Test
    176     public void testVelocityThreshold() {
    177         FloatValueHolder floatValueHolder = new FloatValueHolder();
    178         float lowThreshold = 5f;
    179         final float highThreshold = 10f;
    180         final FlingAnimation animLowThreshold = new FlingAnimation(floatValueHolder);
    181         final FlingAnimation animHighThreshold = new FlingAnimation(floatValueHolder);
    182 
    183         animHighThreshold.setMinimumVisibleChange(highThreshold);
    184         animHighThreshold.addUpdateListener(new DynamicAnimation.OnAnimationUpdateListener() {
    185             @Override
    186             public void onAnimationUpdate(DynamicAnimation animation, float value, float velocity) {
    187                 if (velocity != 0f) {
    188                     // Other than last frame, velocity should always be above threshold
    189                     assertTrue(velocity >= highThreshold);
    190                 }
    191             }
    192         });
    193         animLowThreshold.setMinimumVisibleChange(lowThreshold);
    194 
    195         DynamicAnimation.OnAnimationEndListener listener = mock(
    196                 DynamicAnimation.OnAnimationEndListener.class);
    197         animHighThreshold.addEndListener(listener);
    198         InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
    199             @Override
    200             public void run() {
    201                 animHighThreshold.setStartVelocity(2000).setStartValue(0).start();
    202                 animLowThreshold.setStartVelocity(2000).setStartValue(0).start();
    203             }
    204         });
    205 
    206         verify(listener, timeout(1000)).onAnimationEnd(eq(animHighThreshold), eq(false), floatThat(
    207                 new GreaterThan(200f)), eq(0f));
    208         // By the time high scalar animation finishes, the lower friction animation should still be
    209         // running.
    210         assertTrue(animLowThreshold.isRunning());
    211         InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
    212             @Override
    213             public void run() {
    214                 animLowThreshold.cancel();
    215             }
    216         });
    217 
    218         assertEquals(lowThreshold, animLowThreshold.getMinimumVisibleChange(), 0f);
    219         assertEquals(highThreshold, animHighThreshold.getMinimumVisibleChange(), 0f);
    220 
    221     }
    222 }
    223