blob: 3d6923fbc9841abbbf5e53329c216bf55515a5d4 [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
Ben Kwa936a7fc2015-12-10 15:21:18 -080019import static com.android.documentsui.dirlist.MultiSelectManager.GridModel.NOT_SET;
20
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070021import android.graphics.Point;
22import android.graphics.Rect;
Ben Kwad72a1da2015-12-01 19:56:57 -080023import android.support.v7.widget.RecyclerView.AdapterDataObserver;
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070024import android.support.v7.widget.RecyclerView.OnScrollListener;
Ben Kwac21888e2015-09-30 14:14:16 -070025import android.test.AndroidTestCase;
Steve McKaybfd87052015-11-12 10:54:31 +090026import android.test.suitebuilder.annotation.SmallTest;
Ben Kwaa017bc12015-10-07 14:15:12 -070027import android.view.View;
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070028
Steve McKayf68210e2015-11-03 15:23:16 -080029import com.android.documentsui.dirlist.MultiSelectManager.GridModel;
Steve McKay37550162015-09-08 17:15:25 -070030
Ben Kwa936a7fc2015-12-10 15:21:18 -080031import java.util.List;
Ben Kwad72a1da2015-12-01 19:56:57 -080032import java.util.Set;
33
Steve McKaybfd87052015-11-12 10:54:31 +090034@SmallTest
Ben Kwac21888e2015-09-30 14:14:16 -070035public class MultiSelectManager_GridModelTest extends AndroidTestCase {
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070036
37 private static final int VIEW_PADDING_PX = 5;
38 private static final int CHILD_VIEW_EDGE_PX = 100;
39 private static final int VIEWPORT_HEIGHT = 500;
40
Steve McKay37550162015-09-08 17:15:25 -070041 private static GridModel model;
Ben Kwaa017bc12015-10-07 14:15:12 -070042 private static TestEnvironment env;
Ben Kwad72a1da2015-12-01 19:56:57 -080043 private static Set<String> lastSelection;
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070044 private static int viewWidth;
45
46 private static void setUp(int numChildren, int numColumns) {
Ben Kwaa017bc12015-10-07 14:15:12 -070047 env = new TestEnvironment(numChildren, numColumns);
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070048 viewWidth = VIEW_PADDING_PX + numColumns * (VIEW_PADDING_PX + CHILD_VIEW_EDGE_PX);
Ben Kwaa017bc12015-10-07 14:15:12 -070049 model = new GridModel(env);
Steve McKay37550162015-09-08 17:15:25 -070050 model.addOnSelectionChangedListener(
51 new GridModel.OnSelectionChangedListener() {
52 @Override
Ben Kwad72a1da2015-12-01 19:56:57 -080053 public void onSelectionChanged(Set<String> updatedSelection) {
Steve McKay37550162015-09-08 17:15:25 -070054 lastSelection = updatedSelection;
55 }
56 });
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070057 }
58
Ben Kwac21888e2015-09-30 14:14:16 -070059 @Override
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070060 public void tearDown() {
Kyle Horimoto62a7fd02015-08-18 13:25:29 -070061 model = null;
Ben Kwaa017bc12015-10-07 14:15:12 -070062 env = null;
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070063 lastSelection = null;
64 }
65
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070066 public void testSelectionLeftOfItems() {
67 setUp(20, 5);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -070068 model.startSelection(new Point(0, 10));
69 model.resizeSelection(new Point(1, 11));
Ben Kwad72a1da2015-12-01 19:56:57 -080070 assertSelected();
Ben Kwa936a7fc2015-12-10 15:21:18 -080071 assertEquals(NOT_SET, model.getPositionNearestOrigin());
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070072 }
73
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070074 public void testSelectionRightOfItems() {
75 setUp(20, 4);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -070076 model.startSelection(new Point(viewWidth - 1, 10));
77 model.resizeSelection(new Point(viewWidth - 2, 11));
Ben Kwad72a1da2015-12-01 19:56:57 -080078 assertSelected();
Ben Kwa936a7fc2015-12-10 15:21:18 -080079 assertEquals(NOT_SET, model.getPositionNearestOrigin());
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070080 }
81
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070082 public void testSelectionAboveItems() {
83 setUp(20, 4);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -070084 model.startSelection(new Point(10, 0));
85 model.resizeSelection(new Point(11, 1));
Ben Kwad72a1da2015-12-01 19:56:57 -080086 assertSelected();
Ben Kwa936a7fc2015-12-10 15:21:18 -080087 assertEquals(NOT_SET, model.getPositionNearestOrigin());
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070088 }
89
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070090 public void testSelectionBelowItems() {
91 setUp(5, 4);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -070092 model.startSelection(new Point(10, VIEWPORT_HEIGHT - 1));
93 model.resizeSelection(new Point(11, VIEWPORT_HEIGHT - 2));
Ben Kwad72a1da2015-12-01 19:56:57 -080094 assertSelected();
Ben Kwa936a7fc2015-12-10 15:21:18 -080095 assertEquals(NOT_SET, model.getPositionNearestOrigin());
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070096 }
97
Kyle Horimoto1ed2c922015-08-06 10:29:37 -070098 public void testVerticalSelectionBetweenItems() {
99 setUp(20, 4);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700100 model.startSelection(new Point(106, 0));
101 model.resizeSelection(new Point(107, 200));
Ben Kwad72a1da2015-12-01 19:56:57 -0800102 assertSelected();
Ben Kwa936a7fc2015-12-10 15:21:18 -0800103 assertEquals(NOT_SET, model.getPositionNearestOrigin());
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700104 }
105
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700106 public void testHorizontalSelectionBetweenItems() {
107 setUp(20, 4);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700108 model.startSelection(new Point(0, 105));
109 model.resizeSelection(new Point(200, 106));
Ben Kwad72a1da2015-12-01 19:56:57 -0800110 assertSelected();
Ben Kwa936a7fc2015-12-10 15:21:18 -0800111 assertEquals(NOT_SET, model.getPositionNearestOrigin());
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700112 }
113
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700114 public void testGrowingAndShrinkingSelection() {
115 setUp(20, 4);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700116 model.startSelection(new Point(0, 0));
117 model.resizeSelection(new Point(5, 5));
Ben Kwad72a1da2015-12-01 19:56:57 -0800118 assertSelected(0);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700119 model.resizeSelection(new Point(109, 109));
Ben Kwad72a1da2015-12-01 19:56:57 -0800120 assertSelected(0);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700121 model.resizeSelection(new Point(110, 109));
Ben Kwad72a1da2015-12-01 19:56:57 -0800122 assertSelected(0, 1);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700123 model.resizeSelection(new Point(110, 110));
Ben Kwad72a1da2015-12-01 19:56:57 -0800124 assertSelected(0, 1, 4, 5);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700125 model.resizeSelection(new Point(214, 214));
Ben Kwad72a1da2015-12-01 19:56:57 -0800126 assertSelected(0, 1, 4, 5);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700127 model.resizeSelection(new Point(215, 214));
Ben Kwad72a1da2015-12-01 19:56:57 -0800128 assertSelected(0, 1, 2, 4, 5, 6);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700129 model.resizeSelection(new Point(214, 214));
Ben Kwad72a1da2015-12-01 19:56:57 -0800130 assertSelected(0, 1, 4, 5);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700131 model.resizeSelection(new Point(110, 110));
Ben Kwad72a1da2015-12-01 19:56:57 -0800132 assertSelected(0, 1, 4, 5);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700133 model.resizeSelection(new Point(110, 109));
Ben Kwad72a1da2015-12-01 19:56:57 -0800134 assertSelected(0, 1);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700135 model.resizeSelection(new Point(109, 109));
Ben Kwad72a1da2015-12-01 19:56:57 -0800136 assertSelected(0);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700137 model.resizeSelection(new Point(5, 5));
Ben Kwad72a1da2015-12-01 19:56:57 -0800138 assertSelected(0);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700139 model.resizeSelection(new Point(0, 0));
Ben Kwad72a1da2015-12-01 19:56:57 -0800140 assertSelected();
Ben Kwa936a7fc2015-12-10 15:21:18 -0800141 assertEquals(NOT_SET, model.getPositionNearestOrigin());
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700142 }
143
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700144 public void testSelectionMovingAroundOrigin() {
145 setUp(16, 4);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700146 model.startSelection(new Point(210, 210));
147 model.resizeSelection(new Point(viewWidth - 1, 0));
Ben Kwad72a1da2015-12-01 19:56:57 -0800148 assertSelected(2, 3, 6, 7);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700149 model.resizeSelection(new Point(0, 0));
Ben Kwad72a1da2015-12-01 19:56:57 -0800150 assertSelected(0, 1, 4, 5);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700151 model.resizeSelection(new Point(0, 420));
Ben Kwad72a1da2015-12-01 19:56:57 -0800152 assertSelected(8, 9, 12, 13);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700153 model.resizeSelection(new Point(viewWidth - 1, 420));
Ben Kwad72a1da2015-12-01 19:56:57 -0800154 assertSelected(10, 11, 14, 15);
Ben Kwa936a7fc2015-12-10 15:21:18 -0800155 assertEquals(10, model.getPositionNearestOrigin());
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700156 }
157
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700158 public void testScrollingBandSelect() {
159 setUp(40, 4);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700160 model.startSelection(new Point(0, 0));
161 model.resizeSelection(new Point(100, VIEWPORT_HEIGHT - 1));
Ben Kwad72a1da2015-12-01 19:56:57 -0800162 assertSelected(0, 4, 8, 12, 16);
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700163 scroll(CHILD_VIEW_EDGE_PX);
Ben Kwad72a1da2015-12-01 19:56:57 -0800164 assertSelected(0, 4, 8, 12, 16, 20);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700165 model.resizeSelection(new Point(200, VIEWPORT_HEIGHT - 1));
Ben Kwad72a1da2015-12-01 19:56:57 -0800166 assertSelected(0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21);
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700167 scroll(CHILD_VIEW_EDGE_PX);
Ben Kwad72a1da2015-12-01 19:56:57 -0800168 assertSelected(0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21, 24, 25);
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700169 scroll(-2 * CHILD_VIEW_EDGE_PX);
Ben Kwad72a1da2015-12-01 19:56:57 -0800170 assertSelected(0, 1, 4, 5, 8, 9, 12, 13, 16, 17);
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700171 model.resizeSelection(new Point(100, VIEWPORT_HEIGHT - 1));
Ben Kwad72a1da2015-12-01 19:56:57 -0800172 assertSelected(0, 4, 8, 12, 16);
Ben Kwa936a7fc2015-12-10 15:21:18 -0800173 assertEquals(0, model.getPositionNearestOrigin());
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700174 }
175
Ben Kwad72a1da2015-12-01 19:56:57 -0800176 private static void assertSelected(int... selectedPositions) {
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700177 assertEquals(selectedPositions.length, lastSelection.size());
178 for (int position : selectedPositions) {
Ben Kwad72a1da2015-12-01 19:56:57 -0800179 assertTrue(lastSelection.contains(Integer.toString(position)));
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700180 }
181 }
182
183 private static void scroll(int dy) {
Ben Kwaa017bc12015-10-07 14:15:12 -0700184 assertTrue(env.verticalOffset + VIEWPORT_HEIGHT + dy <= env.getTotalHeight());
185 env.verticalOffset += dy;
Kyle Horimoto62a7fd02015-08-18 13:25:29 -0700186 model.onScrolled(null, 0, dy);
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700187 }
188
Ben Kwaa017bc12015-10-07 14:15:12 -0700189 private static final class TestEnvironment implements MultiSelectManager.SelectionEnvironment {
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700190
191 public int horizontalOffset = 0;
192 public int verticalOffset = 0;
193 private final int mNumColumns;
194 private final int mNumRows;
195 private final int mNumChildren;
196
Ben Kwaa017bc12015-10-07 14:15:12 -0700197 public TestEnvironment(int numChildren, int numColumns) {
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700198 mNumChildren = numChildren;
199 mNumColumns = numColumns;
200 mNumRows = (int) Math.ceil((double) numChildren / mNumColumns);
201 }
202
203 private int getTotalHeight() {
204 return CHILD_VIEW_EDGE_PX * mNumRows + VIEW_PADDING_PX * (mNumRows + 1);
205 }
206
207 private int getFirstVisibleRowIndex() {
208 return verticalOffset / (CHILD_VIEW_EDGE_PX + VIEW_PADDING_PX);
209 }
210
211 private int getLastVisibleRowIndex() {
212 int lastVisibleRowUncapped =
213 (VIEWPORT_HEIGHT + verticalOffset - 1) / (CHILD_VIEW_EDGE_PX + VIEW_PADDING_PX);
214 return Math.min(lastVisibleRowUncapped, mNumRows - 1);
215 }
216
217 private int getNumItemsInRow(int index) {
218 assertTrue(index >= 0 && index < mNumRows);
219 if (index == mNumRows - 1 && mNumChildren % mNumColumns != 0) {
220 return mNumChildren % mNumColumns;
221 }
222
223 return mNumColumns;
224 }
225
226 @Override
227 public void addOnScrollListener(OnScrollListener listener) {}
228
229 @Override
230 public void removeOnScrollListener(OnScrollListener listener) {}
231
232 @Override
233 public Point createAbsolutePoint(Point relativePoint) {
234 return new Point(
235 relativePoint.x + horizontalOffset, relativePoint.y + verticalOffset);
236 }
237
238 @Override
239 public int getVisibleChildCount() {
240 int childCount = 0;
241 for (int i = getFirstVisibleRowIndex(); i <= getLastVisibleRowIndex(); i++) {
242 childCount += getNumItemsInRow(i);
243 }
244 return childCount;
245 }
246
247 @Override
Ben Kwa936a7fc2015-12-10 15:21:18 -0800248 public int getAdapterPositionAt(int index) {
249 return index + mNumColumns * (getFirstVisibleRowIndex());
250 }
251
252 @Override
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700253 public Rect getAbsoluteRectForChildViewAt(int index) {
Ben Kwad72a1da2015-12-01 19:56:57 -0800254 int adapterPosition = (getFirstVisibleRowIndex() * mNumColumns) + index;
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700255 int rowIndex = adapterPosition / mNumColumns;
256 int columnIndex = adapterPosition % mNumColumns;
257
258 Rect rect = new Rect();
259 rect.top = VIEW_PADDING_PX + rowIndex * (CHILD_VIEW_EDGE_PX + VIEW_PADDING_PX);
260 rect.bottom = rect.top + CHILD_VIEW_EDGE_PX - 1;
261 rect.left = VIEW_PADDING_PX + columnIndex * (CHILD_VIEW_EDGE_PX + VIEW_PADDING_PX);
262 rect.right = rect.left + CHILD_VIEW_EDGE_PX - 1;
263 return rect;
264 }
265
266 @Override
Steve McKay37550162015-09-08 17:15:25 -0700267 public int getChildCount() {
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700268 return mNumChildren;
269 }
270
271 @Override
Steve McKay37550162015-09-08 17:15:25 -0700272 public int getColumnCount() {
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700273 return mNumColumns;
274 }
275
276 @Override
Steve McKay37550162015-09-08 17:15:25 -0700277 public int getRowCount() {
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700278 return mNumRows;
279 }
Steve McKay37550162015-09-08 17:15:25 -0700280
281 @Override
282 public void showBand(Rect rect) {
283 throw new UnsupportedOperationException();
284 }
285
286 @Override
287 public void hideBand() {
288 throw new UnsupportedOperationException();
289 }
290
291 @Override
292 public void scrollBy(int dy) {
293 throw new UnsupportedOperationException();
294 }
295
296 @Override
297 public int getHeight() {
298 throw new UnsupportedOperationException();
299 }
300
301 @Override
302 public void invalidateView() {
303 throw new UnsupportedOperationException();
304 }
305
306 @Override
307 public void runAtNextFrame(Runnable r) {
308 throw new UnsupportedOperationException();
309 }
310
311 @Override
312 public void removeCallback(Runnable r) {
313 throw new UnsupportedOperationException();
314 }
Ben Kwaa017bc12015-10-07 14:15:12 -0700315
316 @Override
317 public int getAdapterPositionForChildView(View view) {
318 throw new UnsupportedOperationException();
319 }
320
321 @Override
322 public void focusItem(int i) {
323 throw new UnsupportedOperationException();
324 }
Ben Kwad72a1da2015-12-01 19:56:57 -0800325
326 @Override
327 public String getModelIdFromAdapterPosition(int position) {
328 return Integer.toString(position);
329 }
330
331 @Override
Ben Kwad72a1da2015-12-01 19:56:57 -0800332 public int getItemCount() {
333 return mNumChildren;
334 }
335
336 @Override
Ben Kwa936a7fc2015-12-10 15:21:18 -0800337 public List<String> getModelIds() {
338 return null;
339 }
340
341 @Override
Ben Kwa6280de02015-12-16 19:42:08 -0800342 public void notifyItemChanged(String id) {
Ben Kwad72a1da2015-12-01 19:56:57 -0800343 throw new UnsupportedOperationException();
344 }
345
346 @Override
347 public void registerDataObserver(AdapterDataObserver observer) {
348 throw new UnsupportedOperationException();
349 }
Kyle Horimoto1ed2c922015-08-06 10:29:37 -0700350 }
351}