Created
September 8, 2016 23:42
-
-
Save operando/ae4d18d264dae3851da7aa539e48ffc6 to your computer and use it in GitHub Desktop.
com.android.support.test:rules rules0.5-0.6-alpha-diff
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -ru ../0.5/android/support/test/annotation/UiThreadTest.java android/support/test/annotation/UiThreadTest.java | |
--- ../0.5/android/support/test/annotation/UiThreadTest.java 2016-02-22 20:52:48.000000000 +0900 | |
+++ android/support/test/annotation/UiThreadTest.java 2016-08-02 22:18:50.000000000 +0900 | |
@@ -22,18 +22,14 @@ | |
import java.lang.annotation.Target; | |
/** | |
- * This annotation should be used along with {@link android.support.test.rule.UiThreadTestRule} | |
- * or with any rule that inherits from it. When the annotation is present, the test method is | |
- * executed on the application's UI thread (or main thread). | |
+ * Methods annotated with this annotation will be executed on the application's UI thread | |
+ * (or main thread). | |
* <p/> | |
- * Note, due to current JUnit limitation, methods annotated with | |
- * <a href="http://junit.sourceforge.net/javadoc/org/junit/Before.html"><code>Before</code></a> and | |
- * <a href="http://junit.sourceforge.net/javadoc/org/junit/After.html"><code>After</code></a> will | |
- * also be executed on the UI Thread. Consider using | |
- * {@link android.support.test.rule.UiThreadTestRule#runOnUiThread(Runnable)} if this is an | |
- * issue. | |
- * | |
- * @see android.support.test.rule.UiThreadTestRule#runOnUiThread(Runnable) | |
+ * This annotation will only take effect for {@link org.junit.Test}, {@link org.junit.Before} | |
+ * or {@link org.junit.After} methods. | |
+ * <p/> | |
+ * @see android.support.test.rule.ActivityTestRule#runOnUiThread(Runnable) if you need to switch in | |
+ * and out of the UI thread within your method. | |
*/ | |
@Target(ElementType.METHOD) | |
@Retention(RetentionPolicy.RUNTIME) | |
Only in ../0.5/android/support/test: internal | |
diff -ru ../0.5/android/support/test/rule/ActivityTestRule.java android/support/test/rule/ActivityTestRule.java | |
--- ../0.5/android/support/test/rule/ActivityTestRule.java 2016-02-22 20:52:48.000000000 +0900 | |
+++ android/support/test/rule/ActivityTestRule.java 2016-08-02 22:18:50.000000000 +0900 | |
@@ -16,16 +16,23 @@ | |
package android.support.test.rule; | |
+import org.junit.rules.TestRule; | |
import org.junit.runner.Description; | |
import org.junit.runners.model.Statement; | |
import android.app.Activity; | |
import android.app.Instrumentation; | |
+import android.content.Context; | |
import android.content.Intent; | |
import android.os.Bundle; | |
+import android.support.annotation.NonNull; | |
import android.support.annotation.Nullable; | |
import android.support.annotation.VisibleForTesting; | |
import android.support.test.InstrumentationRegistry; | |
+import android.support.test.annotation.UiThreadTest; | |
+import android.support.test.internal.runner.junit4.statement.UiThreadStatement; | |
+import android.support.test.runner.intercepting.SingleActivityFactory; | |
+import android.support.test.runner.MonitoringInstrumentation; | |
import android.util.Log; | |
import static android.support.test.internal.util.Checks.checkNotNull; | |
@@ -42,12 +49,18 @@ | |
* | |
* @param <T> The activity to test | |
*/ | |
-public class ActivityTestRule<T extends Activity> extends UiThreadTestRule { | |
+public class ActivityTestRule<T extends Activity> implements TestRule { | |
private static final String TAG = "ActivityTestRule"; | |
+ private static final int NO_FLAGS_SET = 0; | |
+ | |
private final Class<T> mActivityClass; | |
+ private final String mTargetPackage; | |
+ | |
+ private final int mLaunchFlags; | |
+ | |
private Instrumentation mInstrumentation; | |
private boolean mInitialTouchMode = false; | |
@@ -56,8 +69,10 @@ | |
private T mActivity; | |
+ private SingleActivityFactory<T> mActivityFactory; | |
+ | |
/** | |
- * Similar to {@link #ActivityTestRule(Class, boolean, boolean)} but with "touch mode" disabled. | |
+ * Similar to {@link #ActivityTestRule(Class, boolean)} but with "touch mode" disabled. | |
* | |
* @param activityClass The activity under test. This must be a class in the instrumentation | |
* targetPackage specified in the AndroidManifest.xml | |
@@ -87,7 +102,10 @@ | |
} | |
/** | |
- * Creates an {@link ActivityTestRule} for the Activity under test. | |
+ * Similar to {@link #ActivityTestRule(Class, String, int, boolean, boolean)} but defaults to | |
+ * launch the Activity with the default target package name | |
+ * {@link InstrumentationRegistry#getTargetContext()#getPackageName} and | |
+ * {@link Intent#FLAG_ACTIVITY_NEW_TASK} launch flag. | |
* | |
* @param activityClass The activity under test. This must be a class in the instrumentation | |
* targetPackage specified in the AndroidManifest.xml | |
@@ -102,25 +120,81 @@ | |
*/ | |
public ActivityTestRule(Class<T> activityClass, boolean initialTouchMode, | |
boolean launchActivity) { | |
+ this(activityClass, InstrumentationRegistry.getTargetContext().getPackageName(), | |
+ Intent.FLAG_ACTIVITY_NEW_TASK, initialTouchMode, launchActivity); | |
+ } | |
+ | |
+ /** | |
+ * Creates an {@link ActivityTestRule} for the Activity under test. | |
+ * | |
+ * @param activityFactory factory to be used for creating Activity instance | |
+ * @param initialTouchMode true if the Activity should be placed into "touch mode" when started | |
+ * @param launchActivity true if the Activity should be launched once per | |
+ * <a href="http://junit.org/javadoc/latest/org/junit/Test.html"> | |
+ * <code>Test</code></a> method. It will be launched before the first | |
+ * <a href="http://junit.sourceforge.net/javadoc/org/junit/Before.html"> | |
+ * <code>Before</code></a> method, and terminated after the last | |
+ * <a href="http://junit.sourceforge.net/javadoc/org/junit/After.html"> | |
+ * <code>After</code></a> method. | |
+ */ | |
+ public ActivityTestRule(SingleActivityFactory<T> activityFactory, | |
+ boolean initialTouchMode, boolean launchActivity) { | |
+ this(activityFactory.getActivityClassToIntercept(), initialTouchMode, launchActivity); | |
+ mActivityFactory = activityFactory; | |
+ } | |
+ | |
+ /** | |
+ * Creates an {@link ActivityTestRule} for the Activity under test. | |
+ * | |
+ * @param activityClass The activity under test. This must be a class in the instrumentation | |
+ * targetPackage specified in the AndroidManifest.xml | |
+ * @param initialTouchMode true if the Activity should be placed into "touch mode" when started | |
+ * @param launchActivity true if the Activity should be launched once per | |
+ * <a href="http://junit.org/javadoc/latest/org/junit/Test.html"> | |
+ * <code>Test</code></a> method. It will be launched before the first | |
+ * <a href="http://junit.sourceforge.net/javadoc/org/junit/Before.html"> | |
+ * <code>Before</code></a> method, and terminated after the last | |
+ * <a href="http://junit.sourceforge.net/javadoc/org/junit/After.html"> | |
+ * <code>After</code></a> method. | |
+ * @param targetPackage The name of the target package that the Activity is started | |
+ * under. This value is passed down to the start Intent using | |
+ * {@link Intent#setClassName(Context, String)}. Can not be null. | |
+ * @param launchFlags launch flags to start the Activity under test. | |
+ */ | |
+ public ActivityTestRule(Class<T> activityClass, @NonNull String targetPackage, int launchFlags, | |
+ boolean initialTouchMode, boolean launchActivity) { | |
+ mInstrumentation = InstrumentationRegistry.getInstrumentation(); | |
mActivityClass = activityClass; | |
+ mTargetPackage = checkNotNull(targetPackage, "targetPackage cannot be null!"); | |
+ mLaunchFlags = launchFlags; | |
mInitialTouchMode = initialTouchMode; | |
mLaunchActivity = launchActivity; | |
- mInstrumentation = InstrumentationRegistry.getInstrumentation(); | |
} | |
/** | |
- * Override this method to set up Intent as if supplied to | |
- * {@link android.content.Context#startActivity}. | |
+ * Override this method to set up a custom Intent as if supplied to | |
+ * {@link android.content.Context#startActivity}. Custom Intents provided by this method will | |
+ * take precedence over default Intents that where created in the constructor but be overridden | |
+ * by any Intents passed in through {@link #launchActivity(Intent)}. | |
* <p> | |
* The default Intent (if this method returns null or is not overwritten) is: | |
* action = {@link Intent#ACTION_MAIN} | |
* flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK} | |
* All other intent fields are null or empty. | |
- * | |
+ * <p> | |
+ * If the custom Intent provided by this methods overrides any of the following fields: | |
+ * <ul> | |
+ * <li>componentName through {@link Intent#setClassName(String, String)}</li> | |
+ * <li>launch flags through {@link Intent#setFlags(int)}</li> | |
+ * </ul> | |
+ * <p> | |
+ * These custom values will be used to start the Activity. However, if some of these values are | |
+ * not set, the default values documented in | |
+ * {@link #ActivityTestRule(Class, String, int, boolean, boolean)} are supplemented. | |
* @return The Intent as if supplied to {@link android.content.Context#startActivity}. | |
*/ | |
protected Intent getActivityIntent() { | |
- return new Intent(Intent.ACTION_MAIN); | |
+ return null; | |
} | |
/** | |
@@ -168,9 +242,8 @@ | |
return mActivity; | |
} | |
- @Override | |
public Statement apply(final Statement base, Description description) { | |
- return new ActivityStatement(super.apply(base, description)); | |
+ return new ActivityStatement(base); | |
} | |
/** | |
@@ -178,7 +251,7 @@ | |
* <p> | |
* Don't call this method directly, unless you explicitly requested not to lazily launch the | |
* Activity manually using the launchActivity flag in | |
- * {@link ActivityTestRule#ActivityTestRule(Class, boolean, boolean)}. | |
+ * {@link #ActivityTestRule(Class, boolean, boolean)}. | |
* <p> | |
* Usage: | |
* <pre> | |
@@ -188,17 +261,19 @@ | |
* mActivity = mActivityRule.launchActivity(intent); | |
* } | |
* </pre> | |
+ * Note: Custom start Intents provided through this method will take precedence over default | |
+ * Intents that where created in the constructor and any Intent returned from | |
+ * {@link #getActivityIntent()}. The same override rules documented in | |
+ * {@link #getActivityIntent()} apply. | |
* @param startIntent The Intent that will be used to start the Activity under test. If | |
* {@code startIntent} is null, the Intent returned by | |
* {@link ActivityTestRule#getActivityIntent()} is used. | |
* @return the Activity launched by this rule. | |
- * @see ActivityTestRule#getActivityIntent() | |
*/ | |
public T launchActivity(@Nullable Intent startIntent) { | |
// set initial touch mode | |
mInstrumentation.setInTouchMode(mInitialTouchMode); | |
- final String targetPackage = mInstrumentation.getTargetContext().getPackageName(); | |
// inject custom intent, if provided | |
if (null == startIntent) { | |
startIntent = getActivityIntent(); | |
@@ -208,10 +283,18 @@ | |
startIntent = new Intent(Intent.ACTION_MAIN); | |
} | |
} | |
- startIntent.setClassName(targetPackage, mActivityClass.getName()); | |
- startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | |
- Log.d(TAG, String.format("Launching activity %s", | |
- mActivityClass.getName())); | |
+ | |
+ // Set target component if not set Intent | |
+ if (null == startIntent.getComponent()) { | |
+ startIntent.setClassName(mTargetPackage, mActivityClass.getName()); | |
+ } | |
+ | |
+ // Set launch flags where if not set Intent | |
+ if (NO_FLAGS_SET == startIntent.getFlags()) { | |
+ startIntent.addFlags(mLaunchFlags); | |
+ } | |
+ | |
+ Log.i(TAG, String.format("Launching activity: %s", startIntent.getComponent())); | |
beforeActivityLaunched(); | |
// The following cast is correct because the activity we're creating is of the same type as | |
@@ -226,7 +309,7 @@ | |
} else { | |
// Log an error message to logcat/instrumentation, that the Activity failed to launch | |
String errorMessage = String.format("Activity %s, failed to launch", | |
- mActivityClass.getName()); | |
+ startIntent.getComponent()); | |
Bundle bundle = new Bundle(); | |
bundle.putString(Instrumentation.REPORT_KEY_STREAMRESULT, TAG + " " + errorMessage); | |
mInstrumentation.sendStatus(0, bundle); | |
@@ -263,14 +346,40 @@ | |
@Override | |
public void evaluate() throws Throwable { | |
+ MonitoringInstrumentation instrumentation | |
+ = ActivityTestRule.this.mInstrumentation instanceof MonitoringInstrumentation | |
+ ? (MonitoringInstrumentation) ActivityTestRule.this.mInstrumentation | |
+ : null; | |
try { | |
+ if (mActivityFactory != null && instrumentation != null) { | |
+ instrumentation.interceptActivityUsing(mActivityFactory); | |
+ } | |
if (mLaunchActivity) { | |
mActivity = launchActivity(getActivityIntent()); | |
} | |
mBase.evaluate(); | |
} finally { | |
+ if (instrumentation != null) { | |
+ instrumentation.useDefaultInterceptingActivityFactory(); | |
+ } | |
finishActivity(); | |
} | |
} | |
} | |
-} | |
+ | |
+ /** | |
+ * Helper method for running part of a method on the UI thread. | |
+ * <p/> | |
+ * Note: In most cases it is simpler to annotate the test method with | |
+ * {@link UiThreadTest}. | |
+ * <p/> | |
+ * Use this method if you need to switch in and out of the UI thread within your method. | |
+ * | |
+ * @param runnable runnable containing test code in the {@link Runnable#run()} method | |
+ * | |
+ * @see android.support.test.annotation.UiThreadTest | |
+ */ | |
+ public void runOnUiThread(final Runnable runnable) throws Throwable { | |
+ UiThreadStatement.runOnUiThread(runnable); | |
+ } | |
+} | |
\ No newline at end of file | |
diff -ru ../0.5/android/support/test/rule/UiThreadTestRule.java android/support/test/rule/UiThreadTestRule.java | |
--- ../0.5/android/support/test/rule/UiThreadTestRule.java 2016-02-22 20:52:48.000000000 +0900 | |
+++ android/support/test/rule/UiThreadTestRule.java 2016-08-02 22:18:50.000000000 +0900 | |
@@ -16,21 +16,15 @@ | |
package android.support.test.rule; | |
-import android.os.Looper; | |
import android.support.test.annotation.UiThreadTest; | |
-import android.support.test.annotation.Beta; | |
-import android.support.test.internal.statement.UiThreadStatement; | |
+import android.support.test.internal.runner.junit4.statement.UiThreadStatement; | |
import android.util.Log; | |
+import org.junit.internal.runners.statements.FailOnTimeout; | |
import org.junit.rules.TestRule; | |
import org.junit.runner.Description; | |
import org.junit.runners.model.Statement; | |
-import java.util.concurrent.ExecutionException; | |
-import java.util.concurrent.FutureTask; | |
- | |
-import static android.support.test.InstrumentationRegistry.getInstrumentation; | |
- | |
/** | |
* This rule allows the test method annotated with {@link UiThreadTest} to execute on the | |
* application's main thread (or UI thread). | |
@@ -40,49 +34,53 @@ | |
* <a href="http://junit.sourceforge.net/javadoc/org/junit/After.html"><code>After</code></a> will | |
* also be executed on the UI thread. | |
* | |
- * @see android.support.test.annotation.UiThreadTest | |
+ * @see android.support.test.annotation.UiThreadTest if you need to switch in and out of the | |
+ * UI thread within your method. | |
+ * | |
+ * @deprecated use {@link UiThreadTest} directly without this rule. {@link UiThreadTest} is now | |
+ * supported as part of the core Android test runner to provide the ability to run methods | |
+ * annotated with <code>@Before</code> and <code>@After</code> on the UI thread regardless of what | |
+ * <code>@Test</code> is annotated with. | |
*/ | |
public class UiThreadTestRule implements TestRule { | |
- private static final String LOG_TAG = "UiThreadTestRule"; | |
+ private static final String TAG = "UiThreadTestRule"; | |
@Override | |
public Statement apply(final Statement base, Description description) { | |
+ if (base instanceof FailOnTimeout || | |
+ (base instanceof UiThreadStatement && | |
+ !((UiThreadStatement) base).isRunOnUiThread())) { | |
+ // In upstream junit code Rules Statements are handled last. Since we now handle | |
+ // @UiThreadTest as part of the core Android runner, there is a chance that | |
+ // UiThreadStatement was already applied on the current statement. | |
+ // This is mainly for compatibility reasons to deprecated this rule. | |
+ return base; | |
+ } | |
return new UiThreadStatement(base, shouldRunOnUiThread(description)); | |
} | |
protected boolean shouldRunOnUiThread(Description description) { | |
+ if (description.getAnnotation(android.test.UiThreadTest.class) != null) { | |
+ Log.w(TAG, "Deprecated android.test.UiThreadTest annotation is used! please switch " + | |
+ "to using android.support.test.annotation.UiThreadTest instead."); | |
+ return true; | |
+ } | |
return description.getAnnotation(UiThreadTest.class) != null; | |
} | |
/** | |
- * Helper for running portions of a test on the UI thread. | |
+ * Helper method for running part of a method on the UI thread. | |
* <p/> | |
- * Note, in most cases it is simpler to annotate the test method with | |
- * {@link UiThreadTest}, which will run the entire test method including methods annotated with | |
- * <a href="http://junit.sourceforge.net/javadoc/org/junit/Before.html"><code>Before</code></a> | |
- * and <a href="http://junit.sourceforge.net/javadoc/org/junit/After.html"> | |
- * <code>After</code></a> on the UI thread. | |
+ * Note: In most cases it is simpler to annotate the test method with | |
+ * {@link UiThreadTest}. | |
* <p/> | |
- * Use this method if you need to switch in and out of the UI thread to perform your test. | |
+ * Use this method if you need to switch in and out of the UI thread within your method. | |
* | |
* @param runnable runnable containing test code in the {@link Runnable#run()} method | |
* | |
* @see android.support.test.annotation.UiThreadTest | |
*/ | |
public void runOnUiThread(final Runnable runnable) throws Throwable { | |
- if (Looper.myLooper() == Looper.getMainLooper()) { | |
- Log.w(LOG_TAG, "Already on the UI thread, this method should not be called from the " + | |
- "main application thread"); | |
- runnable.run(); | |
- } else { | |
- FutureTask<Void> task = new FutureTask<>(runnable, null); | |
- getInstrumentation().runOnMainSync(task); | |
- try { | |
- task.get(); | |
- } catch (ExecutionException e) { | |
- // Expose the original exception | |
- throw e.getCause(); | |
- } | |
- } | |
+ UiThreadStatement.runOnUiThread(runnable); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment