diff --git a/core/tests/coretests/src/android/view/PinchZoomAction.java b/core/tests/coretests/src/android/view/PinchZoomAction.java index 78a4b31960c2b..97fe980e01dc0 100644 --- a/core/tests/coretests/src/android/view/PinchZoomAction.java +++ b/core/tests/coretests/src/android/view/PinchZoomAction.java @@ -16,23 +16,23 @@ package android.view; -import static android.support.test.espresso.core.deps.guava.base.Preconditions.checkNotNull; import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom; import static android.support.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed; + +import static com.google.common.base.Preconditions.checkNotNull; + import static org.hamcrest.Matchers.allOf; import android.os.SystemClock; import android.support.test.espresso.InjectEventSecurityException; import android.support.test.espresso.PerformException; -import android.support.test.espresso.ViewAction; -import android.support.test.espresso.action.MotionEvents; -import android.support.test.espresso.action.Swiper; import android.support.test.espresso.UiController; +import android.support.test.espresso.ViewAction; +import android.support.test.espresso.action.Swiper; import android.support.test.espresso.util.HumanReadables; import android.view.MotionEvent; import android.view.View; -import android.view.ViewConfiguration; -import javax.annotation.Nullable; + import org.hamcrest.Matcher; /** diff --git a/core/tests/coretests/src/android/widget/espresso/MouseClickAction.java b/core/tests/coretests/src/android/widget/espresso/MouseClickAction.java index bec4180cc1f4f..b50d6f42b7bee 100644 --- a/core/tests/coretests/src/android/widget/espresso/MouseClickAction.java +++ b/core/tests/coretests/src/android/widget/espresso/MouseClickAction.java @@ -16,8 +16,6 @@ package android.widget.espresso; -import org.hamcrest.Matcher; - import android.support.test.espresso.UiController; import android.support.test.espresso.ViewAction; import android.support.test.espresso.action.CoordinatesProvider; @@ -25,10 +23,13 @@ import android.support.test.espresso.action.MotionEvents; import android.support.test.espresso.action.MotionEvents.DownResultHolder; import android.support.test.espresso.action.Press; import android.support.test.espresso.action.Tapper; +import android.view.InputDevice; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; +import org.hamcrest.Matcher; + /** * ViewAction for performing an click on View by a mouse. */ @@ -41,8 +42,9 @@ public final class MouseClickAction implements ViewAction { TRIPLE { @Override public Tapper.Status sendTap(UiController uiController, float[] coordinates, - float[] precision) { - Tapper.Status stat = sendSingleTap(uiController, coordinates, precision); + float[] precision, int inputDevice, int buttonState) { + Tapper.Status stat = sendSingleTap(uiController, coordinates, precision, + inputDevice, buttonState); boolean warning = false; if (stat == Tapper.Status.FAILURE) { return Tapper.Status.FAILURE; @@ -55,7 +57,8 @@ public final class MouseClickAction implements ViewAction { if (0 < doubleTapMinimumTimeout) { uiController.loopMainThreadForAtLeast(doubleTapMinimumTimeout); } - stat = sendSingleTap(uiController, coordinates, precision); + stat = sendSingleTap(uiController, coordinates, precision, inputDevice, + buttonState); if (stat == Tapper.Status.FAILURE) { return Tapper.Status.FAILURE; } else if (stat == Tapper.Status.WARNING) { @@ -69,11 +72,19 @@ public final class MouseClickAction implements ViewAction { return Tapper.Status.SUCCESS; } } + + @Override + public Tapper.Status sendTap(UiController uiController, float[] coordinates, + float[] precision) { + return sendTap(uiController, coordinates, precision, InputDevice.SOURCE_UNKNOWN, + MotionEvent.BUTTON_PRIMARY); + } }; private static Tapper.Status sendSingleTap(UiController uiController, - float[] coordinates, float[] precision) { - DownResultHolder res = MotionEvents.sendDown(uiController, coordinates, precision); + float[] coordinates, float[] precision, int inputDevice, int buttonState) { + DownResultHolder res = MotionEvents.sendDown(uiController, coordinates, precision, + inputDevice, buttonState); try { if (!MotionEvents.sendUp(uiController, res.down)) { MotionEvents.sendCancel(uiController, res.down); diff --git a/core/tests/coretests/src/com/android/internal/widget/MessagingLinearLayoutTest.java b/core/tests/coretests/src/com/android/internal/widget/MessagingLinearLayoutTest.java index 20fd4d3d36f83..dfe851104e1c3 100644 --- a/core/tests/coretests/src/com/android/internal/widget/MessagingLinearLayoutTest.java +++ b/core/tests/coretests/src/com/android/internal/widget/MessagingLinearLayoutTest.java @@ -22,12 +22,12 @@ import static org.junit.Assert.assertTrue; import android.content.Context; import android.support.test.InstrumentationRegistry; -import android.support.test.espresso.core.deps.guava.base.Function; import android.support.test.filters.SmallTest; import android.view.LayoutInflater; import android.view.View.MeasureSpec; import com.android.frameworks.coretests.R; +import com.google.common.base.Function; import org.junit.Before; import org.junit.Test; diff --git a/packages/SystemUI/tests/src/com/android/AAAPlusPlusVerifySysuiRequiredTestPropertiesTest.java b/packages/SystemUI/tests/src/com/android/AAAPlusPlusVerifySysuiRequiredTestPropertiesTest.java index b597868fb22bd..fe235410cc263 100644 --- a/packages/SystemUI/tests/src/com/android/AAAPlusPlusVerifySysuiRequiredTestPropertiesTest.java +++ b/packages/SystemUI/tests/src/com/android/AAAPlusPlusVerifySysuiRequiredTestPropertiesTest.java @@ -22,7 +22,6 @@ import android.support.test.filters.SmallTest; import android.support.test.internal.runner.ClassPathScanner; import android.support.test.internal.runner.ClassPathScanner.ChainedClassNameFilter; import android.support.test.internal.runner.ClassPathScanner.ExternalClassNameFilter; -import android.support.test.internal.runner.TestLoader; import android.testing.AndroidTestingRunner; import android.text.TextUtils; import android.util.Log; @@ -32,8 +31,11 @@ import com.android.systemui.SysuiTestCase; import org.junit.Test; import org.junit.runner.RunWith; +import org.junit.internal.builders.AllDefaultPossibilitiesBuilder; import java.io.IOException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -69,12 +71,11 @@ public class AAAPlusPlusVerifySysuiRequiredTestPropertiesTest extends SysuiTestC }; @Test - public void testAllClassInheritance() { + public void testAllClassInheritance() throws Throwable { boolean anyClassWrong = false; - TestLoader loader = new TestLoader(); for (String className : getClassNamesFromClassPath()) { - Class cls = loader.loadIfTest(className); - if (cls == null) continue; + Class cls = Class.forName(className, false, this.getClass().getClassLoader()); + if (!isTestClass(cls)) continue; boolean hasParent = false; for (Class parent : BASE_CLS_WHITELIST) { @@ -125,4 +126,85 @@ public class AAAPlusPlusVerifySysuiRequiredTestPropertiesTest extends SysuiTestC return TextUtils.join(",", Arrays.asList(BASE_CLS_WHITELIST) .stream().map(cls -> cls.getSimpleName()).toArray()); } + + /** + * Determines if given class is a valid test class. + * + * @param loadedClass + * @return true if loadedClass is a test + */ + private boolean isTestClass(Class loadedClass) { + try { + if (Modifier.isAbstract(loadedClass.getModifiers())) { + logDebug(String.format("Skipping abstract class %s: not a test", + loadedClass.getName())); + return false; + } + // TODO: try to find upstream junit calls to replace these checks + if (junit.framework.Test.class.isAssignableFrom(loadedClass)) { + // ensure that if a TestCase, it has at least one test method otherwise + // TestSuite will throw error + if (junit.framework.TestCase.class.isAssignableFrom(loadedClass)) { + return hasJUnit3TestMethod(loadedClass); + } + return true; + } + // TODO: look for a 'suite' method? + if (loadedClass.isAnnotationPresent(org.junit.runner.RunWith.class)) { + return true; + } + for (Method testMethod : loadedClass.getMethods()) { + if (testMethod.isAnnotationPresent(org.junit.Test.class)) { + return true; + } + } + logDebug(String.format("Skipping class %s: not a test", loadedClass.getName())); + return false; + } catch (Exception e) { + // Defensively catch exceptions - Will throw runtime exception if it cannot load methods. + // For earlier versions of Android (Pre-ICS), Dalvik might try to initialize a class + // during getMethods(), fail to do so, hide the error and throw a NoSuchMethodException. + // Since the java.lang.Class.getMethods does not declare such an exception, resort to a + // generic catch all. + // For ICS+, Dalvik will throw a NoClassDefFoundException. + Log.w(TAG, String.format("%s in isTestClass for %s", e.toString(), + loadedClass.getName())); + return false; + } catch (Error e) { + // defensively catch Errors too + Log.w(TAG, String.format("%s in isTestClass for %s", e.toString(), + loadedClass.getName())); + return false; + } + } + + private boolean hasJUnit3TestMethod(Class loadedClass) { + for (Method testMethod : loadedClass.getMethods()) { + if (isPublicTestMethod(testMethod)) { + return true; + } + } + return false; + } + + // copied from junit.framework.TestSuite + private boolean isPublicTestMethod(Method m) { + return isTestMethod(m) && Modifier.isPublic(m.getModifiers()); + } + + // copied from junit.framework.TestSuite + private boolean isTestMethod(Method m) { + return m.getParameterTypes().length == 0 && m.getName().startsWith("test") + && m.getReturnType().equals(Void.TYPE); + } + + /** + * Utility method for logging debug messages. Only actually logs a message if TAG is marked + * as loggable to limit log spam during normal use. + */ + private void logDebug(String msg) { + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, msg); + } + } }