[android] adapt LocationLayerPlugin's test suite
This commit is contained in:
committed by
Łukasz Paczos
parent
cb771f6aca
commit
465316b4ce
@@ -346,10 +346,6 @@ final class LocationLayer implements PluginAnimator.OnLayerAnimationsValuesChang
|
||||
}
|
||||
|
||||
void setLocationsStale(boolean isStale) {
|
||||
// If options has stale state disabled, just return here.
|
||||
if (!options.enableStaleState()) {
|
||||
return;
|
||||
}
|
||||
locationFeature.addBooleanProperty(PROPERTY_LOCATION_STALE, isStale);
|
||||
refreshSource();
|
||||
if (renderMode != RenderMode.GPS) {
|
||||
|
||||
@@ -114,7 +114,9 @@ public final class LocationLayerPlugin {
|
||||
= new CopyOnWriteArrayList<>();
|
||||
|
||||
/**
|
||||
* Construct a LocationLayerPlugin
|
||||
* Construct a LocationLayerPlugin. In order to display location,
|
||||
* the location layer has to be activated with {@link LocationLayerPlugin#activateLocationLayerPlugin(Context)},
|
||||
* or one of the overloads.
|
||||
*
|
||||
* @param mapboxMap the MapboxMap to apply the LocationLayerPlugin with
|
||||
*/
|
||||
@@ -151,6 +153,22 @@ public final class LocationLayerPlugin {
|
||||
.mapbox_LocationLayer));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will show the location icon and enable the camera tracking the location.
|
||||
* <p>
|
||||
* <strong>Note</strong>: This constructor will initialize and use an internal {@link LocationEngine}.
|
||||
*
|
||||
* @param context the context
|
||||
*/
|
||||
@RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
|
||||
public void activateLocationLayerPlugin(@NonNull Context context, boolean useDefaultLocationEngine) {
|
||||
if (useDefaultLocationEngine) {
|
||||
activateLocationLayerPlugin(context, R.style.mapbox_LocationLayer);
|
||||
} else {
|
||||
activateLocationLayerPlugin(context, null, R.style.mapbox_LocationLayer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will show the location icon and enable the camera tracking the location.
|
||||
* <p>
|
||||
@@ -312,9 +330,7 @@ public final class LocationLayerPlugin {
|
||||
public void applyStyle(LocationLayerOptions options) {
|
||||
this.options = options;
|
||||
locationLayer.applyStyle(options);
|
||||
if (!options.enableStaleState()) {
|
||||
staleStateManager.onStop();
|
||||
}
|
||||
staleStateManager.setEnabled(options.enableStaleState());
|
||||
staleStateManager.setDelayTime(options.staleStateTimeout());
|
||||
updateMapWithOptions(options);
|
||||
}
|
||||
@@ -740,7 +756,7 @@ public final class LocationLayerPlugin {
|
||||
SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
|
||||
compassEngine = new LocationLayerCompassEngine(windowManager, sensorManager);
|
||||
compassEngine.addCompassListener(compassListener);
|
||||
staleStateManager = new StaleStateManager(onLocationStaleListener, options.staleStateTimeout());
|
||||
staleStateManager = new StaleStateManager(onLocationStaleListener, options);
|
||||
|
||||
updateMapWithOptions(options);
|
||||
|
||||
|
||||
@@ -10,35 +10,42 @@ import android.os.Handler;
|
||||
*/
|
||||
class StaleStateManager {
|
||||
|
||||
private boolean isEnabled;
|
||||
private final OnLocationStaleListener innerOnLocationStaleListeners;
|
||||
private final Handler handler;
|
||||
private boolean isStale = true;
|
||||
private long delayTime;
|
||||
|
||||
StaleStateManager(OnLocationStaleListener innerListener, long delayTime) {
|
||||
StaleStateManager(OnLocationStaleListener innerListener, LocationLayerOptions options) {
|
||||
innerOnLocationStaleListeners = innerListener;
|
||||
this.delayTime = delayTime;
|
||||
handler = new Handler();
|
||||
innerOnLocationStaleListeners.onStaleStateChange(true);
|
||||
isEnabled = options.enableStaleState();
|
||||
delayTime = options.staleStateTimeout();
|
||||
}
|
||||
|
||||
private Runnable staleStateRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
isStale = true;
|
||||
innerOnLocationStaleListeners.onStaleStateChange(true);
|
||||
setState(true);
|
||||
}
|
||||
};
|
||||
|
||||
void setEnabled(boolean enabled) {
|
||||
if (enabled) {
|
||||
setState(isStale);
|
||||
} else if (isEnabled) {
|
||||
onStop();
|
||||
innerOnLocationStaleListeners.onStaleStateChange(false);
|
||||
}
|
||||
isEnabled = enabled;
|
||||
}
|
||||
|
||||
boolean isStale() {
|
||||
return isStale;
|
||||
}
|
||||
|
||||
void updateLatestLocationTime() {
|
||||
if (isStale) {
|
||||
isStale = false;
|
||||
innerOnLocationStaleListeners.onStaleStateChange(false);
|
||||
}
|
||||
setState(false);
|
||||
postTheCallback();
|
||||
}
|
||||
|
||||
@@ -61,4 +68,13 @@ class StaleStateManager {
|
||||
handler.removeCallbacksAndMessages(null);
|
||||
handler.postDelayed(staleStateRunnable, delayTime);
|
||||
}
|
||||
|
||||
private void setState(boolean stale) {
|
||||
if (stale != isStale) {
|
||||
isStale = stale;
|
||||
if (isEnabled) {
|
||||
innerOnLocationStaleListeners.onStaleStateChange(stale);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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<LocationLayerPlugin> {
|
||||
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<LocationLayerPlugin> {
|
||||
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<LocationLayerPlugin> {
|
||||
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<LocationLayerPlugin> {
|
||||
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<LocationLayerPlugin> {
|
||||
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<LocationLayerPlugin> {
|
||||
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<LocationLayerPlugin> {
|
||||
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<LocationLayerPlugin> {
|
||||
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<LocationLayerPlugin> {
|
||||
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<LocationLayerPlugin> {
|
||||
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<LocationLayerPlugin> {
|
||||
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<LocationLayerPlugin> {
|
||||
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<LocationLayerPlugin> {
|
||||
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<LocationLayerPlugin>) {
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<T>(private val mapView: MapView, private val mapboxMap: MapboxMap, private val pluginProvider: PluginProvider<T>,
|
||||
private val onPerformGenericPluginAction: OnPerformGenericPluginAction<T>) : ViewAction {
|
||||
|
||||
override fun getConstraints(): Matcher<View> {
|
||||
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<in T> {
|
||||
fun onGenericPluginAction(plugin: T, mapboxMap: MapboxMap, uiController: UiController, context: Context)
|
||||
}
|
||||
|
||||
interface PluginProvider<T> {
|
||||
fun providePlugin(mapView: MapView, mapboxMap: MapboxMap, context: Context): T
|
||||
fun isPluginDataReady(plugin: T, mapboxMap: MapboxMap): Boolean
|
||||
}
|
||||
}
|
||||
@@ -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<View> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
@@ -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<Feature> {
|
||||
return this.getSourceAs<GeoJsonSource>(sourceId)?.querySourceFeatures(null) as List<Feature>
|
||||
return this.getSourceAs<GeoJsonSource>(sourceId)?.querySourceFeatures(null) ?: emptyList()
|
||||
}
|
||||
|
||||
fun MapboxMap.queryRenderedFeatures(location: Location, layerId: String): List<Feature> {
|
||||
@@ -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)
|
||||
|
||||
@@ -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<LocationLayerPlugin> {
|
||||
return object : GenericPluginAction.PluginProvider<LocationLayerPlugin> {
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Activity> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,10 @@ public class SingleActivity extends AppCompatActivity {
|
||||
mapView.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
public MapView getMapView() {
|
||||
return mapView;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
|
||||
@@ -8,6 +8,6 @@
|
||||
android:id="@+id/mapView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:mapbox_cameraZoom="2.0" />
|
||||
app:mapbox_cameraZoomMin="2.0" />
|
||||
|
||||
</RelativeLayout>
|
||||
Reference in New Issue
Block a user