package org.openintents.filemanager.test; import android.annotation.TargetApi; import android.app.Activity; import android.content.Intent; import android.os.Build; import android.support.annotation.NonNull; import android.support.test.rule.ActivityTestRule; import org.hamcrest.Description; import org.hamcrest.Matcher; import org.hamcrest.TypeSafeMatcher; import java.lang.reflect.Field; import static android.app.Instrumentation.ActivityResult; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; public class ActivityResultTestRule<T extends Activity> extends ActivityTestRule<T> { public ActivityResultTestRule(Class<T> activityClass) { this(activityClass, false); } public ActivityResultTestRule(Class<T> activityClass, boolean initialTouchMode) { this(activityClass, initialTouchMode, true); } public ActivityResultTestRule(Class<T> activityClass, boolean initialTouchMode, boolean launchActivity) { super(activityClass, initialTouchMode, launchActivity); } @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) public ActivityResult getActivityResult() { T activity = getActivity(); assertThat("Activity did not finish (destroyed: " + activity.isDestroyed() + ")", activity.isFinishing(), is(true)); try { Field resultCodeField = Activity.class.getDeclaredField("mResultCode"); resultCodeField.setAccessible(true); Field resultDataField = Activity.class.getDeclaredField("mResultData"); resultDataField.setAccessible(true); return new ActivityResult((int) resultCodeField.get(activity), (Intent) resultDataField.get(activity)); } catch (NoSuchFieldException e) { throw new RuntimeException("Looks like the Android Activity class has changed it's" + "private fields for mResultCode or mResultData. Time to update the reflection code.", e); } catch (Exception e) { throw new RuntimeException(e); } } public static Matcher<? super ActivityResult> hasResultData(final Matcher<Intent> intentMatcher) { return new TypeSafeMatcher<ActivityResult>(ActivityResult.class) { @Override public void describeTo(Description description) { description.appendDescriptionOf(intentMatcher); } @Override protected boolean matchesSafely(ActivityResult item) { return intentMatcher.matches(item.getResultData()); } @Override protected void describeMismatchSafely(ActivityResult item, Description mismatchDescription) { intentMatcher.describeMismatch(item.getResultData(), mismatchDescription); } }; } @NonNull public static Matcher<? super ActivityResult> hasResultCode(final int resultCode) { return new TypeSafeMatcher<ActivityResult>(ActivityResult.class) { @Override public void describeTo(Description description) { description.appendText("has result code " + resultCode); } @Override protected boolean matchesSafely(ActivityResult activityResult) { return activityResult.getResultCode() == resultCode; } }; } }