From 31cca05fc6a9d08d3b0028149f7ef2f2348b18e9 Mon Sep 17 00:00:00 2001 From: ryanhamley Date: Thu, 30 Aug 2018 17:18:29 -0700 Subject: Port symbol-z-order symbol layout style-spec property to Native --- .../mapbox/mapboxsdk/testapp/style/SymbolLayerTest.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java') diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerTest.java index 8cf452a6cf..98c9c27fc2 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerTest.java @@ -159,6 +159,20 @@ public class SymbolLayerTest extends BaseActivityTest { }); } + @Test + public void testSymbolZOrderAsConstant() { + validateTestSetup(); + setupLayer(); + Timber.i("symbol-z-order"); + invoke(mapboxMap, (uiController, mapboxMap) -> { + assertNotNull(layer); + + // Set and Get + layer.setProperties(symbolZOrder(SYMBOL_Z_ORDER_VIEWPORT_Y)); + assertEquals((String) layer.getSymbolZOrder().getValue(), (String) SYMBOL_Z_ORDER_VIEWPORT_Y); + }); + } + @Test public void testIconAllowOverlapAsConstant() { validateTestSetup(); -- cgit v1.2.1 From 6e171a62a9cc07ddbb0765e3021e46ebd60313df Mon Sep 17 00:00:00 2001 From: tobrun Date: Fri, 27 Jul 2018 14:00:55 +0200 Subject: [android] - replace platform default implementation using nunicode for uppercasing an lowercasing with an Android specific String.java equivalent --- .../testapp/string/UppperLowerCaseTest.java | 50 ++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/string/UppperLowerCaseTest.java (limited to 'platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java') diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/string/UppperLowerCaseTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/string/UppperLowerCaseTest.java new file mode 100644 index 0000000000..f5b4586a86 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/string/UppperLowerCaseTest.java @@ -0,0 +1,50 @@ +package com.mapbox.mapboxsdk.testapp.string; + +import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest; +import com.mapbox.mapboxsdk.testapp.activity.espresso.EspressoTestActivity; +import org.junit.Test; + +import static junit.framework.Assert.assertEquals; + +/** + * Test verifying if String#toUpperCase and String#toLowerCase produces desired results + *

+ * See core test in https://github.com/mapbox/mapbox-gl-native/blob/master/test/util/text_conversions.test.cpp + *

+ */ +public class UppperLowerCaseTest extends BaseActivityTest { + + @Override + protected Class getActivityClass() { + return EspressoTestActivity.class; + } + + @Test + public void testToUpperCase() { + assertEquals("STREET", "strEEt".toUpperCase()); // EN + assertEquals("ROAD", "rOAd".toUpperCase()); // EN + + assertEquals("STRASSE", "straße".toUpperCase()); // DE + assertEquals("MASSE", "maße".toUpperCase()); // DE + assertEquals("WEISSKOPFSEEADLER", "weißkopfseeadler".toUpperCase()); // DE + + assertEquals("BÊNÇÃO", "bênção".toUpperCase()); // PT + assertEquals("AZƏRBAYCAN", "Azərbaycan".toUpperCase()); // AZ + assertEquals("ὈΔΥΣΣΕΎΣ", "Ὀδυσσεύς".toUpperCase()); // GR + } + + @Test + public void testToLowerCase() { + assertEquals("street", "strEEt".toLowerCase()); // EN + assertEquals("road", "rOAd".toLowerCase()); // EN + + assertEquals("straße", "Straße".toLowerCase()); // DE + assertEquals("strasse", "STRASSE".toLowerCase()); // DE + assertEquals("masse", "MASSE".toLowerCase()); // DE + assertEquals("weisskopfseeadler", "weiSSkopfseeadler".toLowerCase()); // DE + + assertEquals("bênção", "BÊNÇÃO".toLowerCase()); // PT + assertEquals("azərbaycan", "AZƏRBAYCAN".toLowerCase()); // + } + +} -- cgit v1.2.1 From 5d000d090fd1d69fb902fd5b477d3bb996e3c955 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Tue, 28 Aug 2018 17:06:21 +0200 Subject: [android] merge LocationLayerPlugin to Maps SDK --- .../locationlayer/LocationLayerPluginTest.kt | 1089 ++++++++++++++++++++ .../plugins/locationlayer/LocationLayerTest.kt | 356 +++++++ .../mapboxsdk/plugins/utils/GenericPluginAction.kt | 48 + .../mapboxsdk/plugins/utils/MapboxTestingUtils.kt | 79 ++ .../utils/OnMapFragmentReadyIdlingResource.kt | 39 + .../plugins/utils/OnMapReadyIdlingResource.java | 63 ++ .../plugins/utils/PluginGenerationUtil.kt | 51 + .../plugins/utils/StyleChangeIdlingResource.kt | 46 + .../mapboxsdk/plugins/utils/TestLifecycleOwner.kt | 19 + 9 files changed, 1790 insertions(+) create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.kt create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/GenericPluginAction.kt create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/MapboxTestingUtils.kt create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/OnMapFragmentReadyIdlingResource.kt create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/OnMapReadyIdlingResource.java create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/PluginGenerationUtil.kt create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/StyleChangeIdlingResource.kt create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/TestLifecycleOwner.kt (limited to 'platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java') diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt new file mode 100644 index 0000000000..12a64850b0 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt @@ -0,0 +1,1089 @@ +package com.mapbox.mapboxsdk.plugins.locationlayer + +import android.Manifest +import android.R +import android.arch.lifecycle.Lifecycle +import android.content.Context +import android.graphics.Color +import android.graphics.RectF +import android.location.Location +import android.support.test.espresso.Espresso.onView +import android.support.test.espresso.IdlingRegistry +import android.support.test.espresso.UiController +import android.support.test.espresso.assertion.ViewAssertions.matches +import android.support.test.espresso.matcher.ViewMatchers.* +import android.support.test.filters.LargeTest +import android.support.test.rule.ActivityTestRule +import android.support.test.rule.GrantPermissionRule +import android.support.test.runner.AndroidJUnit4 +import android.support.v4.content.ContextCompat +import com.mapbox.geojson.Point +import com.mapbox.mapboxsdk.camera.CameraPosition +import com.mapbox.mapboxsdk.camera.CameraUpdateFactory +import com.mapbox.mapboxsdk.constants.Style +import com.mapbox.mapboxsdk.geometry.LatLng +import com.mapbox.mapboxsdk.maps.MapView +import com.mapbox.mapboxsdk.maps.MapboxMap +import com.mapbox.mapboxsdk.maps.MapboxMapOptions +import com.mapbox.mapboxsdk.maps.SupportMapFragment +import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.* +import com.mapbox.mapboxsdk.plugins.locationlayer.modes.CameraMode +import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode +import com.mapbox.mapboxsdk.plugins.utils.* +import com.mapbox.mapboxsdk.plugins.utils.MapboxTestingUtils.Companion.MAPBOX_HEAVY_STYLE +import com.mapbox.mapboxsdk.plugins.utils.MapboxTestingUtils.Companion.pushSourceUpdates +import com.mapbox.mapboxsdk.plugins.utils.PluginGenerationUtil.Companion.MAP_CONNECTION_DELAY +import com.mapbox.mapboxsdk.plugins.utils.PluginGenerationUtil.Companion.MAP_RENDER_DELAY +import com.mapbox.mapboxsdk.style.layers.PropertyFactory +import com.mapbox.mapboxsdk.style.sources.GeoJsonSource +import com.mapbox.mapboxsdk.testapp.activity.SingleFragmentActivity +import org.hamcrest.CoreMatchers.* +import org.junit.* +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue +import org.junit.rules.TestName +import org.junit.runner.RunWith +import timber.log.Timber + +/** + * Test class that uses a map fragment to keep onMapReady actions isolated to within the test + */ +@RunWith(AndroidJUnit4::class) +@LargeTest +class LocationLayerPluginTest { + + @Rule + @JvmField + val activityRule = ActivityTestRule(SingleFragmentActivity::class.java, true, true) + + @Rule + @JvmField + val nameRule = TestName() + + @Rule + @JvmField + val permissionRule: GrantPermissionRule = GrantPermissionRule.grant(Manifest.permission.ACCESS_FINE_LOCATION) + + private lateinit var idlingResource: OnMapFragmentReadyIdlingResource + private lateinit var styleChangeIdlingResource: StyleChangeIdlingResource + private lateinit var fragment: SupportMapFragment + private lateinit var mapboxMap: MapboxMap + private val location: Location by lazy { + val initLocation = Location("test") + initLocation.latitude = 15.0 + initLocation.longitude = 17.0 + initLocation + } + + @Before + fun beforeTest() { + + // Create a default support map fragment and pass it into the empty activity + val options = MapboxMapOptions() + .camera(CameraPosition.Builder().zoom(2.0).build()) // to match plugins min zoom + fragment = SupportMapFragment.newInstance(options) + activityRule.activity.setFragment(fragment) + + Timber.e("@Before: ${nameRule.methodName} - register idle resource") + // If idlingResource is null, throw Kotlin exception + idlingResource = OnMapFragmentReadyIdlingResource(fragment) + styleChangeIdlingResource = StyleChangeIdlingResource() + IdlingRegistry.getInstance().register(idlingResource) + IdlingRegistry.getInstance().register(styleChangeIdlingResource) + onView(withId(R.id.content)).check(matches(isDisplayed())) + mapboxMap = idlingResource.mapboxMap + } + + @Test + fun locationLayerPlugin_initializesLocationEngineCorrectlyWhenOnesNotProvided() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + + val locationEngine = plugin.locationEngine + assertThat(locationEngine, notNullValue()) + + uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) + assertThat(locationEngine?.isConnected, `is`(true)) + } + } + + executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, true)) + } + + @Test + fun locationLayerPlugin_initializesLocationEngineCorrectlyWhenOnesNotProvidedButHasOptions() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + + val locationEngine = plugin.locationEngine + val pluginOptions = plugin.locationLayerOptions + + assertThat(locationEngine, notNullValue()) + assertThat(pluginOptions, notNullValue()) + + uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) + assertThat(locationEngine?.isConnected, `is`(true)) + assertThat(pluginOptions?.accuracyAlpha(), `is`(.5f)) + assertThat(pluginOptions?.accuracyColor(), `is`(Color.BLUE)) + } + } + + val options = LocationLayerOptions.builder(fragment.activity) + .staleStateTimeout(200) + .enableStaleState(false) + .accuracyAlpha(.5f) + .accuracyColor(Color.BLUE) + .build() + + executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider( + activityRule.activity, true, null, options)) + } + + @Test + fun settingMapStyleImmediatelyBeforeLoadingPlugin_doesStillLoadLayersProperly() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + + uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) + + assertThat(plugin.renderMode, `is`(equalTo(RenderMode.NORMAL))) + assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(SHADOW_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(BEARING_LAYER), `is`(false)) + } + } + + executePluginTest(pluginAction, object : GenericPluginAction.PluginProvider { + override fun providePlugin(mapView: MapView, mapboxMap: MapboxMap, context: Context): LocationLayerPlugin { + // changing the style just before instantiating the plugin + mapboxMap.setStyleUrl(Style.LIGHT) + val plugin = + PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, null, false) + .providePlugin(mapView, mapboxMap, context) + plugin.forceLocationUpdate(location) + return plugin + } + + override fun isPluginDataReady(plugin: LocationLayerPlugin, mapboxMap: MapboxMap): Boolean { + val source = mapboxMap.getSource(LOCATION_SOURCE) + return source != null && (source as GeoJsonSource).querySourceFeatures(null).isNotEmpty() + } + }) + } + + @Test + fun locationLayer_doesntShowUntilFirstLocationFix() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + + // Source should be present but empty + val mapView = fragment.view as MapView + assertThat(mapboxMap.queryRenderedFeatures( + RectF(0f, 0f, mapView.width.toFloat(), mapView.height.toFloat()), FOREGROUND_LAYER) + .isEmpty(), `is`(true)) + + // Force the first location update + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) + + // Check if the puck is visible + assertThat(mapboxMap.queryRenderedFeatures(location, FOREGROUND_LAYER).isEmpty(), `is`(false)) + } + } + executePluginTest(pluginAction) + } + + // + // Location Layer Options + // + + @Test + fun locationLayerOptions_disablingStaleStateDoesWorkCorrectly() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(200) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + + mapboxMap.querySourceFeatures(LOCATION_SOURCE).also { + it.forEach { + assertThat(it.getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(false)) + } + } + } + } + + val options = LocationLayerOptions.builder(fragment.activity) + .staleStateTimeout(200) + .enableStaleState(false) + .build() + executePluginTest(pluginAction, + PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, options)) + } + + @Test + fun locationLayerOptions_loadsForegroundBitmapFromNameOption() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + val foregroundDrawable = ContextCompat.getDrawable(context, R.drawable.ic_media_play) + mapboxMap.addImageFromDrawable("custom-foreground-bitmap", foregroundDrawable!!) + mapboxMap.addImageFromDrawable("custom-background-bitmap", foregroundDrawable) + mapboxMap.addImageFromDrawable("custom-foreground-stale-bitmap", foregroundDrawable) + mapboxMap.addImageFromDrawable("custom-background-stale-bitmap", foregroundDrawable) + mapboxMap.addImageFromDrawable("custom-bearing-bitmap", foregroundDrawable) + + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) + assertThat(mapboxMap.queryRenderedFeatures(location, FOREGROUND_LAYER).isEmpty(), `is`(false)) + + val feature = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0] + assertThat(feature.getStringProperty(PROPERTY_FOREGROUND_ICON), `is`(equalTo("custom-foreground-bitmap"))) + assertThat(feature.getStringProperty(PROPERTY_BACKGROUND_ICON), `is`(equalTo("custom-background-bitmap"))) + assertThat(feature.getStringProperty(PROPERTY_FOREGROUND_STALE_ICON), `is`(equalTo("custom-foreground-stale-bitmap"))) + assertThat(feature.getStringProperty(PROPERTY_BACKGROUND_STALE_ICON), `is`(equalTo("custom-background-stale-bitmap"))) + assertThat(feature.getStringProperty(PROPERTY_BEARING_ICON), `is`(equalTo("custom-bearing-bitmap"))) + } + } + + val options = LocationLayerOptions.builder(fragment.activity) + .foregroundName("custom-foreground-bitmap") + .backgroundName("custom-background-bitmap") + .foregroundStaleName("custom-foreground-stale-bitmap") + .backgroundStaleName("custom-background-stale-bitmap") + .bearingName("custom-bearing-bitmap") + .build() + executePluginTest(pluginAction, + PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, options)) + } + + @Test + fun locationLayerOptions_loadsGpsNameWithGpsRenderMode() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.renderMode = RenderMode.GPS + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + val foregroundDrawable = ContextCompat.getDrawable(context, R.drawable.ic_media_play) + mapboxMap.addImageFromDrawable("custom-foreground-bitmap", foregroundDrawable!!) + mapboxMap.addImageFromDrawable("custom-gps-bitmap", foregroundDrawable) + + val foregroundId = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getStringProperty(PROPERTY_FOREGROUND_ICON) + assertThat(foregroundId, `is`(equalTo("custom-gps-bitmap"))) + } + } + + val options = LocationLayerOptions.builder(fragment.activity) + .foregroundName("custom-foreground-bitmap") + .gpsName("custom-gps-bitmap") + .build() + executePluginTest(pluginAction, + PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, options)) + } + + @Test + fun locationLayerOptions_customIconNameRevertsToDefault() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.renderMode = RenderMode.GPS + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + + val foregroundId = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getStringProperty(PROPERTY_FOREGROUND_ICON) + assertThat(foregroundId, `is`(equalTo("custom-gps-bitmap"))) + + plugin.applyStyle(LocationLayerOptions.builder(fragment.activity).build()) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + + val revertedForegroundId = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getStringProperty(PROPERTY_FOREGROUND_ICON) + assertThat(revertedForegroundId, `is`(equalTo(FOREGROUND_ICON))) + } + } + + val options = LocationLayerOptions.builder(fragment.activity) + .foregroundName("custom-foreground-bitmap") + .gpsName("custom-gps-bitmap") + .build() + executePluginTest(pluginAction, + PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, options)) + } + + @Test + fun locationLayerOptions_customGpsIconNameChangeBackWithMode() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.renderMode = RenderMode.GPS + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + + val foregroundId = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getStringProperty(PROPERTY_FOREGROUND_ICON) + assertThat(foregroundId, `is`(equalTo("custom-gps-bitmap"))) + + plugin.renderMode = RenderMode.NORMAL + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + + val revertedForegroundId = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getStringProperty(PROPERTY_FOREGROUND_ICON) + assertThat(revertedForegroundId, `is`(equalTo(FOREGROUND_ICON))) + } + } + + val options = LocationLayerOptions.builder(fragment.activity) + .gpsName("custom-gps-bitmap") + .build() + executePluginTest(pluginAction, + PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, options)) + } + + @Test + fun stillStaleAfterResuming() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + val testLifecycleOwner = TestLifecycleOwner() + testLifecycleOwner.markState(Lifecycle.State.RESUMED) + testLifecycleOwner.lifecycle.addObserver(plugin) + + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(300) // engaging stale state + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(true)) + + testLifecycleOwner.markState(Lifecycle.State.CREATED) + testLifecycleOwner.markState(Lifecycle.State.RESUMED) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + + assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(true)) + assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(false)) + } + } + val options = LocationLayerOptions.builder(fragment.activity) + .staleStateTimeout(200) + .build() + executePluginTest(pluginAction, + PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, options, false)) + } + + @Test + fun stillNotStaleAfterResuming() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + val testLifecycleOwner = TestLifecycleOwner() + testLifecycleOwner.markState(Lifecycle.State.RESUMED) + testLifecycleOwner.lifecycle.addObserver(plugin) + + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(false)) + + testLifecycleOwner.markState(Lifecycle.State.CREATED) + testLifecycleOwner.markState(Lifecycle.State.RESUMED) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + + assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(false)) + assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(true)) + } + } + executePluginTest(pluginAction, + PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + } + + @Test + fun locationLayerOptions_accuracyRingWithColor() { + val color = Color.parseColor("#4A90E2") + val rgbaColor = PropertyFactory.colorToRgbaString(color) + + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + + // Check that the source property changes correctly + mapboxMap.querySourceFeatures(LOCATION_SOURCE).also { + it.forEach { + assertThat(it.getStringProperty(PROPERTY_ACCURACY_COLOR), `is`(equalTo(rgbaColor))) + } + } + } + } + + val options = LocationLayerOptions.builder(fragment.activity) + .accuracyColor(color) + .build() + executePluginTest(pluginAction, + PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, options)) + } + + @Test + fun forceLocationUpdate_doesMoveLocationLayerIconToCorrectPosition() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + + plugin.forceLocationUpdate(location) + + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + + val point: Point = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].geometry() as Point + + assertThat(plugin.locationEngine, nullValue()) + assertEquals(point.latitude(), location.latitude, 0.1) + assertEquals(point.longitude(), location.longitude, 0.1) + } + } + executePluginTest(pluginAction) + } + + @Test + fun disablingPluginHidesPuck() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + val point: Point = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].geometry() as Point + assertEquals(point.latitude(), location.latitude, 0.1) + assertEquals(point.longitude(), location.longitude, 0.1) + + plugin.isLocationLayerEnabled = false + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE).isEmpty(), `is`(true)) + } + } + executePluginTest(pluginAction) + } + + @Test + fun disablingPluginAndChangingStyleAllowsToEnableAgain() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + + plugin.isLocationLayerEnabled = false + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + mapboxMap.setStyle(Style.LIGHT) + uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) + plugin.isLocationLayerEnabled = true + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true)) + } + } + executePluginTest(pluginAction) + } + + @Test + fun lifecycle_keepsEnabledWhenStoppedAndStarted() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + val testLifecycleOwner = TestLifecycleOwner() + testLifecycleOwner.markState(Lifecycle.State.RESUMED) + testLifecycleOwner.lifecycle.addObserver(plugin) + + assertThat(plugin.isLocationLayerEnabled, `is`(true)) + testLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE) + testLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_STOP) + testLifecycleOwner.markState(Lifecycle.State.RESUMED) + assertThat(plugin.isLocationLayerEnabled, `is`(true)) + } + } + executePluginTest(pluginAction, + PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, null, false)) + } + + @Test + fun lifecycle_keepsDisabledWhenStoppedAndStarted() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.isLocationLayerEnabled = false + + val testLifecycleOwner = TestLifecycleOwner() + testLifecycleOwner.markState(Lifecycle.State.RESUMED) + testLifecycleOwner.lifecycle.addObserver(plugin) + + assertThat(plugin.isLocationLayerEnabled, `is`(false)) + testLifecycleOwner.markState(Lifecycle.State.CREATED) + testLifecycleOwner.markState(Lifecycle.State.RESUMED) + assertThat(plugin.isLocationLayerEnabled, `is`(false)) + } + } + executePluginTest(pluginAction, + PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, null, false)) + } + + @Test + fun lifecycle_ableToChangeStyleAfterResuming() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + + val testLifecycleOwner = TestLifecycleOwner() + testLifecycleOwner.markState(Lifecycle.State.RESUMED) + testLifecycleOwner.lifecycle.addObserver(plugin) + + testLifecycleOwner.markState(Lifecycle.State.CREATED) + testLifecycleOwner.markState(Lifecycle.State.RESUMED) + + mapboxMap.setStyle(Style.DARK) + uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) + } + } + executePluginTest(pluginAction, + PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, null, false)) + } + + @Test + fun lifecycle_interruptedDuringStyleChange() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + + val testLifecycleOwner = TestLifecycleOwner() + testLifecycleOwner.markState(Lifecycle.State.RESUMED) + testLifecycleOwner.lifecycle.addObserver(plugin) + mapboxMap.setStyle(Style.DARK) + + testLifecycleOwner.markState(Lifecycle.State.CREATED) + testLifecycleOwner.markState(Lifecycle.State.RESUMED) + uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) + } + } + executePluginTest(pluginAction, + PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, null, false)) + } + + @Test + fun lifecycle_forceLocationUpdateAfterStopped() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + + val testLifecycleOwner = TestLifecycleOwner() + testLifecycleOwner.markState(Lifecycle.State.RESUMED) + testLifecycleOwner.lifecycle.addObserver(plugin) + + testLifecycleOwner.markState(Lifecycle.State.CREATED) + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + + assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE).isEmpty(), `is`(true)) + } + } + executePluginTest(pluginAction, + PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, null, false)) + } + + @Test + fun lifecycle_acceptAndReuseLocationUpdatesBeforeLayerStarted() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + + val testLifecycleOwner = TestLifecycleOwner() + testLifecycleOwner.markState(Lifecycle.State.RESUMED) + testLifecycleOwner.lifecycle.addObserver(plugin) + + testLifecycleOwner.markState(Lifecycle.State.CREATED) + plugin.forceLocationUpdate(location) + testLifecycleOwner.markState(Lifecycle.State.RESUMED) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + + val point: Point = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].geometry() as Point + assertEquals(point.latitude(), location.latitude, 0.1) + assertEquals(point.longitude(), location.longitude, 0.1) + } + } + executePluginTest(pluginAction, + PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, null, false)) + } + + @Test + fun lifecycle_lifecycleChangeRightAfterStyleReload() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + + val testLifecycleOwner = TestLifecycleOwner() + testLifecycleOwner.markState(Lifecycle.State.RESUMED) + testLifecycleOwner.lifecycle.addObserver(plugin) + + plugin.forceLocationUpdate(location) + mapboxMap.setStyle(Style.LIGHT) + testLifecycleOwner.markState(Lifecycle.State.CREATED) + uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) + testLifecycleOwner.markState(Lifecycle.State.RESUMED) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + + val point: Point = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].geometry() as Point + assertEquals(point.latitude(), location.latitude, 0.1) + assertEquals(point.longitude(), location.longitude, 0.1) + + assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(SHADOW_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(BEARING_LAYER), `is`(false)) + } + } + executePluginTest(pluginAction, + PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, null, false)) + } + + @Test + fun mapChange_settingPluginStyle() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + styleChangeIdlingResource.waitForStyle(fragment.view as MapView, mapboxMap, MAPBOX_HEAVY_STYLE) + val options = LocationLayerOptions.builder(fragment.activity) + .accuracyColor(Color.RED) + .build() + + pushSourceUpdates(styleChangeIdlingResource) { + plugin.applyStyle(options) + } + + uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) + } + } + executePluginTest(pluginAction, + PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + + // Waiting for style to finish loading while pushing updates + onView(withId(R.id.content)).check(matches(isDisplayed())) + } + + @Test + fun mapChange_forcingLocation() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + styleChangeIdlingResource.waitForStyle(fragment.view as MapView, mapboxMap, MAPBOX_HEAVY_STYLE) + + pushSourceUpdates(styleChangeIdlingResource) { + plugin.forceLocationUpdate(location) + } + + uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) + } + } + executePluginTest(pluginAction, + PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + + // Waiting for style to finish loading while pushing updates + onView(withId(R.id.content)).check(matches(isDisplayed())) + } + + @Test + fun mapChange_settingMapStyleBeforePluginCreation() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + val options = LocationLayerOptions.builder(fragment.activity) + .accuracyColor(Color.RED) + .build() + + pushSourceUpdates(styleChangeIdlingResource) { + plugin.forceLocationUpdate(location) + plugin.applyStyle(options) + } + } + } + + executePluginTest(pluginAction, object : GenericPluginAction.PluginProvider { + override fun providePlugin(mapView: MapView, mapboxMap: MapboxMap, context: Context): LocationLayerPlugin { + // changing the style just before instantiating the plugin + styleChangeIdlingResource.waitForStyle(mapView, mapboxMap, MAPBOX_HEAVY_STYLE) + return PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, null, false) + .providePlugin(mapView, mapboxMap, context) + } + + override fun isPluginDataReady(plugin: LocationLayerPlugin, mapboxMap: MapboxMap): Boolean { + return true + } + }) + + // Waiting for style to finish loading while pushing updates + onView(withId(R.id.content)).check(matches(isDisplayed())) + } + + @Test + fun animators_layerBearingCorrect() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.renderMode = RenderMode.GPS + location.bearing = 77f + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(1000) + assertEquals(77.0, mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getNumberProperty(PROPERTY_GPS_BEARING) as Double, 0.1) + + location.bearing = 92f + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(2000) // Waiting for the animation to finish + assertEquals(92.0, mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getNumberProperty(PROPERTY_GPS_BEARING) as Double, 0.1) + } + } + + executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + } + + @Test + fun animators_cameraLatLngBearingCorrect() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.cameraMode = CameraMode.TRACKING_GPS + location.bearing = 77f + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(1000) + assertEquals(77.0, mapboxMap.cameraPosition.bearing, 0.1) + assertEquals(location.latitude, mapboxMap.cameraPosition.target.latitude, 0.1) + assertEquals(location.longitude, mapboxMap.cameraPosition.target.longitude, 0.1) + + location.bearing = 92f + location.latitude = 30.0 + location.longitude = 35.0 + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(2000) // Waiting for the animation to finish + assertEquals(92.0, mapboxMap.cameraPosition.bearing, 0.1) + assertEquals(location.latitude, mapboxMap.cameraPosition.target.latitude, 0.1) + assertEquals(location.longitude, mapboxMap.cameraPosition.target.longitude, 0.1) + } + } + + executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + } + + @Test + fun animators_cameraBearingCorrect() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.cameraMode = CameraMode.NONE_GPS + val latitude = mapboxMap.cameraPosition.target.latitude + val longitude = mapboxMap.cameraPosition.target.longitude + + location.bearing = 77f + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(1000) + assertEquals(77.0, mapboxMap.cameraPosition.bearing, 0.1) + assertEquals(latitude, mapboxMap.cameraPosition.target.latitude, 0.1) + assertEquals(longitude, mapboxMap.cameraPosition.target.longitude, 0.1) + + location.bearing = 92f + location.latitude = 30.0 + location.longitude = 35.0 + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(2000) // Waiting for the animation to finish + assertEquals(92.0, mapboxMap.cameraPosition.bearing, 0.1) + assertEquals(latitude, mapboxMap.cameraPosition.target.latitude, 0.1) + assertEquals(longitude, mapboxMap.cameraPosition.target.longitude, 0.1) + } + } + + executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + } + + @Test + fun animators_cameraNoneCorrect() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.cameraMode = CameraMode.NONE + val latitude = mapboxMap.cameraPosition.target.latitude + val longitude = mapboxMap.cameraPosition.target.longitude + val bearing = mapboxMap.cameraPosition.bearing + + location.bearing = 77f + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(1000) + assertEquals(bearing, mapboxMap.cameraPosition.bearing, 0.1) + assertEquals(latitude, mapboxMap.cameraPosition.target.latitude, 0.1) + assertEquals(longitude, mapboxMap.cameraPosition.target.longitude, 0.1) + + location.bearing = 92f + location.latitude = 30.0 + location.longitude = 35.0 + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(2000) // Waiting for the animation to finish + assertEquals(bearing, mapboxMap.cameraPosition.bearing, 0.1) + assertEquals(latitude, mapboxMap.cameraPosition.target.latitude, 0.1) + assertEquals(longitude, mapboxMap.cameraPosition.target.longitude, 0.1) + } + } + + executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + } + + @Test + fun animators_focalPointAdjustment() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.cameraMode = CameraMode.TRACKING + plugin.cameraMode = CameraMode.NONE + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + + assertThat(mapboxMap.uiSettings.focalPoint, nullValue()) + } + } + + executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + } + + @Test + fun animators_dontZoomWhileNotTracking() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.cameraMode = CameraMode.NONE + val zoom = mapboxMap.cameraPosition.zoom + plugin.zoomWhileTracking(10.0) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIMATION_DURATION) + + assertEquals(zoom, mapboxMap.cameraPosition.zoom, 0.1) + } + } + + executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + } + + @Test + fun animators_zoomWhileTracking() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.cameraMode = CameraMode.TRACKING + plugin.zoomWhileTracking(10.0) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIMATION_DURATION) + + assertEquals(10.0, mapboxMap.cameraPosition.zoom, 0.1) + } + } + + executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + } + + @Test + @Ignore + fun animators_zoomWhileTrackingCanceledOnModeChange() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.cameraMode = CameraMode.TRACKING + plugin.zoomWhileTracking(15.0) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIMATION_DURATION / 2) + plugin.cameraMode = CameraMode.NONE + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIMATION_DURATION / 2) + + assertEquals(15.0 / 2.0, mapboxMap.cameraPosition.zoom, 3.0) + } + } + + executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + } + + @Test + fun animators_dontZoomWhileStopped() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + + val testLifecycleOwner = TestLifecycleOwner() + testLifecycleOwner.markState(Lifecycle.State.RESUMED) + testLifecycleOwner.lifecycle.addObserver(plugin) + + plugin.cameraMode = CameraMode.TRACKING + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + val zoom = mapboxMap.cameraPosition.zoom + + testLifecycleOwner.markState(Lifecycle.State.CREATED) + plugin.zoomWhileTracking(10.0) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIMATION_DURATION) + + assertEquals(zoom, mapboxMap.cameraPosition.zoom, 0.1) + } + } + + executePluginTest(pluginAction, + PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, null, false)) + } + + @Test + @Ignore + fun animators_cancelZoomWhileTracking() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.cameraMode = CameraMode.TRACKING + plugin.zoomWhileTracking(15.0) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIMATION_DURATION / 2) + plugin.cancelZoomWhileTrackingAnimation() + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIMATION_DURATION / 2) + + assertEquals(15.0 / 2.0, mapboxMap.cameraPosition.zoom, 3.0) + } + } + + executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + } + + @Test + fun animators_dontTiltWhileNotTracking() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.cameraMode = CameraMode.NONE + val tilt = mapboxMap.cameraPosition.tilt + plugin.tiltWhileTracking(30.0) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIMATION_DURATION) + + assertEquals(tilt, mapboxMap.cameraPosition.tilt, 0.1) + } + } + + executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + } + + @Test + fun animators_tiltWhileTracking() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.cameraMode = CameraMode.TRACKING + plugin.tiltWhileTracking(30.0) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIMATION_DURATION) + + assertEquals(30.0, mapboxMap.cameraPosition.tilt, 0.1) + } + } + + executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + } + + @Test + @Ignore + fun animators_tiltWhileTrackingCanceledOnModeChange() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.cameraMode = CameraMode.TRACKING + plugin.tiltWhileTracking(30.0) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIMATION_DURATION / 2) + plugin.cameraMode = CameraMode.NONE + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIMATION_DURATION / 2) + + assertEquals(30.0 / 2.0, mapboxMap.cameraPosition.tilt, 3.0) + } + } + + executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + } + + @Test + fun animators_dontTiltWhileStopped() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + + val testLifecycleOwner = TestLifecycleOwner() + testLifecycleOwner.markState(Lifecycle.State.RESUMED) + testLifecycleOwner.lifecycle.addObserver(plugin) + + plugin.cameraMode = CameraMode.TRACKING + val tilt = mapboxMap.cameraPosition.tilt + + testLifecycleOwner.markState(Lifecycle.State.CREATED) + plugin.tiltWhileTracking(30.0) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIMATION_DURATION) + + assertEquals(tilt, mapboxMap.cameraPosition.tilt, 0.1) + } + } + + executePluginTest(pluginAction, + PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, null, false)) + } + + @Test + @Ignore + fun animators_cancelTiltWhileTracking() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.cameraMode = CameraMode.TRACKING + plugin.tiltWhileTracking(30.0) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIMATION_DURATION / 2) + plugin.cancelTiltWhileTrackingAnimation() + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIMATION_DURATION / 2) + + assertEquals(30.0 / 2.0, mapboxMap.cameraPosition.tilt, 3.0) + } + } + + executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + } + + @Test + fun cameraPositionAdjustedToTrackingModeWhenPluginEnabled() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.cameraMode = CameraMode.TRACKING_GPS + plugin.forceLocationUpdate(location) + plugin.isLocationLayerEnabled = false + mapboxMap.moveCamera(CameraUpdateFactory.newLatLng(LatLng(51.0, 17.0))) + mapboxMap.moveCamera(CameraUpdateFactory.bearingTo(90.0)) + plugin.isLocationLayerEnabled = true + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + + assertEquals(location.bearing.toDouble(), mapboxMap.cameraPosition.bearing, 0.1) + assertEquals(location.latitude, mapboxMap.cameraPosition.target.latitude, 0.1) + assertEquals(location.longitude, mapboxMap.cameraPosition.target.longitude, 0.1) + } + } + + executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + } + + @Test + fun onPluginInitialized_defaultCompassEngineIsProvided() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + assertTrue(plugin.compassEngine is LocationLayerCompassEngine) + } + } + + executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + } + + @After + fun afterTest() { + Timber.e("@After: ${nameRule.methodName} - unregister idle resource") + IdlingRegistry.getInstance().unregister(idlingResource) + IdlingRegistry.getInstance().unregister(styleChangeIdlingResource) + } + + private fun executePluginTest(listener: GenericPluginAction.OnPerformGenericPluginAction, + pluginProvider: GenericPluginAction.PluginProvider = PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) { + onView(withId(R.id.content)).perform(GenericPluginAction(fragment.view as MapView, mapboxMap, pluginProvider, listener)) + } +} \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.kt new file mode 100644 index 0000000000..121c8f2d22 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.kt @@ -0,0 +1,356 @@ +package com.mapbox.mapboxsdk.plugins.locationlayer + +import android.Manifest +import android.R +import android.content.Context +import android.location.Location +import android.support.test.espresso.Espresso.onView +import android.support.test.espresso.IdlingRegistry +import android.support.test.espresso.UiController +import android.support.test.espresso.assertion.ViewAssertions.matches +import android.support.test.espresso.matcher.ViewMatchers.isDisplayed +import android.support.test.espresso.matcher.ViewMatchers.withId +import android.support.test.filters.LargeTest +import android.support.test.rule.ActivityTestRule +import android.support.test.rule.GrantPermissionRule +import android.support.test.rule.GrantPermissionRule.grant +import android.support.test.runner.AndroidJUnit4 +import com.mapbox.mapboxsdk.camera.CameraUpdateFactory +import com.mapbox.mapboxsdk.constants.Style +import com.mapbox.mapboxsdk.geometry.LatLng +import com.mapbox.mapboxsdk.maps.MapboxMap +import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.* +import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode +import com.mapbox.mapboxsdk.plugins.utils.* +import com.mapbox.mapboxsdk.plugins.utils.MapboxTestingUtils.Companion.MAPBOX_HEAVY_STYLE +import com.mapbox.mapboxsdk.plugins.utils.MapboxTestingUtils.Companion.pushSourceUpdates +import com.mapbox.mapboxsdk.plugins.utils.PluginGenerationUtil.Companion.MAP_CONNECTION_DELAY +import com.mapbox.mapboxsdk.plugins.utils.PluginGenerationUtil.Companion.MAP_RENDER_DELAY +import com.mapbox.mapboxsdk.style.sources.GeoJsonSource +import com.mapbox.mapboxsdk.testapp.activity.SingleActivity +import org.hamcrest.CoreMatchers.`is` +import org.hamcrest.CoreMatchers.notNullValue +import org.hamcrest.Matchers.equalTo +import org.junit.After +import org.junit.Assert.assertEquals +import org.junit.Assert.assertThat +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.rules.TestName +import org.junit.runner.RunWith +import timber.log.Timber + +@RunWith(AndroidJUnit4::class) +@LargeTest +class LocationLayerTest { + + @Rule + @JvmField + val activityRule = ActivityTestRule(SingleActivity::class.java) + + @Rule + @JvmField + val nameRule = TestName() + + @Rule + @JvmField + val permissionRule: GrantPermissionRule = grant(Manifest.permission.ACCESS_FINE_LOCATION) + + private lateinit var idlingResource: OnMapReadyIdlingResource + private lateinit var styleChangeIdlingResource: StyleChangeIdlingResource + private lateinit var mapboxMap: MapboxMap + private val location: Location by lazy { + val initLocation = Location("test") + initLocation.latitude = 15.0 + initLocation.longitude = 17.0 + initLocation.accuracy = 2000f + initLocation + } + + @Before + fun beforeTest() { + Timber.e("@Before: ${nameRule.methodName} - register idle resource") + // If idlingResource is null, throw Kotlin exception + idlingResource = OnMapReadyIdlingResource(activityRule.activity) + styleChangeIdlingResource = StyleChangeIdlingResource() + IdlingRegistry.getInstance().register(idlingResource) + IdlingRegistry.getInstance().register(styleChangeIdlingResource) + onView(withId(android.R.id.content)).check(matches(isDisplayed())) + mapboxMap = idlingResource.mapboxMap + } + + // + // Location Source + // + + @Test + fun renderModeNormal_sourceDoesGetAdded() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.renderMode = RenderMode.NORMAL + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + assertThat(mapboxMap.getSource(LOCATION_SOURCE), notNullValue()) + } + } + executePluginTest(pluginAction) + } + + // + // Location Layers + // + + @Test + fun renderModeNormal_trackingNormalLayersDoGetAdded() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.renderMode = RenderMode.NORMAL + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(SHADOW_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(BEARING_LAYER), `is`(false)) + } + } + executePluginTest(pluginAction) + } + + @Test + fun renderModeCompass_bearingLayersDoGetAdded() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.renderMode = RenderMode.COMPASS + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(SHADOW_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(BEARING_LAYER), `is`(true)) + } + } + executePluginTest(pluginAction) + } + + @Test + fun renderModeGps_navigationLayersDoGetAdded() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.renderMode = RenderMode.GPS + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(SHADOW_LAYER), `is`(false)) + assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(false)) + assertThat(mapboxMap.isLayerVisible(BEARING_LAYER), `is`(false)) + } + } + executePluginTest(pluginAction) + } + + @Test + fun dontShowPuckWhenRenderModeSetAndPluginDisabled() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.forceLocationUpdate(location) + plugin.isLocationLayerEnabled = false + plugin.renderMode = RenderMode.GPS + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(false)) + assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(false)) + assertThat(mapboxMap.isLayerVisible(SHADOW_LAYER), `is`(false)) + assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(false)) + assertThat(mapboxMap.isLayerVisible(BEARING_LAYER), `is`(false)) + } + } + executePluginTest(pluginAction) + } + + @Test + fun whenLocationLayerPluginDisabled_doesSetAllLayersToVisibilityNone() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.renderMode = RenderMode.NORMAL + plugin.forceLocationUpdate(location) + plugin.isLocationLayerEnabled = false + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + + // Check that all layers visibilities are set to none + assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(false)) + assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(false)) + assertThat(mapboxMap.isLayerVisible(SHADOW_LAYER), `is`(false)) + assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(false)) + assertThat(mapboxMap.isLayerVisible(BEARING_LAYER), `is`(false)) + } + } + executePluginTest(pluginAction) + } + + @Test + fun onMapChange_locationLayerLayersDoGetRedrawn() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.renderMode = RenderMode.NORMAL + plugin.forceLocationUpdate(location) + mapboxMap.setStyleUrl(Style.LIGHT) + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) + + assertThat(plugin.renderMode, `is`(equalTo(RenderMode.NORMAL))) + + // Check that the Source has been re-added to the new map style + val source: GeoJsonSource? = mapboxMap.getSourceAs(LOCATION_SOURCE) + assertThat(source, notNullValue()) + + // Check that all layers visibilities are set to visible + assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(SHADOW_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(BEARING_LAYER), `is`(false)) + } + } + executePluginTest(pluginAction) + } + +// +// Stale state test +// + + @Test + fun whenStyleChanged_continuesUsingStaleIcons() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.applyStyle(LocationLayerOptions.builder(context).staleStateTimeout(100).build()) + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(200) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + + assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(true)) + + mapboxMap.setStyleUrl(Style.LIGHT) + uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) + + assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(true)) + } + } + executePluginTest(pluginAction) + } + + @Test + fun whenStyleChanged_staleStateChanges() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.applyStyle(LocationLayerOptions.builder(context).staleStateTimeout(1).build()) + styleChangeIdlingResource.waitForStyle(idlingResource.mapView, mapboxMap, MAPBOX_HEAVY_STYLE) + pushSourceUpdates(styleChangeIdlingResource) { + plugin.forceLocationUpdate(location) + } + } + } + executePluginTest(pluginAction) + + // Waiting for style to finish loading while pushing updates + onView(withId(R.id.content)).check(matches(isDisplayed())) + } + + @Test + fun whenStyleChanged_layerVisibilityUpdates() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + styleChangeIdlingResource.waitForStyle(idlingResource.mapView, mapboxMap, MAPBOX_HEAVY_STYLE) + var show = true + pushSourceUpdates(styleChangeIdlingResource) { + plugin.isLocationLayerEnabled = show + show = !show + } + + uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) + } + } + executePluginTest(pluginAction) + + // Waiting for style to finish loading while pushing updates + onView(withId(R.id.content)).check(matches(isDisplayed())) + } + + @Test + fun accuracy_visibleWithNewLocation() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(location), 16.0)) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY + ACCURACY_RADIUS_ANIMATION_DURATION) + + assertEquals(Utils.calculateZoomLevelRadius(mapboxMap, location) /*meters projected to radius on zoom 16*/, + mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0] + .getNumberProperty(PROPERTY_ACCURACY_RADIUS).toFloat(), 0.1f) + } + } + executePluginTest(pluginAction) + } + + @Test + fun accuracy_visibleWhenCameraEased() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + mapboxMap.easeCamera(CameraUpdateFactory.newLatLngZoom(LatLng(location), 16.0), 300) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY + 300) + + assertEquals(Utils.calculateZoomLevelRadius(mapboxMap, location) /*meters projected to radius on zoom 16*/, + mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0] + .getNumberProperty(PROPERTY_ACCURACY_RADIUS).toFloat(), 0.1f) + } + } + executePluginTest(pluginAction) + } + + @Test + fun accuracy_visibleWhenCameraMoved() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(location), 16.0)) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY + 300) + + assertEquals(Utils.calculateZoomLevelRadius(mapboxMap, location) /*meters projected to radius on zoom 16*/, + mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0] + .getNumberProperty(PROPERTY_ACCURACY_RADIUS).toFloat(), 0.1f) + } + } + executePluginTest(pluginAction) + } + + @After + fun afterTest() { + Timber.e("@After: ${nameRule.methodName} - unregister idle resource") + IdlingRegistry.getInstance().unregister(idlingResource) + IdlingRegistry.getInstance().unregister(styleChangeIdlingResource) + } + + private fun executePluginTest(listener: GenericPluginAction.OnPerformGenericPluginAction) { + onView(withId(android.R.id.content)).perform(GenericPluginAction(idlingResource.mapView, mapboxMap, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity), listener)) + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/GenericPluginAction.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/GenericPluginAction.kt new file mode 100644 index 0000000000..210f7b4758 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/GenericPluginAction.kt @@ -0,0 +1,48 @@ +package com.mapbox.mapboxsdk.plugins.utils + +import android.content.Context +import android.support.test.espresso.UiController +import android.support.test.espresso.ViewAction +import android.support.test.espresso.matcher.ViewMatchers.isDisplayed +import android.view.View +import com.mapbox.mapboxsdk.maps.MapView +import com.mapbox.mapboxsdk.maps.MapboxMap +import com.mapbox.mapboxsdk.plugins.utils.PluginGenerationUtil.Companion.MAP_RENDER_DELAY +import org.hamcrest.Matcher + +class GenericPluginAction(private val mapView: MapView, private val mapboxMap: MapboxMap, private val pluginProvider: PluginProvider, + private val onPerformGenericPluginAction: OnPerformGenericPluginAction) : ViewAction { + + override fun getConstraints(): Matcher { + return isDisplayed() + } + + override fun getDescription(): String { + return javaClass.simpleName + } + + override fun perform(uiController: UiController, view: View) { + val plugin = pluginProvider.providePlugin(mapView, mapboxMap, view.context) + + // ensuring that the asynchronous renderer has time to render data we want to test + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + while (!pluginProvider.isPluginDataReady(plugin, mapboxMap)) { + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + } + + onPerformGenericPluginAction.onGenericPluginAction( + plugin, + mapboxMap, + uiController, + view.context) + } + + interface OnPerformGenericPluginAction { + fun onGenericPluginAction(plugin: T, mapboxMap: MapboxMap, uiController: UiController, context: Context) + } + + interface PluginProvider { + fun providePlugin(mapView: MapView, mapboxMap: MapboxMap, context: Context): T + fun isPluginDataReady(plugin: T, mapboxMap: MapboxMap): Boolean + } +} \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/MapboxTestingUtils.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/MapboxTestingUtils.kt new file mode 100644 index 0000000000..b65cb3278b --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/MapboxTestingUtils.kt @@ -0,0 +1,79 @@ +package com.mapbox.mapboxsdk.plugins.utils + +import android.graphics.Bitmap +import android.graphics.Canvas +import android.graphics.drawable.BitmapDrawable +import android.graphics.drawable.Drawable +import android.location.Location +import android.os.Handler +import android.os.Looper +import com.mapbox.geojson.Feature +import com.mapbox.mapboxsdk.geometry.LatLng +import com.mapbox.mapboxsdk.maps.MapboxMap +import com.mapbox.mapboxsdk.style.layers.Property +import com.mapbox.mapboxsdk.style.sources.GeoJsonSource + +fun MapboxMap.querySourceFeatures(sourceId: String): List { + return this.getSourceAs(sourceId)?.querySourceFeatures(null) as List +} + +fun MapboxMap.queryRenderedFeatures(location: Location, layerId: String): List { + val latLng = LatLng(location.latitude, location.longitude) + val point = this.projection.toScreenLocation(latLng) + return this.queryRenderedFeatures(point, layerId) +} + +fun MapboxMap.isLayerVisible(layerId: String): Boolean { + return this.getLayer(layerId)?.visibility?.value?.equals(Property.VISIBLE)!! +} + +class MapboxTestingUtils { + companion object { + + /** + * Used to increase style load time for stress testing. + */ + const val MAPBOX_HEAVY_STYLE = "asset://heavy_style.json" + + private const val DATA_PUSH_INTERVAL = 1L + + /** + * Pushes data updates every [DATA_PUSH_INTERVAL] milliseconds until the style has been loaded, + * checked with [StyleChangeIdlingResource]. + */ + fun pushSourceUpdates(styleChangeIdlingResource: StyleChangeIdlingResource, update: () -> Unit) { + val mainHandler = Handler(Looper.getMainLooper()) + val runnable = object : Runnable { + override fun run() { + update.invoke() + if (!styleChangeIdlingResource.isIdleNow) { + mainHandler.postDelayed(this, DATA_PUSH_INTERVAL) + } + } + } + + if (!styleChangeIdlingResource.isIdleNow) { + if (Looper.myLooper() == Looper.getMainLooper()) { + runnable.run() + } else { + mainHandler.post(runnable) + } + } + } + } +} + +fun MapboxMap.addImageFromDrawable(string: String, drawable: Drawable) { + val bitmapFromDrawable = getBitmapFromDrawable(drawable) + this.addImage(string, bitmapFromDrawable) +} + +private fun getBitmapFromDrawable(drawable: Drawable): Bitmap { + if (drawable is BitmapDrawable) return drawable.bitmap + val bitmap = Bitmap.createBitmap(drawable.intrinsicWidth, + drawable.intrinsicHeight, Bitmap.Config.ARGB_8888) + val canvas = Canvas(bitmap) + drawable.setBounds(0, 0, canvas.width, canvas.height) + drawable.draw(canvas) + return bitmap +} \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/OnMapFragmentReadyIdlingResource.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/OnMapFragmentReadyIdlingResource.kt new file mode 100644 index 0000000000..fa6b732770 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/OnMapFragmentReadyIdlingResource.kt @@ -0,0 +1,39 @@ +package com.mapbox.mapboxsdk.plugins.utils + +import android.os.Handler +import android.os.Looper +import android.support.test.espresso.IdlingResource + +import com.mapbox.mapboxsdk.maps.MapboxMap +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback +import com.mapbox.mapboxsdk.maps.SupportMapFragment + +class OnMapFragmentReadyIdlingResource(fragment: SupportMapFragment?) : IdlingResource, OnMapReadyCallback { + + lateinit var mapboxMap: MapboxMap + + private var resourceCallback: IdlingResource.ResourceCallback? = null + + init { + Handler(Looper.getMainLooper()).post { + fragment?.getMapAsync(this) + } + } + + override fun getName(): String { + return javaClass.simpleName + } + + override fun isIdleNow(): Boolean { + return this::mapboxMap.isInitialized + } + + override fun registerIdleTransitionCallback(resourceCallback: IdlingResource.ResourceCallback) { + this.resourceCallback = resourceCallback + } + + override fun onMapReady(mapboxMap: MapboxMap) { + this.mapboxMap = mapboxMap + resourceCallback?.onTransitionToIdle() + } +} \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/OnMapReadyIdlingResource.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/OnMapReadyIdlingResource.java new file mode 100644 index 0000000000..f084343594 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/OnMapReadyIdlingResource.java @@ -0,0 +1,63 @@ +package com.mapbox.mapboxsdk.plugins.utils; + +import android.app.Activity; +import android.os.Handler; +import android.os.Looper; +import android.support.test.espresso.IdlingResource; + +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; + +import java.lang.reflect.Field; + +public class OnMapReadyIdlingResource implements IdlingResource, OnMapReadyCallback { + + private MapboxMap mapboxMap; + private MapView mapView; + private IdlingResource.ResourceCallback resourceCallback; + + public OnMapReadyIdlingResource(Activity activity) { + new Handler(Looper.getMainLooper()).post(() -> { + try { + Field field = activity.getClass().getDeclaredField("mapView"); + field.setAccessible(true); + mapView = ((MapView) field.get(activity)); + mapView.getMapAsync(this); + } catch (Exception err) { + throw new RuntimeException(err); + } + }); + } + + @Override + public String getName() { + return getClass().getSimpleName(); + } + + @Override + public boolean isIdleNow() { + return mapboxMap != null; + } + + @Override + public void registerIdleTransitionCallback(ResourceCallback resourceCallback) { + this.resourceCallback = resourceCallback; + } + + public MapView getMapView() { + return mapView; + } + + public MapboxMap getMapboxMap() { + return mapboxMap; + } + + @Override + public void onMapReady(MapboxMap mapboxMap) { + this.mapboxMap = mapboxMap; + if (resourceCallback != null) { + resourceCallback.onTransitionToIdle(); + } + } +} \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/PluginGenerationUtil.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/PluginGenerationUtil.kt new file mode 100644 index 0000000000..9049a28298 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/PluginGenerationUtil.kt @@ -0,0 +1,51 @@ +package com.mapbox.mapboxsdk.plugins.utils + +import android.content.Context +import android.support.v7.app.AppCompatActivity +import com.mapbox.android.core.location.LocationEngine +import com.mapbox.mapboxsdk.maps.MapView +import com.mapbox.mapboxsdk.maps.MapboxMap +import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerOptions +import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerPlugin + +class PluginGenerationUtil { + companion object { + fun getLocationLayerPluginProvider(activity: AppCompatActivity, + useDefaultEngine: Boolean = false, + engine: LocationEngine? = null, + options: LocationLayerOptions? = null, + registerLifecycleObserver: Boolean = true) + : GenericPluginAction.PluginProvider { + return object : GenericPluginAction.PluginProvider { + override fun providePlugin(mapView: MapView, mapboxMap: MapboxMap, context: Context): LocationLayerPlugin { + val plugin = if (useDefaultEngine) { + if (options != null) { + LocationLayerPlugin(mapView, mapboxMap, options) + } else { + LocationLayerPlugin(mapView, mapboxMap) + } + } else { + if (options != null) { + LocationLayerPlugin(mapView, mapboxMap, engine, options) + } else { + LocationLayerPlugin(mapView, mapboxMap, engine) + } + } + + if (registerLifecycleObserver) { + activity.lifecycle.addObserver(plugin) + } + + return plugin + } + + override fun isPluginDataReady(plugin: LocationLayerPlugin, mapboxMap: MapboxMap): Boolean { + return mapboxMap.getSource("mapbox-location-source") != null + } + } + } + + const val MAP_RENDER_DELAY = 250L + const val MAP_CONNECTION_DELAY = 1000L + } +} \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/StyleChangeIdlingResource.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/StyleChangeIdlingResource.kt new file mode 100644 index 0000000000..ab2c855c65 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/StyleChangeIdlingResource.kt @@ -0,0 +1,46 @@ +package com.mapbox.mapboxsdk.plugins.utils + +import android.support.test.espresso.IdlingResource +import com.mapbox.mapboxsdk.maps.MapView +import com.mapbox.mapboxsdk.maps.MapboxMap + +/** + * Resource, that's idling until the provided style is loaded. + * Remember to add any espresso action (like view assertion) after the [waitForStyle] call + * for the test to keep running. + */ +class StyleChangeIdlingResource : IdlingResource { + + private var callback: IdlingResource.ResourceCallback? = null + private var isIdle = true + + override fun getName(): String { + return javaClass.simpleName + } + + override fun isIdleNow(): Boolean { + return isIdle + } + + override fun registerIdleTransitionCallback(callback: IdlingResource.ResourceCallback?) { + this.callback = callback + } + + private fun setIdle() { + isIdle = true + callback?.onTransitionToIdle() + } + + fun waitForStyle(mapView: MapView, mapboxMap: MapboxMap, styleUrl: String) { + isIdle = false + mapView.addOnMapChangedListener(object : MapView.OnMapChangedListener { + override fun onMapChanged(change: Int) { + if (change == MapView.DID_FINISH_LOADING_STYLE) { + mapView.removeOnMapChangedListener(this) + setIdle() + } + } + }) + mapboxMap.setStyleUrl(styleUrl) + } +} \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/TestLifecycleOwner.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/TestLifecycleOwner.kt new file mode 100644 index 0000000000..ccb8da17a7 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/TestLifecycleOwner.kt @@ -0,0 +1,19 @@ +package com.mapbox.mapboxsdk.plugins.utils + +import android.arch.lifecycle.Lifecycle +import android.arch.lifecycle.LifecycleOwner +import android.arch.lifecycle.LifecycleRegistry + +class TestLifecycleOwner : LifecycleOwner { + private val lifecycleRegistry = LifecycleRegistry(this) + + override fun getLifecycle() = lifecycleRegistry + + fun markState(state: Lifecycle.State) { + lifecycleRegistry.markState(state) + } + + fun handleLifecycleEvent(event: Lifecycle.Event) { + lifecycleRegistry.handleLifecycleEvent(event) + } +} \ No newline at end of file -- cgit v1.2.1 From 465316b4cef4b0d4630d855a789f5b6acef2084e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Mon, 3 Sep 2018 21:51:43 +0200 Subject: [android] adapt LocationLayerPlugin's test suite --- .../locationlayer/LocationLayerPluginTest.kt | 860 +++++++++++---------- .../plugins/locationlayer/LocationLayerTest.kt | 177 ++--- .../mapboxsdk/plugins/utils/GenericPluginAction.kt | 48 -- .../plugins/utils/LocationLayerPluginAction.kt | 40 + .../mapboxsdk/plugins/utils/MapboxTestingUtils.kt | 30 +- .../plugins/utils/PluginGenerationUtil.kt | 51 -- .../mapboxsdk/plugins/utils/TestLifecycleOwner.kt | 19 - .../mapboxsdk/testapp/action/MapboxMapAction.java | 3 +- .../testapp/activity/BaseActivityTest.java | 19 +- 9 files changed, 614 insertions(+), 633 deletions(-) delete mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/GenericPluginAction.kt create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/LocationLayerPluginAction.kt delete mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/PluginGenerationUtil.kt delete mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/TestLifecycleOwner.kt (limited to 'platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java') diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt index 12a64850b0..1820d56d95 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt @@ -2,7 +2,6 @@ package com.mapbox.mapboxsdk.plugins.locationlayer import android.Manifest import android.R -import android.arch.lifecycle.Lifecycle import android.content.Context import android.graphics.Color import android.graphics.RectF @@ -12,93 +11,69 @@ import android.support.test.espresso.IdlingRegistry import android.support.test.espresso.UiController import android.support.test.espresso.assertion.ViewAssertions.matches import android.support.test.espresso.matcher.ViewMatchers.* -import android.support.test.filters.LargeTest -import android.support.test.rule.ActivityTestRule import android.support.test.rule.GrantPermissionRule -import android.support.test.runner.AndroidJUnit4 import android.support.v4.content.ContextCompat import com.mapbox.geojson.Point -import com.mapbox.mapboxsdk.camera.CameraPosition import com.mapbox.mapboxsdk.camera.CameraUpdateFactory import com.mapbox.mapboxsdk.constants.Style import com.mapbox.mapboxsdk.geometry.LatLng -import com.mapbox.mapboxsdk.maps.MapView import com.mapbox.mapboxsdk.maps.MapboxMap -import com.mapbox.mapboxsdk.maps.MapboxMapOptions -import com.mapbox.mapboxsdk.maps.SupportMapFragment import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.* import com.mapbox.mapboxsdk.plugins.locationlayer.modes.CameraMode import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode import com.mapbox.mapboxsdk.plugins.utils.* import com.mapbox.mapboxsdk.plugins.utils.MapboxTestingUtils.Companion.MAPBOX_HEAVY_STYLE +import com.mapbox.mapboxsdk.plugins.utils.MapboxTestingUtils.Companion.MAP_CONNECTION_DELAY +import com.mapbox.mapboxsdk.plugins.utils.MapboxTestingUtils.Companion.MAP_RENDER_DELAY import com.mapbox.mapboxsdk.plugins.utils.MapboxTestingUtils.Companion.pushSourceUpdates -import com.mapbox.mapboxsdk.plugins.utils.PluginGenerationUtil.Companion.MAP_CONNECTION_DELAY -import com.mapbox.mapboxsdk.plugins.utils.PluginGenerationUtil.Companion.MAP_RENDER_DELAY -import com.mapbox.mapboxsdk.style.layers.PropertyFactory -import com.mapbox.mapboxsdk.style.sources.GeoJsonSource -import com.mapbox.mapboxsdk.testapp.activity.SingleFragmentActivity +import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest +import com.mapbox.mapboxsdk.testapp.activity.SingleActivity +import com.mapbox.mapboxsdk.utils.ColorUtils import org.hamcrest.CoreMatchers.* import org.junit.* import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue -import org.junit.rules.TestName -import org.junit.runner.RunWith -import timber.log.Timber -/** - * Test class that uses a map fragment to keep onMapReady actions isolated to within the test - */ -@RunWith(AndroidJUnit4::class) -@LargeTest -class LocationLayerPluginTest { - - @Rule - @JvmField - val activityRule = ActivityTestRule(SingleFragmentActivity::class.java, true, true) - - @Rule - @JvmField - val nameRule = TestName() +class LocationLayerPluginTest : BaseActivityTest() { @Rule @JvmField val permissionRule: GrantPermissionRule = GrantPermissionRule.grant(Manifest.permission.ACCESS_FINE_LOCATION) - private lateinit var idlingResource: OnMapFragmentReadyIdlingResource + override fun getActivityClass(): Class<*> { + return SingleActivity::class.java + } + private lateinit var styleChangeIdlingResource: StyleChangeIdlingResource - private lateinit var fragment: SupportMapFragment - private lateinit var mapboxMap: MapboxMap private val location: Location by lazy { val initLocation = Location("test") initLocation.latitude = 15.0 initLocation.longitude = 17.0 + initLocation.bearing = 10f + initLocation.accuracy = 150f initLocation } @Before - fun beforeTest() { + override fun beforeTest() { + super.beforeTest() - // Create a default support map fragment and pass it into the empty activity - val options = MapboxMapOptions() - .camera(CameraPosition.Builder().zoom(2.0).build()) // to match plugins min zoom - fragment = SupportMapFragment.newInstance(options) - activityRule.activity.setFragment(fragment) + location.latitude = 15.0 + location.longitude = 17.0 + location.bearing = 10f + location.accuracy = 150f - Timber.e("@Before: ${nameRule.methodName} - register idle resource") - // If idlingResource is null, throw Kotlin exception - idlingResource = OnMapFragmentReadyIdlingResource(fragment) styleChangeIdlingResource = StyleChangeIdlingResource() - IdlingRegistry.getInstance().register(idlingResource) IdlingRegistry.getInstance().register(styleChangeIdlingResource) - onView(withId(R.id.content)).check(matches(isDisplayed())) - mapboxMap = idlingResource.mapboxMap } @Test fun locationLayerPlugin_initializesLocationEngineCorrectlyWhenOnesNotProvided() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + validateTestSetup() + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context) val locationEngine = plugin.locationEngine assertThat(locationEngine, notNullValue()) @@ -108,14 +83,23 @@ class LocationLayerPluginTest { } } - executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, true)) + executePluginTest(pluginAction) } @Test fun locationLayerPlugin_initializesLocationEngineCorrectlyWhenOnesNotProvidedButHasOptions() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + validateTestSetup() + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin( + context, + LocationLayerOptions.builder(context) + .staleStateTimeout(200) + .enableStaleState(false) + .accuracyAlpha(.5f) + .accuracyColor(Color.BLUE) + .build()) val locationEngine = plugin.locationEngine val pluginOptions = plugin.locationLayerOptions @@ -130,24 +114,49 @@ class LocationLayerPluginTest { } } - val options = LocationLayerOptions.builder(fragment.activity) - .staleStateTimeout(200) - .enableStaleState(false) - .accuracyAlpha(.5f) - .accuracyColor(Color.BLUE) - .build() - - executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider( - activityRule.activity, true, null, options)) + executePluginTest(pluginAction) } @Test - fun settingMapStyleImmediatelyBeforeLoadingPlugin_doesStillLoadLayersProperly() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + fun locationLayerPlugin_doesntInitializeEngineWhenNullProvided() { + validateTestSetup() + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin( + null, + LocationLayerOptions.builder(context) + .staleStateTimeout(200) + .enableStaleState(false) + .accuracyAlpha(.5f) + .accuracyColor(Color.BLUE) + .build()) + + val locationEngine = plugin.locationEngine + val pluginOptions = plugin.locationLayerOptions + + assertThat(locationEngine, nullValue()) + assertThat(pluginOptions, notNullValue()) uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) + assertThat(pluginOptions?.accuracyAlpha(), `is`(.5f)) + assertThat(pluginOptions?.accuracyColor(), `is`(Color.BLUE)) + } + } + + executePluginTest(pluginAction) + } + + @Test + fun settingMapStyleImmediatelyBeforeLoadingPlugin_doesStillLoadLayersProperly() { + validateTestSetup() + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + mapboxMap.setStyle(Style.LIGHT) + plugin.activateLocationLayerPlugin(context, false) + plugin.forceLocationUpdate(location) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) assertThat(plugin.renderMode, `is`(equalTo(RenderMode.NORMAL))) assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true)) @@ -158,39 +167,26 @@ class LocationLayerPluginTest { } } - executePluginTest(pluginAction, object : GenericPluginAction.PluginProvider { - override fun providePlugin(mapView: MapView, mapboxMap: MapboxMap, context: Context): LocationLayerPlugin { - // changing the style just before instantiating the plugin - mapboxMap.setStyleUrl(Style.LIGHT) - val plugin = - PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, null, false) - .providePlugin(mapView, mapboxMap, context) - plugin.forceLocationUpdate(location) - return plugin - } - - override fun isPluginDataReady(plugin: LocationLayerPlugin, mapboxMap: MapboxMap): Boolean { - val source = mapboxMap.getSource(LOCATION_SOURCE) - return source != null && (source as GeoJsonSource).querySourceFeatures(null).isNotEmpty() - } - }) + executePluginTest(pluginAction) } @Test fun locationLayer_doesntShowUntilFirstLocationFix() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + validateTestSetup() + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) // Source should be present but empty - val mapView = fragment.view as MapView + val mapView = (rule.activity as SingleActivity).mapView assertThat(mapboxMap.queryRenderedFeatures( RectF(0f, 0f, mapView.width.toFloat(), mapView.height.toFloat()), FOREGROUND_LAYER) .isEmpty(), `is`(true)) // Force the first location update plugin.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) // Check if the puck is visible assertThat(mapboxMap.queryRenderedFeatures(location, FOREGROUND_LAYER).isEmpty(), `is`(false)) @@ -205,11 +201,18 @@ class LocationLayerPluginTest { @Test fun locationLayerOptions_disablingStaleStateDoesWorkCorrectly() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + validateTestSetup() + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, + LocationLayerOptions.builder(context) + .staleStateTimeout(200) + .enableStaleState(false) + .build()) plugin.forceLocationUpdate(location) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) uiController.loopMainThreadForAtLeast(200) uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) @@ -221,28 +224,34 @@ class LocationLayerPluginTest { } } - val options = LocationLayerOptions.builder(fragment.activity) - .staleStateTimeout(200) - .enableStaleState(false) - .build() - executePluginTest(pluginAction, - PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, options)) + executePluginTest(pluginAction) } @Test fun locationLayerOptions_loadsForegroundBitmapFromNameOption() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, + LocationLayerOptions.builder(context) + .foregroundName("custom-foreground-bitmap") + .backgroundName("custom-background-bitmap") + .foregroundStaleName("custom-foreground-stale-bitmap") + .backgroundStaleName("custom-background-stale-bitmap") + .bearingName("custom-bearing-bitmap") + .build()) + val foregroundDrawable = ContextCompat.getDrawable(context, R.drawable.ic_media_play) - mapboxMap.addImageFromDrawable("custom-foreground-bitmap", foregroundDrawable!!) - mapboxMap.addImageFromDrawable("custom-background-bitmap", foregroundDrawable) - mapboxMap.addImageFromDrawable("custom-foreground-stale-bitmap", foregroundDrawable) - mapboxMap.addImageFromDrawable("custom-background-stale-bitmap", foregroundDrawable) - mapboxMap.addImageFromDrawable("custom-bearing-bitmap", foregroundDrawable) + foregroundDrawable?.let { + mapboxMap.addImageFromDrawable("custom-foreground-bitmap", it) + mapboxMap.addImageFromDrawable("custom-background-bitmap", it) + mapboxMap.addImageFromDrawable("custom-foreground-stale-bitmap", it) + mapboxMap.addImageFromDrawable("custom-background-stale-bitmap", it) + mapboxMap.addImageFromDrawable("custom-bearing-bitmap", it) + } plugin.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) assertThat(mapboxMap.queryRenderedFeatures(location, FOREGROUND_LAYER).isEmpty(), `is`(false)) val feature = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0] @@ -254,55 +263,56 @@ class LocationLayerPluginTest { } } - val options = LocationLayerOptions.builder(fragment.activity) - .foregroundName("custom-foreground-bitmap") - .backgroundName("custom-background-bitmap") - .foregroundStaleName("custom-foreground-stale-bitmap") - .backgroundStaleName("custom-background-stale-bitmap") - .bearingName("custom-bearing-bitmap") - .build() - executePluginTest(pluginAction, - PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, options)) + executePluginTest(pluginAction) } @Test fun locationLayerOptions_loadsGpsNameWithGpsRenderMode() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, + LocationLayerOptions.builder(context) + .foregroundName("custom-foreground-bitmap") + .gpsName("custom-gps-bitmap") + .build()) + plugin.renderMode = RenderMode.GPS plugin.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) val foregroundDrawable = ContextCompat.getDrawable(context, R.drawable.ic_media_play) - mapboxMap.addImageFromDrawable("custom-foreground-bitmap", foregroundDrawable!!) - mapboxMap.addImageFromDrawable("custom-gps-bitmap", foregroundDrawable) + foregroundDrawable?.let { + mapboxMap.addImageFromDrawable("custom-foreground-bitmap", it) + mapboxMap.addImageFromDrawable("custom-gps-bitmap", it) + } val foregroundId = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getStringProperty(PROPERTY_FOREGROUND_ICON) assertThat(foregroundId, `is`(equalTo("custom-gps-bitmap"))) } } - val options = LocationLayerOptions.builder(fragment.activity) - .foregroundName("custom-foreground-bitmap") - .gpsName("custom-gps-bitmap") - .build() - executePluginTest(pluginAction, - PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, options)) + executePluginTest(pluginAction) } @Test fun locationLayerOptions_customIconNameRevertsToDefault() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, + LocationLayerOptions.builder(context) + .foregroundName("custom-foreground-bitmap") + .gpsName("custom-gps-bitmap") + .build()) + plugin.renderMode = RenderMode.GPS plugin.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) val foregroundId = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getStringProperty(PROPERTY_FOREGROUND_ICON) assertThat(foregroundId, `is`(equalTo("custom-gps-bitmap"))) - plugin.applyStyle(LocationLayerOptions.builder(fragment.activity).build()) + plugin.applyStyle(LocationLayerOptions.builder(context).build()) uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) val revertedForegroundId = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getStringProperty(PROPERTY_FOREGROUND_ICON) @@ -310,22 +320,23 @@ class LocationLayerPluginTest { } } - val options = LocationLayerOptions.builder(fragment.activity) - .foregroundName("custom-foreground-bitmap") - .gpsName("custom-gps-bitmap") - .build() - executePluginTest(pluginAction, - PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, options)) + executePluginTest(pluginAction) } @Test fun locationLayerOptions_customGpsIconNameChangeBackWithMode() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + + plugin.activateLocationLayerPlugin(context, + LocationLayerOptions.builder(context) + .gpsName("custom-gps-bitmap") + .build()) + plugin.renderMode = RenderMode.GPS plugin.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) val foregroundId = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getStringProperty(PROPERTY_FOREGROUND_ICON) assertThat(foregroundId, `is`(equalTo("custom-gps-bitmap"))) @@ -338,75 +349,73 @@ class LocationLayerPluginTest { } } - val options = LocationLayerOptions.builder(fragment.activity) - .gpsName("custom-gps-bitmap") - .build() - executePluginTest(pluginAction, - PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, options)) + executePluginTest(pluginAction) } @Test fun stillStaleAfterResuming() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - val testLifecycleOwner = TestLifecycleOwner() - testLifecycleOwner.markState(Lifecycle.State.RESUMED) - testLifecycleOwner.lifecycle.addObserver(plugin) + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, + LocationLayerOptions.builder(context) + .staleStateTimeout(200) + .build()) plugin.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(300) // engaging stale state + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + uiController.loopMainThreadForAtLeast(250) // engaging stale state uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(true)) - testLifecycleOwner.markState(Lifecycle.State.CREATED) - testLifecycleOwner.markState(Lifecycle.State.RESUMED) - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + plugin.onStop() + plugin.onStart() + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(true)) assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(false)) } } - val options = LocationLayerOptions.builder(fragment.activity) - .staleStateTimeout(200) - .build() - executePluginTest(pluginAction, - PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, options, false)) + + executePluginTest(pluginAction) } @Test fun stillNotStaleAfterResuming() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - val testLifecycleOwner = TestLifecycleOwner() - testLifecycleOwner.markState(Lifecycle.State.RESUMED) - testLifecycleOwner.lifecycle.addObserver(plugin) - + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) plugin.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(false)) - testLifecycleOwner.markState(Lifecycle.State.CREATED) - testLifecycleOwner.markState(Lifecycle.State.RESUMED) + plugin.onStop() + plugin.onStart() uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(false)) assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(true)) } } - executePluginTest(pluginAction, - PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + executePluginTest(pluginAction) } @Test fun locationLayerOptions_accuracyRingWithColor() { val color = Color.parseColor("#4A90E2") - val rgbaColor = PropertyFactory.colorToRgbaString(color) + val rgbaColor = ColorUtils.colorToRgbaString(color) - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, + LocationLayerOptions.builder(context) + .accuracyColor(color) + .build()) + + plugin.forceLocationUpdate(location) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) // Check that the source property changes correctly mapboxMap.querySourceFeatures(LOCATION_SOURCE).also { @@ -417,22 +426,17 @@ class LocationLayerPluginTest { } } - val options = LocationLayerOptions.builder(fragment.activity) - .accuracyColor(color) - .build() - executePluginTest(pluginAction, - PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, options)) + executePluginTest(pluginAction) } @Test fun forceLocationUpdate_doesMoveLocationLayerIconToCorrectPosition() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) plugin.forceLocationUpdate(location) - - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) val point: Point = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].geometry() as Point @@ -446,19 +450,20 @@ class LocationLayerPluginTest { @Test fun disablingPluginHidesPuck() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) plugin.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) - val point: Point = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].geometry() as Point + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + + val point: Point = mapboxMap.queryRenderedFeatures(location, FOREGROUND_LAYER)[0].geometry() as Point assertEquals(point.latitude(), location.latitude, 0.1) assertEquals(point.longitude(), location.longitude, 0.1) - plugin.isLocationLayerEnabled = false + plugin.deactivateLocationLayerPlugin() uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) - assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE).isEmpty(), `is`(true)) + assertThat(mapboxMap.queryRenderedFeatures(location, FOREGROUND_LAYER).isEmpty(), `is`(true)) } } executePluginTest(pluginAction) @@ -466,19 +471,18 @@ class LocationLayerPluginTest { @Test fun disablingPluginAndChangingStyleAllowsToEnableAgain() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) plugin.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - plugin.isLocationLayerEnabled = false - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + plugin.deactivateLocationLayerPlugin() mapboxMap.setStyle(Style.LIGHT) - uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) - plugin.isLocationLayerEnabled = true - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + + plugin.activateLocationLayerPlugin(context, false) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true)) } } @@ -486,148 +490,131 @@ class LocationLayerPluginTest { } @Test - fun lifecycle_keepsEnabledWhenStoppedAndStarted() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - val testLifecycleOwner = TestLifecycleOwner() - testLifecycleOwner.markState(Lifecycle.State.RESUMED) - testLifecycleOwner.lifecycle.addObserver(plugin) + fun lifecycle_isDisabledOnStart() { + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + assertThat(plugin.isLocationLayerEnabled, `is`(false)) + plugin.onStop() + plugin.onStart() + assertThat(plugin.isLocationLayerEnabled, `is`(false)) + plugin.activateLocationLayerPlugin(context, false) + assertThat(plugin.isLocationLayerEnabled, `is`(true)) + } + } + executePluginTest(pluginAction) + } + @Test + fun lifecycle_keepsEnabledWhenStoppedAndStarted() { + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) assertThat(plugin.isLocationLayerEnabled, `is`(true)) - testLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE) - testLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_STOP) - testLifecycleOwner.markState(Lifecycle.State.RESUMED) + plugin.onStop() + plugin.onStart() assertThat(plugin.isLocationLayerEnabled, `is`(true)) } } - executePluginTest(pluginAction, - PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, null, false)) + executePluginTest(pluginAction) } @Test fun lifecycle_keepsDisabledWhenStoppedAndStarted() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.isLocationLayerEnabled = false - - val testLifecycleOwner = TestLifecycleOwner() - testLifecycleOwner.markState(Lifecycle.State.RESUMED) - testLifecycleOwner.lifecycle.addObserver(plugin) - + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) + plugin.deactivateLocationLayerPlugin() assertThat(plugin.isLocationLayerEnabled, `is`(false)) - testLifecycleOwner.markState(Lifecycle.State.CREATED) - testLifecycleOwner.markState(Lifecycle.State.RESUMED) + plugin.onStop() + plugin.onStart() assertThat(plugin.isLocationLayerEnabled, `is`(false)) } } - executePluginTest(pluginAction, - PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, null, false)) + executePluginTest(pluginAction) } @Test fun lifecycle_ableToChangeStyleAfterResuming() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - - val testLifecycleOwner = TestLifecycleOwner() - testLifecycleOwner.markState(Lifecycle.State.RESUMED) - testLifecycleOwner.lifecycle.addObserver(plugin) + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) - testLifecycleOwner.markState(Lifecycle.State.CREATED) - testLifecycleOwner.markState(Lifecycle.State.RESUMED) + plugin.onStop() + plugin.onStart() mapboxMap.setStyle(Style.DARK) uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) } } - executePluginTest(pluginAction, - PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, null, false)) + executePluginTest(pluginAction) } @Test fun lifecycle_interruptedDuringStyleChange() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - - val testLifecycleOwner = TestLifecycleOwner() - testLifecycleOwner.markState(Lifecycle.State.RESUMED) - testLifecycleOwner.lifecycle.addObserver(plugin) + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) mapboxMap.setStyle(Style.DARK) - - testLifecycleOwner.markState(Lifecycle.State.CREATED) - testLifecycleOwner.markState(Lifecycle.State.RESUMED) + plugin.onStop() + plugin.onStart() uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) } } - executePluginTest(pluginAction, - PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, null, false)) + executePluginTest(pluginAction) } @Test fun lifecycle_forceLocationUpdateAfterStopped() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - - val testLifecycleOwner = TestLifecycleOwner() - testLifecycleOwner.markState(Lifecycle.State.RESUMED) - testLifecycleOwner.lifecycle.addObserver(plugin) - - testLifecycleOwner.markState(Lifecycle.State.CREATED) + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) + plugin.onStop() plugin.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE).isEmpty(), `is`(true)) } } - executePluginTest(pluginAction, - PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, null, false)) + executePluginTest(pluginAction) } @Test fun lifecycle_acceptAndReuseLocationUpdatesBeforeLayerStarted() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - - val testLifecycleOwner = TestLifecycleOwner() - testLifecycleOwner.markState(Lifecycle.State.RESUMED) - testLifecycleOwner.lifecycle.addObserver(plugin) - - testLifecycleOwner.markState(Lifecycle.State.CREATED) + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) + plugin.onStop() plugin.forceLocationUpdate(location) - testLifecycleOwner.markState(Lifecycle.State.RESUMED) - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + plugin.onStart() + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) val point: Point = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].geometry() as Point assertEquals(point.latitude(), location.latitude, 0.1) assertEquals(point.longitude(), location.longitude, 0.1) } } - executePluginTest(pluginAction, - PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, null, false)) + executePluginTest(pluginAction) } @Test fun lifecycle_lifecycleChangeRightAfterStyleReload() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - - val testLifecycleOwner = TestLifecycleOwner() - testLifecycleOwner.markState(Lifecycle.State.RESUMED) - testLifecycleOwner.lifecycle.addObserver(plugin) - + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) plugin.forceLocationUpdate(location) mapboxMap.setStyle(Style.LIGHT) - testLifecycleOwner.markState(Lifecycle.State.CREATED) + plugin.onStop() uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) - testLifecycleOwner.markState(Lifecycle.State.RESUMED) - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + plugin.onStart() + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) val point: Point = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].geometry() as Point assertEquals(point.latitude(), location.latitude, 0.1) @@ -640,17 +627,17 @@ class LocationLayerPluginTest { assertThat(mapboxMap.isLayerVisible(BEARING_LAYER), `is`(false)) } } - executePluginTest(pluginAction, - PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, null, false)) + executePluginTest(pluginAction) } @Test fun mapChange_settingPluginStyle() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - styleChangeIdlingResource.waitForStyle(fragment.view as MapView, mapboxMap, MAPBOX_HEAVY_STYLE) - val options = LocationLayerOptions.builder(fragment.activity) + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) + styleChangeIdlingResource.waitForStyle((rule.activity as SingleActivity).mapView, mapboxMap, MAPBOX_HEAVY_STYLE) + val options = LocationLayerOptions.builder(context) .accuracyColor(Color.RED) .build() @@ -661,8 +648,7 @@ class LocationLayerPluginTest { uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) } } - executePluginTest(pluginAction, - PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + executePluginTest(pluginAction) // Waiting for style to finish loading while pushing updates onView(withId(R.id.content)).check(matches(isDisplayed())) @@ -670,10 +656,11 @@ class LocationLayerPluginTest { @Test fun mapChange_forcingLocation() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - styleChangeIdlingResource.waitForStyle(fragment.view as MapView, mapboxMap, MAPBOX_HEAVY_STYLE) + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) + styleChangeIdlingResource.waitForStyle((rule.activity as SingleActivity).mapView, mapboxMap, MAPBOX_HEAVY_STYLE) pushSourceUpdates(styleChangeIdlingResource) { plugin.forceLocationUpdate(location) @@ -682,8 +669,7 @@ class LocationLayerPluginTest { uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) } } - executePluginTest(pluginAction, - PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + executePluginTest(pluginAction) // Waiting for style to finish loading while pushing updates onView(withId(R.id.content)).check(matches(isDisplayed())) @@ -691,10 +677,13 @@ class LocationLayerPluginTest { @Test fun mapChange_settingMapStyleBeforePluginCreation() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - val options = LocationLayerOptions.builder(fragment.activity) + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + styleChangeIdlingResource.waitForStyle((rule.activity as SingleActivity).mapView, mapboxMap, MAPBOX_HEAVY_STYLE) + plugin.activateLocationLayerPlugin(context, false) + + val options = LocationLayerOptions.builder(context) .accuracyColor(Color.RED) .build() @@ -704,19 +693,7 @@ class LocationLayerPluginTest { } } } - - executePluginTest(pluginAction, object : GenericPluginAction.PluginProvider { - override fun providePlugin(mapView: MapView, mapboxMap: MapboxMap, context: Context): LocationLayerPlugin { - // changing the style just before instantiating the plugin - styleChangeIdlingResource.waitForStyle(mapView, mapboxMap, MAPBOX_HEAVY_STYLE) - return PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, null, false) - .providePlugin(mapView, mapboxMap, context) - } - - override fun isPluginDataReady(plugin: LocationLayerPlugin, mapboxMap: MapboxMap): Boolean { - return true - } - }) + executePluginTest(pluginAction) // Waiting for style to finish loading while pushing updates onView(withId(R.id.content)).check(matches(isDisplayed())) @@ -724,34 +701,36 @@ class LocationLayerPluginTest { @Test fun animators_layerBearingCorrect() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) plugin.renderMode = RenderMode.GPS location.bearing = 77f plugin.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(1000) + uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS + MAP_RENDER_DELAY) assertEquals(77.0, mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getNumberProperty(PROPERTY_GPS_BEARING) as Double, 0.1) location.bearing = 92f plugin.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(2000) // Waiting for the animation to finish + uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS + MAP_RENDER_DELAY) // Waiting for the animation to finish assertEquals(92.0, mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getNumberProperty(PROPERTY_GPS_BEARING) as Double, 0.1) } } - executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + executePluginTest(pluginAction) } @Test fun animators_cameraLatLngBearingCorrect() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) plugin.cameraMode = CameraMode.TRACKING_GPS location.bearing = 77f plugin.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(1000) + uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS + MAP_RENDER_DELAY) assertEquals(77.0, mapboxMap.cameraPosition.bearing, 0.1) assertEquals(location.latitude, mapboxMap.cameraPosition.target.latitude, 0.1) assertEquals(location.longitude, mapboxMap.cameraPosition.target.longitude, 0.1) @@ -760,28 +739,29 @@ class LocationLayerPluginTest { location.latitude = 30.0 location.longitude = 35.0 plugin.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(2000) // Waiting for the animation to finish + uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS + MAP_RENDER_DELAY) // Waiting for the animation to finish assertEquals(92.0, mapboxMap.cameraPosition.bearing, 0.1) assertEquals(location.latitude, mapboxMap.cameraPosition.target.latitude, 0.1) assertEquals(location.longitude, mapboxMap.cameraPosition.target.longitude, 0.1) } } - executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + executePluginTest(pluginAction) } @Test fun animators_cameraBearingCorrect() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) plugin.cameraMode = CameraMode.NONE_GPS val latitude = mapboxMap.cameraPosition.target.latitude val longitude = mapboxMap.cameraPosition.target.longitude location.bearing = 77f plugin.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(1000) + uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS + MAP_RENDER_DELAY) assertEquals(77.0, mapboxMap.cameraPosition.bearing, 0.1) assertEquals(latitude, mapboxMap.cameraPosition.target.latitude, 0.1) assertEquals(longitude, mapboxMap.cameraPosition.target.longitude, 0.1) @@ -790,21 +770,22 @@ class LocationLayerPluginTest { location.latitude = 30.0 location.longitude = 35.0 plugin.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(2000) // Waiting for the animation to finish + uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS + MAP_RENDER_DELAY) assertEquals(92.0, mapboxMap.cameraPosition.bearing, 0.1) assertEquals(latitude, mapboxMap.cameraPosition.target.latitude, 0.1) assertEquals(longitude, mapboxMap.cameraPosition.target.longitude, 0.1) } } - executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + executePluginTest(pluginAction) } @Test fun animators_cameraNoneCorrect() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) plugin.cameraMode = CameraMode.NONE val latitude = mapboxMap.cameraPosition.target.latitude val longitude = mapboxMap.cameraPosition.target.longitude @@ -812,7 +793,7 @@ class LocationLayerPluginTest { location.bearing = 77f plugin.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(1000) + uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS + MAP_RENDER_DELAY) assertEquals(bearing, mapboxMap.cameraPosition.bearing, 0.1) assertEquals(latitude, mapboxMap.cameraPosition.target.latitude, 0.1) assertEquals(longitude, mapboxMap.cameraPosition.target.longitude, 0.1) @@ -821,38 +802,40 @@ class LocationLayerPluginTest { location.latitude = 30.0 location.longitude = 35.0 plugin.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(2000) // Waiting for the animation to finish + uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS + MAP_RENDER_DELAY) // Waiting for the animation to finish assertEquals(bearing, mapboxMap.cameraPosition.bearing, 0.1) assertEquals(latitude, mapboxMap.cameraPosition.target.latitude, 0.1) assertEquals(longitude, mapboxMap.cameraPosition.target.longitude, 0.1) } } - executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + executePluginTest(pluginAction) } @Test fun animators_focalPointAdjustment() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) plugin.cameraMode = CameraMode.TRACKING plugin.cameraMode = CameraMode.NONE plugin.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) assertThat(mapboxMap.uiSettings.focalPoint, nullValue()) } } - executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + executePluginTest(pluginAction) } @Test fun animators_dontZoomWhileNotTracking() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) plugin.cameraMode = CameraMode.NONE val zoom = mapboxMap.cameraPosition.zoom plugin.zoomWhileTracking(10.0) @@ -862,14 +845,15 @@ class LocationLayerPluginTest { } } - executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + executePluginTest(pluginAction) } @Test fun animators_zoomWhileTracking() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) plugin.cameraMode = CameraMode.TRACKING plugin.zoomWhileTracking(10.0) uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIMATION_DURATION) @@ -878,15 +862,16 @@ class LocationLayerPluginTest { } } - executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + executePluginTest(pluginAction) } @Test @Ignore fun animators_zoomWhileTrackingCanceledOnModeChange() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) plugin.cameraMode = CameraMode.TRACKING plugin.zoomWhileTracking(15.0) uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIMATION_DURATION / 2) @@ -897,24 +882,21 @@ class LocationLayerPluginTest { } } - executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + executePluginTest(pluginAction) } @Test fun animators_dontZoomWhileStopped() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - - val testLifecycleOwner = TestLifecycleOwner() - testLifecycleOwner.markState(Lifecycle.State.RESUMED) - testLifecycleOwner.lifecycle.addObserver(plugin) + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) plugin.cameraMode = CameraMode.TRACKING uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) val zoom = mapboxMap.cameraPosition.zoom - testLifecycleOwner.markState(Lifecycle.State.CREATED) + plugin.onStop() plugin.zoomWhileTracking(10.0) uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIMATION_DURATION) @@ -922,16 +904,16 @@ class LocationLayerPluginTest { } } - executePluginTest(pluginAction, - PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, null, false)) + executePluginTest(pluginAction) } @Test @Ignore fun animators_cancelZoomWhileTracking() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) plugin.cameraMode = CameraMode.TRACKING plugin.zoomWhileTracking(15.0) uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIMATION_DURATION / 2) @@ -942,14 +924,15 @@ class LocationLayerPluginTest { } } - executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + executePluginTest(pluginAction) } @Test fun animators_dontTiltWhileNotTracking() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) plugin.cameraMode = CameraMode.NONE val tilt = mapboxMap.cameraPosition.tilt plugin.tiltWhileTracking(30.0) @@ -959,14 +942,15 @@ class LocationLayerPluginTest { } } - executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + executePluginTest(pluginAction) } @Test fun animators_tiltWhileTracking() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) plugin.cameraMode = CameraMode.TRACKING plugin.tiltWhileTracking(30.0) uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIMATION_DURATION) @@ -975,15 +959,16 @@ class LocationLayerPluginTest { } } - executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + executePluginTest(pluginAction) } @Test @Ignore fun animators_tiltWhileTrackingCanceledOnModeChange() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) plugin.cameraMode = CameraMode.TRACKING plugin.tiltWhileTracking(30.0) uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIMATION_DURATION / 2) @@ -994,23 +979,19 @@ class LocationLayerPluginTest { } } - executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + executePluginTest(pluginAction) } @Test fun animators_dontTiltWhileStopped() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - - val testLifecycleOwner = TestLifecycleOwner() - testLifecycleOwner.markState(Lifecycle.State.RESUMED) - testLifecycleOwner.lifecycle.addObserver(plugin) - + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) plugin.cameraMode = CameraMode.TRACKING val tilt = mapboxMap.cameraPosition.tilt - testLifecycleOwner.markState(Lifecycle.State.CREATED) + plugin.onStop() plugin.tiltWhileTracking(30.0) uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIMATION_DURATION) @@ -1018,16 +999,16 @@ class LocationLayerPluginTest { } } - executePluginTest(pluginAction, - PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity, false, null, null, false)) + executePluginTest(pluginAction) } @Test @Ignore fun animators_cancelTiltWhileTracking() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) plugin.cameraMode = CameraMode.TRACKING plugin.tiltWhileTracking(30.0) uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIMATION_DURATION / 2) @@ -1038,21 +1019,22 @@ class LocationLayerPluginTest { } } - executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + executePluginTest(pluginAction) } @Test fun cameraPositionAdjustedToTrackingModeWhenPluginEnabled() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) plugin.cameraMode = CameraMode.TRACKING_GPS plugin.forceLocationUpdate(location) - plugin.isLocationLayerEnabled = false + plugin.deactivateLocationLayerPlugin() mapboxMap.moveCamera(CameraUpdateFactory.newLatLng(LatLng(51.0, 17.0))) mapboxMap.moveCamera(CameraUpdateFactory.bearingTo(90.0)) - plugin.isLocationLayerEnabled = true - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + plugin.activateLocationLayerPlugin(context, false) + uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS + MAP_RENDER_DELAY) assertEquals(location.bearing.toDouble(), mapboxMap.cameraPosition.bearing, 0.1) assertEquals(location.latitude, mapboxMap.cameraPosition.target.latitude, 0.1) @@ -1060,30 +1042,66 @@ class LocationLayerPluginTest { } } - executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + executePluginTest(pluginAction) } @Test - fun onPluginInitialized_defaultCompassEngineIsProvided() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + fun compassEngine_onPluginInitializedDefaultIsProvided() { + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) assertTrue(plugin.compassEngine is LocationLayerCompassEngine) } } - executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) + executePluginTest(pluginAction) + } + + @Test + fun compassEngine_changesWhenNewProvided() { + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) + val engine: CompassEngine = object : CompassEngine { + override fun addCompassListener(compassListener: CompassListener) { + } + + override fun removeCompassListener(compassListener: CompassListener) { + } + + override fun getLastHeading(): Float { + return 0f + } + + override fun getLastAccuracySensorStatus(): Int { + return 0 + } + + override fun onStart() { + } + + override fun onStop() { + } + } + + plugin.compassEngine = engine + assertThat(plugin.compassEngine, notNullValue()) + assertThat(plugin.compassEngine, `is`(equalTo(engine))) + } + } + + executePluginTest(pluginAction) } @After - fun afterTest() { - Timber.e("@After: ${nameRule.methodName} - unregister idle resource") - IdlingRegistry.getInstance().unregister(idlingResource) + override fun afterTest() { + super.afterTest() IdlingRegistry.getInstance().unregister(styleChangeIdlingResource) } - private fun executePluginTest(listener: GenericPluginAction.OnPerformGenericPluginAction, - pluginProvider: GenericPluginAction.PluginProvider = PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity)) { - onView(withId(R.id.content)).perform(GenericPluginAction(fragment.view as MapView, mapboxMap, pluginProvider, listener)) + private fun executePluginTest(listener: LocationLayerPluginAction.OnPerformLocationLayerPluginAction) { + onView(withId(R.id.content)).perform(LocationLayerPluginAction(mapboxMap, listener)) } } \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.kt index 121c8f2d22..d7823031fc 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.kt @@ -10,11 +10,8 @@ import android.support.test.espresso.UiController import android.support.test.espresso.assertion.ViewAssertions.matches import android.support.test.espresso.matcher.ViewMatchers.isDisplayed import android.support.test.espresso.matcher.ViewMatchers.withId -import android.support.test.filters.LargeTest -import android.support.test.rule.ActivityTestRule import android.support.test.rule.GrantPermissionRule import android.support.test.rule.GrantPermissionRule.grant -import android.support.test.runner.AndroidJUnit4 import com.mapbox.mapboxsdk.camera.CameraUpdateFactory import com.mapbox.mapboxsdk.constants.Style import com.mapbox.mapboxsdk.geometry.LatLng @@ -23,10 +20,11 @@ import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.* import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode import com.mapbox.mapboxsdk.plugins.utils.* import com.mapbox.mapboxsdk.plugins.utils.MapboxTestingUtils.Companion.MAPBOX_HEAVY_STYLE +import com.mapbox.mapboxsdk.plugins.utils.MapboxTestingUtils.Companion.MAP_CONNECTION_DELAY +import com.mapbox.mapboxsdk.plugins.utils.MapboxTestingUtils.Companion.MAP_RENDER_DELAY import com.mapbox.mapboxsdk.plugins.utils.MapboxTestingUtils.Companion.pushSourceUpdates -import com.mapbox.mapboxsdk.plugins.utils.PluginGenerationUtil.Companion.MAP_CONNECTION_DELAY -import com.mapbox.mapboxsdk.plugins.utils.PluginGenerationUtil.Companion.MAP_RENDER_DELAY import com.mapbox.mapboxsdk.style.sources.GeoJsonSource +import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest import com.mapbox.mapboxsdk.testapp.activity.SingleActivity import org.hamcrest.CoreMatchers.`is` import org.hamcrest.CoreMatchers.notNullValue @@ -37,47 +35,32 @@ import org.junit.Assert.assertThat import org.junit.Before import org.junit.Rule import org.junit.Test -import org.junit.rules.TestName -import org.junit.runner.RunWith -import timber.log.Timber -@RunWith(AndroidJUnit4::class) -@LargeTest -class LocationLayerTest { - - @Rule - @JvmField - val activityRule = ActivityTestRule(SingleActivity::class.java) - - @Rule - @JvmField - val nameRule = TestName() +class LocationLayerTest : BaseActivityTest() { @Rule @JvmField val permissionRule: GrantPermissionRule = grant(Manifest.permission.ACCESS_FINE_LOCATION) - private lateinit var idlingResource: OnMapReadyIdlingResource + override fun getActivityClass(): Class<*> { + return SingleActivity::class.java + } + private lateinit var styleChangeIdlingResource: StyleChangeIdlingResource - private lateinit var mapboxMap: MapboxMap private val location: Location by lazy { val initLocation = Location("test") initLocation.latitude = 15.0 initLocation.longitude = 17.0 + initLocation.bearing = 10f initLocation.accuracy = 2000f initLocation } @Before - fun beforeTest() { - Timber.e("@Before: ${nameRule.methodName} - register idle resource") - // If idlingResource is null, throw Kotlin exception - idlingResource = OnMapReadyIdlingResource(activityRule.activity) + override fun beforeTest() { + super.beforeTest() styleChangeIdlingResource = StyleChangeIdlingResource() - IdlingRegistry.getInstance().register(idlingResource) IdlingRegistry.getInstance().register(styleChangeIdlingResource) - onView(withId(android.R.id.content)).check(matches(isDisplayed())) - mapboxMap = idlingResource.mapboxMap } // @@ -86,9 +69,10 @@ class LocationLayerTest { @Test fun renderModeNormal_sourceDoesGetAdded() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) plugin.renderMode = RenderMode.NORMAL uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) assertThat(mapboxMap.getSource(LOCATION_SOURCE), notNullValue()) @@ -103,12 +87,13 @@ class LocationLayerTest { @Test fun renderModeNormal_trackingNormalLayersDoGetAdded() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) plugin.renderMode = RenderMode.NORMAL plugin.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true)) assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(true)) assertThat(mapboxMap.isLayerVisible(SHADOW_LAYER), `is`(true)) @@ -121,12 +106,13 @@ class LocationLayerTest { @Test fun renderModeCompass_bearingLayersDoGetAdded() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) plugin.renderMode = RenderMode.COMPASS plugin.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true)) assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(true)) assertThat(mapboxMap.isLayerVisible(SHADOW_LAYER), `is`(true)) @@ -139,12 +125,13 @@ class LocationLayerTest { @Test fun renderModeGps_navigationLayersDoGetAdded() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) plugin.renderMode = RenderMode.GPS plugin.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true)) assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(true)) assertThat(mapboxMap.isLayerVisible(SHADOW_LAYER), `is`(false)) @@ -157,11 +144,14 @@ class LocationLayerTest { @Test fun dontShowPuckWhenRenderModeSetAndPluginDisabled() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) plugin.forceLocationUpdate(location) - plugin.isLocationLayerEnabled = false + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + plugin.deactivateLocationLayerPlugin() + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER, shouldDisappear = true) plugin.renderMode = RenderMode.GPS uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(false)) @@ -176,12 +166,15 @@ class LocationLayerTest { @Test fun whenLocationLayerPluginDisabled_doesSetAllLayersToVisibilityNone() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) plugin.renderMode = RenderMode.NORMAL plugin.forceLocationUpdate(location) - plugin.isLocationLayerEnabled = false + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + plugin.deactivateLocationLayerPlugin() + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER, shouldDisappear = true) uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) // Check that all layers visibilities are set to none @@ -197,14 +190,17 @@ class LocationLayerTest { @Test fun onMapChange_locationLayerLayersDoGetRedrawn() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) plugin.renderMode = RenderMode.NORMAL plugin.forceLocationUpdate(location) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) mapboxMap.setStyleUrl(Style.LIGHT) - plugin.forceLocationUpdate(location) uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) + plugin.forceLocationUpdate(location) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) assertThat(plugin.renderMode, `is`(equalTo(RenderMode.NORMAL))) @@ -229,18 +225,21 @@ class LocationLayerTest { @Test fun whenStyleChanged_continuesUsingStaleIcons() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) plugin.applyStyle(LocationLayerOptions.builder(context).staleStateTimeout(100).build()) plugin.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(200) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + uiController.loopMainThreadForAtLeast(150) uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(true)) mapboxMap.setStyleUrl(Style.LIGHT) uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(true)) } @@ -250,11 +249,12 @@ class LocationLayerTest { @Test fun whenStyleChanged_staleStateChanges() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) plugin.applyStyle(LocationLayerOptions.builder(context).staleStateTimeout(1).build()) - styleChangeIdlingResource.waitForStyle(idlingResource.mapView, mapboxMap, MAPBOX_HEAVY_STYLE) + styleChangeIdlingResource.waitForStyle((rule.activity as SingleActivity).mapView, mapboxMap, MAPBOX_HEAVY_STYLE) pushSourceUpdates(styleChangeIdlingResource) { plugin.forceLocationUpdate(location) } @@ -268,13 +268,17 @@ class LocationLayerTest { @Test fun whenStyleChanged_layerVisibilityUpdates() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - styleChangeIdlingResource.waitForStyle(idlingResource.mapView, mapboxMap, MAPBOX_HEAVY_STYLE) + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + styleChangeIdlingResource.waitForStyle((rule.activity as SingleActivity).mapView, mapboxMap, MAPBOX_HEAVY_STYLE) var show = true pushSourceUpdates(styleChangeIdlingResource) { - plugin.isLocationLayerEnabled = show + if (show) { + plugin.activateLocationLayerPlugin(context, false) + } else { + plugin.deactivateLocationLayerPlugin() + } show = !show } @@ -289,13 +293,14 @@ class LocationLayerTest { @Test fun accuracy_visibleWithNewLocation() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(location), 16.0)) - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) plugin.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY + ACCURACY_RADIUS_ANIMATION_DURATION) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + uiController.loopMainThreadForAtLeast(ACCURACY_RADIUS_ANIMATION_DURATION) assertEquals(Utils.calculateZoomLevelRadius(mapboxMap, location) /*meters projected to radius on zoom 16*/, mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0] @@ -307,12 +312,12 @@ class LocationLayerTest { @Test fun accuracy_visibleWhenCameraEased() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) plugin.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) mapboxMap.easeCamera(CameraUpdateFactory.newLatLngZoom(LatLng(location), 16.0), 300) uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY + 300) @@ -326,9 +331,10 @@ class LocationLayerTest { @Test fun accuracy_visibleWhenCameraMoved() { - val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { - override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { + override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.activateLocationLayerPlugin(context, false) uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) plugin.forceLocationUpdate(location) uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) @@ -344,13 +350,12 @@ class LocationLayerTest { } @After - fun afterTest() { - Timber.e("@After: ${nameRule.methodName} - unregister idle resource") - IdlingRegistry.getInstance().unregister(idlingResource) + override fun afterTest() { + super.afterTest() IdlingRegistry.getInstance().unregister(styleChangeIdlingResource) } - private fun executePluginTest(listener: GenericPluginAction.OnPerformGenericPluginAction) { - onView(withId(android.R.id.content)).perform(GenericPluginAction(idlingResource.mapView, mapboxMap, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity), listener)) + private fun executePluginTest(listener: LocationLayerPluginAction.OnPerformLocationLayerPluginAction) { + onView(withId(R.id.content)).perform(LocationLayerPluginAction(mapboxMap, listener)) } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/GenericPluginAction.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/GenericPluginAction.kt deleted file mode 100644 index 210f7b4758..0000000000 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/GenericPluginAction.kt +++ /dev/null @@ -1,48 +0,0 @@ -package com.mapbox.mapboxsdk.plugins.utils - -import android.content.Context -import android.support.test.espresso.UiController -import android.support.test.espresso.ViewAction -import android.support.test.espresso.matcher.ViewMatchers.isDisplayed -import android.view.View -import com.mapbox.mapboxsdk.maps.MapView -import com.mapbox.mapboxsdk.maps.MapboxMap -import com.mapbox.mapboxsdk.plugins.utils.PluginGenerationUtil.Companion.MAP_RENDER_DELAY -import org.hamcrest.Matcher - -class GenericPluginAction(private val mapView: MapView, private val mapboxMap: MapboxMap, private val pluginProvider: PluginProvider, - private val onPerformGenericPluginAction: OnPerformGenericPluginAction) : ViewAction { - - override fun getConstraints(): Matcher { - return isDisplayed() - } - - override fun getDescription(): String { - return javaClass.simpleName - } - - override fun perform(uiController: UiController, view: View) { - val plugin = pluginProvider.providePlugin(mapView, mapboxMap, view.context) - - // ensuring that the asynchronous renderer has time to render data we want to test - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) - while (!pluginProvider.isPluginDataReady(plugin, mapboxMap)) { - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) - } - - onPerformGenericPluginAction.onGenericPluginAction( - plugin, - mapboxMap, - uiController, - view.context) - } - - interface OnPerformGenericPluginAction { - fun onGenericPluginAction(plugin: T, mapboxMap: MapboxMap, uiController: UiController, context: Context) - } - - interface PluginProvider { - fun providePlugin(mapView: MapView, mapboxMap: MapboxMap, context: Context): T - fun isPluginDataReady(plugin: T, mapboxMap: MapboxMap): Boolean - } -} \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/LocationLayerPluginAction.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/LocationLayerPluginAction.kt new file mode 100644 index 0000000000..af2c9adf35 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/LocationLayerPluginAction.kt @@ -0,0 +1,40 @@ +package com.mapbox.mapboxsdk.plugins.utils + +import android.content.Context +import android.support.test.espresso.UiController +import android.support.test.espresso.ViewAction +import android.support.test.espresso.matcher.ViewMatchers.isDisplayed +import android.view.View +import com.mapbox.mapboxsdk.maps.MapboxMap +import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerPlugin +import org.hamcrest.Matcher + +class LocationLayerPluginAction(private val mapboxMap: MapboxMap, + private val onPerformLocationLayerPluginAction: OnPerformLocationLayerPluginAction) : ViewAction { + + override fun getConstraints(): Matcher { + return isDisplayed() + } + + override fun getDescription(): String { + return javaClass.simpleName + } + + override fun perform(uiController: UiController, view: View) { + val plugin = mapboxMap.locationLayerPlugin + + while (mapboxMap.getSource("mapbox-location-source") == null) { + uiController.loopMainThreadForAtLeast(MapboxTestingUtils.MAP_RENDER_DELAY) + } + + onPerformLocationLayerPluginAction.onLocationLayerPluginAction( + plugin, + mapboxMap, + uiController, + view.context) + } + + interface OnPerformLocationLayerPluginAction { + fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, uiController: UiController, context: Context) + } +} \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/MapboxTestingUtils.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/MapboxTestingUtils.kt index b65cb3278b..b77ab127d9 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/MapboxTestingUtils.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/MapboxTestingUtils.kt @@ -7,6 +7,7 @@ import android.graphics.drawable.Drawable import android.location.Location import android.os.Handler import android.os.Looper +import android.support.test.espresso.UiController import com.mapbox.geojson.Feature import com.mapbox.mapboxsdk.geometry.LatLng import com.mapbox.mapboxsdk.maps.MapboxMap @@ -14,7 +15,7 @@ import com.mapbox.mapboxsdk.style.layers.Property import com.mapbox.mapboxsdk.style.sources.GeoJsonSource fun MapboxMap.querySourceFeatures(sourceId: String): List { - return this.getSourceAs(sourceId)?.querySourceFeatures(null) as List + return this.getSourceAs(sourceId)?.querySourceFeatures(null) ?: emptyList() } fun MapboxMap.queryRenderedFeatures(location: Location, layerId: String): List { @@ -27,9 +28,34 @@ fun MapboxMap.isLayerVisible(layerId: String): Boolean { return this.getLayer(layerId)?.visibility?.value?.equals(Property.VISIBLE)!! } +fun MapboxMap.waitForSource(uiController: UiController, sourceId: String) { + var counter = 0 + val delay = MapboxTestingUtils.MAP_RENDER_DELAY + while (this.querySourceFeatures(sourceId).isEmpty() && delay * counter < MapboxTestingUtils.RENDER_TIMEOUT) { + uiController.loopMainThreadForAtLeast(delay) + counter++ + } +} + +fun MapboxMap.waitForLayer(uiController: UiController, location: Location, layerId: String, shouldDisappear: Boolean = false) { + var counter = 0 + val delay = MapboxTestingUtils.MAP_RENDER_DELAY + while ( + if (shouldDisappear) this.queryRenderedFeatures(location, layerId).isNotEmpty() else this.queryRenderedFeatures(location, layerId).isEmpty() + && delay * counter < MapboxTestingUtils.RENDER_TIMEOUT) { + uiController.loopMainThreadForAtLeast(delay) + counter++ + } +} + + class MapboxTestingUtils { companion object { + const val MAP_RENDER_DELAY = 250L + const val MAP_CONNECTION_DELAY = 1000L + const val RENDER_TIMEOUT = 3_000L + /** * Used to increase style load time for stress testing. */ @@ -71,7 +97,7 @@ fun MapboxMap.addImageFromDrawable(string: String, drawable: Drawable) { private fun getBitmapFromDrawable(drawable: Drawable): Bitmap { if (drawable is BitmapDrawable) return drawable.bitmap val bitmap = Bitmap.createBitmap(drawable.intrinsicWidth, - drawable.intrinsicHeight, Bitmap.Config.ARGB_8888) + drawable.intrinsicHeight, Bitmap.Config.ARGB_8888) val canvas = Canvas(bitmap) drawable.setBounds(0, 0, canvas.width, canvas.height) drawable.draw(canvas) diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/PluginGenerationUtil.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/PluginGenerationUtil.kt deleted file mode 100644 index 9049a28298..0000000000 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/PluginGenerationUtil.kt +++ /dev/null @@ -1,51 +0,0 @@ -package com.mapbox.mapboxsdk.plugins.utils - -import android.content.Context -import android.support.v7.app.AppCompatActivity -import com.mapbox.android.core.location.LocationEngine -import com.mapbox.mapboxsdk.maps.MapView -import com.mapbox.mapboxsdk.maps.MapboxMap -import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerOptions -import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerPlugin - -class PluginGenerationUtil { - companion object { - fun getLocationLayerPluginProvider(activity: AppCompatActivity, - useDefaultEngine: Boolean = false, - engine: LocationEngine? = null, - options: LocationLayerOptions? = null, - registerLifecycleObserver: Boolean = true) - : GenericPluginAction.PluginProvider { - return object : GenericPluginAction.PluginProvider { - override fun providePlugin(mapView: MapView, mapboxMap: MapboxMap, context: Context): LocationLayerPlugin { - val plugin = if (useDefaultEngine) { - if (options != null) { - LocationLayerPlugin(mapView, mapboxMap, options) - } else { - LocationLayerPlugin(mapView, mapboxMap) - } - } else { - if (options != null) { - LocationLayerPlugin(mapView, mapboxMap, engine, options) - } else { - LocationLayerPlugin(mapView, mapboxMap, engine) - } - } - - if (registerLifecycleObserver) { - activity.lifecycle.addObserver(plugin) - } - - return plugin - } - - override fun isPluginDataReady(plugin: LocationLayerPlugin, mapboxMap: MapboxMap): Boolean { - return mapboxMap.getSource("mapbox-location-source") != null - } - } - } - - const val MAP_RENDER_DELAY = 250L - const val MAP_CONNECTION_DELAY = 1000L - } -} \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/TestLifecycleOwner.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/TestLifecycleOwner.kt deleted file mode 100644 index ccb8da17a7..0000000000 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/TestLifecycleOwner.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.mapbox.mapboxsdk.plugins.utils - -import android.arch.lifecycle.Lifecycle -import android.arch.lifecycle.LifecycleOwner -import android.arch.lifecycle.LifecycleRegistry - -class TestLifecycleOwner : LifecycleOwner { - private val lifecycleRegistry = LifecycleRegistry(this) - - override fun getLifecycle() = lifecycleRegistry - - fun markState(state: Lifecycle.State) { - lifecycleRegistry.markState(state) - } - - fun handleLifecycleEvent(event: Lifecycle.Event) { - lifecycleRegistry.handleLifecycleEvent(event) - } -} \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/action/MapboxMapAction.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/action/MapboxMapAction.java index 5e8f3ed365..926212afc8 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/action/MapboxMapAction.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/action/MapboxMapAction.java @@ -1,5 +1,6 @@ package com.mapbox.mapboxsdk.testapp.action; +import android.support.annotation.NonNull; import android.support.test.espresso.UiController; import android.support.test.espresso.ViewAction; import android.view.View; @@ -42,7 +43,7 @@ public class MapboxMapAction implements ViewAction { } public interface OnInvokeActionListener { - void onInvokeAction(UiController uiController, MapboxMap mapboxMap); + void onInvokeAction(@NonNull UiController uiController, @NonNull MapboxMap mapboxMap); } } 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 5480aa7a1c..3682440aeb 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 @@ -4,19 +4,24 @@ import android.app.Activity; import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; -import android.support.test.espresso.Espresso; +import android.support.test.espresso.IdlingRegistry; import android.support.test.espresso.IdlingResourceTimeoutException; import android.support.test.espresso.ViewInteraction; import android.support.test.rule.ActivityTestRule; + import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.testapp.R; import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction; import com.mapbox.mapboxsdk.testapp.action.WaitAction; import com.mapbox.mapboxsdk.testapp.utils.OnMapReadyIdlingResource; + import junit.framework.Assert; + import org.junit.After; import org.junit.Before; import org.junit.Rule; +import org.junit.rules.TestName; + import timber.log.Timber; import static android.support.test.espresso.Espresso.onView; @@ -28,15 +33,19 @@ public abstract class BaseActivityTest { @Rule public ActivityTestRule rule = new ActivityTestRule<>(getActivityClass()); + + @Rule + public TestName testNameRule = new TestName(); + protected MapboxMap mapboxMap; protected OnMapReadyIdlingResource idlingResource; @Before public void beforeTest() { try { - Timber.e("@Before test: register idle resource"); + Timber.e(String.format("%s - %s", testNameRule.getMethodName(), "@Before test: register idle resource")); idlingResource = new OnMapReadyIdlingResource(rule.getActivity()); - Espresso.registerIdlingResources(idlingResource); + IdlingRegistry.getInstance().register(idlingResource); checkViewIsDisplayed(R.id.mapView); mapboxMap = idlingResource.getMapboxMap(); } catch (IdlingResourceTimeoutException idlingResourceTimeoutException) { @@ -91,8 +100,8 @@ public abstract class BaseActivityTest { @After public void afterTest() { - Timber.e("@After test: unregister idle resource"); - Espresso.unregisterIdlingResources(idlingResource); + Timber.e(String.format("%s - %s", testNameRule.getMethodName(), "@After test: unregister idle resource")); + IdlingRegistry.getInstance().unregister(idlingResource); } } -- cgit v1.2.1 From cf7752c80c1dab6a818fb5093bee5cd964990525 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Wed, 5 Sep 2018 13:38:12 +0200 Subject: [android] save location state --- .../locationlayer/LocationLayerPluginTest.kt | 37 ++++++++++------------ .../plugins/locationlayer/LocationLayerTest.kt | 9 +++--- 2 files changed, 21 insertions(+), 25 deletions(-) (limited to 'platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java') diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt index 1820d56d95..e9552f974b 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt @@ -12,6 +12,7 @@ import android.support.test.espresso.UiController import android.support.test.espresso.assertion.ViewAssertions.matches import android.support.test.espresso.matcher.ViewMatchers.* import android.support.test.rule.GrantPermissionRule +import android.support.test.runner.AndroidJUnit4 import android.support.v4.content.ContextCompat import com.mapbox.geojson.Point import com.mapbox.mapboxsdk.camera.CameraUpdateFactory @@ -33,7 +34,9 @@ import org.hamcrest.CoreMatchers.* import org.junit.* import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue +import org.junit.runner.RunWith +@RunWith(AndroidJUnit4::class) class LocationLayerPluginTest : BaseActivityTest() { @Rule @@ -57,12 +60,6 @@ class LocationLayerPluginTest : BaseActivityTest() { @Before override fun beforeTest() { super.beforeTest() - - location.latitude = 15.0 - location.longitude = 17.0 - location.bearing = 10f - location.accuracy = 150f - styleChangeIdlingResource = StyleChangeIdlingResource() IdlingRegistry.getInstance().register(styleChangeIdlingResource) } @@ -839,7 +836,7 @@ class LocationLayerPluginTest : BaseActivityTest() { plugin.cameraMode = CameraMode.NONE val zoom = mapboxMap.cameraPosition.zoom plugin.zoomWhileTracking(10.0) - uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIMATION_DURATION) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIM_DURATION) assertEquals(zoom, mapboxMap.cameraPosition.zoom, 0.1) } @@ -856,7 +853,7 @@ class LocationLayerPluginTest : BaseActivityTest() { plugin.activateLocationLayerPlugin(context, false) plugin.cameraMode = CameraMode.TRACKING plugin.zoomWhileTracking(10.0) - uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIMATION_DURATION) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIM_DURATION) assertEquals(10.0, mapboxMap.cameraPosition.zoom, 0.1) } @@ -874,9 +871,9 @@ class LocationLayerPluginTest : BaseActivityTest() { plugin.activateLocationLayerPlugin(context, false) plugin.cameraMode = CameraMode.TRACKING plugin.zoomWhileTracking(15.0) - uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIMATION_DURATION / 2) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIM_DURATION / 2) plugin.cameraMode = CameraMode.NONE - uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIMATION_DURATION / 2) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIM_DURATION / 2) assertEquals(15.0 / 2.0, mapboxMap.cameraPosition.zoom, 3.0) } @@ -898,7 +895,7 @@ class LocationLayerPluginTest : BaseActivityTest() { plugin.onStop() plugin.zoomWhileTracking(10.0) - uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIMATION_DURATION) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIM_DURATION) assertEquals(zoom, mapboxMap.cameraPosition.zoom, 0.1) } @@ -916,9 +913,9 @@ class LocationLayerPluginTest : BaseActivityTest() { plugin.activateLocationLayerPlugin(context, false) plugin.cameraMode = CameraMode.TRACKING plugin.zoomWhileTracking(15.0) - uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIMATION_DURATION / 2) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIM_DURATION / 2) plugin.cancelZoomWhileTrackingAnimation() - uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIMATION_DURATION / 2) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIM_DURATION / 2) assertEquals(15.0 / 2.0, mapboxMap.cameraPosition.zoom, 3.0) } @@ -936,7 +933,7 @@ class LocationLayerPluginTest : BaseActivityTest() { plugin.cameraMode = CameraMode.NONE val tilt = mapboxMap.cameraPosition.tilt plugin.tiltWhileTracking(30.0) - uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIMATION_DURATION) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIM_DURATION) assertEquals(tilt, mapboxMap.cameraPosition.tilt, 0.1) } @@ -953,7 +950,7 @@ class LocationLayerPluginTest : BaseActivityTest() { plugin.activateLocationLayerPlugin(context, false) plugin.cameraMode = CameraMode.TRACKING plugin.tiltWhileTracking(30.0) - uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIMATION_DURATION) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIM_DURATION) assertEquals(30.0, mapboxMap.cameraPosition.tilt, 0.1) } @@ -971,9 +968,9 @@ class LocationLayerPluginTest : BaseActivityTest() { plugin.activateLocationLayerPlugin(context, false) plugin.cameraMode = CameraMode.TRACKING plugin.tiltWhileTracking(30.0) - uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIMATION_DURATION / 2) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIM_DURATION / 2) plugin.cameraMode = CameraMode.NONE - uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIMATION_DURATION / 2) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIM_DURATION / 2) assertEquals(30.0 / 2.0, mapboxMap.cameraPosition.tilt, 3.0) } @@ -993,7 +990,7 @@ class LocationLayerPluginTest : BaseActivityTest() { plugin.onStop() plugin.tiltWhileTracking(30.0) - uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIMATION_DURATION) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIM_DURATION) assertEquals(tilt, mapboxMap.cameraPosition.tilt, 0.1) } @@ -1011,9 +1008,9 @@ class LocationLayerPluginTest : BaseActivityTest() { plugin.activateLocationLayerPlugin(context, false) plugin.cameraMode = CameraMode.TRACKING plugin.tiltWhileTracking(30.0) - uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIMATION_DURATION / 2) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIM_DURATION / 2) plugin.cancelTiltWhileTrackingAnimation() - uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIMATION_DURATION / 2) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIM_DURATION / 2) assertEquals(30.0 / 2.0, mapboxMap.cameraPosition.tilt, 3.0) } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.kt index d7823031fc..a0f23ce485 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.kt @@ -12,6 +12,7 @@ import android.support.test.espresso.matcher.ViewMatchers.isDisplayed import android.support.test.espresso.matcher.ViewMatchers.withId import android.support.test.rule.GrantPermissionRule import android.support.test.rule.GrantPermissionRule.grant +import android.support.test.runner.AndroidJUnit4 import com.mapbox.mapboxsdk.camera.CameraUpdateFactory import com.mapbox.mapboxsdk.constants.Style import com.mapbox.mapboxsdk.geometry.LatLng @@ -35,7 +36,9 @@ import org.junit.Assert.assertThat import org.junit.Before import org.junit.Rule import org.junit.Test +import org.junit.runner.RunWith +@RunWith(AndroidJUnit4::class) class LocationLayerTest : BaseActivityTest() { @Rule @@ -52,7 +55,7 @@ class LocationLayerTest : BaseActivityTest() { initLocation.latitude = 15.0 initLocation.longitude = 17.0 initLocation.bearing = 10f - initLocation.accuracy = 2000f + initLocation.accuracy = 150f initLocation } @@ -219,10 +222,6 @@ class LocationLayerTest : BaseActivityTest() { executePluginTest(pluginAction) } -// -// Stale state test -// - @Test fun whenStyleChanged_continuesUsingStaleIcons() { val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { -- cgit v1.2.1 From 907612e93d8a2b156d4604fda348707ccb347836 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Wed, 5 Sep 2018 14:30:36 +0200 Subject: [android] updated naming scheme and packages structure for LocationLayerPlugin, now called LocationComponent --- .../mapboxsdk/location/LocationComponentTest.kt | 1104 ++++++++++++++++++++ .../location/LocationLayerControllerTest.kt | 360 +++++++ .../location/utils/LocationComponentAction.kt | 40 + .../mapboxsdk/location/utils/MapboxTestingUtils.kt | 105 ++ .../utils/OnMapFragmentReadyIdlingResource.kt | 39 + .../location/utils/OnMapReadyIdlingResource.java | 63 ++ .../location/utils/StyleChangeIdlingResource.kt | 46 + .../locationlayer/LocationLayerPluginTest.kt | 1104 -------------------- .../plugins/locationlayer/LocationLayerTest.kt | 360 ------- .../plugins/utils/LocationLayerPluginAction.kt | 40 - .../mapboxsdk/plugins/utils/MapboxTestingUtils.kt | 105 -- .../utils/OnMapFragmentReadyIdlingResource.kt | 39 - .../plugins/utils/OnMapReadyIdlingResource.java | 63 -- .../plugins/utils/StyleChangeIdlingResource.kt | 46 - 14 files changed, 1757 insertions(+), 1757 deletions(-) create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationLayerControllerTest.kt create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/utils/LocationComponentAction.kt create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/utils/MapboxTestingUtils.kt create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/utils/OnMapFragmentReadyIdlingResource.kt create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/utils/OnMapReadyIdlingResource.java create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/utils/StyleChangeIdlingResource.kt delete mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt delete mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.kt delete mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/LocationLayerPluginAction.kt delete mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/MapboxTestingUtils.kt delete mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/OnMapFragmentReadyIdlingResource.kt delete mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/OnMapReadyIdlingResource.java delete mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/StyleChangeIdlingResource.kt (limited to 'platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java') diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt new file mode 100644 index 0000000000..1d7c0c404b --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt @@ -0,0 +1,1104 @@ +package com.mapbox.mapboxsdk.location + +import android.Manifest +import android.R +import android.content.Context +import android.graphics.Color +import android.graphics.RectF +import android.location.Location +import android.support.test.espresso.Espresso.onView +import android.support.test.espresso.IdlingRegistry +import android.support.test.espresso.UiController +import android.support.test.espresso.assertion.ViewAssertions.matches +import android.support.test.espresso.matcher.ViewMatchers.* +import android.support.test.rule.GrantPermissionRule +import android.support.test.runner.AndroidJUnit4 +import android.support.v4.content.ContextCompat +import com.mapbox.geojson.Point +import com.mapbox.mapboxsdk.camera.CameraUpdateFactory +import com.mapbox.mapboxsdk.constants.Style +import com.mapbox.mapboxsdk.geometry.LatLng +import com.mapbox.mapboxsdk.maps.MapboxMap +import com.mapbox.mapboxsdk.location.LocationComponentConstants.* +import com.mapbox.mapboxsdk.location.modes.CameraMode +import com.mapbox.mapboxsdk.location.modes.RenderMode +import com.mapbox.mapboxsdk.location.utils.* +import com.mapbox.mapboxsdk.location.utils.MapboxTestingUtils.Companion.MAPBOX_HEAVY_STYLE +import com.mapbox.mapboxsdk.location.utils.MapboxTestingUtils.Companion.MAP_CONNECTION_DELAY +import com.mapbox.mapboxsdk.location.utils.MapboxTestingUtils.Companion.MAP_RENDER_DELAY +import com.mapbox.mapboxsdk.location.utils.MapboxTestingUtils.Companion.pushSourceUpdates +import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest +import com.mapbox.mapboxsdk.testapp.activity.SingleActivity +import com.mapbox.mapboxsdk.utils.ColorUtils +import org.hamcrest.CoreMatchers.* +import org.junit.* +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class LocationComponentTest : BaseActivityTest() { + + @Rule + @JvmField + val permissionRule: GrantPermissionRule = GrantPermissionRule.grant(Manifest.permission.ACCESS_FINE_LOCATION) + + override fun getActivityClass(): Class<*> { + return SingleActivity::class.java + } + + private lateinit var styleChangeIdlingResource: StyleChangeIdlingResource + private val location: Location by lazy { + val initLocation = Location("") + initLocation.latitude = 15.0 + initLocation.longitude = 17.0 + initLocation.bearing = 10f + initLocation.accuracy = 150f + initLocation + } + + @Before + override fun beforeTest() { + super.beforeTest() + styleChangeIdlingResource = StyleChangeIdlingResource() + IdlingRegistry.getInstance().register(styleChangeIdlingResource) + } + + @Test + fun locationComponent_initializesLocationEngineCorrectlyWhenOnesNotProvided() { + validateTestSetup() + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context) + + val locationEngine = component.locationEngine + assertThat(locationEngine, notNullValue()) + + uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) + assertThat(locationEngine?.isConnected, `is`(true)) + } + } + + executeComponentTest(componentAction) + } + + @Test + fun locationComponent_initializesLocationEngineCorrectlyWhenOnesNotProvidedButHasOptions() { + validateTestSetup() + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent( + context, + LocationComponentOptions.builder(context) + .staleStateTimeout(200) + .enableStaleState(false) + .accuracyAlpha(.5f) + .accuracyColor(Color.BLUE) + .build()) + + val locationEngine = component.locationEngine + val componentOptions = component.locationComponentOptions + + assertThat(locationEngine, notNullValue()) + assertThat(componentOptions, notNullValue()) + + uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) + assertThat(locationEngine?.isConnected, `is`(true)) + assertThat(componentOptions?.accuracyAlpha(), `is`(.5f)) + assertThat(componentOptions?.accuracyColor(), `is`(Color.BLUE)) + } + } + + executeComponentTest(componentAction) + } + + @Test + fun locationComponent_doesntInitializeEngineWhenNullProvided() { + validateTestSetup() + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent( + null, + LocationComponentOptions.builder(context) + .staleStateTimeout(200) + .enableStaleState(false) + .accuracyAlpha(.5f) + .accuracyColor(Color.BLUE) + .build()) + + val locationEngine = component.locationEngine + val componentOptions = component.locationComponentOptions + + assertThat(locationEngine, nullValue()) + assertThat(componentOptions, notNullValue()) + + uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) + assertThat(componentOptions?.accuracyAlpha(), `is`(.5f)) + assertThat(componentOptions?.accuracyColor(), `is`(Color.BLUE)) + } + } + + executeComponentTest(componentAction) + } + + @Test + fun settingMapStyleImmediatelyBeforeLoadingComponent_doesStillLoadLayersProperly() { + validateTestSetup() + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + mapboxMap.setStyle(Style.LIGHT) + component.activateLocationComponent(context, false) + component.forceLocationUpdate(location) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + + assertThat(component.renderMode, `is`(equalTo(RenderMode.NORMAL))) + assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(SHADOW_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(BEARING_LAYER), `is`(false)) + } + } + + executeComponentTest(componentAction) + } + + @Test + fun locationComponent_doesntShowUntilFirstLocationFix() { + validateTestSetup() + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + + // Source should be present but empty + val mapView = (rule.activity as SingleActivity).mapView + assertThat(mapboxMap.queryRenderedFeatures( + RectF(0f, 0f, mapView.width.toFloat(), mapView.height.toFloat()), FOREGROUND_LAYER) + .isEmpty(), `is`(true)) + + // Force the first location update + component.forceLocationUpdate(location) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + + // Check if the puck is visible + assertThat(mapboxMap.queryRenderedFeatures(location, FOREGROUND_LAYER).isEmpty(), `is`(false)) + } + } + executeComponentTest(componentAction) + } + + // + // Location Layer Options + // + + @Test + fun locationComponentOptions_disablingStaleStateDoesWorkCorrectly() { + validateTestSetup() + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, + LocationComponentOptions.builder(context) + .staleStateTimeout(200) + .enableStaleState(false) + .build()) + + component.forceLocationUpdate(location) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + uiController.loopMainThreadForAtLeast(200) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + + mapboxMap.querySourceFeatures(LOCATION_SOURCE).also { + it.forEach { + assertThat(it.getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(false)) + } + } + } + } + + executeComponentTest(componentAction) + } + + @Test + fun locationComponentOptions_loadsForegroundBitmapFromNameOption() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, + LocationComponentOptions.builder(context) + .foregroundName("custom-foreground-bitmap") + .backgroundName("custom-background-bitmap") + .foregroundStaleName("custom-foreground-stale-bitmap") + .backgroundStaleName("custom-background-stale-bitmap") + .bearingName("custom-bearing-bitmap") + .build()) + + val foregroundDrawable = ContextCompat.getDrawable(context, R.drawable.ic_media_play) + foregroundDrawable?.let { + mapboxMap.addImageFromDrawable("custom-foreground-bitmap", it) + mapboxMap.addImageFromDrawable("custom-background-bitmap", it) + mapboxMap.addImageFromDrawable("custom-foreground-stale-bitmap", it) + mapboxMap.addImageFromDrawable("custom-background-stale-bitmap", it) + mapboxMap.addImageFromDrawable("custom-bearing-bitmap", it) + } + + component.forceLocationUpdate(location) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + assertThat(mapboxMap.queryRenderedFeatures(location, FOREGROUND_LAYER).isEmpty(), `is`(false)) + + val feature = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0] + assertThat(feature.getStringProperty(PROPERTY_FOREGROUND_ICON), `is`(equalTo("custom-foreground-bitmap"))) + assertThat(feature.getStringProperty(PROPERTY_BACKGROUND_ICON), `is`(equalTo("custom-background-bitmap"))) + assertThat(feature.getStringProperty(PROPERTY_FOREGROUND_STALE_ICON), `is`(equalTo("custom-foreground-stale-bitmap"))) + assertThat(feature.getStringProperty(PROPERTY_BACKGROUND_STALE_ICON), `is`(equalTo("custom-background-stale-bitmap"))) + assertThat(feature.getStringProperty(PROPERTY_BEARING_ICON), `is`(equalTo("custom-bearing-bitmap"))) + } + } + + executeComponentTest(componentAction) + } + + @Test + fun locationComponentOptions_loadsGpsNameWithGpsRenderMode() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, + LocationComponentOptions.builder(context) + .foregroundName("custom-foreground-bitmap") + .gpsName("custom-gps-bitmap") + .build()) + + component.renderMode = RenderMode.GPS + component.forceLocationUpdate(location) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + val foregroundDrawable = ContextCompat.getDrawable(context, R.drawable.ic_media_play) + foregroundDrawable?.let { + mapboxMap.addImageFromDrawable("custom-foreground-bitmap", it) + mapboxMap.addImageFromDrawable("custom-gps-bitmap", it) + } + + val foregroundId = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getStringProperty(PROPERTY_FOREGROUND_ICON) + assertThat(foregroundId, `is`(equalTo("custom-gps-bitmap"))) + } + } + + executeComponentTest(componentAction) + } + + @Test + fun locationComponentOptions_customIconNameRevertsToDefault() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, + LocationComponentOptions.builder(context) + .foregroundName("custom-foreground-bitmap") + .gpsName("custom-gps-bitmap") + .build()) + + component.renderMode = RenderMode.GPS + component.forceLocationUpdate(location) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + + val foregroundId = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getStringProperty(PROPERTY_FOREGROUND_ICON) + assertThat(foregroundId, `is`(equalTo("custom-gps-bitmap"))) + + component.applyStyle(LocationComponentOptions.builder(context).build()) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + + val revertedForegroundId = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getStringProperty(PROPERTY_FOREGROUND_ICON) + assertThat(revertedForegroundId, `is`(equalTo(FOREGROUND_ICON))) + } + } + + executeComponentTest(componentAction) + } + + @Test + fun locationComponentOptions_customGpsIconNameChangeBackWithMode() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + + component.activateLocationComponent(context, + LocationComponentOptions.builder(context) + .gpsName("custom-gps-bitmap") + .build()) + + component.renderMode = RenderMode.GPS + component.forceLocationUpdate(location) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + + val foregroundId = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getStringProperty(PROPERTY_FOREGROUND_ICON) + assertThat(foregroundId, `is`(equalTo("custom-gps-bitmap"))) + + component.renderMode = RenderMode.NORMAL + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + + val revertedForegroundId = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getStringProperty(PROPERTY_FOREGROUND_ICON) + assertThat(revertedForegroundId, `is`(equalTo(FOREGROUND_ICON))) + } + } + + executeComponentTest(componentAction) + } + + @Test + fun stillStaleAfterResuming() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, + LocationComponentOptions.builder(context) + .staleStateTimeout(200) + .build()) + + component.forceLocationUpdate(location) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + uiController.loopMainThreadForAtLeast(250) // engaging stale state + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(true)) + + component.onStop() + component.onStart() + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + + assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(true)) + assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(false)) + } + } + + executeComponentTest(componentAction) + } + + @Test + fun stillNotStaleAfterResuming() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + component.forceLocationUpdate(location) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(false)) + + component.onStop() + component.onStart() + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + + assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(false)) + assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(true)) + } + } + executeComponentTest(componentAction) + } + + @Test + fun locationComponentOptions_accuracyRingWithColor() { + val color = Color.parseColor("#4A90E2") + val rgbaColor = ColorUtils.colorToRgbaString(color) + + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, + LocationComponentOptions.builder(context) + .accuracyColor(color) + .build()) + + component.forceLocationUpdate(location) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + + // Check that the source property changes correctly + mapboxMap.querySourceFeatures(LOCATION_SOURCE).also { + it.forEach { + assertThat(it.getStringProperty(PROPERTY_ACCURACY_COLOR), `is`(equalTo(rgbaColor))) + } + } + } + } + + executeComponentTest(componentAction) + } + + @Test + fun forceLocationUpdate_doesMoveLocationLayerIconToCorrectPosition() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + component.forceLocationUpdate(location) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + + val point: Point = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].geometry() as Point + + assertThat(component.locationEngine, nullValue()) + assertEquals(point.latitude(), location.latitude, 0.1) + assertEquals(point.longitude(), location.longitude, 0.1) + } + } + executeComponentTest(componentAction) + } + + @Test + fun disablingComponentHidesPuck() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + component.forceLocationUpdate(location) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + + val point: Point = mapboxMap.queryRenderedFeatures(location, FOREGROUND_LAYER)[0].geometry() as Point + assertEquals(point.latitude(), location.latitude, 0.1) + assertEquals(point.longitude(), location.longitude, 0.1) + + component.deactivateLocationComponent() + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + assertThat(mapboxMap.queryRenderedFeatures(location, FOREGROUND_LAYER).isEmpty(), `is`(true)) + } + } + executeComponentTest(componentAction) + } + + @Test + fun disablingComponentAndChangingStyleAllowsToEnableAgain() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + component.forceLocationUpdate(location) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + + component.deactivateLocationComponent() + mapboxMap.setStyle(Style.LIGHT) + + component.activateLocationComponent(context, false) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true)) + } + } + executeComponentTest(componentAction) + } + + @Test + fun lifecycle_isDisabledOnStart() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + assertThat(component.isLocationLayerEnabled, `is`(false)) + component.onStop() + component.onStart() + assertThat(component.isLocationLayerEnabled, `is`(false)) + component.activateLocationComponent(context, false) + assertThat(component.isLocationLayerEnabled, `is`(true)) + } + } + executeComponentTest(componentAction) + } + + @Test + fun lifecycle_keepsEnabledWhenStoppedAndStarted() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + assertThat(component.isLocationLayerEnabled, `is`(true)) + component.onStop() + component.onStart() + assertThat(component.isLocationLayerEnabled, `is`(true)) + } + } + executeComponentTest(componentAction) + } + + @Test + fun lifecycle_keepsDisabledWhenStoppedAndStarted() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + component.deactivateLocationComponent() + assertThat(component.isLocationLayerEnabled, `is`(false)) + component.onStop() + component.onStart() + assertThat(component.isLocationLayerEnabled, `is`(false)) + } + } + executeComponentTest(componentAction) + } + + @Test + fun lifecycle_ableToChangeStyleAfterResuming() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + + component.onStop() + component.onStart() + + mapboxMap.setStyle(Style.DARK) + uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) + } + } + executeComponentTest(componentAction) + } + + @Test + fun lifecycle_interruptedDuringStyleChange() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + mapboxMap.setStyle(Style.DARK) + component.onStop() + component.onStart() + uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) + } + } + executeComponentTest(componentAction) + } + + @Test + fun lifecycle_forceLocationUpdateAfterStopped() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + component.onStop() + component.forceLocationUpdate(location) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + + assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE).isEmpty(), `is`(true)) + } + } + executeComponentTest(componentAction) + } + + @Test + fun lifecycle_acceptAndReuseLocationUpdatesBeforeLayerStarted() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + component.onStop() + component.forceLocationUpdate(location) + component.onStart() + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + + val point: Point = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].geometry() as Point + assertEquals(point.latitude(), location.latitude, 0.1) + assertEquals(point.longitude(), location.longitude, 0.1) + } + } + executeComponentTest(componentAction) + } + + @Test + fun lifecycle_lifecycleChangeRightAfterStyleReload() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + component.forceLocationUpdate(location) + mapboxMap.setStyle(Style.LIGHT) + component.onStop() + uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) + component.onStart() + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + + val point: Point = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].geometry() as Point + assertEquals(point.latitude(), location.latitude, 0.1) + assertEquals(point.longitude(), location.longitude, 0.1) + + assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(SHADOW_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(BEARING_LAYER), `is`(false)) + } + } + executeComponentTest(componentAction) + } + + @Test + fun mapChange_settingComponentStyle() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + styleChangeIdlingResource.waitForStyle((rule.activity as SingleActivity).mapView, mapboxMap, MAPBOX_HEAVY_STYLE) + val options = LocationComponentOptions.builder(context) + .accuracyColor(Color.RED) + .build() + + pushSourceUpdates(styleChangeIdlingResource) { + component.applyStyle(options) + } + + uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) + } + } + executeComponentTest(componentAction) + + // Waiting for style to finish loading while pushing updates + onView(withId(R.id.content)).check(matches(isDisplayed())) + } + + @Test + fun mapChange_forcingLocation() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + styleChangeIdlingResource.waitForStyle((rule.activity as SingleActivity).mapView, mapboxMap, MAPBOX_HEAVY_STYLE) + + pushSourceUpdates(styleChangeIdlingResource) { + component.forceLocationUpdate(location) + } + + uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) + } + } + executeComponentTest(componentAction) + + // Waiting for style to finish loading while pushing updates + onView(withId(R.id.content)).check(matches(isDisplayed())) + } + + @Test + fun mapChange_settingMapStyleBeforeComponentCreation() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + styleChangeIdlingResource.waitForStyle((rule.activity as SingleActivity).mapView, mapboxMap, MAPBOX_HEAVY_STYLE) + component.activateLocationComponent(context, false) + + val options = LocationComponentOptions.builder(context) + .accuracyColor(Color.RED) + .build() + + pushSourceUpdates(styleChangeIdlingResource) { + component.forceLocationUpdate(location) + component.applyStyle(options) + } + } + } + executeComponentTest(componentAction) + + // Waiting for style to finish loading while pushing updates + onView(withId(R.id.content)).check(matches(isDisplayed())) + } + + @Test + fun animators_layerBearingCorrect() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + component.renderMode = RenderMode.GPS + location.bearing = 77f + component.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS + MAP_RENDER_DELAY) + assertEquals(77.0, mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getNumberProperty(PROPERTY_GPS_BEARING) as Double, 0.1) + + location.bearing = 92f + component.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS + MAP_RENDER_DELAY) // Waiting for the animation to finish + assertEquals(92.0, mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getNumberProperty(PROPERTY_GPS_BEARING) as Double, 0.1) + } + } + + executeComponentTest(componentAction) + } + + @Test + fun animators_cameraLatLngBearingCorrect() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + component.cameraMode = CameraMode.TRACKING_GPS + location.bearing = 77f + component.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS + MAP_RENDER_DELAY) + assertEquals(77.0, mapboxMap.cameraPosition.bearing, 0.1) + assertEquals(location.latitude, mapboxMap.cameraPosition.target.latitude, 0.1) + assertEquals(location.longitude, mapboxMap.cameraPosition.target.longitude, 0.1) + + location.bearing = 92f + location.latitude = 30.0 + location.longitude = 35.0 + component.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS + MAP_RENDER_DELAY) // Waiting for the animation to finish + assertEquals(92.0, mapboxMap.cameraPosition.bearing, 0.1) + assertEquals(location.latitude, mapboxMap.cameraPosition.target.latitude, 0.1) + assertEquals(location.longitude, mapboxMap.cameraPosition.target.longitude, 0.1) + } + } + + executeComponentTest(componentAction) + } + + @Test + fun animators_cameraBearingCorrect() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + component.cameraMode = CameraMode.NONE_GPS + val latitude = mapboxMap.cameraPosition.target.latitude + val longitude = mapboxMap.cameraPosition.target.longitude + + location.bearing = 77f + component.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS + MAP_RENDER_DELAY) + assertEquals(77.0, mapboxMap.cameraPosition.bearing, 0.1) + assertEquals(latitude, mapboxMap.cameraPosition.target.latitude, 0.1) + assertEquals(longitude, mapboxMap.cameraPosition.target.longitude, 0.1) + + location.bearing = 92f + location.latitude = 30.0 + location.longitude = 35.0 + component.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS + MAP_RENDER_DELAY) + assertEquals(92.0, mapboxMap.cameraPosition.bearing, 0.1) + assertEquals(latitude, mapboxMap.cameraPosition.target.latitude, 0.1) + assertEquals(longitude, mapboxMap.cameraPosition.target.longitude, 0.1) + } + } + + executeComponentTest(componentAction) + } + + @Test + fun animators_cameraNoneCorrect() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + component.cameraMode = CameraMode.NONE + val latitude = mapboxMap.cameraPosition.target.latitude + val longitude = mapboxMap.cameraPosition.target.longitude + val bearing = mapboxMap.cameraPosition.bearing + + location.bearing = 77f + component.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS + MAP_RENDER_DELAY) + assertEquals(bearing, mapboxMap.cameraPosition.bearing, 0.1) + assertEquals(latitude, mapboxMap.cameraPosition.target.latitude, 0.1) + assertEquals(longitude, mapboxMap.cameraPosition.target.longitude, 0.1) + + location.bearing = 92f + location.latitude = 30.0 + location.longitude = 35.0 + component.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS + MAP_RENDER_DELAY) // Waiting for the animation to finish + assertEquals(bearing, mapboxMap.cameraPosition.bearing, 0.1) + assertEquals(latitude, mapboxMap.cameraPosition.target.latitude, 0.1) + assertEquals(longitude, mapboxMap.cameraPosition.target.longitude, 0.1) + } + } + + executeComponentTest(componentAction) + } + + @Test + fun animators_focalPointAdjustment() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + component.cameraMode = CameraMode.TRACKING + component.cameraMode = CameraMode.NONE + component.forceLocationUpdate(location) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + + assertThat(mapboxMap.uiSettings.focalPoint, nullValue()) + } + } + + executeComponentTest(componentAction) + } + + @Test + fun animators_dontZoomWhileNotTracking() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + component.cameraMode = CameraMode.NONE + val zoom = mapboxMap.cameraPosition.zoom + component.zoomWhileTracking(10.0) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIM_DURATION) + + assertEquals(zoom, mapboxMap.cameraPosition.zoom, 0.1) + } + } + + executeComponentTest(componentAction) + } + + @Test + fun animators_zoomWhileTracking() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + component.cameraMode = CameraMode.TRACKING + component.zoomWhileTracking(10.0) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIM_DURATION) + + assertEquals(10.0, mapboxMap.cameraPosition.zoom, 0.1) + } + } + + executeComponentTest(componentAction) + } + + @Test + @Ignore + fun animators_zoomWhileTrackingCanceledOnModeChange() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + component.cameraMode = CameraMode.TRACKING + component.zoomWhileTracking(15.0) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIM_DURATION / 2) + component.cameraMode = CameraMode.NONE + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIM_DURATION / 2) + + assertEquals(15.0 / 2.0, mapboxMap.cameraPosition.zoom, 3.0) + } + } + + executeComponentTest(componentAction) + } + + @Test + fun animators_dontZoomWhileStopped() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + + component.cameraMode = CameraMode.TRACKING + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + val zoom = mapboxMap.cameraPosition.zoom + + component.onStop() + component.zoomWhileTracking(10.0) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIM_DURATION) + + assertEquals(zoom, mapboxMap.cameraPosition.zoom, 0.1) + } + } + + executeComponentTest(componentAction) + } + + @Test + @Ignore + fun animators_cancelZoomWhileTracking() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + component.cameraMode = CameraMode.TRACKING + component.zoomWhileTracking(15.0) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIM_DURATION / 2) + component.cancelZoomWhileTrackingAnimation() + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIM_DURATION / 2) + + assertEquals(15.0 / 2.0, mapboxMap.cameraPosition.zoom, 3.0) + } + } + + executeComponentTest(componentAction) + } + + @Test + fun animators_dontTiltWhileNotTracking() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + component.cameraMode = CameraMode.NONE + val tilt = mapboxMap.cameraPosition.tilt + component.tiltWhileTracking(30.0) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIM_DURATION) + + assertEquals(tilt, mapboxMap.cameraPosition.tilt, 0.1) + } + } + + executeComponentTest(componentAction) + } + + @Test + fun animators_tiltWhileTracking() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + component.cameraMode = CameraMode.TRACKING + component.tiltWhileTracking(30.0) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIM_DURATION) + + assertEquals(30.0, mapboxMap.cameraPosition.tilt, 0.1) + } + } + + executeComponentTest(componentAction) + } + + @Test + @Ignore + fun animators_tiltWhileTrackingCanceledOnModeChange() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + component.cameraMode = CameraMode.TRACKING + component.tiltWhileTracking(30.0) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIM_DURATION / 2) + component.cameraMode = CameraMode.NONE + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIM_DURATION / 2) + + assertEquals(30.0 / 2.0, mapboxMap.cameraPosition.tilt, 3.0) + } + } + + executeComponentTest(componentAction) + } + + @Test + fun animators_dontTiltWhileStopped() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + component.cameraMode = CameraMode.TRACKING + val tilt = mapboxMap.cameraPosition.tilt + + component.onStop() + component.tiltWhileTracking(30.0) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIM_DURATION) + + assertEquals(tilt, mapboxMap.cameraPosition.tilt, 0.1) + } + } + + executeComponentTest(componentAction) + } + + @Test + @Ignore + fun animators_cancelTiltWhileTracking() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + component.cameraMode = CameraMode.TRACKING + component.tiltWhileTracking(30.0) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIM_DURATION / 2) + component.cancelTiltWhileTrackingAnimation() + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIM_DURATION / 2) + + assertEquals(30.0 / 2.0, mapboxMap.cameraPosition.tilt, 3.0) + } + } + + executeComponentTest(componentAction) + } + + @Test + fun cameraPositionAdjustedToTrackingModeWhenComponentEnabled() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + component.cameraMode = CameraMode.TRACKING_GPS + component.forceLocationUpdate(location) + component.deactivateLocationComponent() + mapboxMap.moveCamera(CameraUpdateFactory.newLatLng(LatLng(51.0, 17.0))) + mapboxMap.moveCamera(CameraUpdateFactory.bearingTo(90.0)) + component.activateLocationComponent(context, false) + uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS + MAP_RENDER_DELAY) + + assertEquals(location.bearing.toDouble(), mapboxMap.cameraPosition.bearing, 0.1) + assertEquals(location.latitude, mapboxMap.cameraPosition.target.latitude, 0.1) + assertEquals(location.longitude, mapboxMap.cameraPosition.target.longitude, 0.1) + } + } + + executeComponentTest(componentAction) + } + + @Test + fun compassEngine_onComponentInitializedDefaultIsProvided() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + assertTrue(component.compassEngine is LocationComponentCompassEngine) + } + } + + executeComponentTest(componentAction) + } + + @Test + fun compassEngine_changesWhenNewProvided() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + val engine: CompassEngine = object : CompassEngine { + override fun addCompassListener(compassListener: CompassListener) { + } + + override fun removeCompassListener(compassListener: CompassListener) { + } + + override fun getLastHeading(): Float { + return 0f + } + + override fun getLastAccuracySensorStatus(): Int { + return 0 + } + + override fun onStart() { + } + + override fun onStop() { + } + } + + component.compassEngine = engine + assertThat(component.compassEngine, notNullValue()) + assertThat(component.compassEngine, `is`(equalTo(engine))) + } + } + + executeComponentTest(componentAction) + } + + @After + override fun afterTest() { + super.afterTest() + IdlingRegistry.getInstance().unregister(styleChangeIdlingResource) + } + + private fun executeComponentTest(listener: LocationComponentAction.OnPerformLocationComponentAction) { + onView(withId(R.id.content)).perform(LocationComponentAction(mapboxMap, listener)) + } +} \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationLayerControllerTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationLayerControllerTest.kt new file mode 100644 index 0000000000..c50d1817fd --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationLayerControllerTest.kt @@ -0,0 +1,360 @@ +package com.mapbox.mapboxsdk.location + +import android.Manifest +import android.R +import android.content.Context +import android.location.Location +import android.support.test.espresso.Espresso.onView +import android.support.test.espresso.IdlingRegistry +import android.support.test.espresso.UiController +import android.support.test.espresso.assertion.ViewAssertions.matches +import android.support.test.espresso.matcher.ViewMatchers.isDisplayed +import android.support.test.espresso.matcher.ViewMatchers.withId +import android.support.test.rule.GrantPermissionRule +import android.support.test.rule.GrantPermissionRule.grant +import android.support.test.runner.AndroidJUnit4 +import com.mapbox.mapboxsdk.camera.CameraUpdateFactory +import com.mapbox.mapboxsdk.constants.Style +import com.mapbox.mapboxsdk.geometry.LatLng +import com.mapbox.mapboxsdk.maps.MapboxMap +import com.mapbox.mapboxsdk.location.LocationComponentConstants.* +import com.mapbox.mapboxsdk.location.modes.RenderMode +import com.mapbox.mapboxsdk.location.utils.* +import com.mapbox.mapboxsdk.location.utils.MapboxTestingUtils.Companion.MAPBOX_HEAVY_STYLE +import com.mapbox.mapboxsdk.location.utils.MapboxTestingUtils.Companion.MAP_CONNECTION_DELAY +import com.mapbox.mapboxsdk.location.utils.MapboxTestingUtils.Companion.MAP_RENDER_DELAY +import com.mapbox.mapboxsdk.location.utils.MapboxTestingUtils.Companion.pushSourceUpdates +import com.mapbox.mapboxsdk.style.sources.GeoJsonSource +import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest +import com.mapbox.mapboxsdk.testapp.activity.SingleActivity +import org.hamcrest.CoreMatchers.`is` +import org.hamcrest.CoreMatchers.notNullValue +import org.hamcrest.Matchers.equalTo +import org.junit.After +import org.junit.Assert.assertEquals +import org.junit.Assert.assertThat +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class LocationLayerControllerTest : BaseActivityTest() { + + @Rule + @JvmField + val permissionRule: GrantPermissionRule = grant(Manifest.permission.ACCESS_FINE_LOCATION) + + override fun getActivityClass(): Class<*> { + return SingleActivity::class.java + } + + private lateinit var styleChangeIdlingResource: StyleChangeIdlingResource + private val location: Location by lazy { + val initLocation = Location("") + initLocation.latitude = 15.0 + initLocation.longitude = 17.0 + initLocation.bearing = 10f + initLocation.accuracy = 150f + initLocation + } + + @Before + override fun beforeTest() { + super.beforeTest() + styleChangeIdlingResource = StyleChangeIdlingResource() + IdlingRegistry.getInstance().register(styleChangeIdlingResource) + } + + // + // Location Source + // + + @Test + fun renderModeNormal_sourceDoesGetAdded() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + component.renderMode = RenderMode.NORMAL + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + assertThat(mapboxMap.getSource(LOCATION_SOURCE), notNullValue()) + } + } + executeComponentTest(componentAction) + } + + // + // Location Layers + // + + @Test + fun renderModeNormal_trackingNormalLayersDoGetAdded() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + component.renderMode = RenderMode.NORMAL + component.forceLocationUpdate(location) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(SHADOW_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(BEARING_LAYER), `is`(false)) + } + } + executeComponentTest(componentAction) + } + + @Test + fun renderModeCompass_bearingLayersDoGetAdded() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + component.renderMode = RenderMode.COMPASS + component.forceLocationUpdate(location) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(SHADOW_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(BEARING_LAYER), `is`(true)) + } + } + executeComponentTest(componentAction) + } + + @Test + fun renderModeGps_navigationLayersDoGetAdded() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + component.renderMode = RenderMode.GPS + component.forceLocationUpdate(location) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(SHADOW_LAYER), `is`(false)) + assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(false)) + assertThat(mapboxMap.isLayerVisible(BEARING_LAYER), `is`(false)) + } + } + executeComponentTest(componentAction) + } + + @Test + fun dontShowPuckWhenRenderModeSetAndComponentDisabled() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + component.forceLocationUpdate(location) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + component.deactivateLocationComponent() + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER, shouldDisappear = true) + component.renderMode = RenderMode.GPS + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(false)) + assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(false)) + assertThat(mapboxMap.isLayerVisible(SHADOW_LAYER), `is`(false)) + assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(false)) + assertThat(mapboxMap.isLayerVisible(BEARING_LAYER), `is`(false)) + } + } + executeComponentTest(componentAction) + } + + @Test + fun whenLocationComponentDisabled_doesSetAllLayersToVisibilityNone() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + component.renderMode = RenderMode.NORMAL + component.forceLocationUpdate(location) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + component.deactivateLocationComponent() + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER, shouldDisappear = true) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + + // Check that all layers visibilities are set to none + assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(false)) + assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(false)) + assertThat(mapboxMap.isLayerVisible(SHADOW_LAYER), `is`(false)) + assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(false)) + assertThat(mapboxMap.isLayerVisible(BEARING_LAYER), `is`(false)) + } + } + executeComponentTest(componentAction) + } + + @Test + fun onMapChange_locationComponentLayersDoGetRedrawn() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + component.renderMode = RenderMode.NORMAL + component.forceLocationUpdate(location) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + mapboxMap.setStyleUrl(Style.LIGHT) + uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) + component.forceLocationUpdate(location) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + + assertThat(component.renderMode, `is`(equalTo(RenderMode.NORMAL))) + + // Check that the Source has been re-added to the new map style + val source: GeoJsonSource? = mapboxMap.getSourceAs(LOCATION_SOURCE) + assertThat(source, notNullValue()) + + // Check that all layers visibilities are set to visible + assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(SHADOW_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(true)) + assertThat(mapboxMap.isLayerVisible(BEARING_LAYER), `is`(false)) + } + } + executeComponentTest(componentAction) + } + + @Test + fun whenStyleChanged_continuesUsingStaleIcons() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + component.applyStyle(LocationComponentOptions.builder(context).staleStateTimeout(100).build()) + component.forceLocationUpdate(location) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + uiController.loopMainThreadForAtLeast(150) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + + assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(true)) + + mapboxMap.setStyleUrl(Style.LIGHT) + uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + + assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(true)) + } + } + executeComponentTest(componentAction) + } + + @Test + fun whenStyleChanged_staleStateChanges() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + component.applyStyle(LocationComponentOptions.builder(context).staleStateTimeout(1).build()) + styleChangeIdlingResource.waitForStyle((rule.activity as SingleActivity).mapView, mapboxMap, MAPBOX_HEAVY_STYLE) + pushSourceUpdates(styleChangeIdlingResource) { + component.forceLocationUpdate(location) + } + } + } + executeComponentTest(componentAction) + + // Waiting for style to finish loading while pushing updates + onView(withId(R.id.content)).check(matches(isDisplayed())) + } + + @Test + fun whenStyleChanged_layerVisibilityUpdates() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + styleChangeIdlingResource.waitForStyle((rule.activity as SingleActivity).mapView, mapboxMap, MAPBOX_HEAVY_STYLE) + var show = true + pushSourceUpdates(styleChangeIdlingResource) { + if (show) { + component.activateLocationComponent(context, false) + } else { + component.deactivateLocationComponent() + } + show = !show + } + + uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) + } + } + executeComponentTest(componentAction) + + // Waiting for style to finish loading while pushing updates + onView(withId(R.id.content)).check(matches(isDisplayed())) + } + + @Test + fun accuracy_visibleWithNewLocation() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(location), 16.0)) + component.forceLocationUpdate(location) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + uiController.loopMainThreadForAtLeast(ACCURACY_RADIUS_ANIMATION_DURATION) + + assertEquals(Utils.calculateZoomLevelRadius(mapboxMap, location) /*meters projected to radius on zoom 16*/, + mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0] + .getNumberProperty(PROPERTY_ACCURACY_RADIUS).toFloat(), 0.1f) + } + } + executeComponentTest(componentAction) + } + + @Test + fun accuracy_visibleWhenCameraEased() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + component.forceLocationUpdate(location) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + mapboxMap.easeCamera(CameraUpdateFactory.newLatLngZoom(LatLng(location), 16.0), 300) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY + 300) + + assertEquals(Utils.calculateZoomLevelRadius(mapboxMap, location) /*meters projected to radius on zoom 16*/, + mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0] + .getNumberProperty(PROPERTY_ACCURACY_RADIUS).toFloat(), 0.1f) + } + } + executeComponentTest(componentAction) + } + + @Test + fun accuracy_visibleWhenCameraMoved() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + component.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(location), 16.0)) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY + 300) + + assertEquals(Utils.calculateZoomLevelRadius(mapboxMap, location) /*meters projected to radius on zoom 16*/, + mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0] + .getNumberProperty(PROPERTY_ACCURACY_RADIUS).toFloat(), 0.1f) + } + } + executeComponentTest(componentAction) + } + + @After + override fun afterTest() { + super.afterTest() + IdlingRegistry.getInstance().unregister(styleChangeIdlingResource) + } + + private fun executeComponentTest(listener: LocationComponentAction.OnPerformLocationComponentAction) { + onView(withId(R.id.content)).perform(LocationComponentAction(mapboxMap, listener)) + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/utils/LocationComponentAction.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/utils/LocationComponentAction.kt new file mode 100644 index 0000000000..ad80a3333e --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/utils/LocationComponentAction.kt @@ -0,0 +1,40 @@ +package com.mapbox.mapboxsdk.location.utils + +import android.content.Context +import android.support.test.espresso.UiController +import android.support.test.espresso.ViewAction +import android.support.test.espresso.matcher.ViewMatchers.isDisplayed +import android.view.View +import com.mapbox.mapboxsdk.maps.MapboxMap +import com.mapbox.mapboxsdk.location.LocationComponent +import org.hamcrest.Matcher + +class LocationComponentAction(private val mapboxMap: MapboxMap, + private val onPerformLocationComponentAction: OnPerformLocationComponentAction) : ViewAction { + + override fun getConstraints(): Matcher { + return isDisplayed() + } + + override fun getDescription(): String { + return javaClass.simpleName + } + + override fun perform(uiController: UiController, view: View) { + val component = mapboxMap.locationComponent + + while (mapboxMap.getSource("mapbox-location-source") == null) { + uiController.loopMainThreadForAtLeast(MapboxTestingUtils.MAP_RENDER_DELAY) + } + + onPerformLocationComponentAction.onLocationComponentAction( + component, + mapboxMap, + uiController, + view.context) + } + + interface OnPerformLocationComponentAction { + fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, uiController: UiController, context: Context) + } +} \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/utils/MapboxTestingUtils.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/utils/MapboxTestingUtils.kt new file mode 100644 index 0000000000..591901385f --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/utils/MapboxTestingUtils.kt @@ -0,0 +1,105 @@ +package com.mapbox.mapboxsdk.location.utils + +import android.graphics.Bitmap +import android.graphics.Canvas +import android.graphics.drawable.BitmapDrawable +import android.graphics.drawable.Drawable +import android.location.Location +import android.os.Handler +import android.os.Looper +import android.support.test.espresso.UiController +import com.mapbox.geojson.Feature +import com.mapbox.mapboxsdk.geometry.LatLng +import com.mapbox.mapboxsdk.maps.MapboxMap +import com.mapbox.mapboxsdk.style.layers.Property +import com.mapbox.mapboxsdk.style.sources.GeoJsonSource + +fun MapboxMap.querySourceFeatures(sourceId: String): List { + return this.getSourceAs(sourceId)?.querySourceFeatures(null) ?: emptyList() +} + +fun MapboxMap.queryRenderedFeatures(location: Location, layerId: String): List { + val latLng = LatLng(location.latitude, location.longitude) + val point = this.projection.toScreenLocation(latLng) + return this.queryRenderedFeatures(point, layerId) +} + +fun MapboxMap.isLayerVisible(layerId: String): Boolean { + return this.getLayer(layerId)?.visibility?.value?.equals(Property.VISIBLE)!! +} + +fun MapboxMap.waitForSource(uiController: UiController, sourceId: String) { + var counter = 0 + val delay = MapboxTestingUtils.MAP_RENDER_DELAY + while (this.querySourceFeatures(sourceId).isEmpty() && delay * counter < MapboxTestingUtils.RENDER_TIMEOUT) { + uiController.loopMainThreadForAtLeast(delay) + counter++ + } +} + +fun MapboxMap.waitForLayer(uiController: UiController, location: Location, layerId: String, shouldDisappear: Boolean = false) { + var counter = 0 + val delay = MapboxTestingUtils.MAP_RENDER_DELAY + while ( + if (shouldDisappear) this.queryRenderedFeatures(location, layerId).isNotEmpty() else this.queryRenderedFeatures(location, layerId).isEmpty() + && delay * counter < MapboxTestingUtils.RENDER_TIMEOUT) { + uiController.loopMainThreadForAtLeast(delay) + counter++ + } +} + + +class MapboxTestingUtils { + companion object { + + const val MAP_RENDER_DELAY = 250L + const val MAP_CONNECTION_DELAY = 1000L + const val RENDER_TIMEOUT = 3_000L + + /** + * Used to increase style load time for stress testing. + */ + const val MAPBOX_HEAVY_STYLE = "asset://heavy_style.json" + + private const val DATA_PUSH_INTERVAL = 1L + + /** + * Pushes data updates every [DATA_PUSH_INTERVAL] milliseconds until the style has been loaded, + * checked with [StyleChangeIdlingResource]. + */ + fun pushSourceUpdates(styleChangeIdlingResource: StyleChangeIdlingResource, update: () -> Unit) { + val mainHandler = Handler(Looper.getMainLooper()) + val runnable = object : Runnable { + override fun run() { + update.invoke() + if (!styleChangeIdlingResource.isIdleNow) { + mainHandler.postDelayed(this, DATA_PUSH_INTERVAL) + } + } + } + + if (!styleChangeIdlingResource.isIdleNow) { + if (Looper.myLooper() == Looper.getMainLooper()) { + runnable.run() + } else { + mainHandler.post(runnable) + } + } + } + } +} + +fun MapboxMap.addImageFromDrawable(string: String, drawable: Drawable) { + val bitmapFromDrawable = getBitmapFromDrawable(drawable) + this.addImage(string, bitmapFromDrawable) +} + +private fun getBitmapFromDrawable(drawable: Drawable): Bitmap { + if (drawable is BitmapDrawable) return drawable.bitmap + val bitmap = Bitmap.createBitmap(drawable.intrinsicWidth, + drawable.intrinsicHeight, Bitmap.Config.ARGB_8888) + val canvas = Canvas(bitmap) + drawable.setBounds(0, 0, canvas.width, canvas.height) + drawable.draw(canvas) + return bitmap +} \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/utils/OnMapFragmentReadyIdlingResource.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/utils/OnMapFragmentReadyIdlingResource.kt new file mode 100644 index 0000000000..4d02a4d2bf --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/utils/OnMapFragmentReadyIdlingResource.kt @@ -0,0 +1,39 @@ +package com.mapbox.mapboxsdk.location.utils + +import android.os.Handler +import android.os.Looper +import android.support.test.espresso.IdlingResource + +import com.mapbox.mapboxsdk.maps.MapboxMap +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback +import com.mapbox.mapboxsdk.maps.SupportMapFragment + +class OnMapFragmentReadyIdlingResource(fragment: SupportMapFragment?) : IdlingResource, OnMapReadyCallback { + + lateinit var mapboxMap: MapboxMap + + private var resourceCallback: IdlingResource.ResourceCallback? = null + + init { + Handler(Looper.getMainLooper()).post { + fragment?.getMapAsync(this) + } + } + + override fun getName(): String { + return javaClass.simpleName + } + + override fun isIdleNow(): Boolean { + return this::mapboxMap.isInitialized + } + + override fun registerIdleTransitionCallback(resourceCallback: IdlingResource.ResourceCallback) { + this.resourceCallback = resourceCallback + } + + override fun onMapReady(mapboxMap: MapboxMap) { + this.mapboxMap = mapboxMap + resourceCallback?.onTransitionToIdle() + } +} \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/utils/OnMapReadyIdlingResource.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/utils/OnMapReadyIdlingResource.java new file mode 100644 index 0000000000..9adb30ee32 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/utils/OnMapReadyIdlingResource.java @@ -0,0 +1,63 @@ +package com.mapbox.mapboxsdk.location.utils; + +import android.app.Activity; +import android.os.Handler; +import android.os.Looper; +import android.support.test.espresso.IdlingResource; + +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; + +import java.lang.reflect.Field; + +public class OnMapReadyIdlingResource implements IdlingResource, OnMapReadyCallback { + + private MapboxMap mapboxMap; + private MapView mapView; + private IdlingResource.ResourceCallback resourceCallback; + + public OnMapReadyIdlingResource(Activity activity) { + new Handler(Looper.getMainLooper()).post(() -> { + try { + Field field = activity.getClass().getDeclaredField("mapView"); + field.setAccessible(true); + mapView = ((MapView) field.get(activity)); + mapView.getMapAsync(this); + } catch (Exception err) { + throw new RuntimeException(err); + } + }); + } + + @Override + public String getName() { + return getClass().getSimpleName(); + } + + @Override + public boolean isIdleNow() { + return mapboxMap != null; + } + + @Override + public void registerIdleTransitionCallback(ResourceCallback resourceCallback) { + this.resourceCallback = resourceCallback; + } + + public MapView getMapView() { + return mapView; + } + + public MapboxMap getMapboxMap() { + return mapboxMap; + } + + @Override + public void onMapReady(MapboxMap mapboxMap) { + this.mapboxMap = mapboxMap; + if (resourceCallback != null) { + resourceCallback.onTransitionToIdle(); + } + } +} \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/utils/StyleChangeIdlingResource.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/utils/StyleChangeIdlingResource.kt new file mode 100644 index 0000000000..0f37498a29 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/utils/StyleChangeIdlingResource.kt @@ -0,0 +1,46 @@ +package com.mapbox.mapboxsdk.location.utils + +import android.support.test.espresso.IdlingResource +import com.mapbox.mapboxsdk.maps.MapView +import com.mapbox.mapboxsdk.maps.MapboxMap + +/** + * Resource, that's idling until the provided style is loaded. + * Remember to add any espresso action (like view assertion) after the [waitForStyle] call + * for the test to keep running. + */ +class StyleChangeIdlingResource : IdlingResource { + + private var callback: IdlingResource.ResourceCallback? = null + private var isIdle = true + + override fun getName(): String { + return javaClass.simpleName + } + + override fun isIdleNow(): Boolean { + return isIdle + } + + override fun registerIdleTransitionCallback(callback: IdlingResource.ResourceCallback?) { + this.callback = callback + } + + private fun setIdle() { + isIdle = true + callback?.onTransitionToIdle() + } + + fun waitForStyle(mapView: MapView, mapboxMap: MapboxMap, styleUrl: String) { + isIdle = false + mapView.addOnMapChangedListener(object : MapView.OnMapChangedListener { + override fun onMapChanged(change: Int) { + if (change == MapView.DID_FINISH_LOADING_STYLE) { + mapView.removeOnMapChangedListener(this) + setIdle() + } + } + }) + mapboxMap.setStyleUrl(styleUrl) + } +} \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt deleted file mode 100644 index e9552f974b..0000000000 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt +++ /dev/null @@ -1,1104 +0,0 @@ -package com.mapbox.mapboxsdk.plugins.locationlayer - -import android.Manifest -import android.R -import android.content.Context -import android.graphics.Color -import android.graphics.RectF -import android.location.Location -import android.support.test.espresso.Espresso.onView -import android.support.test.espresso.IdlingRegistry -import android.support.test.espresso.UiController -import android.support.test.espresso.assertion.ViewAssertions.matches -import android.support.test.espresso.matcher.ViewMatchers.* -import android.support.test.rule.GrantPermissionRule -import android.support.test.runner.AndroidJUnit4 -import android.support.v4.content.ContextCompat -import com.mapbox.geojson.Point -import com.mapbox.mapboxsdk.camera.CameraUpdateFactory -import com.mapbox.mapboxsdk.constants.Style -import com.mapbox.mapboxsdk.geometry.LatLng -import com.mapbox.mapboxsdk.maps.MapboxMap -import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.* -import com.mapbox.mapboxsdk.plugins.locationlayer.modes.CameraMode -import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode -import com.mapbox.mapboxsdk.plugins.utils.* -import com.mapbox.mapboxsdk.plugins.utils.MapboxTestingUtils.Companion.MAPBOX_HEAVY_STYLE -import com.mapbox.mapboxsdk.plugins.utils.MapboxTestingUtils.Companion.MAP_CONNECTION_DELAY -import com.mapbox.mapboxsdk.plugins.utils.MapboxTestingUtils.Companion.MAP_RENDER_DELAY -import com.mapbox.mapboxsdk.plugins.utils.MapboxTestingUtils.Companion.pushSourceUpdates -import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest -import com.mapbox.mapboxsdk.testapp.activity.SingleActivity -import com.mapbox.mapboxsdk.utils.ColorUtils -import org.hamcrest.CoreMatchers.* -import org.junit.* -import org.junit.Assert.assertEquals -import org.junit.Assert.assertTrue -import org.junit.runner.RunWith - -@RunWith(AndroidJUnit4::class) -class LocationLayerPluginTest : BaseActivityTest() { - - @Rule - @JvmField - val permissionRule: GrantPermissionRule = GrantPermissionRule.grant(Manifest.permission.ACCESS_FINE_LOCATION) - - override fun getActivityClass(): Class<*> { - return SingleActivity::class.java - } - - private lateinit var styleChangeIdlingResource: StyleChangeIdlingResource - private val location: Location by lazy { - val initLocation = Location("test") - initLocation.latitude = 15.0 - initLocation.longitude = 17.0 - initLocation.bearing = 10f - initLocation.accuracy = 150f - initLocation - } - - @Before - override fun beforeTest() { - super.beforeTest() - styleChangeIdlingResource = StyleChangeIdlingResource() - IdlingRegistry.getInstance().register(styleChangeIdlingResource) - } - - @Test - fun locationLayerPlugin_initializesLocationEngineCorrectlyWhenOnesNotProvided() { - validateTestSetup() - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context) - - val locationEngine = plugin.locationEngine - assertThat(locationEngine, notNullValue()) - - uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) - assertThat(locationEngine?.isConnected, `is`(true)) - } - } - - executePluginTest(pluginAction) - } - - @Test - fun locationLayerPlugin_initializesLocationEngineCorrectlyWhenOnesNotProvidedButHasOptions() { - validateTestSetup() - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin( - context, - LocationLayerOptions.builder(context) - .staleStateTimeout(200) - .enableStaleState(false) - .accuracyAlpha(.5f) - .accuracyColor(Color.BLUE) - .build()) - - val locationEngine = plugin.locationEngine - val pluginOptions = plugin.locationLayerOptions - - assertThat(locationEngine, notNullValue()) - assertThat(pluginOptions, notNullValue()) - - uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) - assertThat(locationEngine?.isConnected, `is`(true)) - assertThat(pluginOptions?.accuracyAlpha(), `is`(.5f)) - assertThat(pluginOptions?.accuracyColor(), `is`(Color.BLUE)) - } - } - - executePluginTest(pluginAction) - } - - @Test - fun locationLayerPlugin_doesntInitializeEngineWhenNullProvided() { - validateTestSetup() - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin( - null, - LocationLayerOptions.builder(context) - .staleStateTimeout(200) - .enableStaleState(false) - .accuracyAlpha(.5f) - .accuracyColor(Color.BLUE) - .build()) - - val locationEngine = plugin.locationEngine - val pluginOptions = plugin.locationLayerOptions - - assertThat(locationEngine, nullValue()) - assertThat(pluginOptions, notNullValue()) - - uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) - assertThat(pluginOptions?.accuracyAlpha(), `is`(.5f)) - assertThat(pluginOptions?.accuracyColor(), `is`(Color.BLUE)) - } - } - - executePluginTest(pluginAction) - } - - @Test - fun settingMapStyleImmediatelyBeforeLoadingPlugin_doesStillLoadLayersProperly() { - validateTestSetup() - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - mapboxMap.setStyle(Style.LIGHT) - plugin.activateLocationLayerPlugin(context, false) - plugin.forceLocationUpdate(location) - mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - - assertThat(plugin.renderMode, `is`(equalTo(RenderMode.NORMAL))) - assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true)) - assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(true)) - assertThat(mapboxMap.isLayerVisible(SHADOW_LAYER), `is`(true)) - assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(true)) - assertThat(mapboxMap.isLayerVisible(BEARING_LAYER), `is`(false)) - } - } - - executePluginTest(pluginAction) - } - - @Test - fun locationLayer_doesntShowUntilFirstLocationFix() { - validateTestSetup() - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - - // Source should be present but empty - val mapView = (rule.activity as SingleActivity).mapView - assertThat(mapboxMap.queryRenderedFeatures( - RectF(0f, 0f, mapView.width.toFloat(), mapView.height.toFloat()), FOREGROUND_LAYER) - .isEmpty(), `is`(true)) - - // Force the first location update - plugin.forceLocationUpdate(location) - mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - - // Check if the puck is visible - assertThat(mapboxMap.queryRenderedFeatures(location, FOREGROUND_LAYER).isEmpty(), `is`(false)) - } - } - executePluginTest(pluginAction) - } - - // - // Location Layer Options - // - - @Test - fun locationLayerOptions_disablingStaleStateDoesWorkCorrectly() { - validateTestSetup() - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, - LocationLayerOptions.builder(context) - .staleStateTimeout(200) - .enableStaleState(false) - .build()) - - plugin.forceLocationUpdate(location) - mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - uiController.loopMainThreadForAtLeast(200) - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) - - mapboxMap.querySourceFeatures(LOCATION_SOURCE).also { - it.forEach { - assertThat(it.getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(false)) - } - } - } - } - - executePluginTest(pluginAction) - } - - @Test - fun locationLayerOptions_loadsForegroundBitmapFromNameOption() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, - LocationLayerOptions.builder(context) - .foregroundName("custom-foreground-bitmap") - .backgroundName("custom-background-bitmap") - .foregroundStaleName("custom-foreground-stale-bitmap") - .backgroundStaleName("custom-background-stale-bitmap") - .bearingName("custom-bearing-bitmap") - .build()) - - val foregroundDrawable = ContextCompat.getDrawable(context, R.drawable.ic_media_play) - foregroundDrawable?.let { - mapboxMap.addImageFromDrawable("custom-foreground-bitmap", it) - mapboxMap.addImageFromDrawable("custom-background-bitmap", it) - mapboxMap.addImageFromDrawable("custom-foreground-stale-bitmap", it) - mapboxMap.addImageFromDrawable("custom-background-stale-bitmap", it) - mapboxMap.addImageFromDrawable("custom-bearing-bitmap", it) - } - - plugin.forceLocationUpdate(location) - mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - assertThat(mapboxMap.queryRenderedFeatures(location, FOREGROUND_LAYER).isEmpty(), `is`(false)) - - val feature = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0] - assertThat(feature.getStringProperty(PROPERTY_FOREGROUND_ICON), `is`(equalTo("custom-foreground-bitmap"))) - assertThat(feature.getStringProperty(PROPERTY_BACKGROUND_ICON), `is`(equalTo("custom-background-bitmap"))) - assertThat(feature.getStringProperty(PROPERTY_FOREGROUND_STALE_ICON), `is`(equalTo("custom-foreground-stale-bitmap"))) - assertThat(feature.getStringProperty(PROPERTY_BACKGROUND_STALE_ICON), `is`(equalTo("custom-background-stale-bitmap"))) - assertThat(feature.getStringProperty(PROPERTY_BEARING_ICON), `is`(equalTo("custom-bearing-bitmap"))) - } - } - - executePluginTest(pluginAction) - } - - @Test - fun locationLayerOptions_loadsGpsNameWithGpsRenderMode() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, - LocationLayerOptions.builder(context) - .foregroundName("custom-foreground-bitmap") - .gpsName("custom-gps-bitmap") - .build()) - - plugin.renderMode = RenderMode.GPS - plugin.forceLocationUpdate(location) - mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - val foregroundDrawable = ContextCompat.getDrawable(context, R.drawable.ic_media_play) - foregroundDrawable?.let { - mapboxMap.addImageFromDrawable("custom-foreground-bitmap", it) - mapboxMap.addImageFromDrawable("custom-gps-bitmap", it) - } - - val foregroundId = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getStringProperty(PROPERTY_FOREGROUND_ICON) - assertThat(foregroundId, `is`(equalTo("custom-gps-bitmap"))) - } - } - - executePluginTest(pluginAction) - } - - @Test - fun locationLayerOptions_customIconNameRevertsToDefault() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, - LocationLayerOptions.builder(context) - .foregroundName("custom-foreground-bitmap") - .gpsName("custom-gps-bitmap") - .build()) - - plugin.renderMode = RenderMode.GPS - plugin.forceLocationUpdate(location) - mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - - val foregroundId = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getStringProperty(PROPERTY_FOREGROUND_ICON) - assertThat(foregroundId, `is`(equalTo("custom-gps-bitmap"))) - - plugin.applyStyle(LocationLayerOptions.builder(context).build()) - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) - - val revertedForegroundId = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getStringProperty(PROPERTY_FOREGROUND_ICON) - assertThat(revertedForegroundId, `is`(equalTo(FOREGROUND_ICON))) - } - } - - executePluginTest(pluginAction) - } - - @Test - fun locationLayerOptions_customGpsIconNameChangeBackWithMode() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - - plugin.activateLocationLayerPlugin(context, - LocationLayerOptions.builder(context) - .gpsName("custom-gps-bitmap") - .build()) - - plugin.renderMode = RenderMode.GPS - plugin.forceLocationUpdate(location) - mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - - val foregroundId = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getStringProperty(PROPERTY_FOREGROUND_ICON) - assertThat(foregroundId, `is`(equalTo("custom-gps-bitmap"))) - - plugin.renderMode = RenderMode.NORMAL - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) - - val revertedForegroundId = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getStringProperty(PROPERTY_FOREGROUND_ICON) - assertThat(revertedForegroundId, `is`(equalTo(FOREGROUND_ICON))) - } - } - - executePluginTest(pluginAction) - } - - @Test - fun stillStaleAfterResuming() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, - LocationLayerOptions.builder(context) - .staleStateTimeout(200) - .build()) - - plugin.forceLocationUpdate(location) - mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - uiController.loopMainThreadForAtLeast(250) // engaging stale state - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) - assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(true)) - - plugin.onStop() - plugin.onStart() - mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - - assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(true)) - assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(false)) - } - } - - executePluginTest(pluginAction) - } - - @Test - fun stillNotStaleAfterResuming() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - plugin.forceLocationUpdate(location) - mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(false)) - - plugin.onStop() - plugin.onStart() - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) - - assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(false)) - assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(true)) - } - } - executePluginTest(pluginAction) - } - - @Test - fun locationLayerOptions_accuracyRingWithColor() { - val color = Color.parseColor("#4A90E2") - val rgbaColor = ColorUtils.colorToRgbaString(color) - - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, - LocationLayerOptions.builder(context) - .accuracyColor(color) - .build()) - - plugin.forceLocationUpdate(location) - mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - - // Check that the source property changes correctly - mapboxMap.querySourceFeatures(LOCATION_SOURCE).also { - it.forEach { - assertThat(it.getStringProperty(PROPERTY_ACCURACY_COLOR), `is`(equalTo(rgbaColor))) - } - } - } - } - - executePluginTest(pluginAction) - } - - @Test - fun forceLocationUpdate_doesMoveLocationLayerIconToCorrectPosition() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - plugin.forceLocationUpdate(location) - mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - - val point: Point = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].geometry() as Point - - assertThat(plugin.locationEngine, nullValue()) - assertEquals(point.latitude(), location.latitude, 0.1) - assertEquals(point.longitude(), location.longitude, 0.1) - } - } - executePluginTest(pluginAction) - } - - @Test - fun disablingPluginHidesPuck() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - plugin.forceLocationUpdate(location) - mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - - val point: Point = mapboxMap.queryRenderedFeatures(location, FOREGROUND_LAYER)[0].geometry() as Point - assertEquals(point.latitude(), location.latitude, 0.1) - assertEquals(point.longitude(), location.longitude, 0.1) - - plugin.deactivateLocationLayerPlugin() - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) - assertThat(mapboxMap.queryRenderedFeatures(location, FOREGROUND_LAYER).isEmpty(), `is`(true)) - } - } - executePluginTest(pluginAction) - } - - @Test - fun disablingPluginAndChangingStyleAllowsToEnableAgain() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - plugin.forceLocationUpdate(location) - mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - - plugin.deactivateLocationLayerPlugin() - mapboxMap.setStyle(Style.LIGHT) - - plugin.activateLocationLayerPlugin(context, false) - mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true)) - } - } - executePluginTest(pluginAction) - } - - @Test - fun lifecycle_isDisabledOnStart() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - assertThat(plugin.isLocationLayerEnabled, `is`(false)) - plugin.onStop() - plugin.onStart() - assertThat(plugin.isLocationLayerEnabled, `is`(false)) - plugin.activateLocationLayerPlugin(context, false) - assertThat(plugin.isLocationLayerEnabled, `is`(true)) - } - } - executePluginTest(pluginAction) - } - - @Test - fun lifecycle_keepsEnabledWhenStoppedAndStarted() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - assertThat(plugin.isLocationLayerEnabled, `is`(true)) - plugin.onStop() - plugin.onStart() - assertThat(plugin.isLocationLayerEnabled, `is`(true)) - } - } - executePluginTest(pluginAction) - } - - @Test - fun lifecycle_keepsDisabledWhenStoppedAndStarted() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - plugin.deactivateLocationLayerPlugin() - assertThat(plugin.isLocationLayerEnabled, `is`(false)) - plugin.onStop() - plugin.onStart() - assertThat(plugin.isLocationLayerEnabled, `is`(false)) - } - } - executePluginTest(pluginAction) - } - - @Test - fun lifecycle_ableToChangeStyleAfterResuming() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - - plugin.onStop() - plugin.onStart() - - mapboxMap.setStyle(Style.DARK) - uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) - } - } - executePluginTest(pluginAction) - } - - @Test - fun lifecycle_interruptedDuringStyleChange() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - mapboxMap.setStyle(Style.DARK) - plugin.onStop() - plugin.onStart() - uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) - } - } - executePluginTest(pluginAction) - } - - @Test - fun lifecycle_forceLocationUpdateAfterStopped() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - plugin.onStop() - plugin.forceLocationUpdate(location) - mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - - assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE).isEmpty(), `is`(true)) - } - } - executePluginTest(pluginAction) - } - - @Test - fun lifecycle_acceptAndReuseLocationUpdatesBeforeLayerStarted() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - plugin.onStop() - plugin.forceLocationUpdate(location) - plugin.onStart() - mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - - val point: Point = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].geometry() as Point - assertEquals(point.latitude(), location.latitude, 0.1) - assertEquals(point.longitude(), location.longitude, 0.1) - } - } - executePluginTest(pluginAction) - } - - @Test - fun lifecycle_lifecycleChangeRightAfterStyleReload() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - plugin.forceLocationUpdate(location) - mapboxMap.setStyle(Style.LIGHT) - plugin.onStop() - uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) - plugin.onStart() - mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - - val point: Point = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].geometry() as Point - assertEquals(point.latitude(), location.latitude, 0.1) - assertEquals(point.longitude(), location.longitude, 0.1) - - assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true)) - assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(true)) - assertThat(mapboxMap.isLayerVisible(SHADOW_LAYER), `is`(true)) - assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(true)) - assertThat(mapboxMap.isLayerVisible(BEARING_LAYER), `is`(false)) - } - } - executePluginTest(pluginAction) - } - - @Test - fun mapChange_settingPluginStyle() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - styleChangeIdlingResource.waitForStyle((rule.activity as SingleActivity).mapView, mapboxMap, MAPBOX_HEAVY_STYLE) - val options = LocationLayerOptions.builder(context) - .accuracyColor(Color.RED) - .build() - - pushSourceUpdates(styleChangeIdlingResource) { - plugin.applyStyle(options) - } - - uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) - } - } - executePluginTest(pluginAction) - - // Waiting for style to finish loading while pushing updates - onView(withId(R.id.content)).check(matches(isDisplayed())) - } - - @Test - fun mapChange_forcingLocation() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - styleChangeIdlingResource.waitForStyle((rule.activity as SingleActivity).mapView, mapboxMap, MAPBOX_HEAVY_STYLE) - - pushSourceUpdates(styleChangeIdlingResource) { - plugin.forceLocationUpdate(location) - } - - uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) - } - } - executePluginTest(pluginAction) - - // Waiting for style to finish loading while pushing updates - onView(withId(R.id.content)).check(matches(isDisplayed())) - } - - @Test - fun mapChange_settingMapStyleBeforePluginCreation() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - styleChangeIdlingResource.waitForStyle((rule.activity as SingleActivity).mapView, mapboxMap, MAPBOX_HEAVY_STYLE) - plugin.activateLocationLayerPlugin(context, false) - - val options = LocationLayerOptions.builder(context) - .accuracyColor(Color.RED) - .build() - - pushSourceUpdates(styleChangeIdlingResource) { - plugin.forceLocationUpdate(location) - plugin.applyStyle(options) - } - } - } - executePluginTest(pluginAction) - - // Waiting for style to finish loading while pushing updates - onView(withId(R.id.content)).check(matches(isDisplayed())) - } - - @Test - fun animators_layerBearingCorrect() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - plugin.renderMode = RenderMode.GPS - location.bearing = 77f - plugin.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS + MAP_RENDER_DELAY) - assertEquals(77.0, mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getNumberProperty(PROPERTY_GPS_BEARING) as Double, 0.1) - - location.bearing = 92f - plugin.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS + MAP_RENDER_DELAY) // Waiting for the animation to finish - assertEquals(92.0, mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getNumberProperty(PROPERTY_GPS_BEARING) as Double, 0.1) - } - } - - executePluginTest(pluginAction) - } - - @Test - fun animators_cameraLatLngBearingCorrect() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - plugin.cameraMode = CameraMode.TRACKING_GPS - location.bearing = 77f - plugin.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS + MAP_RENDER_DELAY) - assertEquals(77.0, mapboxMap.cameraPosition.bearing, 0.1) - assertEquals(location.latitude, mapboxMap.cameraPosition.target.latitude, 0.1) - assertEquals(location.longitude, mapboxMap.cameraPosition.target.longitude, 0.1) - - location.bearing = 92f - location.latitude = 30.0 - location.longitude = 35.0 - plugin.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS + MAP_RENDER_DELAY) // Waiting for the animation to finish - assertEquals(92.0, mapboxMap.cameraPosition.bearing, 0.1) - assertEquals(location.latitude, mapboxMap.cameraPosition.target.latitude, 0.1) - assertEquals(location.longitude, mapboxMap.cameraPosition.target.longitude, 0.1) - } - } - - executePluginTest(pluginAction) - } - - @Test - fun animators_cameraBearingCorrect() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - plugin.cameraMode = CameraMode.NONE_GPS - val latitude = mapboxMap.cameraPosition.target.latitude - val longitude = mapboxMap.cameraPosition.target.longitude - - location.bearing = 77f - plugin.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS + MAP_RENDER_DELAY) - assertEquals(77.0, mapboxMap.cameraPosition.bearing, 0.1) - assertEquals(latitude, mapboxMap.cameraPosition.target.latitude, 0.1) - assertEquals(longitude, mapboxMap.cameraPosition.target.longitude, 0.1) - - location.bearing = 92f - location.latitude = 30.0 - location.longitude = 35.0 - plugin.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS + MAP_RENDER_DELAY) - assertEquals(92.0, mapboxMap.cameraPosition.bearing, 0.1) - assertEquals(latitude, mapboxMap.cameraPosition.target.latitude, 0.1) - assertEquals(longitude, mapboxMap.cameraPosition.target.longitude, 0.1) - } - } - - executePluginTest(pluginAction) - } - - @Test - fun animators_cameraNoneCorrect() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - plugin.cameraMode = CameraMode.NONE - val latitude = mapboxMap.cameraPosition.target.latitude - val longitude = mapboxMap.cameraPosition.target.longitude - val bearing = mapboxMap.cameraPosition.bearing - - location.bearing = 77f - plugin.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS + MAP_RENDER_DELAY) - assertEquals(bearing, mapboxMap.cameraPosition.bearing, 0.1) - assertEquals(latitude, mapboxMap.cameraPosition.target.latitude, 0.1) - assertEquals(longitude, mapboxMap.cameraPosition.target.longitude, 0.1) - - location.bearing = 92f - location.latitude = 30.0 - location.longitude = 35.0 - plugin.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS + MAP_RENDER_DELAY) // Waiting for the animation to finish - assertEquals(bearing, mapboxMap.cameraPosition.bearing, 0.1) - assertEquals(latitude, mapboxMap.cameraPosition.target.latitude, 0.1) - assertEquals(longitude, mapboxMap.cameraPosition.target.longitude, 0.1) - } - } - - executePluginTest(pluginAction) - } - - @Test - fun animators_focalPointAdjustment() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - plugin.cameraMode = CameraMode.TRACKING - plugin.cameraMode = CameraMode.NONE - plugin.forceLocationUpdate(location) - mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - - assertThat(mapboxMap.uiSettings.focalPoint, nullValue()) - } - } - - executePluginTest(pluginAction) - } - - @Test - fun animators_dontZoomWhileNotTracking() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - plugin.cameraMode = CameraMode.NONE - val zoom = mapboxMap.cameraPosition.zoom - plugin.zoomWhileTracking(10.0) - uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIM_DURATION) - - assertEquals(zoom, mapboxMap.cameraPosition.zoom, 0.1) - } - } - - executePluginTest(pluginAction) - } - - @Test - fun animators_zoomWhileTracking() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - plugin.cameraMode = CameraMode.TRACKING - plugin.zoomWhileTracking(10.0) - uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIM_DURATION) - - assertEquals(10.0, mapboxMap.cameraPosition.zoom, 0.1) - } - } - - executePluginTest(pluginAction) - } - - @Test - @Ignore - fun animators_zoomWhileTrackingCanceledOnModeChange() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - plugin.cameraMode = CameraMode.TRACKING - plugin.zoomWhileTracking(15.0) - uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIM_DURATION / 2) - plugin.cameraMode = CameraMode.NONE - uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIM_DURATION / 2) - - assertEquals(15.0 / 2.0, mapboxMap.cameraPosition.zoom, 3.0) - } - } - - executePluginTest(pluginAction) - } - - @Test - fun animators_dontZoomWhileStopped() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - - plugin.cameraMode = CameraMode.TRACKING - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) - val zoom = mapboxMap.cameraPosition.zoom - - plugin.onStop() - plugin.zoomWhileTracking(10.0) - uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIM_DURATION) - - assertEquals(zoom, mapboxMap.cameraPosition.zoom, 0.1) - } - } - - executePluginTest(pluginAction) - } - - @Test - @Ignore - fun animators_cancelZoomWhileTracking() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - plugin.cameraMode = CameraMode.TRACKING - plugin.zoomWhileTracking(15.0) - uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIM_DURATION / 2) - plugin.cancelZoomWhileTrackingAnimation() - uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIM_DURATION / 2) - - assertEquals(15.0 / 2.0, mapboxMap.cameraPosition.zoom, 3.0) - } - } - - executePluginTest(pluginAction) - } - - @Test - fun animators_dontTiltWhileNotTracking() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - plugin.cameraMode = CameraMode.NONE - val tilt = mapboxMap.cameraPosition.tilt - plugin.tiltWhileTracking(30.0) - uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIM_DURATION) - - assertEquals(tilt, mapboxMap.cameraPosition.tilt, 0.1) - } - } - - executePluginTest(pluginAction) - } - - @Test - fun animators_tiltWhileTracking() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - plugin.cameraMode = CameraMode.TRACKING - plugin.tiltWhileTracking(30.0) - uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIM_DURATION) - - assertEquals(30.0, mapboxMap.cameraPosition.tilt, 0.1) - } - } - - executePluginTest(pluginAction) - } - - @Test - @Ignore - fun animators_tiltWhileTrackingCanceledOnModeChange() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - plugin.cameraMode = CameraMode.TRACKING - plugin.tiltWhileTracking(30.0) - uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIM_DURATION / 2) - plugin.cameraMode = CameraMode.NONE - uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIM_DURATION / 2) - - assertEquals(30.0 / 2.0, mapboxMap.cameraPosition.tilt, 3.0) - } - } - - executePluginTest(pluginAction) - } - - @Test - fun animators_dontTiltWhileStopped() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - plugin.cameraMode = CameraMode.TRACKING - val tilt = mapboxMap.cameraPosition.tilt - - plugin.onStop() - plugin.tiltWhileTracking(30.0) - uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIM_DURATION) - - assertEquals(tilt, mapboxMap.cameraPosition.tilt, 0.1) - } - } - - executePluginTest(pluginAction) - } - - @Test - @Ignore - fun animators_cancelTiltWhileTracking() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - plugin.cameraMode = CameraMode.TRACKING - plugin.tiltWhileTracking(30.0) - uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIM_DURATION / 2) - plugin.cancelTiltWhileTrackingAnimation() - uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIM_DURATION / 2) - - assertEquals(30.0 / 2.0, mapboxMap.cameraPosition.tilt, 3.0) - } - } - - executePluginTest(pluginAction) - } - - @Test - fun cameraPositionAdjustedToTrackingModeWhenPluginEnabled() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - plugin.cameraMode = CameraMode.TRACKING_GPS - plugin.forceLocationUpdate(location) - plugin.deactivateLocationLayerPlugin() - mapboxMap.moveCamera(CameraUpdateFactory.newLatLng(LatLng(51.0, 17.0))) - mapboxMap.moveCamera(CameraUpdateFactory.bearingTo(90.0)) - plugin.activateLocationLayerPlugin(context, false) - uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS + MAP_RENDER_DELAY) - - assertEquals(location.bearing.toDouble(), mapboxMap.cameraPosition.bearing, 0.1) - assertEquals(location.latitude, mapboxMap.cameraPosition.target.latitude, 0.1) - assertEquals(location.longitude, mapboxMap.cameraPosition.target.longitude, 0.1) - } - } - - executePluginTest(pluginAction) - } - - @Test - fun compassEngine_onPluginInitializedDefaultIsProvided() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - assertTrue(plugin.compassEngine is LocationLayerCompassEngine) - } - } - - executePluginTest(pluginAction) - } - - @Test - fun compassEngine_changesWhenNewProvided() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - val engine: CompassEngine = object : CompassEngine { - override fun addCompassListener(compassListener: CompassListener) { - } - - override fun removeCompassListener(compassListener: CompassListener) { - } - - override fun getLastHeading(): Float { - return 0f - } - - override fun getLastAccuracySensorStatus(): Int { - return 0 - } - - override fun onStart() { - } - - override fun onStop() { - } - } - - plugin.compassEngine = engine - assertThat(plugin.compassEngine, notNullValue()) - assertThat(plugin.compassEngine, `is`(equalTo(engine))) - } - } - - executePluginTest(pluginAction) - } - - @After - override fun afterTest() { - super.afterTest() - IdlingRegistry.getInstance().unregister(styleChangeIdlingResource) - } - - private fun executePluginTest(listener: LocationLayerPluginAction.OnPerformLocationLayerPluginAction) { - onView(withId(R.id.content)).perform(LocationLayerPluginAction(mapboxMap, listener)) - } -} \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.kt deleted file mode 100644 index a0f23ce485..0000000000 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.kt +++ /dev/null @@ -1,360 +0,0 @@ -package com.mapbox.mapboxsdk.plugins.locationlayer - -import android.Manifest -import android.R -import android.content.Context -import android.location.Location -import android.support.test.espresso.Espresso.onView -import android.support.test.espresso.IdlingRegistry -import android.support.test.espresso.UiController -import android.support.test.espresso.assertion.ViewAssertions.matches -import android.support.test.espresso.matcher.ViewMatchers.isDisplayed -import android.support.test.espresso.matcher.ViewMatchers.withId -import android.support.test.rule.GrantPermissionRule -import android.support.test.rule.GrantPermissionRule.grant -import android.support.test.runner.AndroidJUnit4 -import com.mapbox.mapboxsdk.camera.CameraUpdateFactory -import com.mapbox.mapboxsdk.constants.Style -import com.mapbox.mapboxsdk.geometry.LatLng -import com.mapbox.mapboxsdk.maps.MapboxMap -import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.* -import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode -import com.mapbox.mapboxsdk.plugins.utils.* -import com.mapbox.mapboxsdk.plugins.utils.MapboxTestingUtils.Companion.MAPBOX_HEAVY_STYLE -import com.mapbox.mapboxsdk.plugins.utils.MapboxTestingUtils.Companion.MAP_CONNECTION_DELAY -import com.mapbox.mapboxsdk.plugins.utils.MapboxTestingUtils.Companion.MAP_RENDER_DELAY -import com.mapbox.mapboxsdk.plugins.utils.MapboxTestingUtils.Companion.pushSourceUpdates -import com.mapbox.mapboxsdk.style.sources.GeoJsonSource -import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest -import com.mapbox.mapboxsdk.testapp.activity.SingleActivity -import org.hamcrest.CoreMatchers.`is` -import org.hamcrest.CoreMatchers.notNullValue -import org.hamcrest.Matchers.equalTo -import org.junit.After -import org.junit.Assert.assertEquals -import org.junit.Assert.assertThat -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(AndroidJUnit4::class) -class LocationLayerTest : BaseActivityTest() { - - @Rule - @JvmField - val permissionRule: GrantPermissionRule = grant(Manifest.permission.ACCESS_FINE_LOCATION) - - override fun getActivityClass(): Class<*> { - return SingleActivity::class.java - } - - private lateinit var styleChangeIdlingResource: StyleChangeIdlingResource - private val location: Location by lazy { - val initLocation = Location("test") - initLocation.latitude = 15.0 - initLocation.longitude = 17.0 - initLocation.bearing = 10f - initLocation.accuracy = 150f - initLocation - } - - @Before - override fun beforeTest() { - super.beforeTest() - styleChangeIdlingResource = StyleChangeIdlingResource() - IdlingRegistry.getInstance().register(styleChangeIdlingResource) - } - - // - // Location Source - // - - @Test - fun renderModeNormal_sourceDoesGetAdded() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - plugin.renderMode = RenderMode.NORMAL - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) - assertThat(mapboxMap.getSource(LOCATION_SOURCE), notNullValue()) - } - } - executePluginTest(pluginAction) - } - - // - // Location Layers - // - - @Test - fun renderModeNormal_trackingNormalLayersDoGetAdded() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - plugin.renderMode = RenderMode.NORMAL - plugin.forceLocationUpdate(location) - mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true)) - assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(true)) - assertThat(mapboxMap.isLayerVisible(SHADOW_LAYER), `is`(true)) - assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(true)) - assertThat(mapboxMap.isLayerVisible(BEARING_LAYER), `is`(false)) - } - } - executePluginTest(pluginAction) - } - - @Test - fun renderModeCompass_bearingLayersDoGetAdded() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - plugin.renderMode = RenderMode.COMPASS - plugin.forceLocationUpdate(location) - mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true)) - assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(true)) - assertThat(mapboxMap.isLayerVisible(SHADOW_LAYER), `is`(true)) - assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(true)) - assertThat(mapboxMap.isLayerVisible(BEARING_LAYER), `is`(true)) - } - } - executePluginTest(pluginAction) - } - - @Test - fun renderModeGps_navigationLayersDoGetAdded() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - plugin.renderMode = RenderMode.GPS - plugin.forceLocationUpdate(location) - mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true)) - assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(true)) - assertThat(mapboxMap.isLayerVisible(SHADOW_LAYER), `is`(false)) - assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(false)) - assertThat(mapboxMap.isLayerVisible(BEARING_LAYER), `is`(false)) - } - } - executePluginTest(pluginAction) - } - - @Test - fun dontShowPuckWhenRenderModeSetAndPluginDisabled() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - plugin.forceLocationUpdate(location) - mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - plugin.deactivateLocationLayerPlugin() - mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER, shouldDisappear = true) - plugin.renderMode = RenderMode.GPS - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) - assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(false)) - assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(false)) - assertThat(mapboxMap.isLayerVisible(SHADOW_LAYER), `is`(false)) - assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(false)) - assertThat(mapboxMap.isLayerVisible(BEARING_LAYER), `is`(false)) - } - } - executePluginTest(pluginAction) - } - - @Test - fun whenLocationLayerPluginDisabled_doesSetAllLayersToVisibilityNone() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - plugin.renderMode = RenderMode.NORMAL - plugin.forceLocationUpdate(location) - mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - plugin.deactivateLocationLayerPlugin() - mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER, shouldDisappear = true) - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) - - // Check that all layers visibilities are set to none - assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(false)) - assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(false)) - assertThat(mapboxMap.isLayerVisible(SHADOW_LAYER), `is`(false)) - assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(false)) - assertThat(mapboxMap.isLayerVisible(BEARING_LAYER), `is`(false)) - } - } - executePluginTest(pluginAction) - } - - @Test - fun onMapChange_locationLayerLayersDoGetRedrawn() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - plugin.renderMode = RenderMode.NORMAL - plugin.forceLocationUpdate(location) - mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - mapboxMap.setStyleUrl(Style.LIGHT) - uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) - plugin.forceLocationUpdate(location) - mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - - assertThat(plugin.renderMode, `is`(equalTo(RenderMode.NORMAL))) - - // Check that the Source has been re-added to the new map style - val source: GeoJsonSource? = mapboxMap.getSourceAs(LOCATION_SOURCE) - assertThat(source, notNullValue()) - - // Check that all layers visibilities are set to visible - assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true)) - assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(true)) - assertThat(mapboxMap.isLayerVisible(SHADOW_LAYER), `is`(true)) - assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(true)) - assertThat(mapboxMap.isLayerVisible(BEARING_LAYER), `is`(false)) - } - } - executePluginTest(pluginAction) - } - - @Test - fun whenStyleChanged_continuesUsingStaleIcons() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - plugin.applyStyle(LocationLayerOptions.builder(context).staleStateTimeout(100).build()) - plugin.forceLocationUpdate(location) - mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - uiController.loopMainThreadForAtLeast(150) - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) - - assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(true)) - - mapboxMap.setStyleUrl(Style.LIGHT) - uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) - mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - - assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(true)) - } - } - executePluginTest(pluginAction) - } - - @Test - fun whenStyleChanged_staleStateChanges() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - plugin.applyStyle(LocationLayerOptions.builder(context).staleStateTimeout(1).build()) - styleChangeIdlingResource.waitForStyle((rule.activity as SingleActivity).mapView, mapboxMap, MAPBOX_HEAVY_STYLE) - pushSourceUpdates(styleChangeIdlingResource) { - plugin.forceLocationUpdate(location) - } - } - } - executePluginTest(pluginAction) - - // Waiting for style to finish loading while pushing updates - onView(withId(R.id.content)).check(matches(isDisplayed())) - } - - @Test - fun whenStyleChanged_layerVisibilityUpdates() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - styleChangeIdlingResource.waitForStyle((rule.activity as SingleActivity).mapView, mapboxMap, MAPBOX_HEAVY_STYLE) - var show = true - pushSourceUpdates(styleChangeIdlingResource) { - if (show) { - plugin.activateLocationLayerPlugin(context, false) - } else { - plugin.deactivateLocationLayerPlugin() - } - show = !show - } - - uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) - } - } - executePluginTest(pluginAction) - - // Waiting for style to finish loading while pushing updates - onView(withId(R.id.content)).check(matches(isDisplayed())) - } - - @Test - fun accuracy_visibleWithNewLocation() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(location), 16.0)) - plugin.forceLocationUpdate(location) - mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - uiController.loopMainThreadForAtLeast(ACCURACY_RADIUS_ANIMATION_DURATION) - - assertEquals(Utils.calculateZoomLevelRadius(mapboxMap, location) /*meters projected to radius on zoom 16*/, - mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0] - .getNumberProperty(PROPERTY_ACCURACY_RADIUS).toFloat(), 0.1f) - } - } - executePluginTest(pluginAction) - } - - @Test - fun accuracy_visibleWhenCameraEased() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - plugin.forceLocationUpdate(location) - mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - mapboxMap.easeCamera(CameraUpdateFactory.newLatLngZoom(LatLng(location), 16.0), 300) - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY + 300) - - assertEquals(Utils.calculateZoomLevelRadius(mapboxMap, location) /*meters projected to radius on zoom 16*/, - mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0] - .getNumberProperty(PROPERTY_ACCURACY_RADIUS).toFloat(), 0.1f) - } - } - executePluginTest(pluginAction) - } - - @Test - fun accuracy_visibleWhenCameraMoved() { - val pluginAction = object : LocationLayerPluginAction.OnPerformLocationLayerPluginAction { - override fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - plugin.activateLocationLayerPlugin(context, false) - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) - plugin.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) - mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(location), 16.0)) - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY + 300) - - assertEquals(Utils.calculateZoomLevelRadius(mapboxMap, location) /*meters projected to radius on zoom 16*/, - mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0] - .getNumberProperty(PROPERTY_ACCURACY_RADIUS).toFloat(), 0.1f) - } - } - executePluginTest(pluginAction) - } - - @After - override fun afterTest() { - super.afterTest() - IdlingRegistry.getInstance().unregister(styleChangeIdlingResource) - } - - private fun executePluginTest(listener: LocationLayerPluginAction.OnPerformLocationLayerPluginAction) { - onView(withId(R.id.content)).perform(LocationLayerPluginAction(mapboxMap, listener)) - } -} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/LocationLayerPluginAction.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/LocationLayerPluginAction.kt deleted file mode 100644 index af2c9adf35..0000000000 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/LocationLayerPluginAction.kt +++ /dev/null @@ -1,40 +0,0 @@ -package com.mapbox.mapboxsdk.plugins.utils - -import android.content.Context -import android.support.test.espresso.UiController -import android.support.test.espresso.ViewAction -import android.support.test.espresso.matcher.ViewMatchers.isDisplayed -import android.view.View -import com.mapbox.mapboxsdk.maps.MapboxMap -import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerPlugin -import org.hamcrest.Matcher - -class LocationLayerPluginAction(private val mapboxMap: MapboxMap, - private val onPerformLocationLayerPluginAction: OnPerformLocationLayerPluginAction) : ViewAction { - - override fun getConstraints(): Matcher { - return isDisplayed() - } - - override fun getDescription(): String { - return javaClass.simpleName - } - - override fun perform(uiController: UiController, view: View) { - val plugin = mapboxMap.locationLayerPlugin - - while (mapboxMap.getSource("mapbox-location-source") == null) { - uiController.loopMainThreadForAtLeast(MapboxTestingUtils.MAP_RENDER_DELAY) - } - - onPerformLocationLayerPluginAction.onLocationLayerPluginAction( - plugin, - mapboxMap, - uiController, - view.context) - } - - interface OnPerformLocationLayerPluginAction { - fun onLocationLayerPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, uiController: UiController, context: Context) - } -} \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/MapboxTestingUtils.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/MapboxTestingUtils.kt deleted file mode 100644 index b77ab127d9..0000000000 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/MapboxTestingUtils.kt +++ /dev/null @@ -1,105 +0,0 @@ -package com.mapbox.mapboxsdk.plugins.utils - -import android.graphics.Bitmap -import android.graphics.Canvas -import android.graphics.drawable.BitmapDrawable -import android.graphics.drawable.Drawable -import android.location.Location -import android.os.Handler -import android.os.Looper -import android.support.test.espresso.UiController -import com.mapbox.geojson.Feature -import com.mapbox.mapboxsdk.geometry.LatLng -import com.mapbox.mapboxsdk.maps.MapboxMap -import com.mapbox.mapboxsdk.style.layers.Property -import com.mapbox.mapboxsdk.style.sources.GeoJsonSource - -fun MapboxMap.querySourceFeatures(sourceId: String): List { - return this.getSourceAs(sourceId)?.querySourceFeatures(null) ?: emptyList() -} - -fun MapboxMap.queryRenderedFeatures(location: Location, layerId: String): List { - val latLng = LatLng(location.latitude, location.longitude) - val point = this.projection.toScreenLocation(latLng) - return this.queryRenderedFeatures(point, layerId) -} - -fun MapboxMap.isLayerVisible(layerId: String): Boolean { - return this.getLayer(layerId)?.visibility?.value?.equals(Property.VISIBLE)!! -} - -fun MapboxMap.waitForSource(uiController: UiController, sourceId: String) { - var counter = 0 - val delay = MapboxTestingUtils.MAP_RENDER_DELAY - while (this.querySourceFeatures(sourceId).isEmpty() && delay * counter < MapboxTestingUtils.RENDER_TIMEOUT) { - uiController.loopMainThreadForAtLeast(delay) - counter++ - } -} - -fun MapboxMap.waitForLayer(uiController: UiController, location: Location, layerId: String, shouldDisappear: Boolean = false) { - var counter = 0 - val delay = MapboxTestingUtils.MAP_RENDER_DELAY - while ( - if (shouldDisappear) this.queryRenderedFeatures(location, layerId).isNotEmpty() else this.queryRenderedFeatures(location, layerId).isEmpty() - && delay * counter < MapboxTestingUtils.RENDER_TIMEOUT) { - uiController.loopMainThreadForAtLeast(delay) - counter++ - } -} - - -class MapboxTestingUtils { - companion object { - - const val MAP_RENDER_DELAY = 250L - const val MAP_CONNECTION_DELAY = 1000L - const val RENDER_TIMEOUT = 3_000L - - /** - * Used to increase style load time for stress testing. - */ - const val MAPBOX_HEAVY_STYLE = "asset://heavy_style.json" - - private const val DATA_PUSH_INTERVAL = 1L - - /** - * Pushes data updates every [DATA_PUSH_INTERVAL] milliseconds until the style has been loaded, - * checked with [StyleChangeIdlingResource]. - */ - fun pushSourceUpdates(styleChangeIdlingResource: StyleChangeIdlingResource, update: () -> Unit) { - val mainHandler = Handler(Looper.getMainLooper()) - val runnable = object : Runnable { - override fun run() { - update.invoke() - if (!styleChangeIdlingResource.isIdleNow) { - mainHandler.postDelayed(this, DATA_PUSH_INTERVAL) - } - } - } - - if (!styleChangeIdlingResource.isIdleNow) { - if (Looper.myLooper() == Looper.getMainLooper()) { - runnable.run() - } else { - mainHandler.post(runnable) - } - } - } - } -} - -fun MapboxMap.addImageFromDrawable(string: String, drawable: Drawable) { - val bitmapFromDrawable = getBitmapFromDrawable(drawable) - this.addImage(string, bitmapFromDrawable) -} - -private fun getBitmapFromDrawable(drawable: Drawable): Bitmap { - if (drawable is BitmapDrawable) return drawable.bitmap - val bitmap = Bitmap.createBitmap(drawable.intrinsicWidth, - drawable.intrinsicHeight, Bitmap.Config.ARGB_8888) - val canvas = Canvas(bitmap) - drawable.setBounds(0, 0, canvas.width, canvas.height) - drawable.draw(canvas) - return bitmap -} \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/OnMapFragmentReadyIdlingResource.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/OnMapFragmentReadyIdlingResource.kt deleted file mode 100644 index fa6b732770..0000000000 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/OnMapFragmentReadyIdlingResource.kt +++ /dev/null @@ -1,39 +0,0 @@ -package com.mapbox.mapboxsdk.plugins.utils - -import android.os.Handler -import android.os.Looper -import android.support.test.espresso.IdlingResource - -import com.mapbox.mapboxsdk.maps.MapboxMap -import com.mapbox.mapboxsdk.maps.OnMapReadyCallback -import com.mapbox.mapboxsdk.maps.SupportMapFragment - -class OnMapFragmentReadyIdlingResource(fragment: SupportMapFragment?) : IdlingResource, OnMapReadyCallback { - - lateinit var mapboxMap: MapboxMap - - private var resourceCallback: IdlingResource.ResourceCallback? = null - - init { - Handler(Looper.getMainLooper()).post { - fragment?.getMapAsync(this) - } - } - - override fun getName(): String { - return javaClass.simpleName - } - - override fun isIdleNow(): Boolean { - return this::mapboxMap.isInitialized - } - - override fun registerIdleTransitionCallback(resourceCallback: IdlingResource.ResourceCallback) { - this.resourceCallback = resourceCallback - } - - override fun onMapReady(mapboxMap: MapboxMap) { - this.mapboxMap = mapboxMap - resourceCallback?.onTransitionToIdle() - } -} \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/OnMapReadyIdlingResource.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/OnMapReadyIdlingResource.java deleted file mode 100644 index f084343594..0000000000 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/OnMapReadyIdlingResource.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.mapbox.mapboxsdk.plugins.utils; - -import android.app.Activity; -import android.os.Handler; -import android.os.Looper; -import android.support.test.espresso.IdlingResource; - -import com.mapbox.mapboxsdk.maps.MapView; -import com.mapbox.mapboxsdk.maps.MapboxMap; -import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; - -import java.lang.reflect.Field; - -public class OnMapReadyIdlingResource implements IdlingResource, OnMapReadyCallback { - - private MapboxMap mapboxMap; - private MapView mapView; - private IdlingResource.ResourceCallback resourceCallback; - - public OnMapReadyIdlingResource(Activity activity) { - new Handler(Looper.getMainLooper()).post(() -> { - try { - Field field = activity.getClass().getDeclaredField("mapView"); - field.setAccessible(true); - mapView = ((MapView) field.get(activity)); - mapView.getMapAsync(this); - } catch (Exception err) { - throw new RuntimeException(err); - } - }); - } - - @Override - public String getName() { - return getClass().getSimpleName(); - } - - @Override - public boolean isIdleNow() { - return mapboxMap != null; - } - - @Override - public void registerIdleTransitionCallback(ResourceCallback resourceCallback) { - this.resourceCallback = resourceCallback; - } - - public MapView getMapView() { - return mapView; - } - - public MapboxMap getMapboxMap() { - return mapboxMap; - } - - @Override - public void onMapReady(MapboxMap mapboxMap) { - this.mapboxMap = mapboxMap; - if (resourceCallback != null) { - resourceCallback.onTransitionToIdle(); - } - } -} \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/StyleChangeIdlingResource.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/StyleChangeIdlingResource.kt deleted file mode 100644 index ab2c855c65..0000000000 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/StyleChangeIdlingResource.kt +++ /dev/null @@ -1,46 +0,0 @@ -package com.mapbox.mapboxsdk.plugins.utils - -import android.support.test.espresso.IdlingResource -import com.mapbox.mapboxsdk.maps.MapView -import com.mapbox.mapboxsdk.maps.MapboxMap - -/** - * Resource, that's idling until the provided style is loaded. - * Remember to add any espresso action (like view assertion) after the [waitForStyle] call - * for the test to keep running. - */ -class StyleChangeIdlingResource : IdlingResource { - - private var callback: IdlingResource.ResourceCallback? = null - private var isIdle = true - - override fun getName(): String { - return javaClass.simpleName - } - - override fun isIdleNow(): Boolean { - return isIdle - } - - override fun registerIdleTransitionCallback(callback: IdlingResource.ResourceCallback?) { - this.callback = callback - } - - private fun setIdle() { - isIdle = true - callback?.onTransitionToIdle() - } - - fun waitForStyle(mapView: MapView, mapboxMap: MapboxMap, styleUrl: String) { - isIdle = false - mapView.addOnMapChangedListener(object : MapView.OnMapChangedListener { - override fun onMapChanged(change: Int) { - if (change == MapView.DID_FINISH_LOADING_STYLE) { - mapView.removeOnMapChangedListener(this) - setIdle() - } - } - }) - mapboxMap.setStyleUrl(styleUrl) - } -} \ No newline at end of file -- cgit v1.2.1 From d4a2123bec4289848a4a0634d2727e2d4c77f180 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Thu, 6 Sep 2018 12:43:11 +0200 Subject: [android] location saved state tests, default location engine deactivation test --- .../mapboxsdk/location/LocationComponentTest.kt | 106 +++++++++++++++++++-- 1 file changed, 99 insertions(+), 7 deletions(-) (limited to 'platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java') diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt index 1d7c0c404b..6541abb748 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt @@ -6,6 +6,7 @@ import android.content.Context import android.graphics.Color import android.graphics.RectF import android.location.Location +import android.os.Bundle import android.support.test.espresso.Espresso.onView import android.support.test.espresso.IdlingRegistry import android.support.test.espresso.UiController @@ -491,12 +492,12 @@ class LocationComponentTest : BaseActivityTest() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, uiController: UiController, context: Context) { - assertThat(component.isLocationLayerEnabled, `is`(false)) + assertThat(component.isLocationComponentEnabled, `is`(false)) component.onStop() component.onStart() - assertThat(component.isLocationLayerEnabled, `is`(false)) + assertThat(component.isLocationComponentEnabled, `is`(false)) component.activateLocationComponent(context, false) - assertThat(component.isLocationLayerEnabled, `is`(true)) + assertThat(component.isLocationComponentEnabled, `is`(true)) } } executeComponentTest(componentAction) @@ -508,10 +509,10 @@ class LocationComponentTest : BaseActivityTest() { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, uiController: UiController, context: Context) { component.activateLocationComponent(context, false) - assertThat(component.isLocationLayerEnabled, `is`(true)) + assertThat(component.isLocationComponentEnabled, `is`(true)) component.onStop() component.onStart() - assertThat(component.isLocationLayerEnabled, `is`(true)) + assertThat(component.isLocationComponentEnabled, `is`(true)) } } executeComponentTest(componentAction) @@ -524,10 +525,10 @@ class LocationComponentTest : BaseActivityTest() { uiController: UiController, context: Context) { component.activateLocationComponent(context, false) component.deactivateLocationComponent() - assertThat(component.isLocationLayerEnabled, `is`(false)) + assertThat(component.isLocationComponentEnabled, `is`(false)) component.onStop() component.onStart() - assertThat(component.isLocationLayerEnabled, `is`(false)) + assertThat(component.isLocationComponentEnabled, `is`(false)) } } executeComponentTest(componentAction) @@ -1092,6 +1093,97 @@ class LocationComponentTest : BaseActivityTest() { executeComponentTest(componentAction) } + @Test + fun savedState_bundleCreationDeactivated() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + val bundle = Bundle() + component.onSaveInstanceState(bundle) + assertThat(bundle.getBoolean(STATE_LOCATION_ENABLED), `is`(component.isLocationComponentEnabled)) + assertThat(bundle.getParcelable(STATE_LOCATION_OPTIONS), `is`(equalTo(component.locationComponentOptions))) + assertThat(bundle.getInt(STATE_LOCATION_RENDER_MODE), `is`(equalTo(component.renderMode))) + assertThat(bundle.getInt(STATE_LOCATION_CAMERA_MODE), `is`(equalTo(component.cameraMode))) + assertThat(bundle.getParcelable(STATE_LOCATION_LAST_LOCATION), `is`(equalTo(component.lastKnownLocation))) + } + } + + executeComponentTest(componentAction) + } + + @Test + fun savedState_bundleCreationActivated() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + val options = LocationComponentOptions.builder(context) + .accuracyColor(Color.RED) + .build() + component.activateLocationComponent(null, options) + component.cameraMode = CameraMode.TRACKING + component.renderMode = RenderMode.GPS + component.forceLocationUpdate(location) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) + + val bundle = Bundle() + component.onSaveInstanceState(bundle) + assertThat(bundle.getBoolean(STATE_LOCATION_ENABLED), `is`(component.isLocationComponentEnabled)) + assertThat(bundle.getParcelable(STATE_LOCATION_OPTIONS), `is`(equalTo(component.locationComponentOptions))) + assertThat(bundle.getInt(STATE_LOCATION_RENDER_MODE), `is`(component.renderMode)) + assertThat(bundle.getInt(STATE_LOCATION_CAMERA_MODE), `is`(component.cameraMode)) + assertThat(bundle.getParcelable(STATE_LOCATION_LAST_LOCATION), `is`(equalTo(component.lastKnownLocation))) + } + } + + executeComponentTest(componentAction) + } + + @Test + fun savedState_componentRecreated() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + val options = LocationComponentOptions.builder(context) + .accuracyColor(Color.RED) + .build() + + val bundle = Bundle() + bundle.putBoolean(STATE_LOCATION_ENABLED, true) + bundle.putParcelable(STATE_LOCATION_OPTIONS, options) + bundle.putInt(STATE_LOCATION_RENDER_MODE, RenderMode.GPS) + bundle.putInt(STATE_LOCATION_CAMERA_MODE, CameraMode.TRACKING) + bundle.putParcelable(STATE_LOCATION_LAST_LOCATION, location) + + component.onRestoreInstanceState(bundle) + assertThat(component.isLocationComponentEnabled, `is`(true)) + assertThat(component.locationComponentOptions, `is`(equalTo(options))) + assertThat(component.renderMode, `is`(RenderMode.GPS)) + assertThat(component.cameraMode, `is`(CameraMode.TRACKING)) + assertThat(component.lastKnownLocation, `is`(equalTo(location))) + } + } + + executeComponentTest(componentAction) + } + + @Test + fun defaultLocationEngine_deactivatedWhenDestroyed() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context) + uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) + assertThat(component.locationEngine?.isConnected, `is`(true)) + + component.onStop() + component.onDestroy() + assertThat(component.locationEngine?.isConnected, `is`(false)) + } + } + + executeComponentTest(componentAction) + } + @After override fun afterTest() { super.afterTest() -- cgit v1.2.1 From caebcd08e3803f5758353fbadefc9b75093b4015 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Thu, 6 Sep 2018 14:04:02 +0200 Subject: [android] LocationComponent - javadoc fixes, improved initialization, removed location save state --- .../mapboxsdk/location/LocationComponentTest.kt | 224 +++++++++------------ .../location/LocationLayerControllerTest.kt | 23 ++- .../location/utils/LocationComponentAction.kt | 8 +- 3 files changed, 116 insertions(+), 139 deletions(-) (limited to 'platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java') diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt index 6541abb748..1d4c4af149 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt @@ -19,7 +19,6 @@ import com.mapbox.geojson.Point import com.mapbox.mapboxsdk.camera.CameraUpdateFactory import com.mapbox.mapboxsdk.constants.Style import com.mapbox.mapboxsdk.geometry.LatLng -import com.mapbox.mapboxsdk.maps.MapboxMap import com.mapbox.mapboxsdk.location.LocationComponentConstants.* import com.mapbox.mapboxsdk.location.modes.CameraMode import com.mapbox.mapboxsdk.location.modes.RenderMode @@ -28,6 +27,7 @@ import com.mapbox.mapboxsdk.location.utils.MapboxTestingUtils.Companion.MAPBOX_H import com.mapbox.mapboxsdk.location.utils.MapboxTestingUtils.Companion.MAP_CONNECTION_DELAY import com.mapbox.mapboxsdk.location.utils.MapboxTestingUtils.Companion.MAP_RENDER_DELAY import com.mapbox.mapboxsdk.location.utils.MapboxTestingUtils.Companion.pushSourceUpdates +import com.mapbox.mapboxsdk.maps.MapboxMap import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest import com.mapbox.mapboxsdk.testapp.activity.SingleActivity import com.mapbox.mapboxsdk.utils.ColorUtils @@ -70,8 +70,9 @@ class LocationComponentTest : BaseActivityTest() { validateTestSetup() val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context) + component.isLocationComponentEnabled = true val locationEngine = component.locationEngine assertThat(locationEngine, notNullValue()) @@ -89,7 +90,7 @@ class LocationComponentTest : BaseActivityTest() { validateTestSetup() val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent( context, LocationComponentOptions.builder(context) @@ -98,6 +99,7 @@ class LocationComponentTest : BaseActivityTest() { .accuracyAlpha(.5f) .accuracyColor(Color.BLUE) .build()) + component.isLocationComponentEnabled = true val locationEngine = component.locationEngine val componentOptions = component.locationComponentOptions @@ -120,8 +122,9 @@ class LocationComponentTest : BaseActivityTest() { validateTestSetup() val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent( + context, null, LocationComponentOptions.builder(context) .staleStateTimeout(200) @@ -129,6 +132,7 @@ class LocationComponentTest : BaseActivityTest() { .accuracyAlpha(.5f) .accuracyColor(Color.BLUE) .build()) + component.isLocationComponentEnabled = true val locationEngine = component.locationEngine val componentOptions = component.locationComponentOptions @@ -150,9 +154,10 @@ class LocationComponentTest : BaseActivityTest() { validateTestSetup() val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { mapboxMap.setStyle(Style.LIGHT) component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.forceLocationUpdate(location) mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) @@ -173,8 +178,9 @@ class LocationComponentTest : BaseActivityTest() { validateTestSetup() val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true // Source should be present but empty val mapView = (rule.activity as SingleActivity).mapView @@ -202,12 +208,13 @@ class LocationComponentTest : BaseActivityTest() { validateTestSetup() val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, LocationComponentOptions.builder(context) .staleStateTimeout(200) .enableStaleState(false) .build()) + component.isLocationComponentEnabled = true component.forceLocationUpdate(location) mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) @@ -229,7 +236,7 @@ class LocationComponentTest : BaseActivityTest() { fun locationComponentOptions_loadsForegroundBitmapFromNameOption() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, LocationComponentOptions.builder(context) .foregroundName("custom-foreground-bitmap") @@ -238,6 +245,7 @@ class LocationComponentTest : BaseActivityTest() { .backgroundStaleName("custom-background-stale-bitmap") .bearingName("custom-bearing-bitmap") .build()) + component.isLocationComponentEnabled = true val foregroundDrawable = ContextCompat.getDrawable(context, R.drawable.ic_media_play) foregroundDrawable?.let { @@ -268,12 +276,13 @@ class LocationComponentTest : BaseActivityTest() { fun locationComponentOptions_loadsGpsNameWithGpsRenderMode() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, LocationComponentOptions.builder(context) .foregroundName("custom-foreground-bitmap") .gpsName("custom-gps-bitmap") .build()) + component.isLocationComponentEnabled = true component.renderMode = RenderMode.GPS component.forceLocationUpdate(location) @@ -296,12 +305,13 @@ class LocationComponentTest : BaseActivityTest() { fun locationComponentOptions_customIconNameRevertsToDefault() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, LocationComponentOptions.builder(context) .foregroundName("custom-foreground-bitmap") .gpsName("custom-gps-bitmap") .build()) + component.isLocationComponentEnabled = true component.renderMode = RenderMode.GPS component.forceLocationUpdate(location) @@ -325,12 +335,13 @@ class LocationComponentTest : BaseActivityTest() { fun locationComponentOptions_customGpsIconNameChangeBackWithMode() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, LocationComponentOptions.builder(context) .gpsName("custom-gps-bitmap") .build()) + component.isLocationComponentEnabled = true component.renderMode = RenderMode.GPS component.forceLocationUpdate(location) @@ -354,11 +365,12 @@ class LocationComponentTest : BaseActivityTest() { fun stillStaleAfterResuming() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, LocationComponentOptions.builder(context) .staleStateTimeout(200) .build()) + component.isLocationComponentEnabled = true component.forceLocationUpdate(location) mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) @@ -382,8 +394,9 @@ class LocationComponentTest : BaseActivityTest() { fun stillNotStaleAfterResuming() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.forceLocationUpdate(location) mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(false)) @@ -406,11 +419,12 @@ class LocationComponentTest : BaseActivityTest() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, LocationComponentOptions.builder(context) .accuracyColor(color) .build()) + component.isLocationComponentEnabled = true component.forceLocationUpdate(location) mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) @@ -431,8 +445,9 @@ class LocationComponentTest : BaseActivityTest() { fun forceLocationUpdate_doesMoveLocationLayerIconToCorrectPosition() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.forceLocationUpdate(location) mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) @@ -450,8 +465,9 @@ class LocationComponentTest : BaseActivityTest() { fun disablingComponentHidesPuck() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.forceLocationUpdate(location) mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) @@ -459,7 +475,7 @@ class LocationComponentTest : BaseActivityTest() { assertEquals(point.latitude(), location.latitude, 0.1) assertEquals(point.longitude(), location.longitude, 0.1) - component.deactivateLocationComponent() + component.isLocationComponentEnabled = false uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) assertThat(mapboxMap.queryRenderedFeatures(location, FOREGROUND_LAYER).isEmpty(), `is`(true)) } @@ -471,15 +487,16 @@ class LocationComponentTest : BaseActivityTest() { fun disablingComponentAndChangingStyleAllowsToEnableAgain() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.forceLocationUpdate(location) mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - component.deactivateLocationComponent() + component.isLocationComponentEnabled = false mapboxMap.setStyle(Style.LIGHT) - component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true)) } @@ -491,12 +508,13 @@ class LocationComponentTest : BaseActivityTest() { fun lifecycle_isDisabledOnStart() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { assertThat(component.isLocationComponentEnabled, `is`(false)) component.onStop() component.onStart() assertThat(component.isLocationComponentEnabled, `is`(false)) component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true assertThat(component.isLocationComponentEnabled, `is`(true)) } } @@ -507,8 +525,9 @@ class LocationComponentTest : BaseActivityTest() { fun lifecycle_keepsEnabledWhenStoppedAndStarted() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true assertThat(component.isLocationComponentEnabled, `is`(true)) component.onStop() component.onStart() @@ -522,9 +541,10 @@ class LocationComponentTest : BaseActivityTest() { fun lifecycle_keepsDisabledWhenStoppedAndStarted() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) - component.deactivateLocationComponent() + component.isLocationComponentEnabled = true + component.isLocationComponentEnabled = false assertThat(component.isLocationComponentEnabled, `is`(false)) component.onStop() component.onStart() @@ -538,8 +558,9 @@ class LocationComponentTest : BaseActivityTest() { fun lifecycle_ableToChangeStyleAfterResuming() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.onStop() component.onStart() @@ -555,8 +576,9 @@ class LocationComponentTest : BaseActivityTest() { fun lifecycle_interruptedDuringStyleChange() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true mapboxMap.setStyle(Style.DARK) component.onStop() component.onStart() @@ -570,8 +592,9 @@ class LocationComponentTest : BaseActivityTest() { fun lifecycle_forceLocationUpdateAfterStopped() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.onStop() component.forceLocationUpdate(location) mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) @@ -586,8 +609,9 @@ class LocationComponentTest : BaseActivityTest() { fun lifecycle_acceptAndReuseLocationUpdatesBeforeLayerStarted() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.onStop() component.forceLocationUpdate(location) component.onStart() @@ -605,8 +629,9 @@ class LocationComponentTest : BaseActivityTest() { fun lifecycle_lifecycleChangeRightAfterStyleReload() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.forceLocationUpdate(location) mapboxMap.setStyle(Style.LIGHT) component.onStop() @@ -632,8 +657,9 @@ class LocationComponentTest : BaseActivityTest() { fun mapChange_settingComponentStyle() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true styleChangeIdlingResource.waitForStyle((rule.activity as SingleActivity).mapView, mapboxMap, MAPBOX_HEAVY_STYLE) val options = LocationComponentOptions.builder(context) .accuracyColor(Color.RED) @@ -656,8 +682,9 @@ class LocationComponentTest : BaseActivityTest() { fun mapChange_forcingLocation() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true styleChangeIdlingResource.waitForStyle((rule.activity as SingleActivity).mapView, mapboxMap, MAPBOX_HEAVY_STYLE) pushSourceUpdates(styleChangeIdlingResource) { @@ -677,9 +704,10 @@ class LocationComponentTest : BaseActivityTest() { fun mapChange_settingMapStyleBeforeComponentCreation() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { styleChangeIdlingResource.waitForStyle((rule.activity as SingleActivity).mapView, mapboxMap, MAPBOX_HEAVY_STYLE) component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true val options = LocationComponentOptions.builder(context) .accuracyColor(Color.RED) @@ -701,8 +729,9 @@ class LocationComponentTest : BaseActivityTest() { fun animators_layerBearingCorrect() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.renderMode = RenderMode.GPS location.bearing = 77f component.forceLocationUpdate(location) @@ -723,8 +752,9 @@ class LocationComponentTest : BaseActivityTest() { fun animators_cameraLatLngBearingCorrect() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.cameraMode = CameraMode.TRACKING_GPS location.bearing = 77f component.forceLocationUpdate(location) @@ -751,8 +781,9 @@ class LocationComponentTest : BaseActivityTest() { fun animators_cameraBearingCorrect() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.cameraMode = CameraMode.NONE_GPS val latitude = mapboxMap.cameraPosition.target.latitude val longitude = mapboxMap.cameraPosition.target.longitude @@ -782,8 +813,9 @@ class LocationComponentTest : BaseActivityTest() { fun animators_cameraNoneCorrect() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.cameraMode = CameraMode.NONE val latitude = mapboxMap.cameraPosition.target.latitude val longitude = mapboxMap.cameraPosition.target.longitude @@ -814,8 +846,9 @@ class LocationComponentTest : BaseActivityTest() { fun animators_focalPointAdjustment() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.cameraMode = CameraMode.TRACKING component.cameraMode = CameraMode.NONE component.forceLocationUpdate(location) @@ -832,8 +865,9 @@ class LocationComponentTest : BaseActivityTest() { fun animators_dontZoomWhileNotTracking() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.cameraMode = CameraMode.NONE val zoom = mapboxMap.cameraPosition.zoom component.zoomWhileTracking(10.0) @@ -850,8 +884,9 @@ class LocationComponentTest : BaseActivityTest() { fun animators_zoomWhileTracking() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.cameraMode = CameraMode.TRACKING component.zoomWhileTracking(10.0) uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIM_DURATION) @@ -868,8 +903,9 @@ class LocationComponentTest : BaseActivityTest() { fun animators_zoomWhileTrackingCanceledOnModeChange() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.cameraMode = CameraMode.TRACKING component.zoomWhileTracking(15.0) uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIM_DURATION / 2) @@ -887,8 +923,9 @@ class LocationComponentTest : BaseActivityTest() { fun animators_dontZoomWhileStopped() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.cameraMode = CameraMode.TRACKING uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) @@ -910,8 +947,9 @@ class LocationComponentTest : BaseActivityTest() { fun animators_cancelZoomWhileTracking() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.cameraMode = CameraMode.TRACKING component.zoomWhileTracking(15.0) uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIM_DURATION / 2) @@ -929,8 +967,9 @@ class LocationComponentTest : BaseActivityTest() { fun animators_dontTiltWhileNotTracking() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.cameraMode = CameraMode.NONE val tilt = mapboxMap.cameraPosition.tilt component.tiltWhileTracking(30.0) @@ -947,8 +986,9 @@ class LocationComponentTest : BaseActivityTest() { fun animators_tiltWhileTracking() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.cameraMode = CameraMode.TRACKING component.tiltWhileTracking(30.0) uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIM_DURATION) @@ -965,8 +1005,9 @@ class LocationComponentTest : BaseActivityTest() { fun animators_tiltWhileTrackingCanceledOnModeChange() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.cameraMode = CameraMode.TRACKING component.tiltWhileTracking(30.0) uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIM_DURATION / 2) @@ -984,8 +1025,9 @@ class LocationComponentTest : BaseActivityTest() { fun animators_dontTiltWhileStopped() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.cameraMode = CameraMode.TRACKING val tilt = mapboxMap.cameraPosition.tilt @@ -1005,8 +1047,9 @@ class LocationComponentTest : BaseActivityTest() { fun animators_cancelTiltWhileTracking() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.cameraMode = CameraMode.TRACKING component.tiltWhileTracking(30.0) uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIM_DURATION / 2) @@ -1024,14 +1067,15 @@ class LocationComponentTest : BaseActivityTest() { fun cameraPositionAdjustedToTrackingModeWhenComponentEnabled() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.cameraMode = CameraMode.TRACKING_GPS component.forceLocationUpdate(location) - component.deactivateLocationComponent() + component.isLocationComponentEnabled = false mapboxMap.moveCamera(CameraUpdateFactory.newLatLng(LatLng(51.0, 17.0))) mapboxMap.moveCamera(CameraUpdateFactory.bearingTo(90.0)) - component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS + MAP_RENDER_DELAY) assertEquals(location.bearing.toDouble(), mapboxMap.cameraPosition.bearing, 0.1) @@ -1047,8 +1091,9 @@ class LocationComponentTest : BaseActivityTest() { fun compassEngine_onComponentInitializedDefaultIsProvided() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true assertTrue(component.compassEngine is LocationComponentCompassEngine) } } @@ -1060,8 +1105,9 @@ class LocationComponentTest : BaseActivityTest() { fun compassEngine_changesWhenNewProvided() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true val engine: CompassEngine = object : CompassEngine { override fun addCompassListener(compassListener: CompassListener) { } @@ -1093,85 +1139,13 @@ class LocationComponentTest : BaseActivityTest() { executeComponentTest(componentAction) } - @Test - fun savedState_bundleCreationDeactivated() { - val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { - override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - val bundle = Bundle() - component.onSaveInstanceState(bundle) - assertThat(bundle.getBoolean(STATE_LOCATION_ENABLED), `is`(component.isLocationComponentEnabled)) - assertThat(bundle.getParcelable(STATE_LOCATION_OPTIONS), `is`(equalTo(component.locationComponentOptions))) - assertThat(bundle.getInt(STATE_LOCATION_RENDER_MODE), `is`(equalTo(component.renderMode))) - assertThat(bundle.getInt(STATE_LOCATION_CAMERA_MODE), `is`(equalTo(component.cameraMode))) - assertThat(bundle.getParcelable(STATE_LOCATION_LAST_LOCATION), `is`(equalTo(component.lastKnownLocation))) - } - } - - executeComponentTest(componentAction) - } - - @Test - fun savedState_bundleCreationActivated() { - val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { - override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - val options = LocationComponentOptions.builder(context) - .accuracyColor(Color.RED) - .build() - component.activateLocationComponent(null, options) - component.cameraMode = CameraMode.TRACKING - component.renderMode = RenderMode.GPS - component.forceLocationUpdate(location) - mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - - val bundle = Bundle() - component.onSaveInstanceState(bundle) - assertThat(bundle.getBoolean(STATE_LOCATION_ENABLED), `is`(component.isLocationComponentEnabled)) - assertThat(bundle.getParcelable(STATE_LOCATION_OPTIONS), `is`(equalTo(component.locationComponentOptions))) - assertThat(bundle.getInt(STATE_LOCATION_RENDER_MODE), `is`(component.renderMode)) - assertThat(bundle.getInt(STATE_LOCATION_CAMERA_MODE), `is`(component.cameraMode)) - assertThat(bundle.getParcelable(STATE_LOCATION_LAST_LOCATION), `is`(equalTo(component.lastKnownLocation))) - } - } - - executeComponentTest(componentAction) - } - - @Test - fun savedState_componentRecreated() { - val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { - override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { - val options = LocationComponentOptions.builder(context) - .accuracyColor(Color.RED) - .build() - - val bundle = Bundle() - bundle.putBoolean(STATE_LOCATION_ENABLED, true) - bundle.putParcelable(STATE_LOCATION_OPTIONS, options) - bundle.putInt(STATE_LOCATION_RENDER_MODE, RenderMode.GPS) - bundle.putInt(STATE_LOCATION_CAMERA_MODE, CameraMode.TRACKING) - bundle.putParcelable(STATE_LOCATION_LAST_LOCATION, location) - - component.onRestoreInstanceState(bundle) - assertThat(component.isLocationComponentEnabled, `is`(true)) - assertThat(component.locationComponentOptions, `is`(equalTo(options))) - assertThat(component.renderMode, `is`(RenderMode.GPS)) - assertThat(component.cameraMode, `is`(CameraMode.TRACKING)) - assertThat(component.lastKnownLocation, `is`(equalTo(location))) - } - } - - executeComponentTest(componentAction) - } - @Test fun defaultLocationEngine_deactivatedWhenDestroyed() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, uiController: UiController, context: Context) { component.activateLocationComponent(context) + component.isLocationComponentEnabled = true uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) assertThat(component.locationEngine?.isConnected, `is`(true)) diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationLayerControllerTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationLayerControllerTest.kt index c50d1817fd..92f4d770fe 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationLayerControllerTest.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationLayerControllerTest.kt @@ -76,6 +76,7 @@ class LocationLayerControllerTest : BaseActivityTest() { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.renderMode = RenderMode.NORMAL uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) assertThat(mapboxMap.getSource(LOCATION_SOURCE), notNullValue()) @@ -94,6 +95,7 @@ class LocationLayerControllerTest : BaseActivityTest() { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.renderMode = RenderMode.NORMAL component.forceLocationUpdate(location) mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) @@ -113,6 +115,7 @@ class LocationLayerControllerTest : BaseActivityTest() { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.renderMode = RenderMode.COMPASS component.forceLocationUpdate(location) mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) @@ -132,6 +135,7 @@ class LocationLayerControllerTest : BaseActivityTest() { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.renderMode = RenderMode.GPS component.forceLocationUpdate(location) mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) @@ -151,9 +155,10 @@ class LocationLayerControllerTest : BaseActivityTest() { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.forceLocationUpdate(location) mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - component.deactivateLocationComponent() + component.isLocationComponentEnabled = false mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER, shouldDisappear = true) component.renderMode = RenderMode.GPS uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) @@ -173,10 +178,11 @@ class LocationLayerControllerTest : BaseActivityTest() { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.renderMode = RenderMode.NORMAL component.forceLocationUpdate(location) mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - component.deactivateLocationComponent() + component.isLocationComponentEnabled = false mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER, shouldDisappear = true) uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) @@ -197,6 +203,7 @@ class LocationLayerControllerTest : BaseActivityTest() { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.renderMode = RenderMode.NORMAL component.forceLocationUpdate(location) mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) @@ -228,6 +235,7 @@ class LocationLayerControllerTest : BaseActivityTest() { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.applyStyle(LocationComponentOptions.builder(context).staleStateTimeout(100).build()) component.forceLocationUpdate(location) mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) @@ -252,6 +260,7 @@ class LocationLayerControllerTest : BaseActivityTest() { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.applyStyle(LocationComponentOptions.builder(context).staleStateTimeout(1).build()) styleChangeIdlingResource.waitForStyle((rule.activity as SingleActivity).mapView, mapboxMap, MAPBOX_HEAVY_STYLE) pushSourceUpdates(styleChangeIdlingResource) { @@ -272,12 +281,9 @@ class LocationLayerControllerTest : BaseActivityTest() { uiController: UiController, context: Context) { styleChangeIdlingResource.waitForStyle((rule.activity as SingleActivity).mapView, mapboxMap, MAPBOX_HEAVY_STYLE) var show = true + component.activateLocationComponent(context, false) pushSourceUpdates(styleChangeIdlingResource) { - if (show) { - component.activateLocationComponent(context, false) - } else { - component.deactivateLocationComponent() - } + component.isLocationComponentEnabled = show show = !show } @@ -296,6 +302,7 @@ class LocationLayerControllerTest : BaseActivityTest() { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(location), 16.0)) component.forceLocationUpdate(location) mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) @@ -315,6 +322,7 @@ class LocationLayerControllerTest : BaseActivityTest() { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true component.forceLocationUpdate(location) mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) mapboxMap.easeCamera(CameraUpdateFactory.newLatLngZoom(LatLng(location), 16.0), 300) @@ -334,6 +342,7 @@ class LocationLayerControllerTest : BaseActivityTest() { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, uiController: UiController, context: Context) { component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) component.forceLocationUpdate(location) uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/utils/LocationComponentAction.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/utils/LocationComponentAction.kt index ad80a3333e..75fae82cf2 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/utils/LocationComponentAction.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/utils/LocationComponentAction.kt @@ -21,14 +21,8 @@ class LocationComponentAction(private val mapboxMap: MapboxMap, } override fun perform(uiController: UiController, view: View) { - val component = mapboxMap.locationComponent - - while (mapboxMap.getSource("mapbox-location-source") == null) { - uiController.loopMainThreadForAtLeast(MapboxTestingUtils.MAP_RENDER_DELAY) - } - onPerformLocationComponentAction.onLocationComponentAction( - component, + mapboxMap.locationComponent, mapboxMap, uiController, view.context) -- cgit v1.2.1 From b2d4b82cdfeb0e3807b2b3027398fbeeda751b03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Thu, 6 Sep 2018 17:07:54 +0200 Subject: [android] updated location tracking gestures management tests --- .../java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java') diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt index 1d4c4af149..53054dfe0e 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt @@ -210,6 +210,7 @@ class LocationComponentTest : BaseActivityTest() { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, uiController: UiController, context: Context) { component.activateLocationComponent(context, + null, LocationComponentOptions.builder(context) .staleStateTimeout(200) .enableStaleState(false) @@ -238,6 +239,7 @@ class LocationComponentTest : BaseActivityTest() { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, uiController: UiController, context: Context) { component.activateLocationComponent(context, + null, LocationComponentOptions.builder(context) .foregroundName("custom-foreground-bitmap") .backgroundName("custom-background-bitmap") @@ -278,6 +280,7 @@ class LocationComponentTest : BaseActivityTest() { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, uiController: UiController, context: Context) { component.activateLocationComponent(context, + null, LocationComponentOptions.builder(context) .foregroundName("custom-foreground-bitmap") .gpsName("custom-gps-bitmap") @@ -307,6 +310,7 @@ class LocationComponentTest : BaseActivityTest() { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, uiController: UiController, context: Context) { component.activateLocationComponent(context, + null, LocationComponentOptions.builder(context) .foregroundName("custom-foreground-bitmap") .gpsName("custom-gps-bitmap") @@ -338,6 +342,7 @@ class LocationComponentTest : BaseActivityTest() { uiController: UiController, context: Context) { component.activateLocationComponent(context, + null, LocationComponentOptions.builder(context) .gpsName("custom-gps-bitmap") .build()) @@ -367,6 +372,7 @@ class LocationComponentTest : BaseActivityTest() { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, uiController: UiController, context: Context) { component.activateLocationComponent(context, + null, LocationComponentOptions.builder(context) .staleStateTimeout(200) .build()) @@ -421,6 +427,7 @@ class LocationComponentTest : BaseActivityTest() { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, uiController: UiController, context: Context) { component.activateLocationComponent(context, + null, LocationComponentOptions.builder(context) .accuracyColor(color) .build()) -- cgit v1.2.1 From 079ba0209ed383c15123902f0810e658c2b0abf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Wed, 12 Sep 2018 12:27:32 +0200 Subject: [android] improved render timeouts in LocationComponent tests --- .../mapboxsdk/location/LocationComponentTest.kt | 33 ++++---- .../location/LocationLayerControllerTest.kt | 95 +++++++++++++++------- .../mapboxsdk/location/utils/MapboxTestingUtils.kt | 10 ++- 3 files changed, 93 insertions(+), 45 deletions(-) (limited to 'platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java') diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt index 53054dfe0e..aa3e2eea6f 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt @@ -6,7 +6,6 @@ import android.content.Context import android.graphics.Color import android.graphics.RectF import android.location.Location -import android.os.Bundle import android.support.test.espresso.Espresso.onView import android.support.test.espresso.IdlingRegistry import android.support.test.espresso.UiController @@ -219,8 +218,7 @@ class LocationComponentTest : BaseActivityTest() { component.forceLocationUpdate(location) mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - uiController.loopMainThreadForAtLeast(200) - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + uiController.loopMainThreadForAtLeast(500) mapboxMap.querySourceFeatures(LOCATION_SOURCE).also { it.forEach { @@ -325,10 +323,12 @@ class LocationComponentTest : BaseActivityTest() { assertThat(foregroundId, `is`(equalTo("custom-gps-bitmap"))) component.applyStyle(LocationComponentOptions.builder(context).build()) - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) - val revertedForegroundId = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getStringProperty(PROPERTY_FOREGROUND_ICON) - assertThat(revertedForegroundId, `is`(equalTo(FOREGROUND_ICON))) + val renderCheck = { + mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getStringProperty(PROPERTY_FOREGROUND_ICON) == FOREGROUND_ICON + } + waitForRenderResult(uiController, renderCheck, true) + assertThat(renderCheck.invoke(), `is`(true)) } } @@ -356,10 +356,12 @@ class LocationComponentTest : BaseActivityTest() { assertThat(foregroundId, `is`(equalTo("custom-gps-bitmap"))) component.renderMode = RenderMode.NORMAL - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) - val revertedForegroundId = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getStringProperty(PROPERTY_FOREGROUND_ICON) - assertThat(revertedForegroundId, `is`(equalTo(FOREGROUND_ICON))) + val renderCheck = { + mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getStringProperty(PROPERTY_FOREGROUND_ICON) == FOREGROUND_ICON + } + waitForRenderResult(uiController, renderCheck, true) + assertThat(renderCheck.invoke(), `is`(true)) } } @@ -381,8 +383,12 @@ class LocationComponentTest : BaseActivityTest() { component.forceLocationUpdate(location) mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) uiController.loopMainThreadForAtLeast(250) // engaging stale state - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) - assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(true)) + + val renderCheck = { + mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE) + } + waitForRenderResult(uiController, renderCheck, true) + assertThat(renderCheck.invoke(), `is`(true)) component.onStop() component.onStart() @@ -409,7 +415,7 @@ class LocationComponentTest : BaseActivityTest() { component.onStop() component.onStart() - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(false)) assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(true)) @@ -483,7 +489,7 @@ class LocationComponentTest : BaseActivityTest() { assertEquals(point.longitude(), location.longitude, 0.1) component.isLocationComponentEnabled = false - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER, true) assertThat(mapboxMap.queryRenderedFeatures(location, FOREGROUND_LAYER).isEmpty(), `is`(true)) } } @@ -935,7 +941,6 @@ class LocationComponentTest : BaseActivityTest() { component.isLocationComponentEnabled = true component.cameraMode = CameraMode.TRACKING - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) val zoom = mapboxMap.cameraPosition.zoom component.onStop() diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationLayerControllerTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationLayerControllerTest.kt index 92f4d770fe..41a349b993 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationLayerControllerTest.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationLayerControllerTest.kt @@ -16,7 +16,6 @@ import android.support.test.runner.AndroidJUnit4 import com.mapbox.mapboxsdk.camera.CameraUpdateFactory import com.mapbox.mapboxsdk.constants.Style import com.mapbox.mapboxsdk.geometry.LatLng -import com.mapbox.mapboxsdk.maps.MapboxMap import com.mapbox.mapboxsdk.location.LocationComponentConstants.* import com.mapbox.mapboxsdk.location.modes.RenderMode import com.mapbox.mapboxsdk.location.utils.* @@ -24,6 +23,7 @@ import com.mapbox.mapboxsdk.location.utils.MapboxTestingUtils.Companion.MAPBOX_H import com.mapbox.mapboxsdk.location.utils.MapboxTestingUtils.Companion.MAP_CONNECTION_DELAY import com.mapbox.mapboxsdk.location.utils.MapboxTestingUtils.Companion.MAP_RENDER_DELAY import com.mapbox.mapboxsdk.location.utils.MapboxTestingUtils.Companion.pushSourceUpdates +import com.mapbox.mapboxsdk.maps.MapboxMap import com.mapbox.mapboxsdk.style.sources.GeoJsonSource import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest import com.mapbox.mapboxsdk.testapp.activity.SingleActivity @@ -74,7 +74,7 @@ class LocationLayerControllerTest : BaseActivityTest() { fun renderModeNormal_sourceDoesGetAdded() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) component.isLocationComponentEnabled = true component.renderMode = RenderMode.NORMAL @@ -93,7 +93,7 @@ class LocationLayerControllerTest : BaseActivityTest() { fun renderModeNormal_trackingNormalLayersDoGetAdded() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) component.isLocationComponentEnabled = true component.renderMode = RenderMode.NORMAL @@ -113,7 +113,7 @@ class LocationLayerControllerTest : BaseActivityTest() { fun renderModeCompass_bearingLayersDoGetAdded() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) component.isLocationComponentEnabled = true component.renderMode = RenderMode.COMPASS @@ -133,7 +133,7 @@ class LocationLayerControllerTest : BaseActivityTest() { fun renderModeGps_navigationLayersDoGetAdded() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) component.isLocationComponentEnabled = true component.renderMode = RenderMode.GPS @@ -153,7 +153,7 @@ class LocationLayerControllerTest : BaseActivityTest() { fun dontShowPuckWhenRenderModeSetAndComponentDisabled() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) component.isLocationComponentEnabled = true component.forceLocationUpdate(location) @@ -161,7 +161,13 @@ class LocationLayerControllerTest : BaseActivityTest() { component.isLocationComponentEnabled = false mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER, shouldDisappear = true) component.renderMode = RenderMode.GPS - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + + // waiting for layer to appear or timing out + val renderCheck = { + mapboxMap.isLayerVisible(FOREGROUND_LAYER) + } + waitForRenderResult(uiController, renderCheck, true) + assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(false)) assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(false)) assertThat(mapboxMap.isLayerVisible(SHADOW_LAYER), `is`(false)) @@ -176,7 +182,7 @@ class LocationLayerControllerTest : BaseActivityTest() { fun whenLocationComponentDisabled_doesSetAllLayersToVisibilityNone() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) component.isLocationComponentEnabled = true component.renderMode = RenderMode.NORMAL @@ -184,7 +190,6 @@ class LocationLayerControllerTest : BaseActivityTest() { mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) component.isLocationComponentEnabled = false mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER, shouldDisappear = true) - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) // Check that all layers visibilities are set to none assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(false)) @@ -201,7 +206,7 @@ class LocationLayerControllerTest : BaseActivityTest() { fun onMapChange_locationComponentLayersDoGetRedrawn() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) component.isLocationComponentEnabled = true component.renderMode = RenderMode.NORMAL @@ -233,16 +238,20 @@ class LocationLayerControllerTest : BaseActivityTest() { fun whenStyleChanged_continuesUsingStaleIcons() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) component.isLocationComponentEnabled = true component.applyStyle(LocationComponentOptions.builder(context).staleStateTimeout(100).build()) component.forceLocationUpdate(location) mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) uiController.loopMainThreadForAtLeast(150) - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) - assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(true)) + val renderCheck = { + mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE) + } + waitForRenderResult(uiController, renderCheck, true) + + assertThat(renderCheck.invoke(), `is`(true)) mapboxMap.setStyleUrl(Style.LIGHT) uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) @@ -258,7 +267,7 @@ class LocationLayerControllerTest : BaseActivityTest() { fun whenStyleChanged_staleStateChanges() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) component.isLocationComponentEnabled = true component.applyStyle(LocationComponentOptions.builder(context).staleStateTimeout(1).build()) @@ -278,7 +287,7 @@ class LocationLayerControllerTest : BaseActivityTest() { fun whenStyleChanged_layerVisibilityUpdates() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { styleChangeIdlingResource.waitForStyle((rule.activity as SingleActivity).mapView, mapboxMap, MAPBOX_HEAVY_STYLE) var show = true component.activateLocationComponent(context, false) @@ -300,7 +309,7 @@ class LocationLayerControllerTest : BaseActivityTest() { fun accuracy_visibleWithNewLocation() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) component.isLocationComponentEnabled = true mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(location), 16.0)) @@ -320,17 +329,31 @@ class LocationLayerControllerTest : BaseActivityTest() { fun accuracy_visibleWhenCameraEased() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) component.isLocationComponentEnabled = true component.forceLocationUpdate(location) mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - mapboxMap.easeCamera(CameraUpdateFactory.newLatLngZoom(LatLng(location), 16.0), 300) - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY + 300) - assertEquals(Utils.calculateZoomLevelRadius(mapboxMap, location) /*meters projected to radius on zoom 16*/, - mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0] - .getNumberProperty(PROPERTY_ACCURACY_RADIUS).toFloat(), 0.1f) + val target = LatLng(location) + val zoom = 16.0 + mapboxMap.easeCamera(CameraUpdateFactory.newLatLngZoom(target, zoom), 300) + uiController.loopMainThreadForAtLeast(300) + + val cameraCheck = { + Math.abs(zoom - mapboxMap.cameraPosition.zoom) < 0.1 + && Math.abs(target.latitude - mapboxMap.cameraPosition.target.latitude) < 0.1 + && Math.abs(target.longitude - mapboxMap.cameraPosition.target.longitude) < 0.1 + } + waitForRenderResult(uiController, cameraCheck, true) + + val expectedRadius = Utils.calculateZoomLevelRadius(mapboxMap, location) /*meters projected to radius on zoom 16*/ + val renderCheck = { + Math.abs(expectedRadius - mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getNumberProperty(PROPERTY_ACCURACY_RADIUS).toFloat()) < 0.1 + } + waitForRenderResult(uiController, renderCheck, true) + + assertThat(renderCheck.invoke(), `is`(true)) } } executeComponentTest(componentAction) @@ -340,18 +363,30 @@ class LocationLayerControllerTest : BaseActivityTest() { fun accuracy_visibleWhenCameraMoved() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, - uiController: UiController, context: Context) { + uiController: UiController, context: Context) { component.activateLocationComponent(context, false) component.isLocationComponentEnabled = true - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) component.forceLocationUpdate(location) - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) - mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(location), 16.0)) - uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY + 300) + mapboxMap.waitForLayer(uiController, location, FOREGROUND_LAYER) - assertEquals(Utils.calculateZoomLevelRadius(mapboxMap, location) /*meters projected to radius on zoom 16*/, - mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0] - .getNumberProperty(PROPERTY_ACCURACY_RADIUS).toFloat(), 0.1f) + val target = LatLng(location) + val zoom = 16.0 + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(target, zoom)) + + val cameraCheck = { + Math.abs(zoom - mapboxMap.cameraPosition.zoom) < 0.1 + && Math.abs(target.latitude - mapboxMap.cameraPosition.target.latitude) < 0.1 + && Math.abs(target.longitude - mapboxMap.cameraPosition.target.longitude) < 0.1 + } + waitForRenderResult(uiController, cameraCheck, true) + + val expectedRadius = Utils.calculateZoomLevelRadius(mapboxMap, location) /*meters projected to radius on zoom 16*/ + val renderCheck = { + Math.abs(expectedRadius - mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getNumberProperty(PROPERTY_ACCURACY_RADIUS).toFloat()) < 0.1 + } + waitForRenderResult(uiController, renderCheck, true) + + assertThat(renderCheck.invoke(), `is`(true)) } } executeComponentTest(componentAction) diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/utils/MapboxTestingUtils.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/utils/MapboxTestingUtils.kt index 591901385f..7d362a6f76 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/utils/MapboxTestingUtils.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/utils/MapboxTestingUtils.kt @@ -48,13 +48,21 @@ fun MapboxMap.waitForLayer(uiController: UiController, location: Location, layer } } +inline fun waitForRenderResult(uiController: UiController, checkFunction: () -> Boolean, expectedResult: Boolean) { + var counter = 0 + val delay = MapboxTestingUtils.MAP_RENDER_DELAY + while (checkFunction.invoke() != expectedResult && delay * counter < MapboxTestingUtils.RENDER_TIMEOUT) { + uiController.loopMainThreadForAtLeast(delay) + counter++ + } +} class MapboxTestingUtils { companion object { const val MAP_RENDER_DELAY = 250L const val MAP_CONNECTION_DELAY = 1000L - const val RENDER_TIMEOUT = 3_000L + const val RENDER_TIMEOUT = 2_500L /** * Used to increase style load time for stress testing. -- cgit v1.2.1