diff options
author | Adam Cohen <adamcohen@google.com> | 2017-07-30 09:56:43 -0700 |
---|---|---|
committer | Adam Cohen <adamcohen@google.com> | 2017-07-30 09:56:43 -0700 |
commit | 9623a6f891a31f1285f360baf77beb335613e7f5 (patch) | |
tree | 3abc4b16dc99c114ee4e1c79780567de1e6e1e1e /tests | |
parent | fdfcf12931a2427d1d7e95a8b79c4baa0047953f (diff) | |
parent | ffea4cbf0ddd8bf758d61ab0af1848a2b296fefb (diff) | |
download | Launcher3-9623a6f891a31f1285f360baf77beb335613e7f5.tar.gz |
merged ub-launcher3-dorval-polish2, and resolved conflicts
Change-Id: Id46c5c59762243403ae15cf951e9723e15bad4e0
Diffstat (limited to 'tests')
5 files changed, 414 insertions, 6 deletions
diff --git a/tests/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithmTest.java b/tests/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithmTest.java index 58dc0c43e1..26ec69b1c7 100644 --- a/tests/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithmTest.java +++ b/tests/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithmTest.java @@ -19,6 +19,7 @@ import android.content.ComponentName; import android.test.InstrumentationTestCase; import com.android.launcher3.AppInfo; +import com.android.launcher3.Utilities; import java.util.ArrayList; import java.util.List; @@ -75,6 +76,25 @@ public class DefaultAppSearchAlgorithmTest extends InstrumentationTestCase { assertTrue(mAlgorithm.matches(getInfo("电子邮件"), "电子")); assertFalse(mAlgorithm.matches(getInfo("电子邮件"), "子")); assertFalse(mAlgorithm.matches(getInfo("电子邮件"), "邮件")); + + assertFalse(mAlgorithm.matches(getInfo("Bot"), "ba")); + assertFalse(mAlgorithm.matches(getInfo("bot"), "ba")); + } + + public void testMatchesVN() { + if (!Utilities.ATLEAST_NOUGAT) { + return; + } + assertTrue(mAlgorithm.matches(getInfo("다운로드"), "다")); + assertTrue(mAlgorithm.matches(getInfo("드라이브"), "드")); + assertTrue(mAlgorithm.matches(getInfo("다운로드 드라이브"), "ㄷ")); + assertTrue(mAlgorithm.matches(getInfo("운로 드라이브"), "ㄷ")); + assertTrue(mAlgorithm.matches(getInfo("abc"), "åbç")); + assertTrue(mAlgorithm.matches(getInfo("Alpha"), "ål")); + + assertFalse(mAlgorithm.matches(getInfo("다운로드 드라이브"), "ㄷㄷ")); + assertFalse(mAlgorithm.matches(getInfo("로드라이브"), "ㄷ")); + assertFalse(mAlgorithm.matches(getInfo("abc"), "åç")); } private AppInfo getInfo(String title) { diff --git a/tests/src/com/android/launcher3/provider/RestoreDbTaskTest.java b/tests/src/com/android/launcher3/provider/RestoreDbTaskTest.java index 29f738bab2..5858e13c1b 100644 --- a/tests/src/com/android/launcher3/provider/RestoreDbTaskTest.java +++ b/tests/src/com/android/launcher3/provider/RestoreDbTaskTest.java @@ -47,11 +47,8 @@ public class RestoreDbTaskTest extends AndroidTestCase { } private int getCount(SQLiteDatabase db, String sql) { - Cursor c = db.rawQuery(sql, null); - try { + try (Cursor c = db.rawQuery(sql, null)) { return c.getCount(); - } finally { - c.getCount(); } } @@ -59,7 +56,7 @@ public class RestoreDbTaskTest extends AndroidTestCase { private final long mProfileId; - public MyDatabaseHelper(long profileId) { + MyDatabaseHelper(long profileId) { super(getContext(), null, null); mProfileId = profileId; } diff --git a/tests/src/com/android/launcher3/testcomponent/TouchEventGenerator.java b/tests/src/com/android/launcher3/testcomponent/TouchEventGenerator.java new file mode 100644 index 0000000000..80d6341e70 --- /dev/null +++ b/tests/src/com/android/launcher3/testcomponent/TouchEventGenerator.java @@ -0,0 +1,275 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.launcher3.testcomponent; + +import android.graphics.Point; +import android.util.Pair; +import android.view.InputDevice; +import android.view.MotionEvent; +import android.view.MotionEvent.PointerCoords; +import android.view.MotionEvent.PointerProperties; + +import java.util.HashMap; +import java.util.Map; + +/** + * Utility class to generate MotionEvent event sequences for testing touch gesture detectors. + */ +public class TouchEventGenerator { + + /** + * Amount of time between two generated events. + */ + private static final long TIME_INCREMENT_MS = 20L; + + /** + * Id of the fake device generating the events. + */ + private static final int DEVICE_ID = 2104; + + /** + * The fingers currently present on the emulated touch screen. + */ + private Map<Integer, Point> mFingers; + + /** + * Initial event time for the current sequence. + */ + private long mInitialTime; + + /** + * Time of the last generated event. + */ + private long mLastEventTime; + + /** + * Time of the next event. + */ + private long mTime; + + /** + * Receives the generated events. + */ + public interface Listener { + + /** + * Called when an event was generated. + */ + void onTouchEvent(MotionEvent event); + } + private final Listener mListener; + + public TouchEventGenerator(Listener listener) { + mListener = listener; + mFingers = new HashMap<Integer, Point>(); + } + + /** + * Adds a finger on the touchscreen. + */ + public TouchEventGenerator put(int id, int x, int y, long ms) { + checkFingerExistence(id, false); + boolean isInitialDown = mFingers.isEmpty(); + mFingers.put(id, new Point(x, y)); + int action; + if (isInitialDown) { + action = MotionEvent.ACTION_DOWN; + } else { + action = MotionEvent.ACTION_POINTER_DOWN; + // Set the id of the changed pointer. + action |= id << MotionEvent.ACTION_POINTER_INDEX_SHIFT; + } + generateEvent(action, ms); + return this; + } + + /** + * Adds a finger on the touchscreen after advancing default time interval. + */ + public TouchEventGenerator put(int id, int x, int y) { + return put(id, x, y, TIME_INCREMENT_MS); + } + + /** + * Adjusts the position of a finger for an upcoming move event. + * + * @see #move(long ms) + */ + public TouchEventGenerator position(int id, int x, int y) { + checkFingerExistence(id, true); + mFingers.get(id).set(x, y); + return this; + } + + /** + * Commits the finger position changes of {@link #position(int, int, int)} by generating a move + * event. + * + * @see #position(int, int, int) + */ + public TouchEventGenerator move(long ms) { + generateEvent(MotionEvent.ACTION_MOVE, ms); + return this; + } + + /** + * Commits the finger position changes of {@link #position(int, int, int)} by generating a move + * event after advancing the default time interval. + * + * @see #position(int, int, int) + */ + public TouchEventGenerator move() { + return move(TIME_INCREMENT_MS); + } + + /** + * Moves a single finger on the touchscreen. + */ + public TouchEventGenerator move(int id, int x, int y, long ms) { + return position(id, x, y).move(ms); + } + + /** + * Moves a single finger on the touchscreen after advancing default time interval. + */ + public TouchEventGenerator move(int id, int x, int y) { + return move(id, x, y, TIME_INCREMENT_MS); + } + + /** + * Removes an existing finger from the touchscreen. + */ + public TouchEventGenerator lift(int id, long ms) { + checkFingerExistence(id, true); + boolean isFinalUp = mFingers.size() == 1; + int action; + if (isFinalUp) { + action = MotionEvent.ACTION_UP; + } else { + action = MotionEvent.ACTION_POINTER_UP; + // Set the id of the changed pointer. + action |= id << MotionEvent.ACTION_POINTER_INDEX_SHIFT; + } + generateEvent(action, ms); + mFingers.remove(id); + return this; + } + + /** + * Removes a finger from the touchscreen. + */ + public TouchEventGenerator lift(int id, int x, int y, long ms) { + checkFingerExistence(id, true); + mFingers.get(id).set(x, y); + return lift(id, ms); + } + + /** + * Removes an existing finger from the touchscreen after advancing default time interval. + */ + public TouchEventGenerator lift(int id) { + return lift(id, TIME_INCREMENT_MS); + } + + /** + * Cancels an ongoing sequence. + */ + public TouchEventGenerator cancel(long ms) { + generateEvent(MotionEvent.ACTION_CANCEL, ms); + mFingers.clear(); + return this; + } + + /** + * Cancels an ongoing sequence. + */ + public TouchEventGenerator cancel() { + return cancel(TIME_INCREMENT_MS); + } + + private void checkFingerExistence(int id, boolean shouldExist) { + if (shouldExist != mFingers.containsKey(id)) { + throw new IllegalArgumentException( + shouldExist ? "Finger does not exist" : "Finger already exists"); + } + } + + private void generateEvent(int action, long ms) { + mTime = mLastEventTime + ms; + Pair<PointerProperties[], PointerCoords[]> state = getFingerState(); + MotionEvent event = MotionEvent.obtain( + mInitialTime, + mTime, + action, + state.first.length, + state.first, + state.second, + 0 /* metaState */, + 0 /* buttonState */, + 1.0f /* xPrecision */, + 1.0f /* yPrecision */, + DEVICE_ID, + 0 /* edgeFlags */, + InputDevice.SOURCE_TOUCHSCREEN, + 0 /* flags */); + mListener.onTouchEvent(event); + if (action == MotionEvent.ACTION_UP) { + resetTime(); + } + event.recycle(); + mLastEventTime = mTime; + } + + /** + * Returns the description of the fingers' state expected by MotionEvent. + */ + private Pair<PointerProperties[], PointerCoords[]> getFingerState() { + int nFingers = mFingers.size(); + PointerProperties[] properties = new PointerProperties[nFingers]; + PointerCoords[] coordinates = new PointerCoords[nFingers]; + + int index = 0; + for (Map.Entry<Integer, Point> entry : mFingers.entrySet()) { + int id = entry.getKey(); + Point location = entry.getValue(); + + PointerProperties property = new PointerProperties(); + property.id = id; + property.toolType = MotionEvent.TOOL_TYPE_FINGER; + properties[index] = property; + + PointerCoords coordinate = new PointerCoords(); + coordinate.x = location.x; + coordinate.y = location.y; + coordinate.pressure = 1.0f; + coordinates[index] = coordinate; + + index++; + } + + return new Pair<MotionEvent.PointerProperties[], MotionEvent.PointerCoords[]>( + properties, coordinates); + } + + /** + * Resets the time references for a new sequence. + */ + private void resetTime() { + mInitialTime = 0L; + mLastEventTime = -1L; + mTime = 0L; + } +} diff --git a/tests/src/com/android/launcher3/touch/SwipeDetectorTest.java b/tests/src/com/android/launcher3/touch/SwipeDetectorTest.java new file mode 100644 index 0000000000..ff83131d10 --- /dev/null +++ b/tests/src/com/android/launcher3/touch/SwipeDetectorTest.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.launcher3.touch; + +import android.support.test.InstrumentationRegistry; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; +import android.util.Log; +import android.view.MotionEvent; +import android.view.ViewConfiguration; + +import com.android.launcher3.testcomponent.TouchEventGenerator; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Matchers.anyFloat; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +@SmallTest +@RunWith(AndroidJUnit4.class) +public class SwipeDetectorTest { + + private static final String TAG = SwipeDetectorTest.class.getSimpleName(); + public static void L(String s, Object... parts) { + Log.d(TAG, (parts.length == 0) ? s : String.format(s, parts)); + } + + private TouchEventGenerator mGenerator; + private SwipeDetector mDetector; + private int mTouchSlop; + + @Mock + private SwipeDetector.Listener mMockListener; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + mGenerator = new TouchEventGenerator(new TouchEventGenerator.Listener() { + @Override + public void onTouchEvent(MotionEvent event) { + mDetector.onTouchEvent(event); + } + }); + + mDetector = new SwipeDetector(mTouchSlop, mMockListener, SwipeDetector.VERTICAL); + mDetector.setDetectableScrollConditions(SwipeDetector.DIRECTION_BOTH, false); + mTouchSlop = ViewConfiguration.get(InstrumentationRegistry.getTargetContext()) + .getScaledTouchSlop(); + L("mTouchSlop=", mTouchSlop); + } + + @Test + public void testDragStart_vertical() throws Exception { + mGenerator.put(0, 100, 100); + mGenerator.move(0, 100, 100 + mTouchSlop); + // TODO: actually calculate the following parameters and do exact value checks. + verify(mMockListener).onDragStart(anyBoolean()); + } + + @Test + public void testDragStart_failed() throws Exception { + mGenerator.put(0, 100, 100); + mGenerator.move(0, 100 + mTouchSlop, 100); + // TODO: actually calculate the following parameters and do exact value checks. + verify(mMockListener, never()).onDragStart(anyBoolean()); + } + + @Test + public void testDragStart_horizontal() throws Exception { + mDetector = new SwipeDetector(mTouchSlop, mMockListener, SwipeDetector.HORIZONTAL); + mDetector.setDetectableScrollConditions(SwipeDetector.DIRECTION_BOTH, false); + + mGenerator.put(0, 100, 100); + mGenerator.move(0, 100 + mTouchSlop, 100); + // TODO: actually calculate the following parameters and do exact value checks. + verify(mMockListener).onDragStart(anyBoolean()); + } + + @Test + public void testDrag() throws Exception { + mGenerator.put(0, 100, 100); + mGenerator.move(0, 100, 100 + mTouchSlop); + // TODO: actually calculate the following parameters and do exact value checks. + verify(mMockListener).onDrag(anyFloat(), anyFloat()); + } + + @Test + public void testDragEnd() throws Exception { + mGenerator.put(0, 100, 100); + mGenerator.move(0, 100, 100 + mTouchSlop); + mGenerator.move(0, 100, 100 + mTouchSlop * 2); + mGenerator.lift(0); + // TODO: actually calculate the following parameters and do exact value checks. + verify(mMockListener).onDragEnd(anyFloat(), anyBoolean()); + } +} diff --git a/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java index 97f7b505a1..221fed1fc5 100644 --- a/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java +++ b/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java @@ -28,6 +28,7 @@ import android.support.test.uiautomator.UiSelector; import android.test.suitebuilder.annotation.LargeTest; import com.android.launcher3.Launcher; +import com.android.launcher3.LauncherAppWidgetHost; import com.android.launcher3.LauncherAppWidgetHostView; import com.android.launcher3.LauncherAppWidgetInfo; import com.android.launcher3.LauncherAppWidgetProviderInfo; @@ -285,7 +286,7 @@ public class BindWidgetTest extends LauncherInstrumentationTestCase { pendingInfo.minSpanY = item.minSpanY; Bundle options = WidgetHostViewLoader.getDefaultOptionsForWidget(mTargetContext, pendingInfo); - AppWidgetHost host = new AppWidgetHost(mTargetContext, Launcher.APPWIDGET_HOST_ID); + AppWidgetHost host = new LauncherAppWidgetHost(mTargetContext); int widgetId = host.allocateAppWidgetId(); if (!mWidgetManager.bindAppWidgetIdIfAllowed(widgetId, info, options)) { host.deleteAppWidgetId(widgetId); |