• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.android.documentsui.dirlist;
18 
19 import android.support.v7.widget.RecyclerView;
20 import android.test.AndroidTestCase;
21 import android.test.suitebuilder.annotation.SmallTest;
22 import android.util.SparseBooleanArray;
23 
24 import com.android.documentsui.TestInputEvent;
25 import com.android.documentsui.dirlist.MultiSelectManager.Selection;
26 import com.google.common.collect.Lists;
27 
28 import java.util.ArrayList;
29 import java.util.HashSet;
30 import java.util.List;
31 import java.util.Set;
32 
33 @SmallTest
34 public 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) {
Integer.toString(i)40             items.add(Integer.toString(i));
41         }
42     }
43 
44     private MultiSelectManager mManager;
45     private TestCallback mCallback;
46     private TestSelectionEnvironment mEnv;
47     private TestDocumentsAdapter mAdapter;
48 
setUp()49     public void setUp() throws Exception {
50         mCallback = new TestCallback();
51         mEnv = new TestSelectionEnvironment(items);
52         mAdapter = new TestDocumentsAdapter(items);
53         mManager = new MultiSelectManager(mEnv, mAdapter, MultiSelectManager.MODE_MULTIPLE, null);
54         mManager.addCallback(mCallback);
55     }
56 
testSelection()57     public void testSelection() {
58         // Check selection.
59         mManager.toggleSelection(items.get(7));
60         assertSelection(items.get(7));
61         // Check deselection.
62         mManager.toggleSelection(items.get(7));
63         assertSelectionSize(0);
64     }
65 
testSelection_NotifiesSelectionChanged()66     public void testSelection_NotifiesSelectionChanged() {
67         // Selection should notify.
68         mManager.toggleSelection(items.get(7));
69         mCallback.assertSelectionChanged();
70         // Deselection should notify.
71         mManager.toggleSelection(items.get(7));
72         mCallback.assertSelectionChanged();
73     }
74 
testMouseClick_ShiftClickExtendsSelection()75     public void testMouseClick_ShiftClickExtendsSelection() {
76         longPress(7);
77         shiftClick(11);
78         assertRangeSelection(7, 11);
79     }
80 
testMouseClick_NoPosition_ClearsSelection()81     public void testMouseClick_NoPosition_ClearsSelection() {
82         longPress(7);
83         click(11);
84         click(RecyclerView.NO_POSITION);
85         assertSelection();
86     }
87 
testSetSelectionFocusBegin()88     public void testSetSelectionFocusBegin() {
89         mManager.setItemsSelected(Lists.newArrayList(items.get(7)), true);
90         mManager.setSelectionRangeBegin(7);
91         shiftClick(11);
92         assertRangeSelection(7, 11);
93     }
94 
testLongPress_StartsSelectionMode()95     public void testLongPress_StartsSelectionMode() {
96         longPress(7);
97         assertSelection(items.get(7));
98     }
99 
testLongPress_SecondPressExtendsSelection()100     public void testLongPress_SecondPressExtendsSelection() {
101         longPress(7);
102         longPress(99);
103         assertSelection(items.get(7), items.get(99));
104     }
105 
testSingleTapUp_UnselectsSelectedItem()106     public void testSingleTapUp_UnselectsSelectedItem() {
107         longPress(7);
108         tap(7);
109         assertSelection();
110     }
111 
testSingleTapUp_NoPosition_ClearsSelection()112     public void testSingleTapUp_NoPosition_ClearsSelection() {
113         longPress(7);
114         tap(11);
115         tap(RecyclerView.NO_POSITION);
116         assertSelection();
117     }
118 
testSingleTapUp_ExtendsSelection()119     public void testSingleTapUp_ExtendsSelection() {
120         longPress(99);
121         tap(7);
122         tap(13);
123         assertSelection(items.get(7), items.get(99), items.get(13));
124     }
125 
testSingleTapUp_ShiftCreatesRangeSelection()126     public void testSingleTapUp_ShiftCreatesRangeSelection() {
127         longPress(7);
128         shiftTap(17);
129         assertRangeSelection(7, 17);
130     }
131 
testSingleTapUp_ShiftCreatesRangeSeletion_Backwards()132     public void testSingleTapUp_ShiftCreatesRangeSeletion_Backwards() {
133         longPress(17);
134         shiftTap(7);
135         assertRangeSelection(7, 17);
136     }
137 
testSingleTapUp_SecondShiftClickExtendsSelection()138     public void testSingleTapUp_SecondShiftClickExtendsSelection() {
139         longPress(7);
140         shiftTap(11);
141         shiftTap(17);
142         assertRangeSelection(7, 17);
143     }
144 
testSingleTapUp_MultipleContiguousRangesSelected()145     public void testSingleTapUp_MultipleContiguousRangesSelected() {
146         longPress(7);
147         shiftTap(11);
148         tap(20);
149         shiftTap(25);
150         assertRangeSelected(7, 11);
151         assertRangeSelected(20, 25);
152         assertSelectionSize(11);
153     }
154 
testSingleTapUp_ShiftReducesSelectionRange_FromPreviousShiftClick()155     public void testSingleTapUp_ShiftReducesSelectionRange_FromPreviousShiftClick() {
156         longPress(7);
157         shiftTap(17);
158         shiftTap(10);
159         assertRangeSelection(7, 10);
160     }
161 
testSingleTapUp_ShiftReducesSelectionRange_FromPreviousShiftClick_Backwards()162     public void testSingleTapUp_ShiftReducesSelectionRange_FromPreviousShiftClick_Backwards() {
163         mManager.onLongPress(TestInputEvent.tap(17));
164         shiftTap(7);
165         shiftTap(14);
166         assertRangeSelection(14, 17);
167     }
168 
testSingleTapUp_ShiftReversesSelectionDirection()169     public void testSingleTapUp_ShiftReversesSelectionDirection() {
170         longPress(7);
171         shiftTap(17);
172         shiftTap(0);
173         assertRangeSelection(0, 7);
174     }
175 
testSingleSelectMode()176     public void testSingleSelectMode() {
177         mManager = new MultiSelectManager(mEnv, mAdapter, MultiSelectManager.MODE_SINGLE, null);
178         mManager.addCallback(mCallback);
179         longPress(20);
180         tap(13);
181         assertSelection(items.get(13));
182     }
183 
testSingleSelectMode_ShiftTap()184     public void testSingleSelectMode_ShiftTap() {
185         mManager = new MultiSelectManager(mEnv, mAdapter, MultiSelectManager.MODE_SINGLE, null);
186         mManager.addCallback(mCallback);
187         longPress(13);
188         shiftTap(20);
189         assertSelection(items.get(20));
190     }
191 
testRangeSelection()192     public void testRangeSelection() {
193         mManager.startRangeSelection(15);
194         mManager.snapRangeSelection(19);
195         assertRangeSelection(15, 19);
196     }
197 
testRangeSelection_snapExpand()198     public void testRangeSelection_snapExpand() {
199         mManager.startRangeSelection(15);
200         mManager.snapRangeSelection(19);
201         mManager.snapRangeSelection(27);
202         assertRangeSelection(15, 27);
203     }
204 
testRangeSelection_snapContract()205     public void testRangeSelection_snapContract() {
206         mManager.startRangeSelection(15);
207         mManager.snapRangeSelection(27);
208         mManager.snapRangeSelection(19);
209         assertRangeSelection(15, 19);
210     }
211 
testRangeSelection_snapInvert()212     public void testRangeSelection_snapInvert() {
213         mManager.startRangeSelection(15);
214         mManager.snapRangeSelection(27);
215         mManager.snapRangeSelection(3);
216         assertRangeSelection(3, 15);
217     }
218 
testRangeSelection_multiple()219     public void testRangeSelection_multiple() {
220         mManager.startRangeSelection(15);
221         mManager.snapRangeSelection(27);
222         mManager.endRangeSelection();
223         mManager.startRangeSelection(42);
224         mManager.snapRangeSelection(57);
225         assertSelectionSize(29);
226         assertRangeSelected(15, 27);
227         assertRangeSelected(42, 57);
228 
229     }
230 
testRangeSelection_singleSelect()231     public void testRangeSelection_singleSelect() {
232         mManager = new MultiSelectManager(mEnv, mAdapter, MultiSelectManager.MODE_SINGLE, null);
233         mManager.addCallback(mCallback);
234         mManager.startRangeSelection(11);
235         mManager.snapRangeSelection(19);
236         assertSelectionSize(1);
237         assertSelection(items.get(19));
238     }
239 
testProvisionalSelection()240     public void testProvisionalSelection() {
241         Selection s = mManager.getSelection();
242         assertSelection();
243 
244         SparseBooleanArray provisional = new SparseBooleanArray();
245         provisional.append(1, true);
246         provisional.append(2, true);
247         s.setProvisionalSelection(getItemIds(provisional));
248         assertSelection(items.get(1), items.get(2));
249     }
250 
testProvisionalSelection_Replace()251     public void testProvisionalSelection_Replace() {
252         Selection s = mManager.getSelection();
253 
254         SparseBooleanArray provisional = new SparseBooleanArray();
255         provisional.append(1, true);
256         provisional.append(2, true);
257         s.setProvisionalSelection(getItemIds(provisional));
258 
259         provisional.clear();
260         provisional.append(3, true);
261         provisional.append(4, true);
262         s.setProvisionalSelection(getItemIds(provisional));
263         assertSelection(items.get(3), items.get(4));
264     }
265 
testProvisionalSelection_IntersectsExistingProvisionalSelection()266     public void testProvisionalSelection_IntersectsExistingProvisionalSelection() {
267         Selection s = mManager.getSelection();
268 
269         SparseBooleanArray provisional = new SparseBooleanArray();
270         provisional.append(1, true);
271         provisional.append(2, true);
272         s.setProvisionalSelection(getItemIds(provisional));
273 
274         provisional.clear();
275         provisional.append(1, true);
276         s.setProvisionalSelection(getItemIds(provisional));
277         assertSelection(items.get(1));
278     }
279 
testProvisionalSelection_Apply()280     public void testProvisionalSelection_Apply() {
281         Selection s = mManager.getSelection();
282 
283         SparseBooleanArray provisional = new SparseBooleanArray();
284         provisional.append(1, true);
285         provisional.append(2, true);
286         s.setProvisionalSelection(getItemIds(provisional));
287         s.applyProvisionalSelection();
288         assertSelection(items.get(1), items.get(2));
289     }
290 
testProvisionalSelection_Cancel()291     public void testProvisionalSelection_Cancel() {
292         mManager.toggleSelection(items.get(1));
293         mManager.toggleSelection(items.get(2));
294         Selection s = mManager.getSelection();
295 
296         SparseBooleanArray provisional = new SparseBooleanArray();
297         provisional.append(3, true);
298         provisional.append(4, true);
299         s.setProvisionalSelection(getItemIds(provisional));
300         s.cancelProvisionalSelection();
301 
302         // Original selection should remain.
303         assertSelection(items.get(1), items.get(2));
304     }
305 
testProvisionalSelection_IntersectsAppliedSelection()306     public void testProvisionalSelection_IntersectsAppliedSelection() {
307         mManager.toggleSelection(items.get(1));
308         mManager.toggleSelection(items.get(2));
309         Selection s = mManager.getSelection();
310 
311         SparseBooleanArray provisional = new SparseBooleanArray();
312         provisional.append(2, true);
313         provisional.append(3, true);
314         s.setProvisionalSelection(getItemIds(provisional));
315         assertSelection(items.get(1), items.get(2), items.get(3));
316     }
317 
getItemIds(SparseBooleanArray selection)318     private static Set<String> getItemIds(SparseBooleanArray selection) {
319         Set<String> ids = new HashSet<>();
320 
321         int count = selection.size();
322         for (int i = 0; i < count; ++i) {
323             ids.add(items.get(selection.keyAt(i)));
324         }
325 
326         return ids;
327     }
328 
longPress(int position)329     private void longPress(int position) {
330         mManager.onLongPress(TestInputEvent.tap(position));
331     }
332 
tap(int position)333     private void tap(int position) {
334         mManager.onSingleTapUp(TestInputEvent.tap(position));
335     }
336 
shiftTap(int position)337     private void shiftTap(int position) {
338         mManager.onSingleTapUp(TestInputEvent.shiftTap(position));
339     }
340 
click(int position)341     private void click(int position) {
342         mManager.onSingleTapUp(TestInputEvent.click(position));
343     }
344 
shiftClick(int position)345     private void shiftClick(int position) {
346         mManager.onSingleTapUp(TestInputEvent.shiftClick(position));
347     }
348 
assertSelected(String... expected)349     private void assertSelected(String... expected) {
350         for (int i = 0; i < expected.length; i++) {
351             Selection selection = mManager.getSelection();
352             String err = String.format(
353                     "Selection %s does not contain %s", selection, expected[i]);
354             assertTrue(err, selection.contains(expected[i]));
355         }
356     }
357 
assertSelection(String... expected)358     private void assertSelection(String... expected) {
359         assertSelectionSize(expected.length);
360         assertSelected(expected);
361     }
362 
assertRangeSelected(int begin, int end)363     private void assertRangeSelected(int begin, int end) {
364         for (int i = begin; i <= end; i++) {
365             assertSelected(items.get(i));
366         }
367     }
368 
assertRangeSelection(int begin, int end)369     private void assertRangeSelection(int begin, int end) {
370         assertSelectionSize(end - begin + 1);
371         assertRangeSelected(begin, end);
372     }
373 
assertSelectionSize(int expected)374     private void assertSelectionSize(int expected) {
375         Selection selection = mManager.getSelection();
376         assertEquals(selection.toString(), expected, selection.size());
377     }
378 
379     private static final class TestCallback implements MultiSelectManager.Callback {
380 
381         Set<String> ignored = new HashSet<>();
382         private boolean mSelectionChanged = false;
383 
384         @Override
onItemStateChanged(String modelId, boolean selected)385         public void onItemStateChanged(String modelId, boolean selected) {}
386 
387         @Override
onBeforeItemStateChange(String modelId, boolean selected)388         public boolean onBeforeItemStateChange(String modelId, boolean selected) {
389             return !ignored.contains(modelId);
390         }
391 
392         @Override
onSelectionChanged()393         public void onSelectionChanged() {
394             mSelectionChanged = true;
395         }
396 
assertSelectionChanged()397         void assertSelectionChanged() {
398             assertTrue(mSelectionChanged);
399         }
400     }
401 }
402