blob: c4b6ce5c7f87c6600ef0f05db1bcbcac91403cc0 [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;
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070023import android.util.SparseBooleanArray;
Ben Kwaa017bc12015-10-07 14:15:12 -070024import android.view.View;
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070025
Steve McKayf68210e2015-11-03 15:23:16 -080026import com.android.documentsui.dirlist.MultiSelectManager.GridModel;
Steve McKay37550162015-09-08 17:15:25 -070027
Ben Kwac21888e2015-09-30 14:14:16 -070028public class MultiSelectManager_GridModelTest extends AndroidTestCase {
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070029
30 private static final int VIEW_PADDING_PX = 5;
31 private static final int CHILD_VIEW_EDGE_PX = 100;
32 private static final int VIEWPORT_HEIGHT = 500;
33
Steve McKay37550162015-09-08 17:15:25 -070034 private static GridModel model;
Ben Kwaa017bc12015-10-07 14:15:12 -070035 private static TestEnvironment env;
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070036 private static SparseBooleanArray lastSelection;
37 private static int viewWidth;
38
39 private static void setUp(int numChildren, int numColumns) {
Ben Kwaa017bc12015-10-07 14:15:12 -070040 env = new TestEnvironment(numChildren, numColumns);
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070041 viewWidth = VIEW_PADDING_PX + numColumns * (VIEW_PADDING_PX + CHILD_VIEW_EDGE_PX);
Ben Kwaa017bc12015-10-07 14:15:12 -070042 model = new GridModel(env);
Steve McKay37550162015-09-08 17:15:25 -070043 model.addOnSelectionChangedListener(
44 new GridModel.OnSelectionChangedListener() {
45 @Override
46 public void onSelectionChanged(SparseBooleanArray updatedSelection) {
47 lastSelection = updatedSelection;
48 }
49 });
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070050 }
51
Ben Kwac21888e2015-09-30 14:14:16 -070052 @Override
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070053 public void tearDown() {
Kyle Horimoto62a7fd02015-08-18 13:25:29 -070054 model = null;
Ben Kwaa017bc12015-10-07 14:15:12 -070055 env = null;
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070056 lastSelection = null;
57 }
58
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070059 public void testSelectionLeftOfItems() {
60 setUp(20, 5);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -070061 model.startSelection(new Point(0, 10));
62 model.resizeSelection(new Point(1, 11));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070063 assertSelected(new int[0]);
Steve McKay37550162015-09-08 17:15:25 -070064 assertEquals(GridModel.NOT_SET, model.getPositionNearestOrigin());
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070065 }
66
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070067 public void testSelectionRightOfItems() {
68 setUp(20, 4);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -070069 model.startSelection(new Point(viewWidth - 1, 10));
70 model.resizeSelection(new Point(viewWidth - 2, 11));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070071 assertSelected(new int[0]);
Steve McKay37550162015-09-08 17:15:25 -070072 assertEquals(GridModel.NOT_SET, model.getPositionNearestOrigin());
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070073 }
74
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070075 public void testSelectionAboveItems() {
76 setUp(20, 4);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -070077 model.startSelection(new Point(10, 0));
78 model.resizeSelection(new Point(11, 1));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070079 assertSelected(new int[0]);
Steve McKay37550162015-09-08 17:15:25 -070080 assertEquals(GridModel.NOT_SET, model.getPositionNearestOrigin());
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070081 }
82
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070083 public void testSelectionBelowItems() {
84 setUp(5, 4);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -070085 model.startSelection(new Point(10, VIEWPORT_HEIGHT - 1));
86 model.resizeSelection(new Point(11, VIEWPORT_HEIGHT - 2));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070087 assertSelected(new int[0]);
Steve McKay37550162015-09-08 17:15:25 -070088 assertEquals(GridModel.NOT_SET, model.getPositionNearestOrigin());
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070089 }
90
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070091 public void testVerticalSelectionBetweenItems() {
92 setUp(20, 4);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -070093 model.startSelection(new Point(106, 0));
94 model.resizeSelection(new Point(107, 200));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070095 assertSelected(new int[0]);
Steve McKay37550162015-09-08 17:15:25 -070096 assertEquals(GridModel.NOT_SET, model.getPositionNearestOrigin());
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070097 }
98
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070099 public void testHorizontalSelectionBetweenItems() {
100 setUp(20, 4);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700101 model.startSelection(new Point(0, 105));
102 model.resizeSelection(new Point(200, 106));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700103 assertSelected(new int[0]);
Steve McKay37550162015-09-08 17:15:25 -0700104 assertEquals(GridModel.NOT_SET, model.getPositionNearestOrigin());
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700105 }
106
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700107 public void testGrowingAndShrinkingSelection() {
108 setUp(20, 4);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700109 model.startSelection(new Point(0, 0));
110 model.resizeSelection(new Point(5, 5));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700111 assertSelected(new int[] {0});
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700112 model.resizeSelection(new Point(109, 109));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700113 assertSelected(new int[] {0});
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700114 model.resizeSelection(new Point(110, 109));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700115 assertSelected(new int[] {0, 1});
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700116 model.resizeSelection(new Point(110, 110));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700117 assertSelected(new int[] {0, 1, 4, 5});
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700118 model.resizeSelection(new Point(214, 214));
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(215, 214));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700121 assertSelected(new int[] {0, 1, 2, 4, 5, 6});
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700122 model.resizeSelection(new Point(214, 214));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700123 assertSelected(new int[] {0, 1, 4, 5});
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700124 model.resizeSelection(new Point(110, 110));
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, 109));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700127 assertSelected(new int[] {0, 1});
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700128 model.resizeSelection(new Point(109, 109));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700129 assertSelected(new int[] {0});
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700130 model.resizeSelection(new Point(5, 5));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700131 assertSelected(new int[] {0});
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700132 model.resizeSelection(new Point(0, 0));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700133 assertSelected(new int[0]);
Steve McKay37550162015-09-08 17:15:25 -0700134 assertEquals(GridModel.NOT_SET, model.getPositionNearestOrigin());
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700135 }
136
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700137 public void testSelectionMovingAroundOrigin() {
138 setUp(16, 4);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700139 model.startSelection(new Point(210, 210));
140 model.resizeSelection(new Point(viewWidth - 1, 0));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700141 assertSelected(new int[] {2, 3, 6, 7});
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700142 model.resizeSelection(new Point(0, 0));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700143 assertSelected(new int[] {0, 1, 4, 5});
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700144 model.resizeSelection(new Point(0, 420));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700145 assertSelected(new int[] {8, 9, 12, 13});
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700146 model.resizeSelection(new Point(viewWidth - 1, 420));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700147 assertSelected(new int[] {10, 11, 14, 15});
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700148 assertEquals(10, model.getPositionNearestOrigin());
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700149 }
150
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700151 public void testScrollingBandSelect() {
152 setUp(40, 4);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700153 model.startSelection(new Point(0, 0));
154 model.resizeSelection(new Point(100, VIEWPORT_HEIGHT - 1));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700155 assertSelected(new int[] {0, 4, 8, 12, 16});
156 scroll(CHILD_VIEW_EDGE_PX);
157 assertSelected(new int[] {0, 4, 8, 12, 16, 20});
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700158 model.resizeSelection(new Point(200, VIEWPORT_HEIGHT - 1));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700159 assertSelected(new int[] {0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21});
160 scroll(CHILD_VIEW_EDGE_PX);
161 assertSelected(new int[] {0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21, 24, 25});
162 scroll(-2 * CHILD_VIEW_EDGE_PX);
163 assertSelected(new int[] {0, 1, 4, 5, 8, 9, 12, 13, 16, 17});
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700164 model.resizeSelection(new Point(100, VIEWPORT_HEIGHT - 1));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700165 assertSelected(new int[] {0, 4, 8, 12, 16});
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700166 assertEquals(0, model.getPositionNearestOrigin());
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700167 }
168
169 private static void assertSelected(int[] selectedPositions) {
170 assertEquals(selectedPositions.length, lastSelection.size());
171 for (int position : selectedPositions) {
172 assertTrue(lastSelection.get(position));
173 }
174 }
175
176 private static void scroll(int dy) {
Ben Kwaa017bc12015-10-07 14:15:12 -0700177 assertTrue(env.verticalOffset + VIEWPORT_HEIGHT + dy <= env.getTotalHeight());
178 env.verticalOffset += dy;
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700179 model.onScrolled(null, 0, dy);
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700180 }
181
Ben Kwaa017bc12015-10-07 14:15:12 -0700182 private static final class TestEnvironment implements MultiSelectManager.SelectionEnvironment {
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700183
184 public int horizontalOffset = 0;
185 public int verticalOffset = 0;
186 private final int mNumColumns;
187 private final int mNumRows;
188 private final int mNumChildren;
189
Ben Kwaa017bc12015-10-07 14:15:12 -0700190 public TestEnvironment(int numChildren, int numColumns) {
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700191 mNumChildren = numChildren;
192 mNumColumns = numColumns;
193 mNumRows = (int) Math.ceil((double) numChildren / mNumColumns);
194 }
195
196 private int getTotalHeight() {
197 return CHILD_VIEW_EDGE_PX * mNumRows + VIEW_PADDING_PX * (mNumRows + 1);
198 }
199
200 private int getFirstVisibleRowIndex() {
201 return verticalOffset / (CHILD_VIEW_EDGE_PX + VIEW_PADDING_PX);
202 }
203
204 private int getLastVisibleRowIndex() {
205 int lastVisibleRowUncapped =
206 (VIEWPORT_HEIGHT + verticalOffset - 1) / (CHILD_VIEW_EDGE_PX + VIEW_PADDING_PX);
207 return Math.min(lastVisibleRowUncapped, mNumRows - 1);
208 }
209
210 private int getNumItemsInRow(int index) {
211 assertTrue(index >= 0 && index < mNumRows);
212 if (index == mNumRows - 1 && mNumChildren % mNumColumns != 0) {
213 return mNumChildren % mNumColumns;
214 }
215
216 return mNumColumns;
217 }
218
219 @Override
220 public void addOnScrollListener(OnScrollListener listener) {}
221
222 @Override
223 public void removeOnScrollListener(OnScrollListener listener) {}
224
225 @Override
226 public Point createAbsolutePoint(Point relativePoint) {
227 return new Point(
228 relativePoint.x + horizontalOffset, relativePoint.y + verticalOffset);
229 }
230
231 @Override
232 public int getVisibleChildCount() {
233 int childCount = 0;
234 for (int i = getFirstVisibleRowIndex(); i <= getLastVisibleRowIndex(); i++) {
235 childCount += getNumItemsInRow(i);
236 }
237 return childCount;
238 }
239
240 @Override
241 public int getAdapterPositionAt(int index) {
242 return index + mNumColumns * (getFirstVisibleRowIndex());
243 }
244
245 @Override
246 public Rect getAbsoluteRectForChildViewAt(int index) {
247 int adapterPosition = getAdapterPositionAt(index);
248 int rowIndex = adapterPosition / mNumColumns;
249 int columnIndex = adapterPosition % mNumColumns;
250
251 Rect rect = new Rect();
252 rect.top = VIEW_PADDING_PX + rowIndex * (CHILD_VIEW_EDGE_PX + VIEW_PADDING_PX);
253 rect.bottom = rect.top + CHILD_VIEW_EDGE_PX - 1;
254 rect.left = VIEW_PADDING_PX + columnIndex * (CHILD_VIEW_EDGE_PX + VIEW_PADDING_PX);
255 rect.right = rect.left + CHILD_VIEW_EDGE_PX - 1;
256 return rect;
257 }
258
259 @Override
Steve McKay37550162015-09-08 17:15:25 -0700260 public int getChildCount() {
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700261 return mNumChildren;
262 }
263
264 @Override
Steve McKay37550162015-09-08 17:15:25 -0700265 public int getColumnCount() {
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700266 return mNumColumns;
267 }
268
269 @Override
Steve McKay37550162015-09-08 17:15:25 -0700270 public int getRowCount() {
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700271 return mNumRows;
272 }
Steve McKay37550162015-09-08 17:15:25 -0700273
274 @Override
275 public void showBand(Rect rect) {
276 throw new UnsupportedOperationException();
277 }
278
279 @Override
280 public void hideBand() {
281 throw new UnsupportedOperationException();
282 }
283
284 @Override
285 public void scrollBy(int dy) {
286 throw new UnsupportedOperationException();
287 }
288
289 @Override
290 public int getHeight() {
291 throw new UnsupportedOperationException();
292 }
293
294 @Override
295 public void invalidateView() {
296 throw new UnsupportedOperationException();
297 }
298
299 @Override
300 public void runAtNextFrame(Runnable r) {
301 throw new UnsupportedOperationException();
302 }
303
304 @Override
305 public void removeCallback(Runnable r) {
306 throw new UnsupportedOperationException();
307 }
Ben Kwaa017bc12015-10-07 14:15:12 -0700308
309 @Override
310 public int getAdapterPositionForChildView(View view) {
311 throw new UnsupportedOperationException();
312 }
313
314 @Override
315 public void focusItem(int i) {
316 throw new UnsupportedOperationException();
317 }
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700318 }
319}