1 /* 2 * Copyright (C) 2016 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.selection; 18 19 import static com.android.documentsui.testing.TestEvents.Mouse.CLICK; 20 import static com.android.documentsui.testing.TestEvents.Mouse.SECONDARY_CLICK; 21 import static com.android.documentsui.testing.TestEvents.Mouse.SHIFT_CLICK; 22 23 import android.support.test.filters.SmallTest; 24 import android.support.test.runner.AndroidJUnit4; 25 26 import com.android.documentsui.selection.SelectionHelper; 27 import com.android.documentsui.selection.testing.SelectionHelpers; 28 import com.android.documentsui.selection.testing.SelectionProbe; 29 import com.android.documentsui.selection.testing.TestData; 30 import com.android.documentsui.selection.testing.TestMouseCallbacks; 31 32 import org.junit.Before; 33 import org.junit.Test; 34 import org.junit.runner.RunWith; 35 36 import java.util.List; 37 38 /** 39 * MouseInputDelegate / SelectHelper integration test covering the shared 40 * responsibility of range selection. 41 */ 42 @RunWith(AndroidJUnit4.class) 43 @SmallTest 44 public final class MouseInputHandler_RangeTest { 45 46 private static final List<String> ITEMS = TestData.create(100); 47 48 private MouseInputHandler mInputDelegate; 49 private SelectionHelper mSelectionMgr; 50 private SelectionProbe mSelection; 51 private TestMouseCallbacks mCallbacks; 52 private TestItemDetailsLookup mDetailsLookup; 53 54 @Before 55 public void setUp() { 56 mSelectionMgr = SelectionHelpers.createTestInstance(ITEMS); 57 mDetailsLookup = new TestItemDetailsLookup(); 58 mSelection = new SelectionProbe(mSelectionMgr); 59 60 mCallbacks = new TestMouseCallbacks(); 61 mInputDelegate = new MouseInputHandler(mSelectionMgr, mDetailsLookup, mCallbacks); 62 } 63 64 @Test 65 public void testExtendRange() { 66 // uni-click just focuses. 67 mDetailsLookup.initAt(7).setInItemSelectRegion(true); 68 mInputDelegate.onSingleTapConfirmed(CLICK); 69 70 mDetailsLookup.initAt(11); 71 mInputDelegate.onSingleTapUp(SHIFT_CLICK); 72 73 mSelection.assertRangeSelection(7, 11); 74 } 75 76 @Test 77 public void testExtendRangeContinues() { 78 mDetailsLookup.initAt(7).setInItemSelectRegion(true); 79 mInputDelegate.onSingleTapConfirmed(CLICK); 80 81 mDetailsLookup.initAt(11); 82 mInputDelegate.onSingleTapUp(SHIFT_CLICK); 83 84 mDetailsLookup.initAt(21); 85 mInputDelegate.onSingleTapUp(SHIFT_CLICK); 86 87 mSelection.assertRangeSelection(7, 21); 88 } 89 90 @Test 91 public void testMultipleContiguousRanges() { 92 mDetailsLookup.initAt(7).setInItemSelectRegion(true); 93 mInputDelegate.onSingleTapConfirmed(CLICK); 94 95 mDetailsLookup.initAt(11); 96 mInputDelegate.onSingleTapUp(SHIFT_CLICK); 97 98 // click without shift sets a new range start point. 99 TestItemDetails item = mDetailsLookup.initAt(20); 100 mInputDelegate.onSingleTapUp(CLICK); 101 mInputDelegate.onSingleTapConfirmed(CLICK); 102 103 mCallbacks.focusItem(item); 104 105 mDetailsLookup.initAt(25); 106 mInputDelegate.onSingleTapUp(SHIFT_CLICK); 107 mInputDelegate.onSingleTapConfirmed(SHIFT_CLICK); 108 109 mSelection.assertRangeNotSelected(7, 11); 110 mSelection.assertRangeSelected(20, 25); 111 mSelection.assertSelectionSize(6); 112 } 113 114 @Test 115 public void testReducesSelectionRange() { 116 mDetailsLookup.initAt(7).setInItemSelectRegion(true); 117 mInputDelegate.onSingleTapConfirmed(CLICK); 118 119 mDetailsLookup.initAt(17); 120 mInputDelegate.onSingleTapUp(SHIFT_CLICK); 121 122 mDetailsLookup.initAt(10); 123 mInputDelegate.onSingleTapUp(SHIFT_CLICK); 124 125 mSelection.assertRangeSelection(7, 10); 126 } 127 128 @Test 129 public void testReducesSelectionRange_Reverse() { 130 mDetailsLookup.initAt(17).setInItemSelectRegion(true); 131 mInputDelegate.onSingleTapConfirmed(CLICK); 132 133 mDetailsLookup.initAt(7); 134 mInputDelegate.onSingleTapUp(SHIFT_CLICK); 135 136 mDetailsLookup.initAt(14); 137 mInputDelegate.onSingleTapUp(SHIFT_CLICK); 138 139 mSelection.assertRangeSelection(14, 17); 140 } 141 142 @Test 143 public void testExtendsRange_Reverse() { 144 mDetailsLookup.initAt(12).setInItemSelectRegion(true); 145 mInputDelegate.onSingleTapConfirmed(CLICK); 146 147 mDetailsLookup.initAt(5); 148 mInputDelegate.onSingleTapUp(SHIFT_CLICK); 149 150 mSelection.assertRangeSelection(5, 12); 151 } 152 153 @Test 154 public void testExtendsRange_ReversesAfterForwardClick() { 155 mDetailsLookup.initAt(7).setInItemSelectRegion(true); 156 mInputDelegate.onSingleTapConfirmed(CLICK); 157 158 mDetailsLookup.initAt(11); 159 mInputDelegate.onSingleTapUp(SHIFT_CLICK); 160 161 mDetailsLookup.initAt(0); 162 mInputDelegate.onSingleTapUp(SHIFT_CLICK); 163 164 mSelection.assertRangeSelection(0, 7); 165 } 166 167 @Test 168 public void testRightClickEstablishesRange() { 169 170 mDetailsLookup.initAt(7).setInItemSelectRegion(true); 171 mInputDelegate.onDown(SECONDARY_CLICK); 172 // This next method call simulates the behavior of the system event dispatch code. 173 // UserInputHandler depends on a specific sequence of events for internal 174 // state to remain valid. It's not an awesome arrangement, but it is currently 175 // necessary. 176 // 177 // See: UserInputHandler.MouseDelegate#mHandledOnDown; 178 mInputDelegate.onSingleTapUp(SECONDARY_CLICK); 179 180 mDetailsLookup.initAt(11); 181 // Now we can send a subsequent event that should extend selection. 182 mInputDelegate.onDown(SHIFT_CLICK); 183 mInputDelegate.onSingleTapUp(SHIFT_CLICK); 184 185 mSelection.assertRangeSelection(7, 11); 186 } 187 } 188