From 704f9c7e8c78b67b4e3855c0524f92df245905d1 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Wed, 17 Jan 2018 14:51:05 +0100 Subject: [android] - add instrumentation tests for FileSource activation/deactivation --- .../com/mapbox/mapboxsdk/storage/FileSource.java | 5 + .../android/MapboxGLAndroidSDKTestApp/build.gradle | 1 + .../com/mapbox/mapboxsdk/maps/OrientationTest.java | 12 +- .../mapboxsdk/testapp/action/WaitAction.java | 39 +++++++ .../testapp/activity/BaseActivityTest.java | 41 ++----- .../testapp/maps/widgets/CompassViewTest.java | 2 +- .../mapboxsdk/testapp/storage/FileSourceTest.java | 129 +++++++++++++++++++++ platform/android/gradle/dependencies.gradle | 1 + platform/android/src/file_source.cpp | 10 +- platform/android/src/file_source.hpp | 2 + 10 files changed, 202 insertions(+), 40 deletions(-) create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/action/WaitAction.java create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/storage/FileSourceTest.java diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/FileSource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/FileSource.java index f0cb8d973a..929e4b4279 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/FileSource.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/FileSource.java @@ -6,6 +6,8 @@ import android.content.pm.PackageManager; import android.content.res.AssetManager; import android.os.Environment; import android.support.annotation.NonNull; +import android.support.annotation.UiThread; + import com.mapbox.mapboxsdk.Mapbox; import com.mapbox.mapboxsdk.constants.MapboxConstants; import timber.log.Timber; @@ -43,6 +45,7 @@ public class FileSource { * @param context the context to derive the cache path from * @return the single instance of FileSource */ + @UiThread public static synchronized FileSource getInstance(Context context) { if (INSTANCE == null) { String cachePath = getCachePath(context); @@ -122,6 +125,8 @@ public class FileSource { initialize(Mapbox.getAccessToken(), cachePath, assetManager); } + public native boolean isActivated(); + public native void activate(); public native void deactivate(); diff --git a/platform/android/MapboxGLAndroidSDKTestApp/build.gradle b/platform/android/MapboxGLAndroidSDKTestApp/build.gradle index caff70e543..6707527bf2 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/build.gradle +++ b/platform/android/MapboxGLAndroidSDKTestApp/build.gradle @@ -72,6 +72,7 @@ dependencies { androidTestImplementation dependenciesList.testRules androidTestImplementation dependenciesList.testEspressoCore androidTestImplementation dependenciesList.testEspressoIntents + androidTestImplementation dependenciesList.testEspressoContrib } apply from: "${rootDir}/gradle/gradle-make.gradle" diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/OrientationTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/OrientationTest.java index 7a1fcbf5f3..89397c30eb 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/OrientationTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/OrientationTest.java @@ -16,17 +16,17 @@ public class OrientationTest extends BaseActivityTest { @Test public void testChangeDeviceOrientation() { onView(isRoot()).perform(orientationLandscape()); - waitLoop(2200); + waitAction(2200); onView(isRoot()).perform(orientationPortrait()); - waitLoop(2500); + waitAction(2500); onView(isRoot()).perform(orientationLandscapeReverse()); - waitLoop(500); + waitAction(500); onView(isRoot()).perform(orientationPortraitReverse()); - waitLoop(1250); + waitAction(1250); onView(isRoot()).perform(orientationLandscape()); - waitLoop(750); + waitAction(750); onView(isRoot()).perform(orientationPortrait()); - waitLoop(950); + waitAction(950); onView(isRoot()).perform(orientationLandscapeReverse()); onView(isRoot()).perform(orientationPortraitReverse()); onView(isRoot()).perform(orientationLandscape()); diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/action/WaitAction.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/action/WaitAction.java new file mode 100644 index 0000000000..26a3a2e4ab --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/action/WaitAction.java @@ -0,0 +1,39 @@ +package com.mapbox.mapboxsdk.testapp.action; + +import android.support.test.espresso.UiController; +import android.support.test.espresso.ViewAction; +import android.view.View; + +import org.hamcrest.Matcher; + +import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; + +public final class WaitAction implements ViewAction { + + private static final long DEFAULT_LOOP_TIME = 375; + private final long loopTime; + + public WaitAction() { + this(DEFAULT_LOOP_TIME); + } + + public WaitAction(long loopTime) { + this.loopTime = loopTime; + } + + @Override + public Matcher getConstraints() { + return isDisplayed(); + } + + @Override + public String getDescription() { + return getClass().getSimpleName(); + } + + @Override + public void perform(UiController uiController, View view) { + uiController.loopMainThreadForAtLeast(loopTime); + } +} + diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/BaseActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/BaseActivityTest.java index 3f32443021..6d90c20a46 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/BaseActivityTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/BaseActivityTest.java @@ -6,18 +6,19 @@ import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.support.test.espresso.Espresso; import android.support.test.espresso.IdlingResourceTimeoutException; -import android.support.test.espresso.UiController; -import android.support.test.espresso.ViewAction; import android.support.test.rule.ActivityTestRule; -import android.view.View; + import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.testapp.R; +import com.mapbox.mapboxsdk.testapp.action.WaitAction; import com.mapbox.mapboxsdk.testapp.utils.OnMapReadyIdlingResource; + import junit.framework.Assert; -import org.hamcrest.Matcher; + import org.junit.After; import org.junit.Before; import org.junit.Rule; + import timber.log.Timber; import static android.support.test.espresso.Espresso.onView; @@ -67,12 +68,12 @@ public abstract class BaseActivityTest { onView(withId(id)).check(matches(isDisplayed())); } - protected void waitLoop() { - waitLoop(500); + protected void waitAction() { + waitAction(500); } - protected void waitLoop(long waitTime) { - onView(withId(R.id.mapView)).perform(new LoopAction(waitTime)); + protected void waitAction(long waitTime) { + onView(withId(R.id.mapView)).perform(new WaitAction(waitTime)); } static boolean isConnected(Context context) { @@ -87,29 +88,5 @@ public abstract class BaseActivityTest { Timber.e("@After test: unregister idle resource"); Espresso.unregisterIdlingResources(idlingResource); } - - private class LoopAction implements ViewAction { - - private long loopTime; - - public LoopAction(long loopTime) { - this.loopTime = loopTime; - } - - @Override - public Matcher getConstraints() { - return isDisplayed(); - } - - @Override - public String getDescription() { - return getClass().getSimpleName(); - } - - @Override - public void perform(UiController uiController, View view) { - uiController.loopMainThreadForAtLeast(loopTime); - } - } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/CompassViewTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/CompassViewTest.java index 2a510b4dc5..26aee2de98 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/CompassViewTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/CompassViewTest.java @@ -62,7 +62,7 @@ public class CompassViewTest extends BaseActivityTest { .build() ))); onView(withId(R.id.compassView)).perform(click()); - waitLoop(); + waitAction(); onView(withId(R.id.compassView)).check(matches(not(isDisplayed()))); invoke(mapboxMap, (uiController, mapboxMap) -> { CameraPosition cameraPosition = mapboxMap.getCameraPosition(); diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/storage/FileSourceTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/storage/FileSourceTest.java new file mode 100644 index 0000000000..554bc988a6 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/storage/FileSourceTest.java @@ -0,0 +1,129 @@ +package com.mapbox.mapboxsdk.testapp.storage; + +import android.os.Looper; +import android.support.test.espresso.UiController; +import android.support.test.espresso.ViewAction; +import android.support.test.rule.ActivityTestRule; +import android.support.test.runner.AndroidJUnit4; +import android.view.View; + +import com.mapbox.mapboxsdk.storage.FileSource; +import com.mapbox.mapboxsdk.testapp.R; +import com.mapbox.mapboxsdk.testapp.action.WaitAction; +import com.mapbox.mapboxsdk.testapp.activity.FeatureOverviewActivity; + +import org.hamcrest.Matcher; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.Espresso.pressBack; +import static android.support.test.espresso.action.ViewActions.click; +import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +import static android.support.test.espresso.matcher.ViewMatchers.isRoot; +import static android.support.test.espresso.matcher.ViewMatchers.withId; +import static android.support.test.espresso.matcher.ViewMatchers.withText; +import static com.mapbox.mapboxsdk.testapp.action.OrientationChangeAction.orientationLandscape; +import static junit.framework.TestCase.assertFalse; +import static junit.framework.TestCase.assertTrue; + +@RunWith(AndroidJUnit4.class) +public class FileSourceTest { + + @Rule + public ActivityTestRule rule = new ActivityTestRule<>(FeatureOverviewActivity.class); + + private FileSource fileSource; + + @Before + public void setUp() throws Exception { + onView(withId(R.id.recyclerView)).perform(new FileSourceCreator()); + } + + @Test + public void testDefault() throws Exception { + assertFalse("FileSource should not be active", fileSource.isActivated()); + } + + @Test + public void testActivateDeactivate() throws Exception { + assertFalse("1) FileSource should not be active", fileSource.isActivated()); + onView(withId(R.id.recyclerView)).perform(new FileSourceActivator(true)); + assertTrue("2) FileSource should be active", fileSource.isActivated()); + onView(withId(R.id.recyclerView)).perform(new FileSourceActivator(false)); + assertFalse("3) FileSource should not be active", fileSource.isActivated()); + } + + @Test + public void testOpenCloseMapView() throws Exception { + assertFalse("1) FileSource should not be active", fileSource.isActivated()); + onView(withText("Simple Map")).perform(click()); + onView(withId(R.id.mapView)).perform(new WaitAction()); + assertTrue("2) FileSource should be active", fileSource.isActivated()); + onView(withId(R.id.mapView)).perform(new WaitAction()); + pressBack(); + assertFalse("3) FileSource should not be active", fileSource.isActivated()); + } + + @Test + public void testRotateMapView() throws Exception { + assertFalse("1) FileSource should not be active", fileSource.isActivated()); + onView(withText("Simple Map")).perform(click()); + onView(withId(R.id.mapView)).perform(new WaitAction()); + onView(isRoot()).perform(orientationLandscape()); + onView(withId(R.id.mapView)).perform(new WaitAction()); + assertTrue("2) FileSource should be active", fileSource.isActivated()); + onView(withId(R.id.mapView)).perform(new WaitAction()); + pressBack(); + assertFalse("3) FileSource should not be active", fileSource.isActivated()); + } + + private class FileSourceCreator implements ViewAction { + @Override + public Matcher getConstraints() { + return isDisplayed(); + } + + @Override + public String getDescription() { + return "Creates the filesource instance on the UI thread"; + } + + @Override + public void perform(UiController uiController, View view) { + assertTrue(Looper.myLooper() == Looper.getMainLooper()); + fileSource = FileSource.getInstance(rule.getActivity()); + } + } + + private class FileSourceActivator implements ViewAction { + + private boolean activate; + + FileSourceActivator(boolean activate) { + this.activate = activate; + } + + @Override + public Matcher getConstraints() { + return isDisplayed(); + } + + @Override + public String getDescription() { + return "Creates the filesource instance on the UI thread"; + } + + @Override + public void perform(UiController uiController, View view) { + assertTrue(Looper.myLooper() == Looper.getMainLooper()); + if (activate) { + fileSource.activate(); + } else { + fileSource.deactivate(); + } + } + } +} \ No newline at end of file diff --git a/platform/android/gradle/dependencies.gradle b/platform/android/gradle/dependencies.gradle index 4ef4ae2f7d..b1b9a065ad 100644 --- a/platform/android/gradle/dependencies.gradle +++ b/platform/android/gradle/dependencies.gradle @@ -38,6 +38,7 @@ ext { testRules : "com.android.support.test:rules:${versions.testRunner}", testEspressoCore : "com.android.support.test.espresso:espresso-core:${versions.espresso}", testEspressoIntents : "com.android.support.test.espresso:espresso-intents:${versions.espresso}", + testEspressoContrib : "com.android.support.test.espresso:espresso-contrib:${versions.espresso}", supportAnnotations : "com.android.support:support-annotations:${versions.supportLib}", supportAppcompatV7 : "com.android.support:appcompat-v7:${versions.supportLib}", diff --git a/platform/android/src/file_source.cpp b/platform/android/src/file_source.cpp index 6a9d7badb0..728935c03f 100644 --- a/platform/android/src/file_source.cpp +++ b/platform/android/src/file_source.cpp @@ -81,6 +81,13 @@ void FileSource::pause(jni::JNIEnv&) { } } +jni::jboolean FileSource::isResumed(jni::JNIEnv&) { + if (activationCounter) { + return (jboolean) (activationCounter > 0); + } + return (jboolean) false; +} + jni::Class FileSource::javaClass; FileSource* FileSource::getNativePeer(jni::JNIEnv& env, jni::Object jFileSource) { @@ -112,7 +119,8 @@ void FileSource::registerNative(jni::JNIEnv& env) { METHOD(&FileSource::setAPIBaseUrl, "setApiBaseUrl"), METHOD(&FileSource::setResourceTransform, "setResourceTransform"), METHOD(&FileSource::resume, "activate"), - METHOD(&FileSource::pause, "deactivate") + METHOD(&FileSource::pause, "deactivate"), + METHOD(&FileSource::isResumed, "isActivated") ); } diff --git a/platform/android/src/file_source.hpp b/platform/android/src/file_source.hpp index 194f784622..e4295e1b84 100644 --- a/platform/android/src/file_source.hpp +++ b/platform/android/src/file_source.hpp @@ -45,6 +45,8 @@ public: void pause(jni::JNIEnv&); + jni::jboolean isResumed(jni::JNIEnv&); + static jni::Class javaClass; static FileSource* getNativePeer(jni::JNIEnv&, jni::Object); -- cgit v1.2.1