blob: c856b2290ea1e1ca04099d0b497d741276dff3b0 [file] [log] [blame]
Kyle Horimoto1ed2c922015-08-06 10:29:37 -07001/*
2 * Copyright (C) 2015 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
Steve McKayf68210e2015-11-03 15:23:16 -080017package com.android.documentsui.dirlist;
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070018
19import android.graphics.Point;
20import android.graphics.Rect;
21import android.support.v7.widget.RecyclerView.OnScrollListener;
Ben Kwac21888e2015-09-30 14:14:16 -070022import android.test.AndroidTestCase;
Steve McKaybfd87052015-11-12 10:54:31 +090023import android.test.suitebuilder.annotation.SmallTest;
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070024import android.util.SparseBooleanArray;
Ben Kwaa017bc12015-10-07 14:15:12 -070025import android.view.View;
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070026
Steve McKayf68210e2015-11-03 15:23:16 -080027import com.android.documentsui.dirlist.MultiSelectManager.GridModel;
Steve McKay37550162015-09-08 17:15:25 -070028
Steve McKaybfd87052015-11-12 10:54:31 +090029@SmallTest
Ben Kwac21888e2015-09-30 14:14:16 -070030public class MultiSelectManager_GridModelTest extends AndroidTestCase {
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070031
32 private static final int VIEW_PADDING_PX = 5;
33 private static final int CHILD_VIEW_EDGE_PX = 100;
34 private static final int VIEWPORT_HEIGHT = 500;
35
Steve McKay37550162015-09-08 17:15:25 -070036 private static GridModel model;
Ben Kwaa017bc12015-10-07 14:15:12 -070037 private static TestEnvironment env;
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070038 private static SparseBooleanArray lastSelection;
39 private static int viewWidth;
40
41 private static void setUp(int numChildren, int numColumns) {
Ben Kwaa017bc12015-10-07 14:15:12 -070042 env = new TestEnvironment(numChildren, numColumns);
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070043 viewWidth = VIEW_PADDING_PX + numColumns * (VIEW_PADDING_PX + CHILD_VIEW_EDGE_PX);
Ben Kwaa017bc12015-10-07 14:15:12 -070044 model = new GridModel(env);
Steve McKay37550162015-09-08 17:15:25 -070045 model.addOnSelectionChangedListener(
46 new GridModel.OnSelectionChangedListener() {
47 @Override
48 public void onSelectionChanged(SparseBooleanArray updatedSelection) {
49 lastSelection = updatedSelection;
50 }
51 });
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070052 }
53
Ben Kwac21888e2015-09-30 14:14:16 -070054 @Override
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070055 public void tearDown() {
Kyle Horimoto62a7fd02015-08-18 13:25:29 -070056 model = null;
Ben Kwaa017bc12015-10-07 14:15:12 -070057 env = null;
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070058 lastSelection = null;
59 }
60
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070061 public void testSelectionLeftOfItems() {
62 setUp(20, 5);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -070063 model.startSelection(new Point(0, 10));
64 model.resizeSelection(new Point(1, 11));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070065 assertSelected(new int[0]);
Steve McKay37550162015-09-08 17:15:25 -070066 assertEquals(GridModel.NOT_SET, model.getPositionNearestOrigin());
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070067 }
68
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070069 public void testSelectionRightOfItems() {
70 setUp(20, 4);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -070071 model.startSelection(new Point(viewWidth - 1, 10));
72 model.resizeSelection(new Point(viewWidth - 2, 11));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070073 assertSelected(new int[0]);
Steve McKay37550162015-09-08 17:15:25 -070074 assertEquals(GridModel.NOT_SET, model.getPositionNearestOrigin());
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070075 }
76
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070077 public void testSelectionAboveItems() {
78 setUp(20, 4);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -070079 model.startSelection(new Point(10, 0));
80 model.resizeSelection(new Point(11, 1));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070081 assertSelected(new int[0]);
Steve McKay37550162015-09-08 17:15:25 -070082 assertEquals(GridModel.NOT_SET, model.getPositionNearestOrigin());
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070083 }
84
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070085 public void testSelectionBelowItems() {
86 setUp(5, 4);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -070087 model.startSelection(new Point(10, VIEWPORT_HEIGHT - 1));
88 model.resizeSelection(new Point(11, VIEWPORT_HEIGHT - 2));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070089 assertSelected(new int[0]);
Steve McKay37550162015-09-08 17:15:25 -070090 assertEquals(GridModel.NOT_SET, model.getPositionNearestOrigin());
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070091 }
92
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070093 public void testVerticalSelectionBetweenItems() {
94 setUp(20, 4);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -070095 model.startSelection(new Point(106, 0));
96 model.resizeSelection(new Point(107, 200));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070097 assertSelected(new int[0]);
Steve McKay37550162015-09-08 17:15:25 -070098 assertEquals(GridModel.NOT_SET, model.getPositionNearestOrigin());
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070099 }
100
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700101 public void testHorizontalSelectionBetweenItems() {
102 setUp(20, 4);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700103 model.startSelection(new Point(0, 105));
104 model.resizeSelection(new Point(200, 106));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700105 assertSelected(new int[0]);
Steve McKay37550162015-09-08 17:15:25 -0700106 assertEquals(GridModel.NOT_SET, model.getPositionNearestOrigin());
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700107 }
108
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700109 public void testGrowingAndShrinkingSelection() {
110 setUp(20, 4);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700111 model.startSelection(new Point(0, 0));
112 model.resizeSelection(new Point(5, 5));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700113 assertSelected(new int[] {0});
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700114 model.resizeSelection(new Point(109, 109));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700115 assertSelected(new int[] {0});
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700116 model.resizeSelection(new Point(110, 109));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700117 assertSelected(new int[] {0, 1});
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700118 model.resizeSelection(new Point(110, 110));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700119 assertSelected(new int[] {0, 1, 4, 5});
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700120 model.resizeSelection(new Point(214, 214));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700121 assertSelected(new int[] {0, 1, 4, 5});
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700122 model.resizeSelection(new Point(215, 214));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700123 assertSelected(new int[] {0, 1, 2, 4, 5, 6});
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700124 model.resizeSelection(new Point(214, 214));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700125 assertSelected(new int[] {0, 1, 4, 5});
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700126 model.resizeSelection(new Point(110, 110));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700127 assertSelected(new int[] {0, 1, 4, 5});
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700128 model.resizeSelection(new Point(110, 109));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700129 assertSelected(new int[] {0, 1});
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700130 model.resizeSelection(new Point(109, 109));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700131 assertSelected(new int[] {0});
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700132 model.resizeSelection(new Point(5, 5));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700133 assertSelected(new int[] {0});
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700134 model.resizeSelection(new Point(0, 0));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700135 assertSelected(new int[0]);
Steve McKay37550162015-09-08 17:15:25 -0700136 assertEquals(GridModel.NOT_SET, model.getPositionNearestOrigin());
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700137 }
138
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700139 public void testSelectionMovingAroundOrigin() {
140 setUp(16, 4);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700141 model.startSelection(new Point(210, 210));
142 model.resizeSelection(new Point(viewWidth - 1, 0));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700143 assertSelected(new int[] {2, 3, 6, 7});
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700144 model.resizeSelection(new Point(0, 0));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700145 assertSelected(new int[] {0, 1, 4, 5});
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700146 model.resizeSelection(new Point(0, 420));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700147 assertSelected(new int[] {8, 9, 12, 13});
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700148 model.resizeSelection(new Point(viewWidth - 1, 420));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700149 assertSelected(new int[] {10, 11, 14, 15});
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700150 assertEquals(10, model.getPositionNearestOrigin());
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700151 }
152
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700153 public void testScrollingBandSelect() {
154 setUp(40, 4);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700155 model.startSelection(new Point(0, 0));
156 model.resizeSelection(new Point(100, VIEWPORT_HEIGHT - 1));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700157 assertSelected(new int[] {0, 4, 8, 12, 16});
158 scroll(CHILD_VIEW_EDGE_PX);
159 assertSelected(new int[] {0, 4, 8, 12, 16, 20});
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700160 model.resizeSelection(new Point(200, VIEWPORT_HEIGHT - 1));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700161 assertSelected(new int[] {0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21});
162 scroll(CHILD_VIEW_EDGE_PX);
163 assertSelected(new int[] {0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21, 24, 25});
164 scroll(-2 * CHILD_VIEW_EDGE_PX);
165 assertSelected(new int[] {0, 1, 4, 5, 8, 9, 12, 13, 16, 17});
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700166 model.resizeSelection(new Point(100, VIEWPORT_HEIGHT - 1));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700167 assertSelected(new int[] {0, 4, 8, 12, 16});
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700168 assertEquals(0, model.getPositionNearestOrigin());
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700169 }
170
171 private static void assertSelected(int[] selectedPositions) {
172 assertEquals(selectedPositions.length, lastSelection.size());
173 for (int position : selectedPositions) {
174 assertTrue(lastSelection.get(position));
175 }
176 }
177
178 private static void scroll(int dy) {
Ben Kwaa017bc12015-10-07 14:15:12 -0700179 assertTrue(env.verticalOffset + VIEWPORT_HEIGHT + dy <= env.getTotalHeight());
180 env.verticalOffset += dy;
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700181 model.onScrolled(null, 0, dy);
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700182 }
183
Ben Kwaa017bc12015-10-07 14:15:12 -0700184 private static final class TestEnvironment implements MultiSelectManager.SelectionEnvironment {
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700185
186 public int horizontalOffset = 0;
187 public int verticalOffset = 0;
188 private final int mNumColumns;
189 private final int mNumRows;
190 private final int mNumChildren;
191
Ben Kwaa017bc12015-10-07 14:15:12 -0700192 public TestEnvironment(int numChildren, int numColumns) {
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700193 mNumChildren = numChildren;
194 mNumColumns = numColumns;
195 mNumRows = (int) Math.ceil((double) numChildren / mNumColumns);
196 }
197
198 private int getTotalHeight() {
199 return CHILD_VIEW_EDGE_PX * mNumRows + VIEW_PADDING_PX * (mNumRows + 1);
200 }
201
202 private int getFirstVisibleRowIndex() {
203 return verticalOffset / (CHILD_VIEW_EDGE_PX + VIEW_PADDING_PX);
204 }
205
206 private int getLastVisibleRowIndex() {
207 int lastVisibleRowUncapped =
208 (VIEWPORT_HEIGHT + verticalOffset - 1) / (CHILD_VIEW_EDGE_PX + VIEW_PADDING_PX);
209 return Math.min(lastVisibleRowUncapped, mNumRows - 1);
210 }
211
212 private int getNumItemsInRow(int index) {
213 assertTrue(index >= 0 && index < mNumRows);
214 if (index == mNumRows - 1 && mNumChildren % mNumColumns != 0) {
215 return mNumChildren % mNumColumns;
216 }
217
218 return mNumColumns;
219 }
220
221 @Override
222 public void addOnScrollListener(OnScrollListener listener) {}
223
224 @Override
225 public void removeOnScrollListener(OnScrollListener listener) {}
226
227 @Override
228 public Point createAbsolutePoint(Point relativePoint) {
229 return new Point(
230 relativePoint.x + horizontalOffset, relativePoint.y + verticalOffset);
231 }
232
233 @Override
234 public int getVisibleChildCount() {
235 int childCount = 0;
236 for (int i = getFirstVisibleRowIndex(); i <= getLastVisibleRowIndex(); i++) {
237 childCount += getNumItemsInRow(i);
238 }
239 return childCount;
240 }
241
242 @Override
243 public int getAdapterPositionAt(int index) {
244 return index + mNumColumns * (getFirstVisibleRowIndex());
245 }
246
247 @Override
248 public Rect getAbsoluteRectForChildViewAt(int index) {
249 int adapterPosition = getAdapterPositionAt(index);
250 int rowIndex = adapterPosition / mNumColumns;
251 int columnIndex = adapterPosition % mNumColumns;
252
253 Rect rect = new Rect();
254 rect.top = VIEW_PADDING_PX + rowIndex * (CHILD_VIEW_EDGE_PX + VIEW_PADDING_PX);
255 rect.bottom = rect.top + CHILD_VIEW_EDGE_PX - 1;
256 rect.left = VIEW_PADDING_PX + columnIndex * (CHILD_VIEW_EDGE_PX + VIEW_PADDING_PX);
257 rect.right = rect.left + CHILD_VIEW_EDGE_PX - 1;
258 return rect;
259 }
260
261 @Override
Steve McKay37550162015-09-08 17:15:25 -0700262 public int getChildCount() {
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700263 return mNumChildren;
264 }
265
266 @Override
Steve McKay37550162015-09-08 17:15:25 -0700267 public int getColumnCount() {
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700268 return mNumColumns;
269 }
270
271 @Override
Steve McKay37550162015-09-08 17:15:25 -0700272 public int getRowCount() {
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700273 return mNumRows;
274 }
Steve McKay37550162015-09-08 17:15:25 -0700275
276 @Override
277 public void showBand(Rect rect) {
278 throw new UnsupportedOperationException();
279 }
280
281 @Override
282 public void hideBand() {
283 throw new UnsupportedOperationException();
284 }
285
286 @Override
287 public void scrollBy(int dy) {
288 throw new UnsupportedOperationException();
289 }
290
291 @Override
292 public int getHeight() {
293 throw new UnsupportedOperationException();
294 }
295
296 @Override
297 public void invalidateView() {
298 throw new UnsupportedOperationException();
299 }
300
301 @Override
302 public void runAtNextFrame(Runnable r) {
303 throw new UnsupportedOperationException();
304 }
305
306 @Override
307 public void removeCallback(Runnable r) {
308 throw new UnsupportedOperationException();
309 }
Ben Kwaa017bc12015-10-07 14:15:12 -0700310
311 @Override
312 public int getAdapterPositionForChildView(View view) {
313 throw new UnsupportedOperationException();
314 }
315
316 @Override
317 public void focusItem(int i) {
318 throw new UnsupportedOperationException();
319 }
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700320 }
321}