1/* 2 * Copyright 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 17package androidx.recyclerview.selection; 18 19import static org.junit.Assert.assertEquals; 20import static org.junit.Assert.assertNotNull; 21import static org.junit.Assert.assertNull; 22 23import android.graphics.Point; 24import android.support.test.filters.SmallTest; 25import android.support.test.runner.AndroidJUnit4; 26 27import androidx.annotation.Nullable; 28import androidx.recyclerview.selection.ViewAutoScroller.ScrollHost; 29 30import org.junit.Before; 31import org.junit.Test; 32import org.junit.runner.RunWith; 33 34@RunWith(AndroidJUnit4.class) 35@SmallTest 36public final class ViewAutoScrollerTest { 37 38 private static final float SCROLL_THRESHOLD_RATIO = 0.125f; 39 private static final int VIEW_HEIGHT = 100; 40 private static final int TOP_Y_POINT = (int) (VIEW_HEIGHT * SCROLL_THRESHOLD_RATIO) - 1; 41 private static final int BOTTOM_Y_POINT = 42 VIEW_HEIGHT - (int) (VIEW_HEIGHT * SCROLL_THRESHOLD_RATIO) + 1; 43 44 private ViewAutoScroller mScroller; 45 private TestHost mHost; 46 47 @Before 48 public void setUp() { 49 mHost = new TestHost(); 50 mScroller = new ViewAutoScroller(mHost, SCROLL_THRESHOLD_RATIO); 51 } 52 53 @Test 54 public void testNoScrollWhenOutOfScrollZone() { 55 mScroller.scroll(new Point(0, VIEW_HEIGHT / 2)); 56 mHost.run(); 57 mHost.assertNotScrolled(); 58 } 59 60// @Test 61// public void testNoScrollWhenDisabled() { 62// mScroller.reset(); 63// mScroller.scroll(mEvent.location(0, TOP_Y_POINT).build()); 64// mHost.assertNotScrolled(); 65// } 66 67 @Test 68 public void testMotionThreshold() { 69 mScroller.scroll(new Point(0, TOP_Y_POINT)); 70 mHost.run(); 71 72 mScroller.scroll(new Point(0, TOP_Y_POINT - 1)); 73 mHost.run(); 74 75 mHost.assertNotScrolled(); 76 } 77 78 @Test 79 public void testMotionThreshold_Resets() { 80 int expectedScrollDistance = mScroller.computeScrollDistance(-21); 81 mScroller.scroll(new Point(0, TOP_Y_POINT)); 82 mHost.run(); 83 // We need enough y motion to overcome motion threshold 84 mScroller.scroll(new Point(0, TOP_Y_POINT - 20)); 85 mHost.run(); 86 87 mHost.reset(); 88 // After resetting events should be required to cross the motion threshold 89 // before auto-scrolling again. 90 mScroller.reset(); 91 92 mScroller.scroll(new Point(0, TOP_Y_POINT)); 93 mHost.run(); 94 95 mHost.assertNotScrolled(); 96 } 97 98 @Test 99 public void testAutoScrolls_Top() { 100 int expectedScrollDistance = mScroller.computeScrollDistance(-21); 101 mScroller.scroll(new Point(0, TOP_Y_POINT)); 102 mHost.run(); 103 // We need enough y motion to overcome motion threshold 104 mScroller.scroll(new Point(0, TOP_Y_POINT - 20)); 105 mHost.run(); 106 107 mHost.assertScrolledBy(expectedScrollDistance); 108 } 109 110 @Test 111 public void testAutoScrolls_Bottom() { 112 int expectedScrollDistance = mScroller.computeScrollDistance(21); 113 mScroller.scroll(new Point(0, BOTTOM_Y_POINT)); 114 mHost.run(); 115 // We need enough y motion to overcome motion threshold 116 mScroller.scroll(new Point(0, BOTTOM_Y_POINT + 20)); 117 mHost.run(); 118 119 mHost.assertScrolledBy(expectedScrollDistance); 120 } 121 122 private final class TestHost extends ScrollHost { 123 124 private @Nullable Integer mScrollDistance; 125 private @Nullable Runnable mRunnable; 126 127 @Override 128 int getViewHeight() { 129 return VIEW_HEIGHT; 130 } 131 132 @Override 133 void scrollBy(int distance) { 134 mScrollDistance = distance; 135 } 136 137 @Override 138 void runAtNextFrame(Runnable r) { 139 mRunnable = r; 140 } 141 142 @Override 143 void removeCallback(Runnable r) { 144 } 145 146 private void reset() { 147 mScrollDistance = null; 148 mRunnable = null; 149 } 150 151 private void run() { 152 mRunnable.run(); 153 } 154 155 private void assertNotScrolled() { 156 assertNull(mScrollDistance); 157 } 158 159 private void assertScrolledBy(int expectedDistance) { 160 assertNotNull(mScrollDistance); 161 assertEquals(expectedDistance, mScrollDistance.intValue()); 162 } 163 } 164} 165