MultiSelectManagerTest.java revision 743c7c2f0f57b4cef7cc11154b2e804a7eb33177
1/* 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 17package com.android.documentsui.dirlist; 18 19import android.support.v7.widget.RecyclerView; 20import android.test.AndroidTestCase; 21import android.test.suitebuilder.annotation.SmallTest; 22import android.util.SparseBooleanArray; 23 24import com.android.documentsui.TestInputEvent; 25import com.android.documentsui.dirlist.MultiSelectManager.Selection; 26import com.google.common.collect.Lists; 27 28import java.util.ArrayList; 29import java.util.HashSet; 30import java.util.List; 31import java.util.Set; 32 33@SmallTest 34public class MultiSelectManagerTest extends AndroidTestCase { 35 36 private static final List<String> items; 37 static { 38 items = new ArrayList<String>(); 39 for (int i = 0; i < 100; ++i) { 40 items.add(Integer.toString(i)); 41 } 42 } 43 44 private MultiSelectManager mManager; 45 private TestCallback mCallback; 46 private TestSelectionEnvironment mEnv; 47 48 public void setUp() throws Exception { 49 mCallback = new TestCallback(); 50 mEnv = new TestSelectionEnvironment(items); 51 mManager = new MultiSelectManager(mEnv, MultiSelectManager.MODE_MULTIPLE); 52 mManager.addCallback(mCallback); 53 } 54 55 public void testMouseClick_StartsSelectionMode() { 56 click(7); 57 assertSelection(items.get(7)); 58 } 59 60 public void testMouseClick_NotifiesSelectionChanged() { 61 click(7); 62 mCallback.assertSelectionChanged(); 63 } 64 65 public void testMouseClick_ShiftClickExtendsSelection() { 66 longPress(7); 67 shiftClick(11); 68 assertRangeSelection(7, 11); 69 } 70 71 public void testMouseClick_NoPosition_ClearsSelection() { 72 longPress(7); 73 click(11); 74 click(RecyclerView.NO_POSITION); 75 assertSelection(); 76 } 77 78 public void testSetSelectionFocusBegin() { 79 mManager.setItemsSelected(Lists.newArrayList(items.get(7)), true); 80 mManager.setSelectionRangeBegin(7); 81 shiftClick(11); 82 assertRangeSelection(7, 11); 83 } 84 85 public void testLongPress_StartsSelectionMode() { 86 longPress(7); 87 assertSelection(items.get(7)); 88 } 89 90 public void testLongPress_SecondPressExtendsSelection() { 91 longPress(7); 92 longPress(99); 93 assertSelection(items.get(7), items.get(99)); 94 } 95 96 public void testSingleTapUp_UnselectsSelectedItem() { 97 longPress(7); 98 tap(7); 99 assertSelection(); 100 } 101 102 public void testSingleTapUp_NoPosition_ClearsSelection() { 103 longPress(7); 104 tap(11); 105 tap(RecyclerView.NO_POSITION); 106 assertSelection(); 107 } 108 109 public void testSingleTapUp_ExtendsSelection() { 110 longPress(99); 111 tap(7); 112 tap(13); 113 assertSelection(items.get(7), items.get(99), items.get(13)); 114 } 115 116 public void testSingleTapUp_ShiftCreatesRangeSelection() { 117 longPress(7); 118 shiftTap(17); 119 assertRangeSelection(7, 17); 120 } 121 122 public void testSingleTapUp_ShiftCreatesRangeSeletion_Backwards() { 123 longPress(17); 124 shiftTap(7); 125 assertRangeSelection(7, 17); 126 } 127 128 public void testSingleTapUp_SecondShiftClickExtendsSelection() { 129 longPress(7); 130 shiftTap(11); 131 shiftTap(17); 132 assertRangeSelection(7, 17); 133 } 134 135 public void testSingleTapUp_MultipleContiguousRangesSelected() { 136 longPress(7); 137 shiftTap(11); 138 tap(20); 139 shiftTap(25); 140 assertRangeSelected(7, 11); 141 assertRangeSelected(20, 25); 142 assertSelectionSize(11); 143 } 144 145 public void testSingleTapUp_ShiftReducesSelectionRange_FromPreviousShiftClick() { 146 longPress(7); 147 shiftTap(17); 148 shiftTap(10); 149 assertRangeSelection(7, 10); 150 } 151 152 public void testSingleTapUp_ShiftReducesSelectionRange_FromPreviousShiftClick_Backwards() { 153 mManager.onLongPress(TestInputEvent.tap(17)); 154 shiftTap(7); 155 shiftTap(14); 156 assertRangeSelection(14, 17); 157 } 158 159 public void testSingleTapUp_ShiftReversesSelectionDirection() { 160 longPress(7); 161 shiftTap(17); 162 shiftTap(0); 163 assertRangeSelection(0, 7); 164 } 165 166 public void testSingleSelectMode() { 167 mManager = new MultiSelectManager(mEnv, MultiSelectManager.MODE_SINGLE); 168 mManager.addCallback(mCallback); 169 longPress(20); 170 tap(13); 171 assertSelection(items.get(13)); 172 } 173 174 public void testSingleSelectMode_ShiftTap() { 175 mManager = new MultiSelectManager(mEnv, MultiSelectManager.MODE_SINGLE); 176 mManager.addCallback(mCallback); 177 longPress(13); 178 shiftTap(20); 179 assertSelection(items.get(20)); 180 } 181 182 public void testSingleSelectMode_ShiftDoesNotExtendSelection() { 183 mManager = new MultiSelectManager(mEnv, MultiSelectManager.MODE_SINGLE); 184 mManager.addCallback(mCallback); 185 longPress(20); 186 keyToPosition(22, true); 187 assertSelection(items.get(22)); 188 } 189 190 public void testProvisionalSelection() { 191 Selection s = mManager.getSelection(); 192 assertSelection(); 193 194 SparseBooleanArray provisional = new SparseBooleanArray(); 195 provisional.append(1, true); 196 provisional.append(2, true); 197 s.setProvisionalSelection(getItemIds(provisional)); 198 assertSelection(items.get(1), items.get(2)); 199 200 provisional.delete(1); 201 provisional.append(3, true); 202 s.setProvisionalSelection(getItemIds(provisional)); 203 assertSelection(items.get(2), items.get(3)); 204 205 s.applyProvisionalSelection(); 206 assertSelection(items.get(2), items.get(3)); 207 208 provisional.clear(); 209 provisional.append(3, true); 210 provisional.append(4, true); 211 s.setProvisionalSelection(getItemIds(provisional)); 212 assertSelection(items.get(2), items.get(3), items.get(4)); 213 214 provisional.delete(3); 215 s.setProvisionalSelection(getItemIds(provisional)); 216 assertSelection(items.get(2), items.get(3), items.get(4)); 217 } 218 219 private static Set<String> getItemIds(SparseBooleanArray selection) { 220 Set<String> ids = new HashSet<>(); 221 222 int count = selection.size(); 223 for (int i = 0; i < count; ++i) { 224 ids.add(items.get(selection.keyAt(i))); 225 } 226 227 return ids; 228 } 229 230 private void longPress(int position) { 231 mManager.onLongPress(TestInputEvent.tap(position)); 232 } 233 234 private void tap(int position) { 235 mManager.onSingleTapUp(TestInputEvent.tap(position)); 236 } 237 238 private void shiftTap(int position) { 239 mManager.onSingleTapUp(TestInputEvent.shiftTap(position)); 240 } 241 242 private void click(int position) { 243 mManager.onSingleTapUp(TestInputEvent.click(position)); 244 } 245 246 private void shiftClick(int position) { 247 mManager.onSingleTapUp(TestInputEvent.shiftClick(position)); 248 } 249 250 private void keyToPosition(int position, boolean shift) { 251 mManager.attemptChangeFocus(position, shift); 252 } 253 254 private void assertSelected(String... expected) { 255 for (int i = 0; i < expected.length; i++) { 256 Selection selection = mManager.getSelection(); 257 String err = String.format( 258 "Selection %s does not contain %s", selection, expected[i]); 259 assertTrue(err, selection.contains(expected[i])); 260 } 261 } 262 263 private void assertSelection(String... expected) { 264 assertSelectionSize(expected.length); 265 assertSelected(expected); 266 } 267 268 private void assertRangeSelected(int begin, int end) { 269 for (int i = begin; i <= end; i++) { 270 assertSelected(items.get(i)); 271 } 272 } 273 274 private void assertRangeSelection(int begin, int end) { 275 assertSelectionSize(end - begin + 1); 276 assertRangeSelected(begin, end); 277 } 278 279 private void assertSelectionSize(int expected) { 280 Selection selection = mManager.getSelection(); 281 assertEquals(selection.toString(), expected, selection.size()); 282 } 283 284 private static final class TestCallback implements MultiSelectManager.Callback { 285 286 Set<String> ignored = new HashSet<>(); 287 private boolean mSelectionChanged = false; 288 289 @Override 290 public void onItemStateChanged(String modelId, boolean selected) {} 291 292 @Override 293 public boolean onBeforeItemStateChange(String modelId, boolean selected) { 294 return !ignored.contains(modelId); 295 } 296 297 @Override 298 public void onSelectionChanged() { 299 mSelectionChanged = true; 300 } 301 302 void assertSelectionChanged() { 303 assertTrue(mSelectionChanged); 304 } 305 } 306} 307