diff options
author | tobrun <tobrun.van.nuland@gmail.com> | 2019-11-01 10:13:22 +0100 |
---|---|---|
committer | tobrun <tobrun.van.nuland@gmail.com> | 2019-11-01 10:13:22 +0100 |
commit | 5825afac23d5cfbab3127cf5bdd09f2e815de5f4 (patch) | |
tree | 314ca31ef9a4278e0798b3de9115db2892bd8dac /platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox | |
parent | c94184c04742e935853a2e6b26d7fe1aa94c3250 (diff) | |
download | qtlocation-mapboxgl-upstream/tvn-test-ci.tar.gz |
Diffstat (limited to 'platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox')
43 files changed, 9183 insertions, 0 deletions
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/BaseLayerTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/BaseLayerTest.kt new file mode 100644 index 0000000000..27c040fbb6 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/BaseLayerTest.kt @@ -0,0 +1,27 @@ +package com.mapbox.mapboxsdk.maps + +import android.support.test.InstrumentationRegistry +import android.support.test.runner.AndroidJUnit4 +import com.mapbox.mapboxsdk.AppCenter +import com.mapbox.mapboxsdk.style.layers.Layer +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +abstract class BaseLayerTest : AppCenter() { + private lateinit var nativeMapView: NativeMap + + companion object { + const val WIDTH = 500 + const val HEIGHT = WIDTH + } + + fun before() { + val context = InstrumentationRegistry.getContext() + nativeMapView = NativeMapView(context, false, null, null, NativeMapViewTest.DummyRenderer(context)) + nativeMapView.resizeView(WIDTH, HEIGHT) + } + + fun setupLayer(layer: Layer) { + nativeMapView.addLayer(layer) + } +}
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/GesturesUiTestUtils.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/GesturesUiTestUtils.kt new file mode 100644 index 0000000000..f3af386457 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/GesturesUiTestUtils.kt @@ -0,0 +1,516 @@ +package com.mapbox.mapboxsdk.maps + +import android.graphics.PointF +import android.os.SystemClock +import android.support.test.espresso.Espresso +import android.support.test.espresso.InjectEventSecurityException +import android.support.test.espresso.UiController +import android.support.test.espresso.ViewAction +import android.support.test.espresso.matcher.ViewMatchers +import android.view.MotionEvent +import android.view.View +import org.hamcrest.Matcher + +object GesturesUiTestUtils { + + private const val DEFAULT_GESTURE_DURATION = 500L + + fun pinch( + startSpan: Float, + endSpan: Float, + center: PointF? = null, + duration: Long = DEFAULT_GESTURE_DURATION + ): ViewAction { + return object : ViewAction { + override fun getConstraints(): Matcher<View> { + return ViewMatchers.isEnabled() + } + + override fun getDescription(): String = "Pinch $startSpan -> $endSpan" + + override fun perform(uiController: UiController, view: View) { + var middlePosition = center + if (middlePosition == null) { + middlePosition = getCenterPointF(view) + } + + val startPoint1 = PointF(middlePosition.x - startSpan / 2f, middlePosition.y) + val startPoint2 = PointF(middlePosition.x + startSpan / 2f, middlePosition.y) + val endPoint1 = PointF(middlePosition.x - endSpan / 2f, middlePosition.y) + val endPoint2 = PointF(middlePosition.x + endSpan / 2f, middlePosition.y) + + performPinch(uiController, startPoint1, startPoint2, endPoint1, endPoint2, duration) + } + } + } + + fun quickScale( + deltaY: Float, + startPoint: PointF? = null, + withVelocity: Boolean = true, + duration: Long = DEFAULT_GESTURE_DURATION, + interrupt: Boolean = false + ): ViewAction { + return object : ViewAction { + override fun getConstraints(): Matcher<View> = ViewMatchers.isEnabled() + + override fun getDescription(): String = "quick scale ${deltaY}Y" + + override fun perform(uiController: UiController, view: View) { + var middlePosition = startPoint + if (middlePosition == null) { + middlePosition = getCenterPointF(view) + } + + val endPoint = PointF(middlePosition.x, middlePosition.y + deltaY) + + performQuickScale(uiController, middlePosition, endPoint, withVelocity, duration, interrupt) + } + } + } + + fun move( + deltaX: Float, + deltaY: Float, + startPoint: PointF? = null, + withVelocity: Boolean = true, + duration: Long = DEFAULT_GESTURE_DURATION + ): ViewAction { + return object : ViewAction { + override fun getConstraints(): Matcher<View> = ViewMatchers.isEnabled() + + override fun getDescription(): String = "move ${deltaX}X, ${deltaY}Y" + + override fun perform(uiController: UiController, view: View) { + var middlePosition = startPoint + if (middlePosition == null) { + middlePosition = getCenterPointF(view) + } + + val endPoint = PointF(middlePosition.x + deltaX, middlePosition.y + deltaY) + + performMove(uiController, middlePosition, endPoint, withVelocity, duration) + } + } + } + + private fun getCenterPointF(view: View): PointF { + val locationOnScreen = IntArray(2) + view.getLocationOnScreen(locationOnScreen) + val viewHeight = view.height * view.scaleY + val viewWidth = view.width * view.scaleX + return PointF( + (locationOnScreen[0] + viewWidth / 2).toInt().toFloat(), + (locationOnScreen[1] + viewHeight / 2).toInt().toFloat() + ) + } + + // https://stackoverflow.com/a/46443628/9126211 + private fun performPinch( + uiController: UiController, + startPoint1: PointF, + startPoint2: PointF, + endPoint1: PointF, + endPoint2: PointF, + duration: Long + ) { + val eventMinInterval: Long = 10 + val startTime = SystemClock.uptimeMillis() + var eventTime = startTime + var event: MotionEvent + var eventX1: Float = startPoint1.x + var eventY1: Float = startPoint1.y + var eventX2: Float = startPoint2.x + var eventY2: Float = startPoint2.y + + // Specify the property for the two touch points + val properties = arrayOfNulls<MotionEvent.PointerProperties>(2) + val pp1 = MotionEvent.PointerProperties() + pp1.id = 0 + pp1.toolType = MotionEvent.TOOL_TYPE_FINGER + val pp2 = MotionEvent.PointerProperties() + pp2.id = 1 + pp2.toolType = MotionEvent.TOOL_TYPE_FINGER + + properties[0] = pp1 + properties[1] = pp2 + + // Specify the coordinations of the two touch points + // NOTE: you MUST set the pressure and size value, or it doesn't work + val pointerCoords = arrayOfNulls<MotionEvent.PointerCoords>(2) + val pc1 = MotionEvent.PointerCoords() + pc1.x = eventX1 + pc1.y = eventY1 + pc1.pressure = 1f + pc1.size = 1f + val pc2 = MotionEvent.PointerCoords() + pc2.x = eventX2 + pc2.y = eventY2 + pc2.pressure = 1f + pc2.size = 1f + pointerCoords[0] = pc1 + pointerCoords[1] = pc2 + + /* + * Events sequence of zoom gesture: + * + * 1. Send ACTION_DOWN event of one start point + * 2. Send ACTION_POINTER_DOWN of two start points + * 3. Send ACTION_MOVE of two middle points + * 4. Repeat step 3 with updated middle points (x,y), until reach the end points + * 5. Send ACTION_POINTER_UP of two end points + * 6. Send ACTION_UP of one end point + */ + + try { + // Step 1 + event = MotionEvent.obtain( + startTime, eventTime, + MotionEvent.ACTION_DOWN, 1, properties, + pointerCoords, 0, 0, 1f, 1f, 0, 0, 0, 0 + ) + injectMotionEventToUiController(uiController, event) + + // Step 2 + event = MotionEvent.obtain( + startTime, eventTime, + MotionEvent.ACTION_POINTER_DOWN + (pp2.id shl MotionEvent.ACTION_POINTER_INDEX_SHIFT), 2, + properties, pointerCoords, 0, 0, 1f, 1f, 0, 0, 0, 0 + ) + injectMotionEventToUiController(uiController, event) + + // Step 3, 4 + val moveEventNumber = duration / eventMinInterval + + val stepX1: Float + val stepY1: Float + val stepX2: Float + val stepY2: Float + + stepX1 = (endPoint1.x - startPoint1.x) / moveEventNumber + stepY1 = (endPoint1.y - startPoint1.y) / moveEventNumber + stepX2 = (endPoint2.x - startPoint2.x) / moveEventNumber + stepY2 = (endPoint2.y - startPoint2.y) / moveEventNumber + + for (i in 0 until moveEventNumber) { + // Update the move events + eventTime += eventMinInterval + eventX1 += stepX1 + eventY1 += stepY1 + eventX2 += stepX2 + eventY2 += stepY2 + + pc1.x = eventX1 + pc1.y = eventY1 + pc2.x = eventX2 + pc2.y = eventY2 + + pointerCoords[0] = pc1 + pointerCoords[1] = pc2 + + event = MotionEvent.obtain( + startTime, eventTime, + MotionEvent.ACTION_MOVE, 2, properties, + pointerCoords, 0, 0, 1f, 1f, 0, 0, 0, 0 + ) + injectMotionEventToUiController(uiController, event) + } + + // Step 5 + pc1.x = endPoint1.x + pc1.y = endPoint1.y + pc2.x = endPoint2.x + pc2.y = endPoint2.y + pointerCoords[0] = pc1 + pointerCoords[1] = pc2 + + eventTime += eventMinInterval + event = MotionEvent.obtain( + startTime, eventTime, + MotionEvent.ACTION_POINTER_UP + (pp2.id shl MotionEvent.ACTION_POINTER_INDEX_SHIFT), 2, properties, + pointerCoords, 0, 0, 1f, 1f, 0, 0, 0, 0 + ) + injectMotionEventToUiController(uiController, event) + + // Step 6 + eventTime += eventMinInterval + event = MotionEvent.obtain( + startTime, eventTime, + MotionEvent.ACTION_UP, 1, properties, + pointerCoords, 0, 0, 1f, 1f, 0, 0, 0, 0 + ) + injectMotionEventToUiController(uiController, event) + } catch (ex: InjectEventSecurityException) { + throw RuntimeException("Could not perform pinch", ex) + } + } + + private fun performQuickScale( + uiController: UiController, + startPoint: PointF, + endPoint: PointF, + withVelocity: Boolean, + duration: Long, + interrupt: Boolean + ) { + val eventMinInterval: Long = 10 + val tapDownMinInterval: Long = 40 // ViewConfiguration#DOUBLE_TAP_MIN_TIME = 40 + val startTime = SystemClock.uptimeMillis() + var eventTime = startTime + var event: MotionEvent + var eventX1: Float = startPoint.x + var eventY1: Float = startPoint.y + + var properties = arrayOfNulls<MotionEvent.PointerProperties>(1) + val pp1 = MotionEvent.PointerProperties() + pp1.id = 0 + pp1.toolType = MotionEvent.TOOL_TYPE_FINGER + properties[0] = pp1 + + var pointerCoords = arrayOfNulls<MotionEvent.PointerCoords>(1) + val pc1 = MotionEvent.PointerCoords() + pc1.x = eventX1 + pc1.y = eventY1 + pc1.pressure = 1f + pc1.size = 1f + pointerCoords[0] = pc1 + + /* + * Events sequence of quick scale gesture: + * + * 1. Send ACTION_DOWN + * 2. Send ACTION_UP + * 3. Send ACTION_DOWN + * 4. Send ACTION_MOVE with updated middle points (x,y), until reach the end points + * 5. Send ACTION_UP of one end point + */ + try { + // Step 1 + event = MotionEvent.obtain( + startTime, eventTime, + MotionEvent.ACTION_DOWN, 1, properties, + pointerCoords, 0, 0, 1f, 1f, 0, 0, 0, 0 + ) + injectMotionEventToUiController(uiController, event) + + // Step 2 + eventTime += eventMinInterval + event = MotionEvent.obtain( + startTime, eventTime, + MotionEvent.ACTION_UP, 1, properties, + pointerCoords, 0, 0, 1f, 1f, 0, 0, 0, 0 + ) + injectMotionEventToUiController(uiController, event) + + // Step 3 + eventTime += tapDownMinInterval + event = MotionEvent.obtain( + startTime, eventTime, + MotionEvent.ACTION_DOWN, 1, properties, + pointerCoords, 0, 0, 1f, 1f, 0, 0, 0, 0 + ) + injectMotionEventToUiController(uiController, event) + + // Step 4 + val moveEventNumber = duration / eventMinInterval + + val stepX1: Float + val stepY1: Float + + stepX1 = (endPoint.x - startPoint.x) / moveEventNumber + stepY1 = (endPoint.y - startPoint.y) / moveEventNumber + + var interrupted = false + + for (i in 0 until moveEventNumber) { + // Update the move events + eventTime += eventMinInterval + eventX1 += stepX1 + eventY1 += stepY1 + + pc1.x = eventX1 + pc1.y = eventY1 + + pointerCoords[0] = pc1 + + event = MotionEvent.obtain( + startTime, eventTime, + MotionEvent.ACTION_MOVE, if (interrupted) 2 else 1, properties, + pointerCoords, 0, 0, 1f, 1f, 0, 0, 0, 0 + ) + injectMotionEventToUiController(uiController, event) + + if (interrupt && i == moveEventNumber / 2) { + // Specify the property for the two touch points + properties = arrayOfNulls<MotionEvent.PointerProperties>(2) + val pp2 = MotionEvent.PointerProperties() + pp2.id = 1 + pp2.toolType = MotionEvent.TOOL_TYPE_FINGER + + properties[0] = pp1 + properties[1] = pp2 + + // Specify the coordinations of the two touch points + // NOTE: you MUST set the pressure and size value, or it doesn't work + pointerCoords = arrayOfNulls<MotionEvent.PointerCoords>(2) + val pc2 = MotionEvent.PointerCoords() + pc2.x = startPoint.x + pc2.y = startPoint.y + pc2.pressure = 1f + pc2.size = 1f + pointerCoords[0] = pc1 + pointerCoords[1] = pc2 + + eventTime += eventMinInterval + event = MotionEvent.obtain( + startTime, eventTime, + MotionEvent.ACTION_POINTER_DOWN + (pp2.id shl MotionEvent.ACTION_POINTER_INDEX_SHIFT), 2, + properties, pointerCoords, 0, 0, 1f, 1f, 0, 0, 0, 0 + ) + injectMotionEventToUiController(uiController, event) + interrupted = true + } + } + + if (!withVelocity) { + eventTime += eventMinInterval + event = MotionEvent.obtain( + startTime, eventTime, + MotionEvent.ACTION_MOVE, 1, properties, + pointerCoords, 0, 0, 1f, 1f, 0, 0, 0, 0 + ) + injectMotionEventToUiController(uiController, event) + } + + // Step 5 + eventTime += eventMinInterval + event = MotionEvent.obtain( + startTime, eventTime, + MotionEvent.ACTION_UP, 1, properties, + pointerCoords, 0, 0, 1f, 1f, 0, 0, 0, 0 + ) + injectMotionEventToUiController(uiController, event) + } catch (ex: InjectEventSecurityException) { + throw RuntimeException("Could not perform quick scale", ex) + } + } + + private fun performMove( + uiController: UiController, + startPoint: PointF, + endPoint: PointF, + withVelocity: Boolean, + duration: Long + ) { + val eventMinInterval: Long = 10 + val startTime = SystemClock.uptimeMillis() + var eventTime = startTime + var event: MotionEvent + var eventX1: Float = startPoint.x + var eventY1: Float = startPoint.y + + val properties = arrayOfNulls<MotionEvent.PointerProperties>(1) + val pp1 = MotionEvent.PointerProperties() + pp1.id = 0 + pp1.toolType = MotionEvent.TOOL_TYPE_FINGER + properties[0] = pp1 + + val pointerCoords = arrayOfNulls<MotionEvent.PointerCoords>(1) + val pc1 = MotionEvent.PointerCoords() + pc1.x = eventX1 + pc1.y = eventY1 + pc1.pressure = 1f + pc1.size = 1f + pointerCoords[0] = pc1 + + /* + * Events sequence of move gesture: + * + * 1. Send ACTION_DOWN + * 2. Send ACTION_MOVE with updated middle points (x,y), until reach the end points + * 3. Send ACTION_UP + */ + try { + // Step 1 + event = MotionEvent.obtain( + startTime, eventTime, + MotionEvent.ACTION_DOWN, 1, properties, + pointerCoords, 0, 0, 1f, 1f, 0, 0, 0, 0 + ) + injectMotionEventToUiController(uiController, event) + + // Step 2 + val moveEventNumber = duration / eventMinInterval + + val stepX1: Float + val stepY1: Float + + stepX1 = (endPoint.x - startPoint.x) / moveEventNumber + stepY1 = (endPoint.y - startPoint.y) / moveEventNumber + + for (i in 0 until moveEventNumber) { + // Update the move events + eventTime += eventMinInterval + eventX1 += stepX1 + eventY1 += stepY1 + + pc1.x = eventX1 + pc1.y = eventY1 + + pointerCoords[0] = pc1 + + event = MotionEvent.obtain( + startTime, eventTime, + MotionEvent.ACTION_MOVE, 1, properties, + pointerCoords, 0, 0, 1f, 1f, 0, 0, 0, 0 + ) + injectMotionEventToUiController(uiController, event) + } + + if (!withVelocity) { + eventTime += eventMinInterval + event = MotionEvent.obtain( + startTime, eventTime, + MotionEvent.ACTION_MOVE, 1, properties, + pointerCoords, 0, 0, 1f, 1f, 0, 0, 0, 0 + ) + injectMotionEventToUiController(uiController, event) + } + + // Step 3 + eventTime += eventMinInterval + event = MotionEvent.obtain( + startTime, eventTime, + MotionEvent.ACTION_UP, 1, properties, + pointerCoords, 0, 0, 1f, 1f, 0, 0, 0, 0 + ) + injectMotionEventToUiController(uiController, event) + } catch (ex: InjectEventSecurityException) { + throw RuntimeException("Could not perform quick scale", ex) + } + } + + /** + * Safely call uiController.injectMotionEvent(event): Detect any error and "convert" it to an + * IllegalStateException + */ + @Throws(InjectEventSecurityException::class) + private fun injectMotionEventToUiController(uiController: UiController, event: MotionEvent) { + val injectEventSucceeded = uiController.injectMotionEvent(event) + if (!injectEventSucceeded) { + throw IllegalStateException("Error performing event $event") + } + } +} + +fun Int.loopFor(millis: Long) { + Espresso.onView(ViewMatchers.withId(this)).perform(object : ViewAction { + override fun getDescription(): String = "waiting for $millis" + + override fun getConstraints(): Matcher<View> = ViewMatchers.isEnabled() + + override fun perform(uiController: UiController?, view: View?) { + uiController?.loopMainThreadForAtLeast(millis) + } + }) +}
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/IconManagerResolver.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/IconManagerResolver.java new file mode 100644 index 0000000000..3e226a7ec5 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/IconManagerResolver.java @@ -0,0 +1,42 @@ +package com.mapbox.mapboxsdk.maps; + +import com.mapbox.mapboxsdk.annotations.Icon; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; + +import timber.log.Timber; + +public class IconManagerResolver { + + private IconManager iconManager; + + public IconManagerResolver(MapboxMap mapboxMap) { + try { + Field annotationManagerField = MapboxMap.class.getDeclaredField("annotationManager"); + annotationManagerField.setAccessible(true); + AnnotationManager annotationManager = (AnnotationManager) annotationManagerField.get(mapboxMap); + + Field iconManagerField = AnnotationManager.class.getDeclaredField("iconManager"); + iconManagerField.setAccessible(true); + iconManager = (IconManager) iconManagerField.get(annotationManager); + } catch (Exception exception) { + Timber.e(exception, "Could not create IconManagerResolver, unable to reflect."); + } + } + + @SuppressWarnings("unchecked") + public Map<Icon, Integer> getIconMap() { + try { + Field field = IconManager.class.getDeclaredField("iconMap"); + field.setAccessible(true); + return (Map<Icon, Integer>) field.get(iconManager); + } catch (NoSuchFieldException exception) { + Timber.e(exception, "Could not getIconMap, unable to reflect."); + } catch (IllegalAccessException exception) { + Timber.e(exception, "Could not getIconMap, unable to reflect."); + } + return new HashMap<>(); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapGestureDetectorTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapGestureDetectorTest.kt new file mode 100644 index 0000000000..525c576df4 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapGestureDetectorTest.kt @@ -0,0 +1,193 @@ +package com.mapbox.mapboxsdk.maps + +import android.support.test.espresso.Espresso.onView +import android.support.test.espresso.matcher.ViewMatchers.withId +import com.mapbox.mapboxsdk.camera.CameraPosition +import com.mapbox.mapboxsdk.camera.CameraUpdateFactory +import com.mapbox.mapboxsdk.constants.MapboxConstants +import com.mapbox.mapboxsdk.geometry.LatLng +import com.mapbox.mapboxsdk.maps.GesturesUiTestUtils.move +import com.mapbox.mapboxsdk.maps.GesturesUiTestUtils.quickScale +import com.mapbox.mapboxsdk.testapp.R +import com.mapbox.mapboxsdk.testapp.activity.BaseTest +import com.mapbox.mapboxsdk.testapp.activity.maplayout.SimpleMapActivity +import org.junit.Assert +import org.junit.Before +import org.junit.Test + +class MapGestureDetectorTest : BaseTest() { + override fun getActivityClass() = SimpleMapActivity::class.java + + private var maxWidth: Int = 0 + private var maxHeight: Int = 0 + + @Before + fun setup() { + maxWidth = mapView.width + maxHeight = mapView.height + } + + @Test + fun sanity_quickZoom() { + validateTestSetup() + var initialZoom: Double? = null + rule.runOnUiThread { + initialZoom = mapboxMap.cameraPosition.zoom + } + onView(withId(R.id.mapView)).perform(quickScale(maxHeight / 2f, withVelocity = false)) + rule.runOnUiThread { + Assert.assertTrue(mapboxMap.cameraPosition.zoom > initialZoom!!) + } + } + + @Test + fun quickZoomDisabled_phantomQuickZoom_moveStillEnabled_15091() { + // regression test for https://github.com/mapbox/mapbox-gl-native/issues/15091 + validateTestSetup() + var initialCameraPosition: CameraPosition? = null + rule.runOnUiThread { + // zoom in so we can move vertically + mapboxMap.moveCamera(CameraUpdateFactory.zoomTo(4.0)) + initialCameraPosition = mapboxMap.cameraPosition + mapboxMap.uiSettings.isQuickZoomGesturesEnabled = false + } + + onView(withId(R.id.mapView)).perform(quickScale(maxHeight / 2f)) + rule.runOnUiThread { + // camera did not move + Assert.assertEquals(initialCameraPosition!!, mapboxMap.cameraPosition) + } + + // move to expected target + onView(withId(R.id.mapView)).perform(move(-maxWidth / 2f, -maxHeight / 2f, withVelocity = false)) + rule.runOnUiThread { + Assert.assertNotEquals(initialCameraPosition!!.target.latitude, mapboxMap.cameraPosition.target.latitude, 1.0) + Assert.assertNotEquals(initialCameraPosition!!.target.longitude, mapboxMap.cameraPosition.target.longitude, 1.0) + } + } + + @Test + fun quickZoom_doNotMove_14227() { + // test for https://github.com/mapbox/mapbox-gl-native/issues/14227 + validateTestSetup() + var initialTarget: LatLng? = null + rule.runOnUiThread { + initialTarget = mapboxMap.cameraPosition.target + } + + onView(withId(R.id.mapView)).perform(quickScale(maxHeight / 2f)) + rule.runOnUiThread { + // camera did not move + Assert.assertEquals(initialTarget!!.latitude, mapboxMap.cameraPosition.target.latitude, 1.0) + Assert.assertEquals(initialTarget!!.longitude, mapboxMap.cameraPosition.target.longitude, 1.0) + } + } + + @Test + fun quickZoom_interrupted_moveStillEnabled_14598() { + // test for https://github.com/mapbox/mapbox-gl-native/issues/14598 + validateTestSetup() + onView(withId(R.id.mapView)).perform(quickScale(maxHeight / 2f, interrupt = true)) + + var initialCameraPosition: CameraPosition? = null + rule.runOnUiThread { + // zoom in so we can move vertically + mapboxMap.moveCamera(CameraUpdateFactory.zoomTo(4.0)) + initialCameraPosition = mapboxMap.cameraPosition + mapboxMap.uiSettings.isQuickZoomGesturesEnabled = false + } + + // move to expected target + onView(withId(R.id.mapView)).perform(move(-maxWidth / 2f, -maxHeight / 2f, withVelocity = false)) + rule.runOnUiThread { + Assert.assertNotEquals(initialCameraPosition!!.target.latitude, mapboxMap.cameraPosition.target.latitude, 1.0) + Assert.assertNotEquals(initialCameraPosition!!.target.longitude, mapboxMap.cameraPosition.target.longitude, 1.0) + } + } + + @Test + fun quickZoom_ignoreDoubleTap() { + // test for https://github.com/mapbox/mapbox-gl-native/issues/14013 + validateTestSetup() + var initialZoom: Double? = null + rule.runOnUiThread { + mapboxMap.moveCamera(CameraUpdateFactory.zoomTo(2.0)) + initialZoom = mapboxMap.cameraPosition.zoom + } + onView(withId(R.id.mapView)).perform(quickScale(-(mapboxMap.gesturesManager.standardScaleGestureDetector.spanSinceStartThreshold * 2), withVelocity = false, duration = 1000L)) + R.id.mapView.loopFor(MapboxConstants.ANIMATION_DURATION.toLong()) + rule.runOnUiThread { + Assert.assertTrue(mapboxMap.cameraPosition.zoom < initialZoom!!) + } + } + + @Test + fun doubleTap_minimalMovement() { + validateTestSetup() + var initialZoom: Double? = null + rule.runOnUiThread { + initialZoom = mapboxMap.cameraPosition.zoom + } + onView(withId(R.id.mapView)).perform(quickScale(mapboxMap.gesturesManager.standardScaleGestureDetector.spanSinceStartThreshold / 2, withVelocity = false, duration = 50L)) + R.id.mapView.loopFor(MapboxConstants.ANIMATION_DURATION.toLong()) + rule.runOnUiThread { + Assert.assertEquals(initialZoom!! + 1, mapboxMap.cameraPosition.zoom, 0.1) + } + } + + @Test + fun doubleTap_overMaxThreshold_ignore_14013() { + // test for https://github.com/mapbox/mapbox-gl-native/issues/14013 + validateTestSetup() + var initialZoom: Double? = null + rule.runOnUiThread { + initialZoom = mapboxMap.cameraPosition.zoom + mapboxMap.uiSettings.isQuickZoomGesturesEnabled = false + } + onView(withId(R.id.mapView)).perform(quickScale(mapboxMap.gesturesManager.standardScaleGestureDetector.spanSinceStartThreshold * 2, withVelocity = false, duration = 50L)) + R.id.mapView.loopFor(MapboxConstants.ANIMATION_DURATION.toLong()) + rule.runOnUiThread { + Assert.assertEquals(initialZoom!!, mapboxMap.cameraPosition.zoom, 0.01) + } + } + + @Test + fun doubleTap_interrupted_moveStillEnabled() { + validateTestSetup() + + rule.runOnUiThread { + mapboxMap.moveCamera(CameraUpdateFactory.zoomTo(4.0)) + } + + onView(withId(R.id.mapView)).perform(quickScale(mapboxMap.gesturesManager.standardScaleGestureDetector.spanSinceStartThreshold / 2, withVelocity = false, duration = 50L, interrupt = true)) + + var initialCameraPosition: CameraPosition? = null + rule.runOnUiThread { + // zoom in so we can move vertically + mapboxMap.moveCamera(CameraUpdateFactory.zoomTo(4.0)) + initialCameraPosition = mapboxMap.cameraPosition + mapboxMap.uiSettings.isQuickZoomGesturesEnabled = false + } + + // move to expected target + onView(withId(R.id.mapView)).perform(move(-maxWidth / 2f, -maxHeight / 2f, withVelocity = false)) + rule.runOnUiThread { + Assert.assertNotEquals(initialCameraPosition!!.target.latitude, mapboxMap.cameraPosition.target.latitude, 1.0) + Assert.assertNotEquals(initialCameraPosition!!.target.longitude, mapboxMap.cameraPosition.target.longitude, 1.0) + } + } + + @Test + fun quickZoom_roundTripping() { + validateTestSetup() + rule.runOnUiThread { + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(51.0, 16.0), 3.0)) + } + onView(withId(R.id.mapView)).perform(quickScale(300f, withVelocity = false, duration = 750L)) + onView(withId(R.id.mapView)).perform(quickScale(-300f, withVelocity = false, duration = 750L)) + + rule.runOnUiThread { + Assert.assertEquals(3.0, mapboxMap.cameraPosition.zoom, 0.0001) + } + } +}
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapboxMapTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapboxMapTest.java new file mode 100644 index 0000000000..00ec1fe601 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapboxMapTest.java @@ -0,0 +1,477 @@ +package com.mapbox.mapboxsdk.maps; + +import android.graphics.Color; +import android.support.test.espresso.UiController; +import android.support.test.espresso.ViewAction; +import android.view.View; +import com.mapbox.mapboxsdk.annotations.BaseMarkerOptions; +import com.mapbox.mapboxsdk.annotations.Marker; +import com.mapbox.mapboxsdk.annotations.MarkerOptions; +import com.mapbox.mapboxsdk.annotations.Polygon; +import com.mapbox.mapboxsdk.annotations.PolygonOptions; +import com.mapbox.mapboxsdk.annotations.Polyline; +import com.mapbox.mapboxsdk.annotations.PolylineOptions; +import com.mapbox.mapboxsdk.exceptions.InvalidMarkerPositionException; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.testapp.R; +import com.mapbox.mapboxsdk.testapp.activity.EspressoTest; +import org.hamcrest.Matcher; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +import static android.support.test.espresso.matcher.ViewMatchers.withId; +import static junit.framework.TestCase.assertFalse; +import static junit.framework.TestCase.assertNotNull; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * This test is responsible for testing the public API. + * <p> + * Methods executed on MapboxMap are called from a ViewAction to ensure correct synchronisation + * with the application UI-thread. + * </p> + * @deprecated remove this file when removing deprecated annotations + */ +@Deprecated +public class MapboxMapTest extends EspressoTest { + + // + // InfoWindow + // + + @Test + public void testConcurrentInfoWindowEnabled() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new MapboxMapAction((uiController, view) -> { + mapboxMap.setAllowConcurrentMultipleOpenInfoWindows(true); + assertTrue("ConcurrentWindows should be true", mapboxMap.isAllowConcurrentMultipleOpenInfoWindows()); + })); + } + + @Test + public void testConcurrentInfoWindowDisabled() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new MapboxMapAction((uiController, view) -> { + mapboxMap.setAllowConcurrentMultipleOpenInfoWindows(false); + assertFalse("ConcurrentWindows should be false", mapboxMap.isAllowConcurrentMultipleOpenInfoWindows()); + })); + } + + @Test + public void testInfoWindowAdapter() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new MapboxMapAction((uiController, view) -> { + MapboxMap.InfoWindowAdapter infoWindowAdapter = marker -> null; + mapboxMap.setInfoWindowAdapter(infoWindowAdapter); + assertEquals("InfoWindowAdpter should be the same", infoWindowAdapter, mapboxMap.getInfoWindowAdapter()); + })); + } + + // + // Annotations + // + + @Test + public void testAddMarker() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new MapboxMapAction((uiController, view) -> { + MarkerOptions markerOptions = new MarkerOptions().position(new LatLng()); + Marker marker = mapboxMap.addMarker(markerOptions); + assertTrue("Marker should be contained", mapboxMap.getMarkers().contains(marker)); + })); + } + + @Test(expected = InvalidMarkerPositionException.class) + public void testAddMarkerInvalidPosition() { + new MarkerOptions().getMarker(); + } + + @Test + public void testAddMarkers() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new MapboxMapAction((uiController, view) -> { + List<BaseMarkerOptions> markerList = new ArrayList<>(); + MarkerOptions markerOptions1 = new MarkerOptions().position(new LatLng()).title("a"); + MarkerOptions markerOptions2 = new MarkerOptions().position(new LatLng()).title("b"); + markerList.add(markerOptions1); + markerList.add(markerOptions2); + List<Marker> markers = mapboxMap.addMarkers(markerList); + assertEquals("Markers size should be 2", 2, mapboxMap.getMarkers().size()); + assertTrue(mapboxMap.getMarkers().contains(markers.get(0))); + assertTrue(mapboxMap.getMarkers().contains(markers.get(1))); + })); + } + + @Test + public void testAddMarkersEmpty() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new MapboxMapAction((uiController, view) -> { + List<BaseMarkerOptions> markerList = new ArrayList<>(); + mapboxMap.addMarkers(markerList); + assertEquals("Markers size should be 0", 0, mapboxMap.getMarkers().size()); + })); + } + + @Test + public void testAddMarkersSingleMarker() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new MapboxMapAction((uiController, view) -> { + List<BaseMarkerOptions> markerList = new ArrayList<>(); + MarkerOptions markerOptions = new MarkerOptions().title("a").position(new LatLng()); + markerList.add(markerOptions); + List<Marker> markers = mapboxMap.addMarkers(markerList); + assertEquals("Markers size should be 1", 1, mapboxMap.getMarkers().size()); + assertTrue(mapboxMap.getMarkers().contains(markers.get(0))); + })); + } + + @Test + public void testAddPolygon() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new MapboxMapAction((uiController, view) -> { + PolygonOptions polygonOptions = new PolygonOptions().add(new LatLng()); + Polygon polygon = mapboxMap.addPolygon(polygonOptions); + assertTrue("Polygon should be contained", mapboxMap.getPolygons().contains(polygon)); + })); + } + + @Test + public void testAddEmptyPolygon() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new MapboxMapAction((uiController, view) -> { + PolygonOptions polygonOptions = new PolygonOptions(); + Polygon polygon = mapboxMap.addPolygon(polygonOptions); + assertTrue("Polygon should be ignored", !mapboxMap.getPolygons().contains(polygon)); + })); + } + + @Test + public void testAddPolygons() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new MapboxMapAction((uiController, view) -> { + List<PolygonOptions> polygonList = new ArrayList<>(); + PolygonOptions polygonOptions1 = new PolygonOptions().fillColor(Color.BLACK).add(new LatLng()); + PolygonOptions polygonOptions2 = new PolygonOptions().fillColor(Color.WHITE).add(new LatLng()); + PolygonOptions polygonOptions3 = new PolygonOptions(); + polygonList.add(polygonOptions1); + polygonList.add(polygonOptions2); + polygonList.add(polygonOptions3); + mapboxMap.addPolygons(polygonList); + assertEquals("Polygons size should be 2", 2, mapboxMap.getPolygons().size()); + assertTrue(mapboxMap.getPolygons().contains(polygonOptions1.getPolygon())); + assertTrue(mapboxMap.getPolygons().contains(polygonOptions2.getPolygon())); + assertTrue("Polygon should be ignored", !mapboxMap.getPolygons().contains(polygonOptions3.getPolygon())); + })); + } + + @Test + public void addPolygonsEmpty() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new MapboxMapAction((uiController, view) -> { + mapboxMap.addPolygons(new ArrayList<PolygonOptions>()); + assertEquals("Polygons size should be 0", 0, mapboxMap.getPolygons().size()); + })); + } + + @Test + public void addPolygonsSingle() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new MapboxMapAction((uiController, view) -> { + List<PolygonOptions> polygonList = new ArrayList<>(); + PolygonOptions polygonOptions = new PolygonOptions().fillColor(Color.BLACK).add(new LatLng()); + polygonList.add(polygonOptions); + mapboxMap.addPolygons(polygonList); + assertEquals("Polygons size should be 1", 1, mapboxMap.getPolygons().size()); + assertTrue(mapboxMap.getPolygons().contains(polygonOptions.getPolygon())); + })); + } + + @Test + public void testAddPolyline() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new MapboxMapAction((uiController, view) -> { + PolylineOptions polylineOptions = new PolylineOptions().add(new LatLng()); + Polyline polyline = mapboxMap.addPolyline(polylineOptions); + assertTrue("Polyline should be contained", mapboxMap.getPolylines().contains(polyline)); + })); + } + + @Test + public void testAddEmptyPolyline() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new MapboxMapAction((uiController, view) -> { + PolylineOptions polylineOptions = new PolylineOptions(); + Polyline polyline = mapboxMap.addPolyline(polylineOptions); + assertTrue("Polyline should be ignored", !mapboxMap.getPolylines().contains(polyline)); + })); + } + + @Test + public void testAddPolylines() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new MapboxMapAction((uiController, view) -> { + List<PolylineOptions> polylineList = new ArrayList<>(); + PolylineOptions polygonOptions1 = new PolylineOptions().color(Color.BLACK).add(new LatLng()); + PolylineOptions polygonOptions2 = new PolylineOptions().color(Color.WHITE).add(new LatLng()); + PolylineOptions polygonOptions3 = new PolylineOptions(); + polylineList.add(polygonOptions1); + polylineList.add(polygonOptions2); + polylineList.add(polygonOptions3); + mapboxMap.addPolylines(polylineList); + assertEquals("Polygons size should be 2", 2, mapboxMap.getPolylines().size()); + assertTrue(mapboxMap.getPolylines().contains(polygonOptions1.getPolyline())); + assertTrue(mapboxMap.getPolylines().contains(polygonOptions2.getPolyline())); + assertTrue( + "Polyline should be ignored", !mapboxMap.getPolylines().contains(polygonOptions3.getPolyline()) + ); + })); + } + + @Test + public void testAddPolylinesEmpty() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new MapboxMapAction((uiController, view) -> { + mapboxMap.addPolylines(new ArrayList<PolylineOptions>()); + assertEquals("Polygons size should be 0", 0, mapboxMap.getPolylines().size()); + })); + } + + @Test + public void testAddPolylinesSingle() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new MapboxMapAction((uiController, view) -> { + List<PolylineOptions> polylineList = new ArrayList<>(); + PolylineOptions polygonOptions = new PolylineOptions().color(Color.BLACK).add(new LatLng()); + polylineList.add(polygonOptions); + mapboxMap.addPolylines(polylineList); + assertEquals("Polygons size should be 1", 1, mapboxMap.getPolylines().size()); + assertTrue(mapboxMap.getPolylines().contains(polygonOptions.getPolyline())); + })); + } + + @Test + public void testRemoveMarker() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new MapboxMapAction((uiController, view) -> { + MarkerOptions markerOptions = new MarkerOptions().position(new LatLng()); + Marker marker = mapboxMap.addMarker(markerOptions); + mapboxMap.removeMarker(marker); + assertTrue("Markers should be empty", mapboxMap.getMarkers().isEmpty()); + })); + } + + @Test + public void testRemovePolygon() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new MapboxMapAction((uiController, view) -> { + PolygonOptions polygonOptions = new PolygonOptions(); + Polygon polygon = mapboxMap.addPolygon(polygonOptions); + mapboxMap.removePolygon(polygon); + assertTrue("Polygons should be empty", mapboxMap.getPolylines().isEmpty()); + })); + } + + @Test + public void testRemovePolyline() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new MapboxMapAction((uiController, view) -> { + PolylineOptions polylineOptions = new PolylineOptions(); + Polyline polyline = mapboxMap.addPolyline(polylineOptions); + mapboxMap.removePolyline(polyline); + assertTrue("Polylines should be empty", mapboxMap.getPolylines().isEmpty()); + })); + } + + @Test + public void testRemoveAnnotation() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new MapboxMapAction((uiController, view) -> { + MarkerOptions markerOptions = new MarkerOptions().position(new LatLng()); + Marker marker = mapboxMap.addMarker(markerOptions); + mapboxMap.removeAnnotation(marker); + assertTrue("Annotations should be empty", mapboxMap.getAnnotations().isEmpty()); + })); + } + + @Test + public void testRemoveAnnotationById() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new MapboxMapAction((uiController, view) -> { + MarkerOptions markerOptions = new MarkerOptions().position(new LatLng()); + mapboxMap.addMarker(markerOptions); + // id will always be 0 in unit tests + mapboxMap.removeAnnotation(0); + assertTrue("Annotations should be empty", mapboxMap.getAnnotations().isEmpty()); + })); + } + + @Test + public void testRemoveAnnotations() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new MapboxMapAction((uiController, view) -> { + List<BaseMarkerOptions> markerList = new ArrayList<>(); + MarkerOptions markerOptions1 = new MarkerOptions().title("a").position(new LatLng()); + MarkerOptions markerOptions2 = new MarkerOptions().title("b").position(new LatLng()); + markerList.add(markerOptions1); + markerList.add(markerOptions2); + mapboxMap.addMarkers(markerList); + mapboxMap.removeAnnotations(); + assertTrue("Annotations should be empty", mapboxMap.getAnnotations().isEmpty()); + })); + } + + @Test + public void testClear() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new MapboxMapAction((uiController, view) -> { + List<BaseMarkerOptions> markerList = new ArrayList<>(); + MarkerOptions markerOptions1 = new MarkerOptions().title("a").position(new LatLng()); + MarkerOptions markerOptions2 = new MarkerOptions().title("b").position(new LatLng()); + markerList.add(markerOptions1); + markerList.add(markerOptions2); + mapboxMap.addMarkers(markerList); + mapboxMap.clear(); + assertTrue("Annotations should be empty", mapboxMap.getAnnotations().isEmpty()); + })); + } + + @Test + public void testRemoveAnnotationsByList() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new MapboxMapAction((uiController, view) -> { + List<BaseMarkerOptions> markerList = new ArrayList<>(); + MarkerOptions markerOptions1 = new MarkerOptions().title("a").position(new LatLng()); + MarkerOptions markerOptions2 = new MarkerOptions().title("b").position(new LatLng()); + markerList.add(markerOptions1); + markerList.add(markerOptions2); + List<Marker> markers = mapboxMap.addMarkers(markerList); + Marker marker = mapboxMap.addMarker(new MarkerOptions().position(new LatLng()).title("c")); + mapboxMap.removeAnnotations(markers); + assertTrue("Annotations should not be empty", mapboxMap.getAnnotations().size() == 1); + assertTrue("Marker should be contained", mapboxMap.getAnnotations().contains(marker)); + })); + } + + @Test + public void testGetAnnotationById() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new MapboxMapAction((uiController, view) -> { + MarkerOptions markerOptions = new MarkerOptions().position(new LatLng()); + Marker initialMarker = mapboxMap.addMarker(markerOptions); + Marker retrievedMarker = (Marker) mapboxMap.getAnnotation(0); + assertEquals("Markers should match", initialMarker, retrievedMarker); + })); + } + + @Test + public void testGetAnnotations() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform( + new MapboxMapAction((uiController, view) -> + assertNotNull("Annotations should be non null", mapboxMap.getAnnotations())) + ); + } + + @Test + public void testGetMarkers() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform( + new MapboxMapAction((uiController, view) -> + assertNotNull("Markers should be non null", mapboxMap.getMarkers())) + ); + } + + @Test + public void testGetPolygons() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new MapboxMapAction((uiController, view) -> + assertNotNull("Polygons should be non null", mapboxMap.getPolygons())) + ); + } + + @Test + public void testGetPolylines() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new MapboxMapAction((uiController, view) -> + assertNotNull("Polylines should be non null", mapboxMap.getPolylines())) + ); + } + + @Test + public void testGetSelectedMarkers() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new MapboxMapAction((uiController, view) -> + assertNotNull("Selected markers should be non null", mapboxMap.getSelectedMarkers())) + ); + } + + @Test + public void testSelectMarker() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new MapboxMapAction((uiController, view) -> { + MarkerOptions markerOptions = new MarkerOptions().position(new LatLng()); + Marker marker = mapboxMap.addMarker(markerOptions); + mapboxMap.selectMarker(marker); + assertTrue("Marker should be contained", mapboxMap.getSelectedMarkers().contains(marker)); + })); + } + + @Test + public void testDeselectMarker() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new MapboxMapAction((uiController, view) -> { + MarkerOptions markerOptions = new MarkerOptions().position(new LatLng()); + Marker marker = mapboxMap.addMarker(markerOptions); + mapboxMap.selectMarker(marker); + mapboxMap.deselectMarker(marker); + assertTrue("Selected markers should be empty", mapboxMap.getSelectedMarkers().isEmpty()); + })); + } + + @Test + public void testDeselectMarkers() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new MapboxMapAction((uiController, view) -> { + MarkerOptions markerOptions = new MarkerOptions().position(new LatLng()); + Marker marker1 = mapboxMap.addMarker(markerOptions); + Marker marker2 = mapboxMap.addMarker(markerOptions); + mapboxMap.selectMarker(marker1); + mapboxMap.selectMarker(marker2); + mapboxMap.deselectMarkers(); + assertTrue("Selected markers should be empty", mapboxMap.getSelectedMarkers().isEmpty()); + })); + } + + public class MapboxMapAction implements ViewAction { + + private InvokeViewAction invokeViewAction; + + MapboxMapAction(InvokeViewAction invokeViewAction) { + this.invokeViewAction = invokeViewAction; + } + + @Override + public Matcher<View> getConstraints() { + return isDisplayed(); + } + + @Override + public String getDescription() { + return getClass().getSimpleName(); + } + + @Override + public void perform(UiController uiController, View view) { + invokeViewAction.onViewAction(uiController, view); + } + } + + interface InvokeViewAction { + void onViewAction(UiController uiController, View view); + } +}
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapboxTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapboxTest.java new file mode 100644 index 0000000000..5b737dd4d2 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapboxTest.java @@ -0,0 +1,111 @@ +package com.mapbox.mapboxsdk.maps; + +import android.support.test.annotation.UiThreadTest; +import android.support.test.runner.AndroidJUnit4; + +import com.mapbox.mapboxsdk.AppCenter; +import com.mapbox.mapboxsdk.Mapbox; +import com.mapbox.mapboxsdk.exceptions.MapboxConfigurationException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; + +import static junit.framework.Assert.assertFalse; +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.assertNull; +import static junit.framework.Assert.assertSame; +import static junit.framework.Assert.assertTrue; + +@RunWith(AndroidJUnit4.class) +public class MapboxTest extends AppCenter { + + private static final String ACCESS_TOKEN = "pk.0000000001"; + private static final String ACCESS_TOKEN_2 = "pk.0000000002"; + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + private String realToken; + + @Before + public void setup() { + realToken = Mapbox.getAccessToken(); + } + + @Test + @UiThreadTest + public void testConnected() { + assertTrue(Mapbox.isConnected()); + + // test manual connectivity + Mapbox.setConnected(true); + assertTrue(Mapbox.isConnected()); + Mapbox.setConnected(false); + assertFalse(Mapbox.isConnected()); + + // reset to Android connectivity + Mapbox.setConnected(null); + assertTrue(Mapbox.isConnected()); + } + + @Test + @UiThreadTest + public void setAccessToken() { + Mapbox.setAccessToken(ACCESS_TOKEN); + assertSame(ACCESS_TOKEN, Mapbox.getAccessToken()); + Mapbox.setAccessToken(ACCESS_TOKEN_2); + assertSame(ACCESS_TOKEN_2, Mapbox.getAccessToken()); + } + + @Test + @UiThreadTest + public void setInvalidAccessToken() { + final String invalidAccessToken = "xyz"; + expectedException.expect(MapboxConfigurationException.class); + expectedException.expectMessage( + "A valid access token parameter is required when using a Mapbox service." + + "\nPlease see https://www.mapbox.com/help/create-api-access-token/ to learn how to create one." + + "\nMore information in this guide https://www.mapbox.com/help/first-steps-android-sdk/#access-tokens." + + "Currently provided token is: " + invalidAccessToken + ); + + Mapbox.setAccessToken(invalidAccessToken); + assertNull(Mapbox.getTelemetry()); + Mapbox.getSkuToken(); + } + + @Test + @UiThreadTest + public void setNullAccessToken() { + expectedException.expect(MapboxConfigurationException.class); + expectedException.expectMessage( + "A valid access token parameter is required when using a Mapbox service." + + "\nPlease see https://www.mapbox.com/help/create-api-access-token/ to learn how to create one." + + "\nMore information in this guide https://www.mapbox.com/help/first-steps-android-sdk/#access-tokens." + + "Currently provided token is: " + null + ); + + Mapbox.setAccessToken(null); + assertNull(Mapbox.getTelemetry()); + Mapbox.getSkuToken(); + } + + @Test + @UiThreadTest + public void setValidAccessToken() { + final String invalidAccessToken = "xyz"; + Mapbox.setAccessToken(invalidAccessToken); + Mapbox.setAccessToken(ACCESS_TOKEN); + assertNotNull(Mapbox.getTelemetry()); + assertNotNull(Mapbox.getSkuToken()); + } + + @After + public void tearDown() { + Mapbox.setAccessToken(realToken); + } +}
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/NativeMapViewTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/NativeMapViewTest.kt new file mode 100644 index 0000000000..dc313b5f64 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/NativeMapViewTest.kt @@ -0,0 +1,421 @@ +package com.mapbox.mapboxsdk.maps + +import android.content.Context +import android.graphics.PointF +import android.support.test.InstrumentationRegistry +import android.support.test.annotation.UiThreadTest +import android.support.test.runner.AndroidJUnit4 +import com.mapbox.mapboxsdk.AppCenter +import com.mapbox.mapboxsdk.camera.CameraPosition +import com.mapbox.mapboxsdk.geometry.LatLng +import com.mapbox.mapboxsdk.geometry.LatLngBounds +import com.mapbox.mapboxsdk.geometry.ProjectedMeters +import com.mapbox.mapboxsdk.maps.renderer.MapRenderer +import com.mapbox.mapboxsdk.style.layers.TransitionOptions +import com.mapbox.mapboxsdk.testapp.utils.TestConstants +import junit.framework.Assert.* +import org.junit.After +import org.junit.Assert +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class NativeMapViewTest : AppCenter() { + + private lateinit var nativeMapView: NativeMap + + companion object { + const val DELTA = 0.000001 + const val DELTA_BIG = 1.0 + const val BEARING_TEST = 60.0 + const val PITCH_TEST = 40.0 + const val ZOOM_TEST = 16.0 + val PADDING_TEST = doubleArrayOf(80.0, 150.0, 0.0, 0.0) + const val WIDTH = 500 + const val HEIGHT = WIDTH + val LATLNG_TEST = LatLng(12.0, 34.0) + } + + @Before + @UiThreadTest + fun before() { + val context = InstrumentationRegistry.getContext() + nativeMapView = NativeMapView(context, 2.0f, false, null, null, DummyRenderer(context)) + nativeMapView.resizeView(WIDTH, HEIGHT) + } + + @After + @UiThreadTest + fun after() { + nativeMapView.destroy() + } + + @Test + @UiThreadTest + fun testSetStyleUrl() { + val expected = Style.DARK + nativeMapView.styleUri = expected + val actual = nativeMapView.styleUri + assertEquals("Style URL should match", expected, actual) + } + + @Test + @UiThreadTest + fun testSetStyleJson() { + val expected = "{}" + nativeMapView.styleJson = expected + val actual = nativeMapView.styleJson + assertEquals("Style JSON should match", expected, actual) + } + + @Test + @UiThreadTest + fun testBearing() { + val expected = BEARING_TEST + nativeMapView.setBearing(expected, 0) + val actual = nativeMapView.bearing + assertEquals("Bearing should match", expected, actual, DELTA) + } + + @Test + @UiThreadTest + fun testLatLng() { + val expected = LATLNG_TEST + nativeMapView.setLatLng(expected, 0) + val actual = nativeMapView.latLng + assertEquals("Latitude should match", expected.latitude, actual.latitude, DELTA) + assertEquals("Longitude should match", expected.longitude, actual.longitude, DELTA) + } + + @Test + @UiThreadTest + fun testLatLngPadding() { + val expected = LATLNG_TEST + nativeMapView.contentPadding = PADDING_TEST + nativeMapView.setLatLng(expected, 0) + val actual = nativeMapView.latLng + assertEquals("Latitude should match", expected.latitude, actual.latitude, DELTA) + assertEquals("Longitude should match", expected.longitude, actual.longitude, DELTA) + Assert.assertArrayEquals(PADDING_TEST, nativeMapView.cameraPosition.padding, DELTA) + } + + @Test + @UiThreadTest + fun testLatLngDefault() { + val expected = LatLng() + val actual = nativeMapView.latLng + assertEquals("Latitude should match", expected.latitude, actual.latitude, DELTA) + assertEquals("Longitude should match", expected.longitude, actual.longitude, DELTA) + } + + @Test + @UiThreadTest + fun testBearingDefault() { + val expected = 0.0 + val actual = nativeMapView.bearing + assertEquals("Bearing should match", expected, actual, DELTA) + } + + @Test + @UiThreadTest + fun testPitch() { + val expected = PITCH_TEST + nativeMapView.setPitch(expected, 0) + val actual = nativeMapView.pitch + assertEquals("Pitch should match", expected, actual, DELTA) + } + + @Test + @UiThreadTest + fun testPitchDefault() { + val expected = 0.0 + val actual = nativeMapView.pitch + assertEquals("Pitch should match", expected, actual, DELTA) + } + + @Test + @UiThreadTest + fun testZoom() { + val expected = ZOOM_TEST + nativeMapView.setZoom(expected, PointF(0.0f, 0.0f), 0) + val actual = nativeMapView.zoom + assertEquals("Zoom should match", expected, actual, DELTA) + } + + @Test + @UiThreadTest + fun testZoomDefault() { + val expected = 0.0 + val actual = nativeMapView.zoom + assertEquals("Zoom should match", expected, actual, DELTA) + } + + @Test + @UiThreadTest + fun testJumpTo() { + val expected = CameraPosition.Builder() + .bearing(BEARING_TEST) + .target(LATLNG_TEST) + .tilt(PITCH_TEST) + .zoom(ZOOM_TEST) + .padding(PADDING_TEST) + .build() + // verify that the lazily set padding is ignored when a value is provided with the camera + nativeMapView.contentPadding = doubleArrayOf(1.0, 2.0, 3.0, 4.0) + nativeMapView.jumpTo(LATLNG_TEST, ZOOM_TEST, PITCH_TEST, BEARING_TEST, PADDING_TEST) + val actual = nativeMapView.cameraPosition + assertEquals("Latitude should match", expected.target.latitude, actual.target.latitude, DELTA) + assertEquals("Longitude should match", expected.target.longitude, actual.target.longitude, DELTA) + assertEquals("Bearing should match", expected.bearing, actual.bearing, DELTA) + assertEquals("Pitch should match", expected.tilt, actual.tilt, DELTA) + assertEquals("Zoom should match", expected.zoom, actual.zoom, DELTA) + Assert.assertArrayEquals(expected.padding, actual.padding, DELTA) + } + + @Test + @UiThreadTest + fun testLatLngForPixel() { + val expected = LATLNG_TEST + nativeMapView.setLatLng(LATLNG_TEST, 0) + val actual = nativeMapView.latLngForPixel( + PointF((WIDTH / 2).toFloat(), (HEIGHT / 2).toFloat()) + ) + assertEquals("Latitude should match", expected.latitude, actual.latitude, DELTA_BIG) + assertEquals("Longitude should match", expected.longitude, actual.longitude, DELTA_BIG) + } + + @Test + @UiThreadTest + fun testPixelForLatLng() { + val expected = PointF((WIDTH / 2).toFloat(), (HEIGHT / 2).toFloat()) + nativeMapView.setLatLng(LATLNG_TEST, 0) + val actual = nativeMapView.pixelForLatLng(LATLNG_TEST) + assertEquals("X should match", expected.x.toDouble(), actual.x.toDouble(), DELTA_BIG) + assertEquals("Y should match", expected.y.toDouble(), actual.y.toDouble(), DELTA_BIG) + } + + @Test + @UiThreadTest + fun testPrefetchTilesTrue() { + val expected = true + nativeMapView.prefetchTiles = true + val actual = nativeMapView.prefetchTiles + assertEquals("Flag should match", expected, actual) + } + + @Test + @UiThreadTest + fun testPrefetchTilesFalse() { + val expected = false + nativeMapView.prefetchTiles = false + val actual = nativeMapView.prefetchTiles + assertEquals("Flag should match", expected, actual) + } + + @Test + @UiThreadTest + fun testPrefetchTilesDefault() { + val expected = true + val actual = nativeMapView.prefetchTiles + assertEquals("Flag should match", expected, actual) + } + + @Test + @UiThreadTest + fun testPrefetchZoomDelta() { + val expected = 2 + nativeMapView.prefetchZoomDelta = 2 + val actual = nativeMapView.prefetchZoomDelta + assertEquals("Prefetch zoom delta should match", expected, actual) + } + + @Test + @UiThreadTest + fun testPrefetchZoomDeltaDefault() { + val expected = 4 + val actual = nativeMapView.prefetchZoomDelta + assertEquals("Prefetch zoom delta should match", expected, actual) + } + + @Test + @UiThreadTest + fun testSetContentPadding() { + val expected = doubleArrayOf(1.0, 2.0, 3.0, 4.0) + nativeMapView.contentPadding = expected + val actual = nativeMapView.contentPadding + assertEquals("Left should match", expected[0], actual[0]) + assertEquals("Top should match", expected[1], actual[1]) + assertEquals("Right should match", expected[2], actual[2]) + assertEquals("Bottom should match", expected[3], actual[3]) + } + + @Test + @UiThreadTest + fun testSetMinZoom() { + val expected = 12.0 + nativeMapView.minZoom = expected + val actual = nativeMapView.minZoom + assertEquals("Min zoom should match", expected, actual) + } + + @Test + @UiThreadTest + fun testSetMaxZoom() { + val expected = 12.0 + nativeMapView.maxZoom = expected + val actual = nativeMapView.maxZoom + assertEquals("Max zoom should match", expected, actual) + } + + @Test + @UiThreadTest + fun testGetProjectedMetersAtLatitude() { + val expected = 77973.67021115532 + val actual = nativeMapView.getMetersPerPixelAtLatitude(5.0) + assertEquals("Get projected meters should match", expected, actual) + } + + @Test + @UiThreadTest + fun testLatLngForProjectedMeters() { + val expected = LatLng(0.01796630538796444, 0.02694945852363162) + val actual = nativeMapView.latLngForProjectedMeters(ProjectedMeters(2000.0, 3000.0)) + assertEquals("Lat for projected meters", expected.latitude, actual.latitude, DELTA) + assertEquals("Lng for projected meters", expected.longitude, actual.longitude, DELTA) + } + + @Test + @UiThreadTest + fun testFlyTo() { + val expected = CameraPosition.Builder() + .zoom(12.0) + .tilt(30.0) + .target(LatLng(12.0, 14.0)) + .bearing(20.0) + .padding(PADDING_TEST) + .build() + // verify that the lazily set padding is ignored when a value is provided with the camera + nativeMapView.contentPadding = doubleArrayOf(1.0, 2.0, 3.0, 4.0) + nativeMapView.flyTo(expected.target, expected.zoom, expected.bearing, expected.tilt, PADDING_TEST, 0) + val actual = nativeMapView.cameraPosition + assertEquals("Bearing should match", expected.bearing, actual.bearing, TestConstants.BEARING_DELTA) + assertEquals("Latitude should match", expected.target.latitude, actual.target.latitude, TestConstants.LAT_LNG_DELTA) + assertEquals("Longitude should match", expected.target.longitude, actual.target.longitude, TestConstants.LAT_LNG_DELTA) + assertEquals("Tilt should match", expected.tilt, actual.tilt, TestConstants.TILT_DELTA) + assertEquals("Zoom should match", expected.zoom, actual.zoom, TestConstants.ZOOM_DELTA) + Assert.assertArrayEquals(expected.padding, actual.padding, DELTA) + } + + @Test + @UiThreadTest + fun testEaseTo() { + val expected = CameraPosition.Builder() + .zoom(12.0) + .tilt(30.0) + .target(LatLng(12.0, 14.0)) + .bearing(20.0) + .padding(PADDING_TEST) + .build() + // verify that the lazily set padding is ignored when a value is provided with the camera + nativeMapView.contentPadding = doubleArrayOf(1.0, 2.0, 3.0, 4.0) + nativeMapView.easeTo(expected.target, expected.zoom, expected.bearing, expected.tilt, PADDING_TEST, 0, false) + val actual = nativeMapView.cameraPosition + assertEquals("Bearing should match", expected.bearing, actual.bearing, TestConstants.BEARING_DELTA) + assertEquals("Latitude should match", expected.target.latitude, actual.target.latitude, TestConstants.LAT_LNG_DELTA) + assertEquals("Longitude should match", expected.target.longitude, actual.target.longitude, TestConstants.LAT_LNG_DELTA) + assertEquals("Tilt should match", expected.tilt, actual.tilt, TestConstants.TILT_DELTA) + assertEquals("Zoom should match", expected.zoom, actual.zoom, TestConstants.ZOOM_DELTA) + Assert.assertArrayEquals(expected.padding, actual.padding, DELTA) + } + + @Test + @UiThreadTest + fun testResetPosition() { + val expected = CameraPosition.Builder() + .zoom(0.0) + .tilt(0.0) + .target(LatLng(0.0, 0.0)) + .bearing(0.0) + .padding(PADDING_TEST) + .build() + nativeMapView.jumpTo(LatLng(1.0, 2.0), 12.0, 23.0, 1.0, PADDING_TEST) + nativeMapView.resetPosition() + val actual = nativeMapView.cameraPosition + assertEquals("Bearing should match", expected.bearing, actual.bearing, TestConstants.BEARING_DELTA) + assertEquals("Latitude should match", expected.target.latitude, actual.target.latitude, TestConstants.LAT_LNG_DELTA) + assertEquals("Longitude should match", expected.target.longitude, actual.target.longitude, TestConstants.LAT_LNG_DELTA) + assertEquals("Tilt should match", expected.tilt, actual.tilt, TestConstants.TILT_DELTA) + assertEquals("Zoom should match", expected.zoom, actual.zoom, TestConstants.ZOOM_DELTA) + Assert.assertArrayEquals(expected.padding, actual.padding, DELTA) + } + + @Test + @UiThreadTest + fun testGetCameraForLatLngBounds() { + val expected = CameraPosition.Builder() + .zoom(3.5258764777024005) + .tilt(0.0) + .target(LatLng(23.182767623652808, 13.999999999994088)) + .bearing(0.0) + .build() + val actual = nativeMapView.getCameraForLatLngBounds( + LatLngBounds.from(30.0, 16.0, 16.0, 12.0), + intArrayOf(0, 0, 0, 0), + 0.0, + 0.0 + ) + assertEquals("Bearing should match", expected.bearing, actual.bearing, TestConstants.BEARING_DELTA) + assertEquals("Latitude should match", expected.target.latitude, actual.target.latitude, TestConstants.LAT_LNG_DELTA) + assertEquals("Longitude should match", expected.target.longitude, actual.target.longitude, TestConstants.LAT_LNG_DELTA) + assertEquals("Tilt should match", expected.tilt, actual.tilt, TestConstants.TILT_DELTA) + assertEquals("Zoom should match", expected.zoom, actual.zoom, TestConstants.ZOOM_DELTA) + } + + @Test + @UiThreadTest + fun testMoveBy() { + val expected = CameraPosition.Builder() + .zoom(0.0) + .tilt(0.0) + .target(LatLng(4.21494310024160, -4.218749958739409)) + .bearing(0.0) + .build() + nativeMapView.moveBy(12.0, 12.0, 0) + val actual = nativeMapView.cameraPosition + assertEquals("Bearing should match", expected.bearing, actual.bearing, TestConstants.BEARING_DELTA) + assertEquals("Latitude should match", expected.target.latitude, actual.target.latitude, TestConstants.LAT_LNG_DELTA) + assertEquals("Longitude should match", expected.target.longitude, actual.target.longitude, TestConstants.LAT_LNG_DELTA) + assertEquals("Tilt should match", expected.tilt, actual.tilt, TestConstants.TILT_DELTA) + assertEquals("Zoom should match", expected.zoom, actual.zoom, TestConstants.ZOOM_DELTA) + } + + @Test + @UiThreadTest + fun testTransitionOptions() { + val transitionOptions = TransitionOptions(500, 500) + nativeMapView.transitionOptions = transitionOptions + assertTrue(transitionOptions.isEnablePlacementTransitions) + assertEquals(transitionOptions, nativeMapView.transitionOptions) + } + + @Test + @UiThreadTest + fun testTransitionOptions_disablePlacementTransitions() { + val transitionOptions = TransitionOptions(500, 500, false) + nativeMapView.transitionOptions = transitionOptions + assertFalse(transitionOptions.isEnablePlacementTransitions) + assertEquals(transitionOptions, nativeMapView.transitionOptions) + } + + class DummyRenderer(context: Context) : MapRenderer(context, null) { + + override fun requestRender() { + // no-op + } + + override fun queueEvent(runnable: Runnable?) { + // no-op + } + } +}
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/TransformTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/TransformTest.kt new file mode 100644 index 0000000000..6b59411ae8 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/TransformTest.kt @@ -0,0 +1,33 @@ +package com.mapbox.mapboxsdk.maps + +import android.support.test.espresso.UiController +import com.mapbox.mapboxsdk.camera.CameraUpdateFactory +import com.mapbox.mapboxsdk.geometry.LatLng +import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke +import com.mapbox.mapboxsdk.testapp.activity.EspressoTest +import org.junit.Assert.assertEquals +import org.junit.Test + +class TransformTest : EspressoTest() { + + companion object { + val initialCameraUpdate = CameraUpdateFactory.newLatLngZoom(LatLng(12.0, 12.0), 12.0)!! + } + + @Test + fun mapboxMapScrollByWithPadding() { + validateTestSetup() + invoke(mapboxMap) { _: UiController, mapboxMap: MapboxMap -> + mapboxMap.moveCamera(initialCameraUpdate) + mapboxMap.scrollBy(400.0f, 0.0f) + val expectedCameraPosition = mapboxMap.cameraPosition + + mapboxMap.moveCamera(initialCameraUpdate) + mapboxMap.setPadding(250, 250, 0, 0) + mapboxMap.scrollBy(400.0f, 0.0f) + val actualCameraPosition = mapboxMap.cameraPosition + + assertEquals("Camera position should match", expectedCameraPosition, actualCameraPosition) + } + } +}
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/VisibleRegionTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/VisibleRegionTest.kt new file mode 100644 index 0000000000..12dff5d452 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/VisibleRegionTest.kt @@ -0,0 +1,400 @@ +package com.mapbox.mapboxsdk.maps + +import android.graphics.PointF +import android.support.test.espresso.UiController +import com.mapbox.mapboxsdk.camera.CameraUpdateFactory +import com.mapbox.mapboxsdk.geometry.LatLng +import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke +import com.mapbox.mapboxsdk.testapp.activity.BaseTest +import com.mapbox.mapboxsdk.testapp.activity.espresso.PixelTestActivity +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Test + +class VisibleRegionTest : BaseTest() { + + override fun getActivityClass(): Class<*> { + return PixelTestActivity::class.java + } + + override + fun beforeTest() { + super.beforeTest() + mapView = (rule.activity as PixelTestActivity).mapView + } + + @Test + fun visibleRegionTest() { + validateTestSetup() + invoke(mapboxMap) { _: UiController, mapboxMap: MapboxMap -> + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(0.0, 0.0), 8.0)) + val latLngs = listOf( + mapboxMap.getLatLngFromScreenCoords(0f, 0f), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, 0f), + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), 0f), + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height / 2f), + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(0f, mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(0f, mapView.height / 2f), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f) + ) + val visibleRegion = mapboxMap.projection.visibleRegion + assertTrue(latLngs.all { visibleRegion.latLngBounds.contains(it) }) + } + } + + @Test + fun paddedVisibleRegionTest() { + validateTestSetup() + invoke(mapboxMap) { _: UiController, mapboxMap: MapboxMap -> + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(0.0, 0.0), 8.0)) + val latLngs = listOf( + mapboxMap.getLatLngFromScreenCoords(0f, 0f), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, 0f), + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), 0f), + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height / 2f), + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(0f, mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(0f, mapView.height / 2f), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f) + ) + + mapboxMap.setPadding( + mapView.width / 4, + mapView.height / 4, + mapView.width / 4, + mapView.height / 4) + + val visibleRegion = mapboxMap.projection.getVisibleRegion(false) + val filtered = latLngs.filter { visibleRegion.latLngBounds.contains(it) } + assertTrue(filtered.size == 1) + assertTrue(filtered.contains(mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f))) + } + } + + @Test + fun paddedLeftVisibleRegionTest() { + validateTestSetup() + invoke(mapboxMap) { _: UiController, mapboxMap: MapboxMap -> + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(0.0, 0.0), 8.0)) + val latLngs = listOf( + mapboxMap.getLatLngFromScreenCoords(0f, 0f), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, 0f), + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), 0f), + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height / 2f), + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(0f, mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(0f, mapView.height / 2f), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f) + ) + + mapboxMap.setPadding(mapView.width / 4, 0, 0, 0) + + val visibleRegion = mapboxMap.projection.getVisibleRegion(false) + val filtered = latLngs.filter { visibleRegion.latLngBounds.contains(it) } + assertTrue(filtered.size == 6) + assertFalse(filtered.contains(mapboxMap.getLatLngFromScreenCoords(0f, mapView.height / 2f))) + } + } + + @Test + fun paddedTopVisibleRegionTest() { + validateTestSetup() + invoke(mapboxMap) { _: UiController, mapboxMap: MapboxMap -> + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(0.0, 0.0), 8.0)) + val latLngs = listOf( + mapboxMap.getLatLngFromScreenCoords(0f, 0f), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, 0f), + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), 0f), + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height / 2f), + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(0f, mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(0f, mapView.height / 2f), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f) + ) + + mapboxMap.setPadding(0, mapView.height / 4, 0, 0) + + val visibleRegion = mapboxMap.projection.getVisibleRegion(false) + val filtered = latLngs.filter { visibleRegion.latLngBounds.contains(it) } + assertTrue(filtered.size == 6) + assertFalse(filtered.contains(mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, 0f))) + } + } + + @Test + fun paddedRightVisibleRegionTest() { + validateTestSetup() + invoke(mapboxMap) { _: UiController, mapboxMap: MapboxMap -> + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(0.0, 0.0), 8.0)) + val latLngs = listOf( + mapboxMap.getLatLngFromScreenCoords(0f, 0f), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, 0f), + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), 0f), + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height / 2f), + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(0f, mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(0f, mapView.height / 2f), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f) + ) + + mapboxMap.setPadding(0, 0, mapView.width / 4, 0) + + val visibleRegion = mapboxMap.projection.getVisibleRegion(false) + val filtered = latLngs.filter { visibleRegion.latLngBounds.contains(it) } + assertTrue(filtered.size == 6) + assertFalse(filtered.contains(mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height / 2f))) + } + } + + @Test + fun paddedBottomVisibleRegionTest() { + validateTestSetup() + invoke(mapboxMap) { _: UiController, mapboxMap: MapboxMap -> + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(0.0, 0.0), 8.0)) + val latLngs = listOf( + mapboxMap.getLatLngFromScreenCoords(0f, 0f), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, 0f), + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), 0f), + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height / 2f), + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(0f, mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(0f, mapView.height / 2f), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f) + ) + + mapboxMap.setPadding(0, 0, 0, mapView.height / 4) + + val visibleRegion = mapboxMap.projection.getVisibleRegion(false) + val filtered = latLngs.filter { visibleRegion.latLngBounds.contains(it) } + assertTrue(filtered.size == 6) + assertFalse(filtered.contains(mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height.toFloat()))) + } + } + + @Test + fun visibleRegionOverDatelineTest() { + validateTestSetup() + invoke(mapboxMap) { _: UiController, mapboxMap: MapboxMap -> + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(0.0, 180.0), 8.0)) + val latLngs = listOf( + mapboxMap.getLatLngFromScreenCoords(0f, 0f), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, 0f), + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), 0f) + .also { it.longitude += 360 }, + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height / 2f) + .also { it.longitude += 360 }, + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height.toFloat()) + .also { it.longitude += 360 }, + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(0f, mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(0f, mapView.height / 2f), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f) + ) + val visibleRegion = mapboxMap.projection.visibleRegion + assertTrue(latLngs.all { visibleRegion.latLngBounds.contains(it) }) + } + } + + @Test + fun paddedVisibleRegionOverDatelineTest() { + validateTestSetup() + invoke(mapboxMap) { _: UiController, mapboxMap: MapboxMap -> + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(0.0, 180.0), 8.0)) + val latLngs = listOf( + mapboxMap.getLatLngFromScreenCoords(0f, 0f), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, 0f), + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), 0f), + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height / 2f), + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(0f, mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(0f, mapView.height / 2f), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f) + ) + + mapboxMap.setPadding( + mapView.width / 4, + mapView.height / 4, + mapView.width / 4, + mapView.height / 4) + + val visibleRegion = mapboxMap.projection.getVisibleRegion(false) + val filtered = latLngs.filter { visibleRegion.latLngBounds.contains(it) } + assertTrue(filtered.size == 1) + assertTrue(filtered.contains(mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f))) + } + } + + @Test + fun paddedLeftVisibleRegionOverDatelineTest() { + validateTestSetup() + invoke(mapboxMap) { _: UiController, mapboxMap: MapboxMap -> + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(0.0, 180.0), 8.0)) + val latLngs = listOf( + mapboxMap.getLatLngFromScreenCoords(0f, 0f), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, 0f), + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), 0f) + .also { it.longitude += 360 }, + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height / 2f) + .also { it.longitude += 360 }, + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height.toFloat()) + .also { it.longitude += 360 }, + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(0f, mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(0f, mapView.height / 2f), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f) + ) + + mapboxMap.setPadding(mapView.width / 4, 0, 0, 0) + + val visibleRegion = mapboxMap.projection.getVisibleRegion(false) + val filtered = latLngs.filter { visibleRegion.latLngBounds.contains(it) } + assertTrue(filtered.size == 6) + assertFalse(filtered.contains(mapboxMap.getLatLngFromScreenCoords(0f, mapView.height / 2f))) + } + } + + @Test + fun paddedTopVisibleRegionOverDatelineTest() { + validateTestSetup() + invoke(mapboxMap) { ui: UiController, mapboxMap: MapboxMap -> + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(0.0, 180.0), 8.0)) + ui.loopMainThreadForAtLeast(5000) + val latLngs = listOf( + mapboxMap.getLatLngFromScreenCoords(0f, 0f), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, 0f), + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), 0f) + .also { it.longitude += 360 }, + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height / 2f) + .also { it.longitude += 360 }, + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height.toFloat()) + .also { it.longitude += 360 }, + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(0f, mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(0f, mapView.height / 2f), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f) + ) + + mapboxMap.setPadding(0, mapView.height / 4, 0, 0) + + val visibleRegion = mapboxMap.projection.getVisibleRegion(false) + val filtered = latLngs.filter { visibleRegion.latLngBounds.contains(it) } + assertTrue(filtered.size == 6) + assertFalse(filtered.contains(mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, 0f))) + } + } + + @Test + fun paddedRightVisibleRegionOverDatelineTest() { + validateTestSetup() + invoke(mapboxMap) { _: UiController, mapboxMap: MapboxMap -> + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(0.0, 180.0), 8.0)) + val latLngs = listOf( + mapboxMap.getLatLngFromScreenCoords(0f, 0f), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, 0f), + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), 0f) + .also { it.longitude += 360 }, + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height / 2f) + .also { it.longitude += 360 }, + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height.toFloat()) + .also { it.longitude += 360 }, + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(0f, mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(0f, mapView.height / 2f), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f) + ) + + mapboxMap.setPadding(0, 0, mapView.width / 4, 0) + + val visibleRegion = mapboxMap.projection.getVisibleRegion(false) + val filtered = latLngs.filter { visibleRegion.latLngBounds.contains(it) } + assertTrue(filtered.size == 6) + assertFalse(filtered.contains(mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height / 2f))) + } + } + + @Test + fun paddedBottomVisibleRegionOverDatelineTest() { + validateTestSetup() + invoke(mapboxMap) { _: UiController, mapboxMap: MapboxMap -> + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(0.0, 180.0), 8.0)) + val latLngs = listOf( + mapboxMap.getLatLngFromScreenCoords(0f, 0f), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, 0f), + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), 0f) + .also { it.longitude += 360 }, + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height / 2f) + .also { it.longitude += 360 }, + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height.toFloat()) + .also { it.longitude += 360 }, + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(0f, mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(0f, mapView.height / 2f), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f) + ) + + mapboxMap.setPadding(0, 0, 0, mapView.height / 4) + + val visibleRegion = mapboxMap.projection.getVisibleRegion(false) + val filtered = latLngs.filter { visibleRegion.latLngBounds.contains(it) } + assertTrue(filtered.size == 6) + assertFalse(filtered.contains(mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height.toFloat()))) + } + } + + @Test + fun visibleRotatedRegionTest() { + validateTestSetup() + invoke(mapboxMap) { _: UiController, mapboxMap: MapboxMap -> + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(0.0, 0.0), 8.0)) + val d = Math.min(mapboxMap.width, mapboxMap.height) / 4 + val latLngs = listOf( + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f - d / 2f, mapView.height / 2f), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f + d / 2f, mapView.height / 2f), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f - d / 2f), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f + d / 2f) + ) + + for (bearing in 45 until 360 step 45) { + mapboxMap.moveCamera(CameraUpdateFactory.bearingTo(bearing.toDouble())) + val visibleRegion = mapboxMap.projection.visibleRegion + assertTrue(latLngs.all { visibleRegion.latLngBounds.contains(it) }) + } + } + } + + @Test + fun visibleRotatedRegionOverDatelineTest() { + validateTestSetup() + invoke(mapboxMap) { _: UiController, mapboxMap: MapboxMap -> + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(0.0, 180.0), 8.0)) + val d = Math.min(mapboxMap.width, mapboxMap.height) / 4 + val latLngs = listOf( + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f - d / 2f, mapView.height / 2f), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f + d / 2f, mapView.height / 2f) + .also { it.longitude += 360 }, + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f - d / 2f), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f + d / 2f) + ) + + for (bearing in 45 until 360 step 45) { + mapboxMap.moveCamera(CameraUpdateFactory.bearingTo(bearing.toDouble())) + val visibleRegion = mapboxMap.projection.visibleRegion + assertTrue(latLngs.all { visibleRegion.latLngBounds.contains(it) }) + } + } + } + + private fun MapboxMap.getLatLngFromScreenCoords(x: Float, y: Float): LatLng { + return this.projection.fromScreenLocation(PointF(x, y)) + } +}
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/IconTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/IconTest.java new file mode 100644 index 0000000000..559213af3d --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/IconTest.java @@ -0,0 +1,138 @@ +package com.mapbox.mapboxsdk.testapp.annotations; + +import android.app.Activity; +import android.support.test.annotation.UiThreadTest; +import android.support.v4.content.res.ResourcesCompat; +import com.mapbox.mapboxsdk.annotations.Icon; +import com.mapbox.mapboxsdk.annotations.IconFactory; +import com.mapbox.mapboxsdk.annotations.Marker; +import com.mapbox.mapboxsdk.annotations.MarkerOptions; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.IconManagerResolver; +import com.mapbox.mapboxsdk.testapp.R; +import com.mapbox.mapboxsdk.testapp.activity.EspressoTest; +import com.mapbox.mapboxsdk.testapp.utils.IconUtils; +import org.junit.Before; +import org.junit.Test; + +import java.util.Map; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertFalse; +import static junit.framework.Assert.assertNull; +import static junit.framework.Assert.assertTrue; + +/** + * Tests integration between Icons and Markers + */ +public class IconTest extends EspressoTest { + + private Map<Icon, Integer> iconMap; + + @Before + public void beforeTest() { + super.beforeTest(); + iconMap = new IconManagerResolver(mapboxMap).getIconMap(); + } + + @Test + @UiThreadTest + public void testAddSameIconMarker() { + validateTestSetup(); + Icon defaultMarker = IconFactory.getInstance(rule.getActivity()).defaultMarker(); + mapboxMap.addMarker(new MarkerOptions().position(new LatLng())); + mapboxMap.addMarker(new MarkerOptions().position(new LatLng(1, 1))); + assertEquals(1, iconMap.size()); + assertEquals(2, iconMap.get(defaultMarker), 0); + } + + @Test + @UiThreadTest + public void testAddDifferentIconMarker() { + validateTestSetup(); + Icon icon = IconFactory.getInstance(rule.getActivity()).fromResource(R.drawable.mapbox_logo_icon); + mapboxMap.addMarker(new MarkerOptions().icon(icon).position(new LatLng())); + mapboxMap.addMarker(new MarkerOptions().position(new LatLng(1, 1))); + assertEquals(iconMap.size(), 2); + assertTrue(iconMap.containsKey(icon)); + assertTrue(iconMap.get(icon) == 1); + } + + @Test + @UiThreadTest + public void testAddRemoveIconMarker() { + validateTestSetup(); + Icon icon = IconFactory.getInstance(rule.getActivity()).fromResource(R.drawable.mapbox_logo_icon); + Marker marker = mapboxMap.addMarker(new MarkerOptions().icon(icon).position(new LatLng())); + mapboxMap.addMarker(new MarkerOptions().position(new LatLng(1, 1))); + assertEquals(iconMap.size(), 2); + assertTrue(iconMap.containsKey(icon)); + assertTrue(iconMap.get(icon) == 1); + + mapboxMap.removeMarker(marker); + assertEquals(iconMap.size(), 1); + assertFalse(iconMap.containsKey(icon)); + } + + @Test + @UiThreadTest + public void testAddRemoveDefaultMarker() { + validateTestSetup(); + Marker marker = mapboxMap.addMarker(new MarkerOptions().position(new LatLng(1, 1))); + assertEquals(iconMap.size(), 1); + + mapboxMap.removeMarker(marker); + assertEquals(iconMap.size(), 0); + + mapboxMap.addMarker(new MarkerOptions().position(new LatLng())); + assertEquals(iconMap.size(), 1); + } + + @Test + @UiThreadTest + public void testAddRemoveMany() { + validateTestSetup(); + Activity activity = rule.getActivity(); + IconFactory iconFactory = IconFactory.getInstance(activity); + + // add 2 default icon markers + Marker defaultMarkerOne = mapboxMap.addMarker(new MarkerOptions().position(new LatLng(1, 1))); + Marker defaultMarkerTwo = mapboxMap.addMarker(new MarkerOptions().position(new LatLng(2, 1))); + + // add 4 unique icon markers + mapboxMap.addMarker(new MarkerOptions() + .icon(iconFactory.fromResource(R.drawable.mapbox_logo_icon)) + .position(new LatLng(3, 1)) + ); + mapboxMap.addMarker(new MarkerOptions() + .icon(iconFactory.fromResource(R.drawable.mapbox_compass_icon)) + .position(new LatLng(4, 1)) + ); + mapboxMap.addMarker(new MarkerOptions() + .icon(IconUtils.drawableToIcon(activity, R.drawable.ic_stars, + ResourcesCompat.getColor(activity.getResources(), + R.color.blueAccent, activity.getTheme()))) + .position(new LatLng(5, 1)) + ); + mapboxMap.addMarker(new MarkerOptions() + .icon(iconFactory.fromResource(R.drawable.ic_android)) + .position(new LatLng(6, 1)) + ); + + assertEquals("Amount of icons should match 5", 5, iconMap.size()); + assertEquals("Refcounter of default marker should match 2", 2, iconMap.get(iconFactory.defaultMarker()), 0); + + mapboxMap.removeMarker(defaultMarkerOne); + + assertEquals("Amount of icons should match 5", 5, iconMap.size()); + assertEquals("Refcounter of default marker should match 1", 1, iconMap.get(iconFactory.defaultMarker()), 0); + + mapboxMap.removeMarker(defaultMarkerTwo); + + assertEquals("Amount of icons should match 4", 4, iconMap.size()); + assertNull("DefaultMarker shouldn't exist anymore", iconMap.get(iconFactory.defaultMarker())); + + mapboxMap.clear(); + assertEquals("Amount of icons should match 0", 0, iconMap.size()); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/MarkerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/MarkerTest.java new file mode 100644 index 0000000000..2328023a3d --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/MarkerTest.java @@ -0,0 +1,63 @@ +package com.mapbox.mapboxsdk.testapp.annotations; + +import com.mapbox.mapboxsdk.annotations.Marker; +import com.mapbox.mapboxsdk.annotations.MarkerOptions; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction; +import com.mapbox.mapboxsdk.testapp.activity.EspressoTest; +import com.mapbox.mapboxsdk.testapp.utils.TestConstants; + +import org.junit.Ignore; +import org.junit.Test; + +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.assertion.ViewAssertions.matches; +import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +import static android.support.test.espresso.matcher.ViewMatchers.withText; +import static com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke; +import static org.junit.Assert.assertEquals; + +public class MarkerTest extends EspressoTest { + + private Marker marker; + + @Test + @Ignore + public void addMarkerTest() { + validateTestSetup(); + MapboxMapAction.invoke(mapboxMap, (uiController, mapboxMap) -> { + assertEquals("Markers should be empty", 0, mapboxMap.getMarkers().size()); + + MarkerOptions options = new MarkerOptions(); + options.setPosition(new LatLng()); + options.setSnippet(TestConstants.TEXT_MARKER_SNIPPET); + options.setTitle(TestConstants.TEXT_MARKER_TITLE); + marker = mapboxMap.addMarker(options); + + assertEquals("Markers size should be 1, ", 1, mapboxMap.getMarkers().size()); + assertEquals("Marker id should be 0", 0, marker.getId()); + assertEquals("Marker target should match", new LatLng(), marker.getPosition()); + assertEquals("Marker snippet should match", TestConstants.TEXT_MARKER_SNIPPET, marker.getSnippet()); + assertEquals("Marker target should match", TestConstants.TEXT_MARKER_TITLE, marker.getTitle()); + mapboxMap.clear(); + assertEquals("Markers should be empty", 0, mapboxMap.getMarkers().size()); + }); + } + + @Test + @Ignore + public void showInfoWindowTest() { + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + final MarkerOptions options = new MarkerOptions(); + options.setPosition(new LatLng()); + options.setSnippet(TestConstants.TEXT_MARKER_SNIPPET); + options.setTitle(TestConstants.TEXT_MARKER_TITLE); + marker = mapboxMap.addMarker(options); + mapboxMap.selectMarker(marker); + }); + onView(withText(TestConstants.TEXT_MARKER_TITLE)).check(matches(isDisplayed())); + onView(withText(TestConstants.TEXT_MARKER_SNIPPET)).check(matches(isDisplayed())); + } + +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/PolygonTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/PolygonTest.java new file mode 100644 index 0000000000..b604bb7da1 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/PolygonTest.java @@ -0,0 +1,46 @@ +package com.mapbox.mapboxsdk.testapp.annotations; + +import android.graphics.Color; + +import com.mapbox.mapboxsdk.annotations.Polygon; +import com.mapbox.mapboxsdk.annotations.PolygonOptions; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.testapp.activity.EspressoTest; + +import org.junit.Ignore; +import org.junit.Test; + +import static com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke; +import static org.junit.Assert.assertEquals; + +public class PolygonTest extends EspressoTest { + + @Test + @Ignore + public void addPolygonTest() { + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + LatLng latLngOne = new LatLng(); + LatLng latLngTwo = new LatLng(1, 0); + LatLng latLngThree = new LatLng(1, 1); + + assertEquals("Polygons should be empty", 0, mapboxMap.getPolygons().size()); + + final PolygonOptions options = new PolygonOptions(); + options.strokeColor(Color.BLUE); + options.fillColor(Color.RED); + options.add(latLngOne); + options.add(latLngTwo); + options.add(latLngThree); + Polygon polygon = mapboxMap.addPolygon(options); + + assertEquals("Polygons should be 1", 1, mapboxMap.getPolygons().size()); + assertEquals("Polygon id should be 0", 0, polygon.getId()); + assertEquals("Polygon points size should match", 3, polygon.getPoints().size()); + assertEquals("Polygon stroke color should match", Color.BLUE, polygon.getStrokeColor()); + assertEquals("Polygon target should match", Color.RED, polygon.getFillColor()); + mapboxMap.clear(); + assertEquals("Polygons should be empty", 0, mapboxMap.getPolygons().size()); + }); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/PolylineTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/PolylineTest.java new file mode 100644 index 0000000000..f977e25981 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/PolylineTest.java @@ -0,0 +1,42 @@ +package com.mapbox.mapboxsdk.testapp.annotations; + +import android.graphics.Color; + +import com.mapbox.mapboxsdk.annotations.Polyline; +import com.mapbox.mapboxsdk.annotations.PolylineOptions; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.testapp.activity.EspressoTest; + +import org.junit.Ignore; +import org.junit.Test; + +import static com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke; +import static org.junit.Assert.assertEquals; + +public class PolylineTest extends EspressoTest { + + @Test + @Ignore + public void addPolylineTest() { + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + LatLng latLngOne = new LatLng(); + LatLng latLngTwo = new LatLng(1, 0); + + assertEquals("Polygons should be empty", 0, mapboxMap.getPolygons().size()); + + final PolylineOptions options = new PolylineOptions(); + options.color(Color.BLUE); + options.add(latLngOne); + options.add(latLngTwo); + Polyline polyline = mapboxMap.addPolyline(options); + + assertEquals("Polylines should be 1", 1, mapboxMap.getPolylines().size()); + assertEquals("Polyline id should be 0", 0, polyline.getId()); + assertEquals("Polyline points size should match", 2, polyline.getPoints().size()); + assertEquals("Polyline stroke color should match", Color.BLUE, polyline.getColor()); + mapboxMap.clear(); + assertEquals("Polyline should be empty", 0, mapboxMap.getPolylines().size()); + }); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/fragment/MapDialogFragmentTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/fragment/MapDialogFragmentTest.kt new file mode 100644 index 0000000000..f695f3efe2 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/fragment/MapDialogFragmentTest.kt @@ -0,0 +1,35 @@ +package com.mapbox.mapboxsdk.testapp.fragment + +import android.support.test.espresso.Espresso +import android.support.test.espresso.Espresso.onView +import android.support.test.espresso.action.ViewActions.click +import android.support.test.espresso.matcher.ViewMatchers.withId +import android.support.test.filters.LargeTest +import android.support.test.rule.ActivityTestRule +import android.support.test.runner.AndroidJUnit4 +import com.mapbox.mapboxsdk.AppCenter +import com.mapbox.mapboxsdk.testapp.R +import com.mapbox.mapboxsdk.testapp.activity.maplayout.MapInDialogActivity +import org.junit.Ignore +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +/** + * Regression test that validates that a map inside a DialogFragment can be opened and closed. + */ +@RunWith(AndroidJUnit4::class) +@LargeTest +class MapDialogFragmentTest : AppCenter() { + + @get:Rule + var activityRule: ActivityTestRule<MapInDialogActivity> = ActivityTestRule(MapInDialogActivity::class.java) + + @Test + @Ignore + fun openCloseDialog() { + onView(withId(R.id.button_open_dialog)).perform(click()) + Thread.sleep(2500) + Espresso.pressBack() + } +}
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/geometry/GeoJsonConversionTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/geometry/GeoJsonConversionTest.java new file mode 100644 index 0000000000..81d10a5f15 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/geometry/GeoJsonConversionTest.java @@ -0,0 +1,148 @@ +package com.mapbox.mapboxsdk.testapp.geometry; + +import android.support.test.annotation.UiThreadTest; +import com.google.gson.JsonArray; +import com.mapbox.geojson.Feature; +import com.mapbox.geojson.Point; +import com.mapbox.geojson.Polygon; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.style.expressions.Expression; +import com.mapbox.mapboxsdk.style.layers.PropertyFactory; +import com.mapbox.mapboxsdk.style.layers.SymbolLayer; +import com.mapbox.mapboxsdk.style.sources.GeoJsonSource; +import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction; +import com.mapbox.mapboxsdk.testapp.activity.EspressoTest; +import com.mapbox.mapboxsdk.testapp.utils.TestingAsyncUtils; +import org.junit.Test; + +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.matcher.ViewMatchers.isRoot; +import static com.mapbox.geojson.Feature.fromGeometry; +import static com.mapbox.geojson.FeatureCollection.fromFeatures; +import static com.mapbox.geojson.GeometryCollection.fromGeometries; +import static com.mapbox.geojson.LineString.fromLngLats; +import static com.mapbox.geojson.MultiLineString.fromLineString; +import static com.mapbox.geojson.MultiPolygon.fromPolygon; +import static java.util.Collections.emptyList; +import static java.util.Collections.singletonList; +import static org.junit.Assert.assertFalse; + +/** + * Instrumentation test to validate java geojson conversion to c++ + */ +public class GeoJsonConversionTest extends EspressoTest { + + // Regression test for #12343 + @Test + @UiThreadTest + public void testEmptyFeatureCollection() { + validateTestSetup(); + mapboxMap.getStyle().addSource( + new GeoJsonSource("test-id", + fromFeatures(singletonList(fromGeometry(fromGeometries(emptyList())))) + ) + ); + mapboxMap.getStyle().addLayer(new SymbolLayer("test-id", "test-id")); + } + + @Test + @UiThreadTest + public void testPointFeatureCollection() { + validateTestSetup(); + mapboxMap.getStyle().addSource( + new GeoJsonSource("test-id", + fromFeatures(singletonList(fromGeometry(Point.fromLngLat(0.0, 0.0)))) + ) + ); + mapboxMap.getStyle().addLayer(new SymbolLayer("test-id", "test-id")); + } + + @Test + @UiThreadTest + public void testMultiPointFeatureCollection() { + validateTestSetup(); + mapboxMap.getStyle().addSource( + new GeoJsonSource("test-id", + fromFeatures(singletonList(fromGeometry(fromLngLats(emptyList())))) + ) + ); + mapboxMap.getStyle().addLayer(new SymbolLayer("test-id", "test-id")); + } + + @Test + @UiThreadTest + public void testPolygonFeatureCollection() { + validateTestSetup(); + mapboxMap.getStyle().addSource( + new GeoJsonSource("test-id", + fromFeatures(singletonList(fromGeometry(Polygon.fromLngLats(emptyList())))) + ) + ); + mapboxMap.getStyle().addLayer(new SymbolLayer("test-id", "test-id")); + } + + @Test + @UiThreadTest + public void testMultiPolygonFeatureCollection() { + validateTestSetup(); + mapboxMap.getStyle().addSource( + new GeoJsonSource("test-id", + fromFeatures(singletonList(fromGeometry(fromPolygon(Polygon.fromLngLats(emptyList()))))) + ) + ); + mapboxMap.getStyle().addLayer(new SymbolLayer("test-id", "test-id")); + } + + @Test + @UiThreadTest + public void testLineStringFeatureCollection() { + validateTestSetup(); + mapboxMap.getStyle().addSource( + new GeoJsonSource("test-id", + fromFeatures(singletonList(fromGeometry(fromLngLats(emptyList())))) + ) + ); + mapboxMap.getStyle().addLayer(new SymbolLayer("test-id", "test-id")); + } + + @Test + @UiThreadTest + public void testMultiLineStringFeatureCollection() { + validateTestSetup(); + mapboxMap.getStyle().addSource( + new GeoJsonSource("test-id", + fromFeatures(singletonList(fromGeometry(fromLineString(fromLngLats(emptyList()))))) + ) + ); + mapboxMap.getStyle().addLayer(new SymbolLayer("test-id", "test-id")); + } + + + @Test + public void testNegativeNumberPropertyConversion() { + validateTestSetup(); + onView(isRoot()).perform(new MapboxMapAction((uiController, mapboxMap) -> { + LatLng latLng = new LatLng(); + Feature feature = Feature.fromGeometry(Point.fromLngLat(latLng.getLongitude(), latLng.getLatitude())); + + JsonArray foregroundJsonArray = new JsonArray(); + foregroundJsonArray.add(0f); + foregroundJsonArray.add(-3f); + feature.addProperty("property", foregroundJsonArray); + + GeoJsonSource source = new GeoJsonSource("source", feature); + mapboxMap.getStyle().addSource(source); + + SymbolLayer layer = new SymbolLayer("layer", "source") + .withProperties( + PropertyFactory.iconOffset(Expression.get("property")), + PropertyFactory.iconImage("zoo-15") + ); + mapboxMap.getStyle().addLayer(layer); + + TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView); + + assertFalse(mapboxMap.queryRenderedFeatures(mapboxMap.getProjection().toScreenLocation(latLng)).isEmpty()); + }, mapboxMap)); + } +}
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/geometry/LatLngBoundsTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/geometry/LatLngBoundsTest.java new file mode 100644 index 0000000000..607d7cd635 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/geometry/LatLngBoundsTest.java @@ -0,0 +1,65 @@ +package com.mapbox.mapboxsdk.testapp.geometry; + +import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.geometry.LatLngBounds; +import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction; +import com.mapbox.mapboxsdk.testapp.activity.BaseTest; +import com.mapbox.mapboxsdk.testapp.activity.feature.QueryRenderedFeaturesBoxHighlightActivity; +import com.mapbox.mapboxsdk.testapp.utils.TestConstants; +import org.junit.Test; + +import static junit.framework.Assert.assertEquals; + +/** + * Instrumentation test to validate integration of LatLngBounds + */ +public class LatLngBoundsTest extends BaseTest { + + private static final double MAP_BEARING = 50; + + @Override + protected Class getActivityClass() { + return QueryRenderedFeaturesBoxHighlightActivity.class; + } + + @Test + public void testLatLngBounds() { + // regression test for #9322 + validateTestSetup(); + MapboxMapAction.invoke(mapboxMap, (uiController, mapboxMap) -> { + LatLngBounds bounds = new LatLngBounds.Builder() + .include(new LatLng(48.8589506, 2.2773457)) + .include(new LatLng(47.2383171, -1.6309316)) + .build(); + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0)); + }); + } + + @Test + public void testLatLngBoundsBearing() { + // regression test for #12549 + validateTestSetup(); + MapboxMapAction.invoke(mapboxMap, (uiController, mapboxMap) -> { + LatLngBounds bounds = new LatLngBounds.Builder() + .include(new LatLng(48.8589506, 2.2773457)) + .include(new LatLng(47.2383171, -1.6309316)) + .build(); + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0)); + mapboxMap.moveCamera(CameraUpdateFactory.bearingTo(MAP_BEARING)); + assertEquals( + "Initial bearing should match for latlngbounds", + mapboxMap.getCameraPosition().bearing, + MAP_BEARING, + TestConstants.BEARING_DELTA + ); + + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0)); + assertEquals("Bearing should match after resetting latlngbounds", + mapboxMap.getCameraPosition().bearing, + MAP_BEARING, + TestConstants.BEARING_DELTA); + }); + } + +}
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/offline/CacheTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/offline/CacheTest.kt new file mode 100644 index 0000000000..a3214c9f11 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/offline/CacheTest.kt @@ -0,0 +1,88 @@ +package com.mapbox.mapboxsdk.testapp.offline + +import android.content.Context +import android.support.test.rule.ActivityTestRule +import android.support.test.runner.AndroidJUnit4 +import com.mapbox.mapboxsdk.offline.OfflineManager +import com.mapbox.mapboxsdk.testapp.activity.FeatureOverviewActivity +import java.util.concurrent.CountDownLatch +import org.junit.Assert +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class CacheTest { + + @Rule + @JvmField + var rule = ActivityTestRule(FeatureOverviewActivity::class.java) + + private val context: Context by lazy { rule.activity } + + private val countDownLatch = CountDownLatch(1) + + @Test + fun testSetMaximumAmbientCacheSize() { + rule.activity.runOnUiThread { + OfflineManager.getInstance(context).setMaximumAmbientCacheSize(10000000, object : OfflineManager.FileSourceCallback { + override fun onSuccess() { + countDownLatch.countDown() + } + + override fun onError(message: String) { + Assert.assertNull("onError should not be called", message) + } + }) + } + countDownLatch.await() + } + + @Test + fun testSetClearAmbientCache() { + rule.activity.runOnUiThread { + OfflineManager.getInstance(context).clearAmbientCache(object : OfflineManager.FileSourceCallback { + override fun onSuccess() { + countDownLatch.countDown() + } + + override fun onError(message: String) { + Assert.assertNull("onError should not be called", message) + } + }) + } + countDownLatch.await() + } + + @Test + fun testSetInvalidateAmbientCache() { + rule.activity.runOnUiThread { + OfflineManager.getInstance(context).invalidateAmbientCache(object : OfflineManager.FileSourceCallback { + override fun onSuccess() { + countDownLatch.countDown() + } + + override fun onError(message: String) { + Assert.assertNull("onError should not be called", message) + } + }) + } + countDownLatch.await() + } + + @Test + fun testSetResetDatabase() { + rule.activity.runOnUiThread { + OfflineManager.getInstance(context).resetDatabase(object : OfflineManager.FileSourceCallback { + override fun onSuccess() { + countDownLatch.countDown() + } + + override fun onError(message: String) { + Assert.assertNull("onError should not be called", message) + } + }) + } + countDownLatch.await() + } +}
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/offline/OfflineManagerTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/offline/OfflineManagerTest.kt new file mode 100644 index 0000000000..e07dc1e9f1 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/offline/OfflineManagerTest.kt @@ -0,0 +1,124 @@ +package com.mapbox.mapboxsdk.testapp.offline + +import android.content.Context +import android.support.test.rule.ActivityTestRule +import android.support.test.runner.AndroidJUnit4 +import com.mapbox.mapboxsdk.AppCenter +import com.mapbox.mapboxsdk.offline.OfflineManager +import com.mapbox.mapboxsdk.offline.OfflineRegion +import com.mapbox.mapboxsdk.storage.FileSource +import com.mapbox.mapboxsdk.testapp.activity.FeatureOverviewActivity +import com.mapbox.mapboxsdk.testapp.utils.FileUtils +import java.io.IOException +import java.util.concurrent.CountDownLatch +import org.junit.FixMethodOrder +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@RunWith(AndroidJUnit4::class) +class OfflineManagerTest : AppCenter() { + + companion object { + private const val TEST_DB_FILE_NAME = "offline_test.db" + private lateinit var mergedRegion: OfflineRegion + } + + @Rule + @JvmField + var rule = ActivityTestRule(FeatureOverviewActivity::class.java) + + private val context: Context by lazy { rule.activity } + + @Test(timeout = 30_000) + fun a_copyFileFromAssets() { + val latch = CountDownLatch(1) + rule.activity.runOnUiThread { + FileUtils.CopyFileFromAssetsTask(rule.activity, object : FileUtils.OnFileCopiedFromAssetsListener { + override fun onFileCopiedFromAssets() { + latch.countDown() + } + + override fun onError() { + throw IOException("Unable to copy DB file.") + } + }).execute(TEST_DB_FILE_NAME, FileSource.getResourcesCachePath(rule.activity)) + } + latch.await() + } + + @Test(timeout = 30_000) + fun b_mergeRegion() { + val latch = CountDownLatch(1) + rule.activity.runOnUiThread { + OfflineManager.getInstance(context).mergeOfflineRegions( + FileSource.getResourcesCachePath(rule.activity) + "/" + TEST_DB_FILE_NAME, + object : OfflineManager.MergeOfflineRegionsCallback { + override fun onMerge(offlineRegions: Array<out OfflineRegion>?) { + assert(offlineRegions?.size == 1) + latch.countDown() + } + + override fun onError(error: String?) { + throw RuntimeException("Unable to merge external offline database. $error") + } + }) + } + latch.await() + } + + @Test(timeout = 30_000) + fun c_listRegion() { + val latch = CountDownLatch(1) + rule.activity.runOnUiThread { + OfflineManager.getInstance(context).listOfflineRegions(object : OfflineManager.ListOfflineRegionsCallback { + override fun onList(offlineRegions: Array<out OfflineRegion>?) { + assert(offlineRegions?.size == 1) + mergedRegion = offlineRegions!![0] + latch.countDown() + } + + override fun onError(error: String?) { + throw RuntimeException("Unable to merge external offline database. $error") + } + }) + } + latch.await() + } + + @Test(timeout = 30_000) + fun d_invalidateRegion() { + val latch = CountDownLatch(1) + rule.activity.runOnUiThread { + mergedRegion.invalidate(object : OfflineRegion.OfflineRegionInvalidateCallback { + override fun onInvalidate() { + latch.countDown() + } + + override fun onError(error: String?) { + throw RuntimeException("Unable to delete region") + } + }) + } + latch.await() + } + + @Test(timeout = 30_000) + fun e_deleteRegion() { + val latch = CountDownLatch(1) + rule.activity.runOnUiThread { + mergedRegion.delete(object : OfflineRegion.OfflineRegionDeleteCallback { + override fun onDelete() { + latch.countDown() + } + + override fun onError(error: String?) { + throw RuntimeException("Unable to delete region") + } + }) + } + latch.await() + } +}
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/offline/OfflineUtilsTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/offline/OfflineUtilsTest.java new file mode 100644 index 0000000000..48eb8e832d --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/offline/OfflineUtilsTest.java @@ -0,0 +1,41 @@ +package com.mapbox.mapboxsdk.testapp.offline; + +import android.support.test.runner.AndroidJUnit4; + +import com.mapbox.mapboxsdk.AppCenter; +import com.mapbox.mapboxsdk.testapp.utils.OfflineUtils; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.io.UnsupportedEncodingException; +import java.util.Arrays; + +import static com.mapbox.mapboxsdk.testapp.activity.offline.OfflineActivity.JSON_CHARSET; +import static junit.framework.Assert.assertEquals; +import static junit.framework.TestCase.assertTrue; + +@RunWith(AndroidJUnit4.class) +public class OfflineUtilsTest extends AppCenter { + + private static final String REGION_NAME = "hello world"; + private static final String CONVERTED_REGION_NAME = "{\"FIELD_REGION_NAME\":\"hello world\"}"; + + @Test + public void testOfflineUtilsConvertToBytes() throws UnsupportedEncodingException { + byte[] expected = CONVERTED_REGION_NAME.getBytes(JSON_CHARSET); + byte[] actual = OfflineUtils.convertRegionName(REGION_NAME); + assertTrue("Bytes arrays should match", Arrays.equals(expected, actual)); + } + + @Test + public void testOfflineUtilsConvertToString() throws UnsupportedEncodingException { + String actual = OfflineUtils.convertRegionName(CONVERTED_REGION_NAME.getBytes(JSON_CHARSET)); + assertEquals("Strings should match", REGION_NAME, actual); + } + + @Test + public void testOfflineUtilsConvertNoOp() { + String convertNoOp = OfflineUtils.convertRegionName(OfflineUtils.convertRegionName(REGION_NAME)); + assertEquals("Strings should match", REGION_NAME, convertNoOp); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/render/RenderTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/render/RenderTest.java new file mode 100644 index 0000000000..c74e110b6c --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/render/RenderTest.java @@ -0,0 +1,74 @@ +package com.mapbox.mapboxsdk.testapp.render; + +import android.Manifest; +import android.support.test.espresso.IdlingPolicies; +import android.support.test.espresso.IdlingRegistry; +import android.support.test.espresso.IdlingResourceTimeoutException; +import android.support.test.rule.ActivityTestRule; +import android.support.test.rule.GrantPermissionRule; +import android.support.test.runner.AndroidJUnit4; + +import com.mapbox.mapboxsdk.AppCenter; +import com.mapbox.mapboxsdk.testapp.activity.render.RenderTestActivity; +import com.mapbox.mapboxsdk.testapp.utils.SnapshotterIdlingResource; +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import timber.log.Timber; + +import java.util.concurrent.TimeUnit; + +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.assertion.ViewAssertions.matches; +import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +import static android.support.test.espresso.matcher.ViewMatchers.withId; + +/** + * Instrumentation render tests + */ +@RunWith(AndroidJUnit4.class) +public class RenderTest extends AppCenter { + + private static final int RENDER_TEST_TIMEOUT = 30; + private SnapshotterIdlingResource idlingResource; + + @Rule + public ActivityTestRule<RenderTestActivity> activityRule = new ActivityTestRule<>(RenderTestActivity.class); + + @Rule + public GrantPermissionRule writeRule = GrantPermissionRule.grant(Manifest.permission.WRITE_EXTERNAL_STORAGE); + + @Rule + public GrantPermissionRule readRule = GrantPermissionRule.grant(Manifest.permission.READ_EXTERNAL_STORAGE); + + @Before + public void beforeTest() { + IdlingPolicies.setMasterPolicyTimeout(RENDER_TEST_TIMEOUT, TimeUnit.MINUTES); + setupIdlingResource(); + } + + private void setupIdlingResource() { + try { + Timber.e("@Before test: register idle resource"); + IdlingPolicies.setIdlingResourceTimeout(RENDER_TEST_TIMEOUT, TimeUnit.MINUTES); + IdlingRegistry.getInstance().register(idlingResource = new SnapshotterIdlingResource(activityRule.getActivity())); + } catch (IdlingResourceTimeoutException idlingResourceTimeoutException) { + throw new RuntimeException("Idling out!"); + } + } + + @Test + @Ignore + public void testRender() { + onView(withId(android.R.id.content)).check(matches(isDisplayed())); + } + + @After + public void afterTest() { + Timber.e("@After test: unregister idle resource"); + IdlingRegistry.getInstance().unregister(idlingResource); + } +}
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/storage/FileSourceMapTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/storage/FileSourceMapTest.kt new file mode 100644 index 0000000000..d08507470e --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/storage/FileSourceMapTest.kt @@ -0,0 +1,59 @@ +package com.mapbox.mapboxsdk.testapp.storage + +import android.support.test.annotation.UiThreadTest +import android.support.test.rule.ActivityTestRule +import android.support.test.runner.AndroidJUnit4 +import com.mapbox.mapboxsdk.AppCenter +import com.mapbox.mapboxsdk.storage.FileSource +import com.mapbox.mapboxsdk.testapp.activity.espresso.EspressoTestActivity +import java.util.concurrent.CountDownLatch +import junit.framework.Assert +import org.junit.After +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.rules.TestName +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +open class FileSourceMapTest : AppCenter() { + + private lateinit var fileSourceTestUtils: FileSourceTestUtils + + @get:Rule + val rule = ActivityTestRule(EspressoTestActivity::class.java) + + @get:Rule + val testName = TestName() + + @Before + @UiThreadTest + fun setup() { + fileSourceTestUtils = FileSourceTestUtils(rule.activity) + fileSourceTestUtils.setup() + } + + @Test + fun changeResourcesPathWhileMapVisible() { + val latch = CountDownLatch(1) + rule.activity.runOnUiThread { + FileSource.setResourcesCachePath(fileSourceTestUtils.testPath, object : FileSource.ResourcesCachePathChangeCallback { + override fun onSuccess(path: String) { + Assert.fail("Requested resources change while the map is running should fail") + } + + override fun onError(message: String) { + Assert.assertEquals("Cannot set path, file source is activated." + + " Make sure that the map or a resources download is not running.", message) + latch.countDown() + } + }) + } + latch.await() + } + + @After + fun cleanup() { + fileSourceTestUtils.cleanup() + } +}
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/storage/FileSourceStandaloneTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/storage/FileSourceStandaloneTest.kt new file mode 100644 index 0000000000..59f0d04237 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/storage/FileSourceStandaloneTest.kt @@ -0,0 +1,116 @@ +package com.mapbox.mapboxsdk.testapp.storage + +import android.support.test.annotation.UiThreadTest +import android.support.test.rule.ActivityTestRule +import android.support.test.runner.AndroidJUnit4 +import com.mapbox.mapboxsdk.AppCenter +import com.mapbox.mapboxsdk.storage.FileSource +import com.mapbox.mapboxsdk.testapp.activity.FeatureOverviewActivity +import java.util.concurrent.CountDownLatch +import java.util.concurrent.TimeUnit +import org.junit.* +import org.junit.rules.TestName +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class FileSourceStandaloneTest : AppCenter() { + + private lateinit var fileSourceTestUtils: FileSourceTestUtils + private lateinit var fileSource: FileSource + + @get:Rule + val rule = ActivityTestRule(FeatureOverviewActivity::class.java) + + @get:Rule + val testName = TestName() + + @Before + @UiThreadTest + fun setup() { + fileSource = FileSource.getInstance(rule.activity) + fileSourceTestUtils = FileSourceTestUtils(rule.activity) + fileSourceTestUtils.setup() + } + + @Test + @UiThreadTest + fun testDefault() { + Assert.assertFalse("FileSource should not be active", fileSource.isActivated) + } + + @Test + @UiThreadTest + fun testActivateDeactivate() { + Assert.assertFalse("1) FileSource should not be active", fileSource.isActivated) + fileSource.activate() + Assert.assertTrue("2) FileSource should be active", fileSource.isActivated) + fileSource.deactivate() + Assert.assertFalse("3) FileSource should not be active", fileSource.isActivated) + } + + @Test + fun pathChangeTest() { + Assert.assertFalse("FileSource should not be active", fileSource.isActivated) + Assert.assertEquals(fileSourceTestUtils.originalPath, FileSource.getResourcesCachePath(rule.activity)) + + fileSourceTestUtils.changePath(fileSourceTestUtils.testPath) + Assert.assertEquals(fileSourceTestUtils.testPath, FileSource.getResourcesCachePath(rule.activity)) + + fileSourceTestUtils.changePath(fileSourceTestUtils.originalPath) + Assert.assertEquals(fileSourceTestUtils.originalPath, FileSource.getResourcesCachePath(rule.activity)) + } + + @Test + fun overridePathChangeCallTest() { + val firstLatch = CountDownLatch(1) + val secondLatch = CountDownLatch(1) + rule.activity.runOnUiThread { + FileSource.setResourcesCachePath( + fileSourceTestUtils.testPath, + object : FileSource.ResourcesCachePathChangeCallback { + override fun onSuccess(path: String) { + Assert.assertEquals(fileSourceTestUtils.testPath, path) + firstLatch.countDown() + } + + override fun onError(message: String) { + Assert.fail("First attempt should succeed.") + } + }) + + FileSource.setResourcesCachePath( + fileSourceTestUtils.testPath2, + object : FileSource.ResourcesCachePathChangeCallback { + override fun onSuccess(path: String) { + Assert.fail("Second attempt should fail because first one is in progress.") + } + + override fun onError(message: String) { + Assert.assertEquals("Another resources cache path change is in progress", message) + secondLatch.countDown() + } + }) + } + + if (!secondLatch.await(5, TimeUnit.SECONDS)) { + rule.runOnUiThread { + // if we fail to call a callback, the file source is not going to be deactivated + fileSource.deactivate() + } + Assert.fail("Second attempt should fail.") + } + + if (!firstLatch.await(5, TimeUnit.SECONDS)) { + rule.runOnUiThread { + // if we fail to call a callback, the file source is not going to be deactivated + fileSource.deactivate() + } + Assert.fail("First attempt should succeed.") + } + } + + @After + fun cleanup() { + fileSourceTestUtils.cleanup() + } +}
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/storage/FileSourceTestUtils.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/storage/FileSourceTestUtils.kt new file mode 100644 index 0000000000..6bd97056a6 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/storage/FileSourceTestUtils.kt @@ -0,0 +1,59 @@ +package com.mapbox.mapboxsdk.testapp.storage + +import android.app.Activity +import android.support.annotation.WorkerThread +import com.mapbox.mapboxsdk.AppCenter +import com.mapbox.mapboxsdk.storage.FileSource +import java.io.File +import java.util.concurrent.CountDownLatch +import junit.framework.Assert + +class FileSourceTestUtils(private val activity: Activity) : AppCenter() { + val originalPath = FileSource.getResourcesCachePath(activity) + val testPath = "$originalPath/test" + val testPath2 = "$originalPath/test2" + + private val paths = listOf(testPath, testPath2) + + fun setup() { + for (path in paths) { + val testFile = File(path) + testFile.mkdirs() + } + } + + @WorkerThread + fun cleanup() { + val currentPath = FileSource.getResourcesCachePath(activity) + if (currentPath != originalPath) { + changePath(originalPath) + } + + for (path in paths) { + val testFile = File(path) + if (testFile.exists()) { + testFile.deleteRecursively() + } + } + } + + @WorkerThread + fun changePath(requestedPath: String) { + val latch = CountDownLatch(1) + activity.runOnUiThread { + FileSource.setResourcesCachePath( + requestedPath, + object : FileSource.ResourcesCachePathChangeCallback { + override fun onSuccess(path: String) { + Assert.assertEquals(requestedPath, path) + latch.countDown() + } + + override fun onError(message: String) { + Assert.fail("Resource path change failed - path: $requestedPath, message: $message") + } + }) + } + latch.await() + } +}
\ No newline at end of file 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..0ef8051a3f --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/string/UppperLowerCaseTest.java @@ -0,0 +1,47 @@ +package com.mapbox.mapboxsdk.testapp.string; + +import android.support.test.runner.AndroidJUnit4; +import com.mapbox.mapboxsdk.testapp.activity.EspressoTest; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static junit.framework.Assert.assertEquals; + +/** + * Test verifying if String#toUpperCase and String#toLowerCase produces desired results + * <p> + * See core test in https://github.com/mapbox/mapbox-gl-native/blob/master/test/util/text_conversions.test.cpp + * </p> + */ +@RunWith(AndroidJUnit4.class) +public class UppperLowerCaseTest extends EspressoTest { + + @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()); // + } + +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/BackgroundLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/BackgroundLayerTest.java new file mode 100644 index 0000000000..d3edfb852d --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/BackgroundLayerTest.java @@ -0,0 +1,141 @@ +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`. + +package com.mapbox.mapboxsdk.testapp.style; + +import android.graphics.Color; +import android.support.test.annotation.UiThreadTest; +import android.support.test.runner.AndroidJUnit4; + +import com.mapbox.mapboxsdk.maps.BaseLayerTest; +import org.junit.Before; +import timber.log.Timber; + +import com.mapbox.mapboxsdk.style.expressions.Expression; +import com.mapbox.mapboxsdk.style.layers.BackgroundLayer; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static com.mapbox.mapboxsdk.style.expressions.Expression.*; +import static org.junit.Assert.*; +import static com.mapbox.mapboxsdk.style.layers.Property.*; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*; + +import com.mapbox.mapboxsdk.style.layers.TransitionOptions; + +/** + * Basic smoke tests for BackgroundLayer + */ +@RunWith(AndroidJUnit4.class) +public class BackgroundLayerTest extends BaseLayerTest { + + private BackgroundLayer layer; + + @Before + @UiThreadTest + public void beforeTest(){ + super.before(); + layer = new BackgroundLayer("my-layer"); + setupLayer(layer); + } + + @Test + @UiThreadTest + public void testSetVisibility() { + Timber.i("Visibility"); + assertNotNull(layer); + + // Get initial + assertEquals(layer.getVisibility().getValue(), VISIBLE); + + // Set + layer.setProperties(visibility(NONE)); + assertEquals(layer.getVisibility().getValue(), NONE); + } + + @Test + @UiThreadTest + public void testBackgroundColorTransition() { + Timber.i("background-colorTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setBackgroundColorTransition(options); + assertEquals(layer.getBackgroundColorTransition(), options); + } + + @Test + @UiThreadTest + public void testBackgroundColorAsConstant() { + Timber.i("background-color"); + assertNotNull(layer); + assertNull(layer.getBackgroundColor().getValue()); + + // Set and Get + String propertyValue = "rgba(255,128,0,0.7)"; + layer.setProperties(backgroundColor(propertyValue)); + assertEquals(layer.getBackgroundColor().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testBackgroundColorAsIntConstant() { + Timber.i("background-color"); + assertNotNull(layer); + + // Set and Get + layer.setProperties(backgroundColor(Color.argb(127, 255, 127, 0))); + assertEquals(layer.getBackgroundColorAsInt(), Color.argb(127, 255, 127, 0)); + } + + @Test + @UiThreadTest + public void testBackgroundPatternTransition() { + Timber.i("background-patternTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setBackgroundPatternTransition(options); + assertEquals(layer.getBackgroundPatternTransition(), options); + } + + @Test + @UiThreadTest + public void testBackgroundPatternAsConstant() { + Timber.i("background-pattern"); + assertNotNull(layer); + assertNull(layer.getBackgroundPattern().getValue()); + + // Set and Get + String propertyValue = "pedestrian-polygon"; + layer.setProperties(backgroundPattern(propertyValue)); + assertEquals(layer.getBackgroundPattern().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testBackgroundOpacityTransition() { + Timber.i("background-opacityTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setBackgroundOpacityTransition(options); + assertEquals(layer.getBackgroundOpacityTransition(), options); + } + + @Test + @UiThreadTest + public void testBackgroundOpacityAsConstant() { + Timber.i("background-opacity"); + assertNotNull(layer); + assertNull(layer.getBackgroundOpacity().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(backgroundOpacity(propertyValue)); + assertEquals(layer.getBackgroundOpacity().getValue(), propertyValue); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CircleLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CircleLayerTest.java new file mode 100644 index 0000000000..146cfc2209 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CircleLayerTest.java @@ -0,0 +1,453 @@ +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`. + +package com.mapbox.mapboxsdk.testapp.style; + +import android.graphics.Color; +import android.support.test.annotation.UiThreadTest; +import android.support.test.runner.AndroidJUnit4; + +import com.mapbox.mapboxsdk.maps.BaseLayerTest; +import org.junit.Before; +import timber.log.Timber; + +import com.mapbox.mapboxsdk.style.expressions.Expression; +import com.mapbox.mapboxsdk.style.layers.CircleLayer; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static com.mapbox.mapboxsdk.style.expressions.Expression.*; +import static org.junit.Assert.*; +import static com.mapbox.mapboxsdk.style.layers.Property.*; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*; + +import com.mapbox.mapboxsdk.style.layers.TransitionOptions; + +/** + * Basic smoke tests for CircleLayer + */ +@RunWith(AndroidJUnit4.class) +public class CircleLayerTest extends BaseLayerTest { + + private CircleLayer layer; + + @Before + @UiThreadTest + public void beforeTest(){ + super.before(); + layer = new CircleLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + setupLayer(layer); + } + + @Test + @UiThreadTest + public void testSourceId() { + Timber.i("SourceId"); + assertNotNull(layer); + assertEquals(layer.getSourceId(), "composite"); + } + + @Test + @UiThreadTest + public void testSetVisibility() { + Timber.i("Visibility"); + assertNotNull(layer); + + // Get initial + assertEquals(layer.getVisibility().getValue(), VISIBLE); + + // Set + layer.setProperties(visibility(NONE)); + assertEquals(layer.getVisibility().getValue(), NONE); + } + + @Test + @UiThreadTest + public void testSourceLayer() { + Timber.i("SourceLayer"); + assertNotNull(layer); + + // Get initial + assertEquals(layer.getSourceLayer(), "composite"); + + // Set + final String sourceLayer = "test"; + layer.setSourceLayer(sourceLayer); + assertEquals(layer.getSourceLayer(), sourceLayer); + } + + @Test + @UiThreadTest + public void testFilter() { + Timber.i("Filter"); + assertNotNull(layer); + + // Get initial + assertEquals(layer.getFilter(), null); + + // Set + Expression filter = eq(get("undefined"), literal(1.0)); + layer.setFilter(filter); + assertEquals(layer.getFilter().toString(), filter.toString()); + + // Set constant + filter = literal(true); + layer.setFilter(filter); + assertEquals(layer.getFilter().toString(), filter.toString()); + } + + + + @Test + @UiThreadTest + public void testCircleRadiusTransition() { + Timber.i("circle-radiusTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setCircleRadiusTransition(options); + assertEquals(layer.getCircleRadiusTransition(), options); + } + + @Test + @UiThreadTest + public void testCircleRadiusAsConstant() { + Timber.i("circle-radius"); + assertNotNull(layer); + assertNull(layer.getCircleRadius().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(circleRadius(propertyValue)); + assertEquals(layer.getCircleRadius().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testCircleRadiusAsExpression() { + Timber.i("circle-radius-expression"); + assertNotNull(layer); + assertNull(layer.getCircleRadius().getExpression()); + + // Set and Get + Expression expression = number(Expression.get("undefined")); + layer.setProperties(circleRadius(expression)); + assertEquals(layer.getCircleRadius().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testCircleColorTransition() { + Timber.i("circle-colorTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setCircleColorTransition(options); + assertEquals(layer.getCircleColorTransition(), options); + } + + @Test + @UiThreadTest + public void testCircleColorAsConstant() { + Timber.i("circle-color"); + assertNotNull(layer); + assertNull(layer.getCircleColor().getValue()); + + // Set and Get + String propertyValue = "rgba(255,128,0,0.7)"; + layer.setProperties(circleColor(propertyValue)); + assertEquals(layer.getCircleColor().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testCircleColorAsExpression() { + Timber.i("circle-color-expression"); + assertNotNull(layer); + assertNull(layer.getCircleColor().getExpression()); + + // Set and Get + Expression expression = toColor(Expression.get("undefined")); + layer.setProperties(circleColor(expression)); + assertEquals(layer.getCircleColor().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testCircleColorAsIntConstant() { + Timber.i("circle-color"); + assertNotNull(layer); + + // Set and Get + layer.setProperties(circleColor(Color.argb(127, 255, 127, 0))); + assertEquals(layer.getCircleColorAsInt(), Color.argb(127, 255, 127, 0)); + } + + @Test + @UiThreadTest + public void testCircleBlurTransition() { + Timber.i("circle-blurTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setCircleBlurTransition(options); + assertEquals(layer.getCircleBlurTransition(), options); + } + + @Test + @UiThreadTest + public void testCircleBlurAsConstant() { + Timber.i("circle-blur"); + assertNotNull(layer); + assertNull(layer.getCircleBlur().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(circleBlur(propertyValue)); + assertEquals(layer.getCircleBlur().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testCircleBlurAsExpression() { + Timber.i("circle-blur-expression"); + assertNotNull(layer); + assertNull(layer.getCircleBlur().getExpression()); + + // Set and Get + Expression expression = number(Expression.get("undefined")); + layer.setProperties(circleBlur(expression)); + assertEquals(layer.getCircleBlur().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testCircleOpacityTransition() { + Timber.i("circle-opacityTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setCircleOpacityTransition(options); + assertEquals(layer.getCircleOpacityTransition(), options); + } + + @Test + @UiThreadTest + public void testCircleOpacityAsConstant() { + Timber.i("circle-opacity"); + assertNotNull(layer); + assertNull(layer.getCircleOpacity().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(circleOpacity(propertyValue)); + assertEquals(layer.getCircleOpacity().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testCircleOpacityAsExpression() { + Timber.i("circle-opacity-expression"); + assertNotNull(layer); + assertNull(layer.getCircleOpacity().getExpression()); + + // Set and Get + Expression expression = number(Expression.get("undefined")); + layer.setProperties(circleOpacity(expression)); + assertEquals(layer.getCircleOpacity().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testCircleTranslateTransition() { + Timber.i("circle-translateTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setCircleTranslateTransition(options); + assertEquals(layer.getCircleTranslateTransition(), options); + } + + @Test + @UiThreadTest + public void testCircleTranslateAsConstant() { + Timber.i("circle-translate"); + assertNotNull(layer); + assertNull(layer.getCircleTranslate().getValue()); + + // Set and Get + Float[] propertyValue = new Float[] {0f, 0f}; + layer.setProperties(circleTranslate(propertyValue)); + assertEquals(layer.getCircleTranslate().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testCircleTranslateAnchorAsConstant() { + Timber.i("circle-translate-anchor"); + assertNotNull(layer); + assertNull(layer.getCircleTranslateAnchor().getValue()); + + // Set and Get + String propertyValue = CIRCLE_TRANSLATE_ANCHOR_MAP; + layer.setProperties(circleTranslateAnchor(propertyValue)); + assertEquals(layer.getCircleTranslateAnchor().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testCirclePitchScaleAsConstant() { + Timber.i("circle-pitch-scale"); + assertNotNull(layer); + assertNull(layer.getCirclePitchScale().getValue()); + + // Set and Get + String propertyValue = CIRCLE_PITCH_SCALE_MAP; + layer.setProperties(circlePitchScale(propertyValue)); + assertEquals(layer.getCirclePitchScale().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testCirclePitchAlignmentAsConstant() { + Timber.i("circle-pitch-alignment"); + assertNotNull(layer); + assertNull(layer.getCirclePitchAlignment().getValue()); + + // Set and Get + String propertyValue = CIRCLE_PITCH_ALIGNMENT_MAP; + layer.setProperties(circlePitchAlignment(propertyValue)); + assertEquals(layer.getCirclePitchAlignment().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testCircleStrokeWidthTransition() { + Timber.i("circle-stroke-widthTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setCircleStrokeWidthTransition(options); + assertEquals(layer.getCircleStrokeWidthTransition(), options); + } + + @Test + @UiThreadTest + public void testCircleStrokeWidthAsConstant() { + Timber.i("circle-stroke-width"); + assertNotNull(layer); + assertNull(layer.getCircleStrokeWidth().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(circleStrokeWidth(propertyValue)); + assertEquals(layer.getCircleStrokeWidth().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testCircleStrokeWidthAsExpression() { + Timber.i("circle-stroke-width-expression"); + assertNotNull(layer); + assertNull(layer.getCircleStrokeWidth().getExpression()); + + // Set and Get + Expression expression = number(Expression.get("undefined")); + layer.setProperties(circleStrokeWidth(expression)); + assertEquals(layer.getCircleStrokeWidth().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testCircleStrokeColorTransition() { + Timber.i("circle-stroke-colorTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setCircleStrokeColorTransition(options); + assertEquals(layer.getCircleStrokeColorTransition(), options); + } + + @Test + @UiThreadTest + public void testCircleStrokeColorAsConstant() { + Timber.i("circle-stroke-color"); + assertNotNull(layer); + assertNull(layer.getCircleStrokeColor().getValue()); + + // Set and Get + String propertyValue = "rgba(255,128,0,0.7)"; + layer.setProperties(circleStrokeColor(propertyValue)); + assertEquals(layer.getCircleStrokeColor().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testCircleStrokeColorAsExpression() { + Timber.i("circle-stroke-color-expression"); + assertNotNull(layer); + assertNull(layer.getCircleStrokeColor().getExpression()); + + // Set and Get + Expression expression = toColor(Expression.get("undefined")); + layer.setProperties(circleStrokeColor(expression)); + assertEquals(layer.getCircleStrokeColor().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testCircleStrokeColorAsIntConstant() { + Timber.i("circle-stroke-color"); + assertNotNull(layer); + + // Set and Get + layer.setProperties(circleStrokeColor(Color.argb(127, 255, 127, 0))); + assertEquals(layer.getCircleStrokeColorAsInt(), Color.argb(127, 255, 127, 0)); + } + + @Test + @UiThreadTest + public void testCircleStrokeOpacityTransition() { + Timber.i("circle-stroke-opacityTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setCircleStrokeOpacityTransition(options); + assertEquals(layer.getCircleStrokeOpacityTransition(), options); + } + + @Test + @UiThreadTest + public void testCircleStrokeOpacityAsConstant() { + Timber.i("circle-stroke-opacity"); + assertNotNull(layer); + assertNull(layer.getCircleStrokeOpacity().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(circleStrokeOpacity(propertyValue)); + assertEquals(layer.getCircleStrokeOpacity().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testCircleStrokeOpacityAsExpression() { + Timber.i("circle-stroke-opacity-expression"); + assertNotNull(layer); + assertNull(layer.getCircleStrokeOpacity().getExpression()); + + // Set and Get + Expression expression = number(Expression.get("undefined")); + layer.setProperties(circleStrokeOpacity(expression)); + assertEquals(layer.getCircleStrokeOpacity().getExpression(), expression); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CustomGeometrySourceTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CustomGeometrySourceTest.kt new file mode 100644 index 0000000000..9c2eb3df81 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CustomGeometrySourceTest.kt @@ -0,0 +1,69 @@ +package com.mapbox.mapboxsdk.testapp.style + +import android.support.test.espresso.Espresso.onView +import android.support.test.espresso.matcher.ViewMatchers.isRoot +import com.mapbox.mapboxsdk.style.sources.CustomGeometrySource.THREAD_POOL_LIMIT +import com.mapbox.mapboxsdk.style.sources.CustomGeometrySource.THREAD_PREFIX +import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke +import com.mapbox.mapboxsdk.testapp.action.OrientationAction.orientationLandscape +import com.mapbox.mapboxsdk.testapp.action.OrientationAction.orientationPortrait +import com.mapbox.mapboxsdk.testapp.action.WaitAction +import com.mapbox.mapboxsdk.testapp.activity.BaseTest +import com.mapbox.mapboxsdk.testapp.activity.style.GridSourceActivity +import com.mapbox.mapboxsdk.testapp.activity.style.GridSourceActivity.ID_GRID_LAYER +import com.mapbox.mapboxsdk.testapp.activity.style.GridSourceActivity.ID_GRID_SOURCE +import com.mapbox.mapboxsdk.testapp.utils.TestingAsyncUtils +import org.junit.Assert +import org.junit.Test + +class CustomGeometrySourceTest : BaseTest() { + + override fun getActivityClass(): Class<*> = GridSourceActivity::class.java + + @Test + fun sourceNotLeakingThreadsTest() { + validateTestSetup() + WaitAction.invoke(4000) + onView(isRoot()).perform(orientationLandscape()) + WaitAction.invoke(2000) + onView(isRoot()).perform(orientationPortrait()) + WaitAction.invoke(2000) + Assert.assertFalse("Threads should be shutdown when the source is destroyed.", + Thread.getAllStackTraces().keys.filter { + it.name.startsWith(THREAD_PREFIX) + }.count() > THREAD_POOL_LIMIT) + } + + @Test + fun threadsShutdownWhenSourceRemovedTest() { + validateTestSetup() + invoke(mapboxMap) { uiController, mapboxMap -> + mapboxMap.style!!.removeLayer(ID_GRID_LAYER) + TestingAsyncUtils.waitForLayer(uiController, mapView) + mapboxMap.style!!.removeSource(ID_GRID_SOURCE) + TestingAsyncUtils.waitForLayer(uiController, mapView) + Assert.assertTrue("There should be no threads running when the source is removed.", + Thread.getAllStackTraces().keys.filter { + it.name.startsWith(THREAD_PREFIX) + }.count() == 0) + } + } + + @Test + fun threadsRestartedWhenSourceReAddedTest() { + validateTestSetup() + invoke(mapboxMap) { uiController, mapboxMap -> + mapboxMap.style!!.removeLayer((rule.activity as GridSourceActivity).layer) + TestingAsyncUtils.waitForLayer(uiController, mapView) + mapboxMap.style!!.removeSource(ID_GRID_SOURCE) + TestingAsyncUtils.waitForLayer(uiController, mapView) + mapboxMap.style!!.addSource((rule.activity as GridSourceActivity).source) + mapboxMap.style!!.addLayer((rule.activity as GridSourceActivity).layer) + TestingAsyncUtils.waitForLayer(uiController, mapView) + Assert.assertTrue("Threads should be restarted when the source is re-added to the map.", + Thread.getAllStackTraces().keys.filter { + it.name.startsWith(THREAD_PREFIX) + }.count() == THREAD_POOL_LIMIT) + } + } +}
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/ExpressionTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/ExpressionTest.java new file mode 100644 index 0000000000..95bd651cff --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/ExpressionTest.java @@ -0,0 +1,786 @@ +package com.mapbox.mapboxsdk.testapp.style; + +import android.graphics.Color; +import android.support.test.runner.AndroidJUnit4; + +import com.mapbox.geojson.Feature; +import com.mapbox.geojson.Point; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.style.expressions.Expression; +import com.mapbox.mapboxsdk.style.layers.CircleLayer; +import com.mapbox.mapboxsdk.style.layers.FillLayer; +import com.mapbox.mapboxsdk.style.layers.Layer; +import com.mapbox.mapboxsdk.style.layers.SymbolLayer; +import com.mapbox.mapboxsdk.style.sources.GeoJsonSource; +import com.mapbox.mapboxsdk.style.sources.Source; +import com.mapbox.mapboxsdk.style.types.Formatted; +import com.mapbox.mapboxsdk.style.types.FormattedSection; +import com.mapbox.mapboxsdk.testapp.R; +import com.mapbox.mapboxsdk.testapp.activity.EspressoTest; +import com.mapbox.mapboxsdk.testapp.utils.ResourceUtils; +import com.mapbox.mapboxsdk.testapp.utils.TestingAsyncUtils; +import com.mapbox.mapboxsdk.utils.ColorUtils; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.io.IOException; +import java.util.HashMap; + +import timber.log.Timber; + +import static com.mapbox.mapboxsdk.style.expressions.Expression.FormatOption.formatFontScale; +import static com.mapbox.mapboxsdk.style.expressions.Expression.FormatOption.formatTextColor; +import static com.mapbox.mapboxsdk.style.expressions.Expression.FormatOption.formatTextFont; +import static com.mapbox.mapboxsdk.style.expressions.Expression.NumberFormatOption.currency; +import static com.mapbox.mapboxsdk.style.expressions.Expression.NumberFormatOption.locale; +import static com.mapbox.mapboxsdk.style.expressions.Expression.NumberFormatOption.maxFractionDigits; +import static com.mapbox.mapboxsdk.style.expressions.Expression.NumberFormatOption.minFractionDigits; +import static com.mapbox.mapboxsdk.style.expressions.Expression.collator; +import static com.mapbox.mapboxsdk.style.expressions.Expression.color; +import static com.mapbox.mapboxsdk.style.expressions.Expression.eq; +import static com.mapbox.mapboxsdk.style.expressions.Expression.exponential; +import static com.mapbox.mapboxsdk.style.expressions.Expression.format; +import static com.mapbox.mapboxsdk.style.expressions.Expression.formatEntry; +import static com.mapbox.mapboxsdk.style.expressions.Expression.get; +import static com.mapbox.mapboxsdk.style.expressions.Expression.interpolate; +import static com.mapbox.mapboxsdk.style.expressions.Expression.literal; +import static com.mapbox.mapboxsdk.style.expressions.Expression.match; +import static com.mapbox.mapboxsdk.style.expressions.Expression.number; +import static com.mapbox.mapboxsdk.style.expressions.Expression.numberFormat; +import static com.mapbox.mapboxsdk.style.expressions.Expression.rgb; +import static com.mapbox.mapboxsdk.style.expressions.Expression.rgba; +import static com.mapbox.mapboxsdk.style.expressions.Expression.step; +import static com.mapbox.mapboxsdk.style.expressions.Expression.stop; +import static com.mapbox.mapboxsdk.style.expressions.Expression.string; +import static com.mapbox.mapboxsdk.style.expressions.Expression.switchCase; +import static com.mapbox.mapboxsdk.style.expressions.Expression.toColor; +import static com.mapbox.mapboxsdk.style.expressions.Expression.zoom; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleColor; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillAntialias; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillColor; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillOutlineColor; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textColor; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textField; +import static com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +@RunWith(AndroidJUnit4.class) +public class ExpressionTest extends EspressoTest { + + private FillLayer layer; + + @Test + public void testConstantExpressionConversion() { + validateTestSetup(); + setupStyle(); + Timber.i("camera function"); + + invoke(mapboxMap, (uiController, mapboxMap) -> { + // create color expression + Expression inputExpression = rgba(255.0f, 0.0f, 0.0f, 1.0f); + + // set color expression + layer.setProperties( + fillColor(inputExpression) + ); + + // get color value + int color = layer.getFillColor().getColorInt(); + + // compare + assertEquals("input expression should match", Color.RED, color); + }); + } + + @Test + public void testGetExpressionWrapping() { + validateTestSetup(); + setupStyle(); + Timber.i("camera function"); + + invoke(mapboxMap, (uiController, mapboxMap) -> { + // create get expression + Expression inputExpression = get("fill"); + + // set get expression + layer.setProperties( + fillColor(inputExpression) + ); + + // get actual expression + Expression actualExpression = layer.getFillColor().getExpression(); + + // create wrapped expected expression + Expression expectedExpression = toColor(get("fill")); + + // compare + assertEquals("input expression should match", expectedExpression, actualExpression); + }); + } + + @Test + public void testCameraFunction() { + validateTestSetup(); + setupStyle(); + Timber.i("camera function"); + + invoke(mapboxMap, (uiController, mapboxMap) -> { + // create camera function expression + Expression inputExpression = interpolate( + exponential(0.5f), zoom(), + stop(1.0f, rgba(255.0f, 0.0f, 0.0f, 1.0f)), + stop(5.0f, rgba(0.0f, 0.0f, 255.0f, 1.0f)), + stop(10.0f, rgba(0.0f, 255.0f, 0.0f, 1.0f)) + ); + + // set camera function expression + layer.setProperties( + fillColor(inputExpression) + ); + + // get camera function expression + Expression outputExpression = layer.getFillColor().getExpression(); + + // compare + assertEquals("input expression should match", inputExpression, outputExpression); + }); + } + + @Test + public void testSourceFunction() { + validateTestSetup(); + setupStyle(); + Timber.i("camera function"); + + invoke(mapboxMap, (uiController, mapboxMap) -> { + // create camera function expression + Expression inputExpression = toColor(get("fill")); + + // set camera function expression + layer.setProperties( + fillColor(inputExpression) + ); + + // get camera function expression + Expression outputExpression = layer.getFillColor().getExpression(); + + // compare + assertEquals("input expression should match", inputExpression, outputExpression); + }); + } + + @Test + public void testCompositeFunction() { + validateTestSetup(); + setupStyle(); + Timber.i("camera function"); + + invoke(mapboxMap, (uiController, mapboxMap) -> { + // create camera function expression + Expression inputExpression = step(zoom(), + rgba(255.0f, 255.0f, 255.0f, 1.0f), + stop(7.0f, match( + string(get("name")), + literal("Westerpark"), rgba(255.0f, 0.0f, 0.0f, 1.0f), + rgba(255.0f, 255.0f, 255.0f, 1.0f) + )), + stop(8.0f, match( + string(get("name")), + literal("Westerpark"), rgba(0.0f, 0.0f, 255.0f, 1.0f), + rgba(255.0f, 255.0f, 255.0f, 1.0f) + )) + ); + + // set camera function expression + layer.setProperties( + fillColor(inputExpression) + ); + + // get camera function expression + Expression outputExpression = layer.getFillColor().getExpression(); + + // compare + assertEquals("input expression should match", inputExpression, outputExpression); + }); + } + + @Test + public void testLiteralProperty() { + validateTestSetup(); + setupStyle(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + layer.setProperties( + fillColor(literal("#4286f4")) + ); + }); + } + + @Test + public void testLiteralMatchExpression() { + validateTestSetup(); + setupStyle(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + Expression expression = match(literal("something"), literal(0f), + stop("1", get("1")), + stop("2", get("2")), + stop("3", get("3")), + stop("4", get("4")) + ); + + layer.setProperties( + fillColor(expression) + ); + expression.toArray(); + }); + } + + @Test + public void testCollatorExpression() { + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + LatLng latLng = new LatLng(51, 17); + + Expression expression1 = eq(literal("Łukasz"), literal("lukasz"), collator(true, true)); + Expression expression2 = eq(literal("Łukasz"), literal("lukasz"), collator(literal(false), eq(literal(1), + literal(1)), literal("en"))); + Expression expression3 = eq(literal("Łukasz"), literal("lukasz"), collator(literal(false), eq(literal(2), + literal(1)))); + + mapboxMap.getStyle() + .addSource(new GeoJsonSource("source", Point.fromLngLat(latLng.getLongitude(), latLng.getLatitude()))); + Layer layer = new CircleLayer("layer", "source") + .withProperties(circleColor( + switchCase( + expression1, literal(ColorUtils.colorToRgbaString(Color.GREEN)), + literal(ColorUtils.colorToRgbaString(Color.RED)) + ) + )); + mapboxMap.getStyle().addLayer(layer); + TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView); + assertFalse(mapboxMap.queryRenderedFeatures(mapboxMap.getProjection().toScreenLocation(latLng), "layer") + .isEmpty()); + + layer.setProperties(circleColor( + switchCase( + expression2, literal(ColorUtils.colorToRgbaString(Color.GREEN)), + literal(ColorUtils.colorToRgbaString(Color.RED)) + ) + )); + TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView); + assertFalse(mapboxMap.queryRenderedFeatures(mapboxMap.getProjection().toScreenLocation(latLng), "layer") + .isEmpty()); + + layer.setProperties(circleColor( + switchCase( + expression3, literal(ColorUtils.colorToRgbaString(Color.GREEN)), + literal(ColorUtils.colorToRgbaString(Color.RED)) + ) + )); + TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView); + assertFalse(mapboxMap.queryRenderedFeatures(mapboxMap.getProjection().toScreenLocation(latLng), "layer") + .isEmpty()); + }); + } + + @Test + public void testConstFormatExpression() { + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + LatLng latLng = new LatLng(51, 17); + mapboxMap.getStyle() + .addSource(new GeoJsonSource("source", Point.fromLngLat(latLng.getLongitude(), latLng.getLatitude()))); + SymbolLayer layer = new SymbolLayer("layer", "source"); + mapboxMap.getStyle().addLayer(layer); + + Expression expression = format( + formatEntry("test") + ); + layer.setProperties(textField(expression)); + TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView); + + assertFalse(mapboxMap.queryRenderedFeatures(mapboxMap.getProjection().toScreenLocation(latLng), "layer") + .isEmpty()); + assertNull(layer.getTextField().getExpression()); + assertEquals(new Formatted(new FormattedSection("test")), layer.getTextField().getValue()); + }); + } + + @Test + public void testConstFormatExpressionFontScaleParam() { + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + LatLng latLng = new LatLng(51, 17); + mapboxMap.getStyle() + .addSource(new GeoJsonSource("source", Point.fromLngLat(latLng.getLongitude(), latLng.getLatitude()))); + SymbolLayer layer = new SymbolLayer("layer", "source"); + mapboxMap.getStyle().addLayer(layer); + + Expression expression = format( + formatEntry("test", formatFontScale(1.75)) + ); + layer.setProperties(textField(expression)); + TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView); + + assertFalse(mapboxMap.queryRenderedFeatures(mapboxMap.getProjection().toScreenLocation(latLng), "layer") + .isEmpty()); + assertNull(layer.getTextField().getExpression()); + assertEquals(new Formatted(new FormattedSection("test", 1.75)), layer.getTextField().getValue()); + }); + } + + @Test + public void testConstFormatExpressionTextFontParam() { + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + LatLng latLng = new LatLng(51, 17); + mapboxMap.getStyle() + .addSource(new GeoJsonSource("source", Point.fromLngLat(latLng.getLongitude(), latLng.getLatitude()))); + SymbolLayer layer = new SymbolLayer("layer", "source"); + mapboxMap.getStyle().addLayer(layer); + + Expression expression = format( + formatEntry( + literal("test"), + formatTextFont(new String[] {"DIN Offc Pro Regular", "Arial Unicode MS Regular"}) + ) + ); + layer.setProperties(textField(expression)); + TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView); + + assertFalse( + mapboxMap.queryRenderedFeatures(mapboxMap.getProjection().toScreenLocation(latLng), "layer").isEmpty() + ); + assertNull(layer.getTextField().getExpression()); + assertEquals(new Formatted( + new FormattedSection("test", + new String[] {"DIN Offc Pro Regular", "Arial Unicode MS Regular"}) + ), layer.getTextField().getValue()); + }); + } + + @Test + public void testConstFormatExpressionTextColorParam() { + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + LatLng latLng = new LatLng(51, 17); + mapboxMap.getStyle() + .addSource(new GeoJsonSource("source", Point.fromLngLat(latLng.getLongitude(), latLng.getLatitude()))); + SymbolLayer layer = new SymbolLayer("layer", "source"); + mapboxMap.getStyle().addLayer(layer); + + Expression expression = format( + formatEntry( + literal("test"), + formatTextColor(literal("yellow")) + ) + ); + layer.setProperties(textField(expression)); + TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView); + + assertFalse( + mapboxMap.queryRenderedFeatures(mapboxMap.getProjection().toScreenLocation(latLng), "layer").isEmpty() + ); + assertNull(layer.getTextField().getExpression()); + assertEquals(new Formatted( + new FormattedSection("test", null, null, "rgba(255,255,0,1)") + ), layer.getTextField().getValue()); + }); + } + + @Test + public void testConstFormatExpressionAllParams() { + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + LatLng latLng = new LatLng(51, 17); + mapboxMap.getStyle() + .addSource(new GeoJsonSource("source", Point.fromLngLat(latLng.getLongitude(), latLng.getLatitude()))); + SymbolLayer layer = new SymbolLayer("layer", "source"); + mapboxMap.getStyle().addLayer(layer); + + Expression expression = format( + formatEntry( + "test", + formatFontScale(0.5), + formatTextFont(new String[] {"DIN Offc Pro Regular", "Arial Unicode MS Regular"}), + formatTextColor(rgb(126, 0, 0)) + ) + ); + layer.setProperties(textField(expression)); + TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView); + + assertFalse( + mapboxMap.queryRenderedFeatures(mapboxMap.getProjection().toScreenLocation(latLng), "layer").isEmpty() + ); + assertNull(layer.getTextField().getExpression()); + assertEquals(new Formatted( + new FormattedSection("test", + 0.5, + new String[] {"DIN Offc Pro Regular", "Arial Unicode MS Regular"}, + "rgba(126,0,0,1)") + ), layer.getTextField().getValue()); + }); + } + + @Test + public void testConstFormatExpressionMultipleInputs() { + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + LatLng latLng = new LatLng(51, 17); + mapboxMap.getStyle() + .addSource(new GeoJsonSource("source", Point.fromLngLat(latLng.getLongitude(), latLng.getLatitude()))); + SymbolLayer layer = new SymbolLayer("layer", "source"); + mapboxMap.getStyle().addLayer(layer); + + Expression expression = format( + formatEntry( + "test", + formatFontScale(1.5), + formatTextFont(new String[] {"DIN Offc Pro Regular", "Arial Unicode MS Regular"}) + ), + formatEntry("\ntest2", formatFontScale(2), formatTextColor(Color.BLUE)), + formatEntry("\ntest3", formatFontScale(2.5), formatTextColor(toColor(literal("rgba(0, 128, 255, 0.5)")))) + ); + layer.setProperties(textField(expression)); + TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView); + + assertFalse( + mapboxMap.queryRenderedFeatures(mapboxMap.getProjection().toScreenLocation(latLng), "layer").isEmpty() + ); + assertNull(layer.getTextField().getExpression()); + assertEquals(new Formatted( + new FormattedSection("test", 1.5, + new String[] {"DIN Offc Pro Regular", "Arial Unicode MS Regular"}), + new FormattedSection("\ntest2", 2.0, null, "rgba(0,0,255,1)"), + new FormattedSection("\ntest3", 2.5, null, "rgba(0,128,255,0.5)") + ), layer.getTextField().getValue()); + }); + } + + @Test + public void testVariableFormatExpression() { + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + LatLng latLng = new LatLng(51, 17); + Feature feature = Feature.fromGeometry(Point.fromLngLat(latLng.getLongitude(), latLng.getLatitude())); + feature.addStringProperty("test_property", "test"); + feature.addNumberProperty("test_property_number", 1.5); + feature.addStringProperty("test_property_color", "green"); + mapboxMap.getStyle().addSource(new GeoJsonSource("source", feature)); + SymbolLayer layer = new SymbolLayer("layer", "source"); + mapboxMap.getStyle().addLayer(layer); + + Expression expression = format( + formatEntry( + get("test_property"), + Expression.FormatOption.formatFontScale(number(get("test_property_number"))), + formatTextFont(new String[] {"Arial Unicode MS Regular", "DIN Offc Pro Regular"}), + formatTextColor(toColor(get("test_property_color"))) + ) + ); + layer.setProperties(textField(expression)); + TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView); + + assertFalse(mapboxMap.queryRenderedFeatures(mapboxMap.getProjection().toScreenLocation(latLng), "layer") + .isEmpty()); + assertEquals(expression, layer.getTextField().getExpression()); + assertNull(layer.getTextField().getValue()); + }); + } + + @Test + public void testVariableFormatExpressionMultipleInputs() { + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + LatLng latLng = new LatLng(51, 17); + Feature feature = Feature.fromGeometry(Point.fromLngLat(latLng.getLongitude(), latLng.getLatitude())); + feature.addStringProperty("test_property", "test"); + feature.addNumberProperty("test_property_number", 1.5); + feature.addStringProperty("test_property_color", "rgba(0, 255, 0, 1)"); + mapboxMap.getStyle().addSource(new GeoJsonSource("source", feature)); + SymbolLayer layer = new SymbolLayer("layer", "source"); + mapboxMap.getStyle().addLayer(layer); + + Expression expression = format( + formatEntry( + get("test_property"), + formatFontScale(1.25), + formatTextFont(new String[] {"Arial Unicode MS Regular", "DIN Offc Pro Regular"}), + formatTextColor(toColor(get("test_property_color"))) + ), + formatEntry("\ntest2", formatFontScale(2)) + ); + layer.setProperties(textField(expression), textColor("rgba(128, 0, 0, 1)")); + TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView); + + assertFalse(mapboxMap.queryRenderedFeatures(mapboxMap.getProjection().toScreenLocation(latLng), "layer") + .isEmpty()); + assertEquals(expression, layer.getTextField().getExpression()); + assertNull(layer.getTextField().getValue()); + }); + } + + @Test + public void testFormatExpressionPlainTextCoercion() { + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + LatLng latLng = new LatLng(51, 17); + mapboxMap.getStyle() + .addSource(new GeoJsonSource("source", Point.fromLngLat(latLng.getLongitude(), latLng.getLatitude()))); + SymbolLayer layer = new SymbolLayer("layer", "source"); + mapboxMap.getStyle().addLayer(layer); + + layer.setProperties(textField("test")); + TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView); + + assertFalse(mapboxMap.queryRenderedFeatures(mapboxMap.getProjection().toScreenLocation(latLng), "layer") + .isEmpty()); + assertNull(layer.getTextField().getExpression()); + assertEquals(new Formatted( + new FormattedSection("test")), layer.getTextField().getValue()); + }); + } + + @Test + public void testTextFieldFormattedArgument() { + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + LatLng latLng = new LatLng(51, 17); + mapboxMap.getStyle() + .addSource(new GeoJsonSource("source", Point.fromLngLat(latLng.getLongitude(), latLng.getLatitude()))); + SymbolLayer layer = new SymbolLayer("layer", "source"); + mapboxMap.getStyle().addLayer(layer); + + Formatted formatted = new Formatted( + new FormattedSection("test", 1.5), + new FormattedSection("\ntest", 0.5, new String[] {"Arial Unicode MS Regular", "DIN Offc Pro Regular"}), + new FormattedSection("test", null, null, "rgba(0,255,0,1)") + ); + layer.setProperties(textField(formatted), textColor("rgba(128,0,0,1)")); + TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView); + + assertFalse(mapboxMap.queryRenderedFeatures(mapboxMap.getProjection().toScreenLocation(latLng), "layer") + .isEmpty()); + assertNull(layer.getTextField().getExpression()); + assertEquals(formatted, layer.getTextField().getValue()); + }); + } + + @Test + public void testNumberFormatCurrencyExpression() { + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + LatLng latLng = new LatLng(51, 17); + mapboxMap.getStyle() + .addSource(new GeoJsonSource("source", Point.fromLngLat(latLng.getLongitude(), latLng.getLatitude()))); + SymbolLayer layer = new SymbolLayer("layer", "source"); + mapboxMap.getStyle().addLayer(layer); + + layer.setProperties( + textField( + numberFormat(12.345, locale("en-US"), currency("USD")) + ) + ); + TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView); + + assertFalse(mapboxMap.queryRenderedFeatures( + mapboxMap.getProjection().toScreenLocation(latLng), "layer").isEmpty() + ); + assertNull(layer.getTextField().getExpression()); + assertEquals("$12.35", layer.getTextField().getValue().getFormattedSections()[0].getText()); + }); + } + + @Test + public void testNumberFormatMaxExpression() { + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + LatLng latLng = new LatLng(51, 17); + mapboxMap.getStyle() + .addSource(new GeoJsonSource("source", Point.fromLngLat(latLng.getLongitude(), latLng.getLatitude()))); + SymbolLayer layer = new SymbolLayer("layer", "source"); + mapboxMap.getStyle().addLayer(layer); + + layer.setProperties( + textField( + numberFormat(12.34567890, maxFractionDigits(5), minFractionDigits(0)) + ) + ); + TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView); + + assertFalse(mapboxMap.queryRenderedFeatures( + mapboxMap.getProjection().toScreenLocation(latLng), "layer").isEmpty() + ); + assertNull(layer.getTextField().getExpression()); + assertEquals("12.34568", layer.getTextField().getValue().getFormattedSections()[0].getText()); + }); + } + + @Test + public void testNumberFormatMinExpression() { + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + LatLng latLng = new LatLng(51, 17); + mapboxMap.getStyle() + .addSource(new GeoJsonSource("source", Point.fromLngLat(latLng.getLongitude(), latLng.getLatitude()))); + SymbolLayer layer = new SymbolLayer("layer", "source"); + mapboxMap.getStyle().addLayer(layer); + + layer.setProperties( + textField( + numberFormat(12.0000001, maxFractionDigits(5), minFractionDigits(0)) + ) + ); + TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView); + + assertFalse(mapboxMap.queryRenderedFeatures( + mapboxMap.getProjection().toScreenLocation(latLng), "layer").isEmpty() + ); + assertNull(layer.getTextField().getExpression()); + assertEquals("12", layer.getTextField().getValue().getFormattedSections()[0].getText()); + }); + } + + @Test + public void testNumberFormatLocaleExpression() { + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + LatLng latLng = new LatLng(51, 17); + mapboxMap.getStyle() + .addSource(new GeoJsonSource("source", Point.fromLngLat(latLng.getLongitude(), latLng.getLatitude()))); + SymbolLayer layer = new SymbolLayer("layer", "source"); + mapboxMap.getStyle().addLayer(layer); + + layer.setProperties( + textField( + numberFormat(12.0000001, locale("nl-BE"), maxFractionDigits(5), minFractionDigits(1)) + ) + ); + TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView); + + assertFalse(mapboxMap.queryRenderedFeatures( + mapboxMap.getProjection().toScreenLocation(latLng), "layer").isEmpty() + ); + assertNull(layer.getTextField().getExpression()); + assertEquals("12,0", layer.getTextField().getValue().getFormattedSections()[0].getText()); + }); + } + + @Test + public void testNumberFormatNonConstantExpression() { + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + LatLng latLng = new LatLng(51, 17); + Feature feature = Feature.fromGeometry(Point.fromLngLat(latLng.getLongitude(), latLng.getLatitude())); + feature.addNumberProperty("number_value", 12.345678); + feature.addStringProperty("locale_value", "nl-BE"); + feature.addNumberProperty("max_value", 5); + feature.addNumberProperty("min_value", 1); + + + mapboxMap.getStyle().addSource(new GeoJsonSource("source", feature)); + SymbolLayer layer = new SymbolLayer("layer", "source"); + mapboxMap.getStyle().addLayer(layer); + + Expression numberFormatExpression = numberFormat( + number(number(get("number_value"))), + locale(string(get("locale_value"))), + maxFractionDigits(number(get("max_value"))), + minFractionDigits(number(get("min_value"))) + ); + + layer.setProperties(textField(numberFormatExpression)); + TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView); + + assertFalse(mapboxMap.queryRenderedFeatures( + mapboxMap.getProjection().toScreenLocation(latLng), "layer").isEmpty() + ); + + assertNotNull(layer.getTextField().getExpression()); + + // Expressions evaluated to string are wrapped by a format expression, take array index 1 to get original + Object[] returnExpression = (Object[]) layer.getTextField().getExpression().toArray()[1]; + Object[] setExpression = numberFormatExpression.toArray(); + assertEquals("Number format should match",returnExpression[0], setExpression[0]); + assertArrayEquals("Get value expression should match", + (Object[]) returnExpression[1], + (Object[]) setExpression[1] + ); + + // number format objects + HashMap<String, Object> returnMap = (HashMap<String, Object>) returnExpression[2]; + HashMap<String, Object> setMap = (HashMap<String, Object>) returnExpression[2]; + + assertArrayEquals("Number format min fraction digits should match ", + (Object[]) returnMap.get("min-fraction-digits"), + (Object[]) setMap.get("min-fraction-digits") + ); + + assertArrayEquals("Number format max fraction digits should match ", + (Object[]) returnMap.get("max-fraction-digits"), + (Object[]) setMap.get("max-fraction-digits") + ); + + assertArrayEquals("Number format min fraction digits should match ", + (Object[]) returnMap.get("locale"), + (Object[]) setMap.get("locale") + ); + }); + + } + + /** + * Regression test for #15532 + */ + @Test + public void testDoubleConversion() { + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + LatLng latLng = new LatLng(51, 17); + mapboxMap.getStyle().addSource( + new GeoJsonSource("source", Point.fromLngLat(latLng.getLongitude(), latLng.getLatitude())) + ); + + CircleLayer layer = new CircleLayer("layer", "source"); + mapboxMap.getStyle().addLayer(layer); + + Expression input = interpolate( + exponential(0.5f), zoom(), + stop(-0.1, color(Color.RED)), + stop(0, color(Color.BLUE)) + ); + + layer.setProperties(circleColor(input)); + + Expression output = layer.getCircleColor().getExpression(); + assertArrayEquals("Expression should match", input.toArray(), output.toArray()); + }); + } + + private void setupStyle() { + invoke(mapboxMap, (uiController, mapboxMap) -> { + // Add a source + Source source; + try { + source = new GeoJsonSource("amsterdam-parks-source", + ResourceUtils.readRawResource(rule.getActivity(), R.raw.amsterdam)); + mapboxMap.getStyle().addSource(source); + } catch (IOException ioException) { + return; + } + + // Add a fill layer + mapboxMap.getStyle().addLayer(layer = new FillLayer("amsterdam-parks-layer", source.getId()) + .withProperties( + fillColor(rgba(0.0f, 0.0f, 0.0f, 0.5f)), + fillOutlineColor(rgb(0, 0, 255)), + fillAntialias(true) + ) + ); + }); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillExtrusionLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillExtrusionLayerTest.java new file mode 100644 index 0000000000..cdfd030f9b --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillExtrusionLayerTest.java @@ -0,0 +1,340 @@ +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`. + +package com.mapbox.mapboxsdk.testapp.style; + +import android.graphics.Color; +import android.support.test.annotation.UiThreadTest; +import android.support.test.runner.AndroidJUnit4; + +import com.mapbox.mapboxsdk.maps.BaseLayerTest; +import org.junit.Before; +import timber.log.Timber; + +import com.mapbox.mapboxsdk.style.expressions.Expression; +import com.mapbox.mapboxsdk.style.layers.FillExtrusionLayer; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static com.mapbox.mapboxsdk.style.expressions.Expression.*; +import static org.junit.Assert.*; +import static com.mapbox.mapboxsdk.style.layers.Property.*; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*; + +import com.mapbox.mapboxsdk.style.layers.TransitionOptions; + +/** + * Basic smoke tests for FillExtrusionLayer + */ +@RunWith(AndroidJUnit4.class) +public class FillExtrusionLayerTest extends BaseLayerTest { + + private FillExtrusionLayer layer; + + @Before + @UiThreadTest + public void beforeTest(){ + super.before(); + layer = new FillExtrusionLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + setupLayer(layer); + } + + @Test + @UiThreadTest + public void testSourceId() { + Timber.i("SourceId"); + assertNotNull(layer); + assertEquals(layer.getSourceId(), "composite"); + } + + @Test + @UiThreadTest + public void testSetVisibility() { + Timber.i("Visibility"); + assertNotNull(layer); + + // Get initial + assertEquals(layer.getVisibility().getValue(), VISIBLE); + + // Set + layer.setProperties(visibility(NONE)); + assertEquals(layer.getVisibility().getValue(), NONE); + } + + @Test + @UiThreadTest + public void testSourceLayer() { + Timber.i("SourceLayer"); + assertNotNull(layer); + + // Get initial + assertEquals(layer.getSourceLayer(), "composite"); + + // Set + final String sourceLayer = "test"; + layer.setSourceLayer(sourceLayer); + assertEquals(layer.getSourceLayer(), sourceLayer); + } + + @Test + @UiThreadTest + public void testFilter() { + Timber.i("Filter"); + assertNotNull(layer); + + // Get initial + assertEquals(layer.getFilter(), null); + + // Set + Expression filter = eq(get("undefined"), literal(1.0)); + layer.setFilter(filter); + assertEquals(layer.getFilter().toString(), filter.toString()); + + // Set constant + filter = literal(true); + layer.setFilter(filter); + assertEquals(layer.getFilter().toString(), filter.toString()); + } + + + + @Test + @UiThreadTest + public void testFillExtrusionOpacityTransition() { + Timber.i("fill-extrusion-opacityTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setFillExtrusionOpacityTransition(options); + assertEquals(layer.getFillExtrusionOpacityTransition(), options); + } + + @Test + @UiThreadTest + public void testFillExtrusionOpacityAsConstant() { + Timber.i("fill-extrusion-opacity"); + assertNotNull(layer); + assertNull(layer.getFillExtrusionOpacity().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(fillExtrusionOpacity(propertyValue)); + assertEquals(layer.getFillExtrusionOpacity().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testFillExtrusionColorTransition() { + Timber.i("fill-extrusion-colorTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setFillExtrusionColorTransition(options); + assertEquals(layer.getFillExtrusionColorTransition(), options); + } + + @Test + @UiThreadTest + public void testFillExtrusionColorAsConstant() { + Timber.i("fill-extrusion-color"); + assertNotNull(layer); + assertNull(layer.getFillExtrusionColor().getValue()); + + // Set and Get + String propertyValue = "rgba(255,128,0,0.7)"; + layer.setProperties(fillExtrusionColor(propertyValue)); + assertEquals(layer.getFillExtrusionColor().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testFillExtrusionColorAsExpression() { + Timber.i("fill-extrusion-color-expression"); + assertNotNull(layer); + assertNull(layer.getFillExtrusionColor().getExpression()); + + // Set and Get + Expression expression = toColor(Expression.get("undefined")); + layer.setProperties(fillExtrusionColor(expression)); + assertEquals(layer.getFillExtrusionColor().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testFillExtrusionColorAsIntConstant() { + Timber.i("fill-extrusion-color"); + assertNotNull(layer); + + // Set and Get + layer.setProperties(fillExtrusionColor(Color.argb(127, 255, 127, 0))); + assertEquals(layer.getFillExtrusionColorAsInt(), Color.argb(127, 255, 127, 0)); + } + + @Test + @UiThreadTest + public void testFillExtrusionTranslateTransition() { + Timber.i("fill-extrusion-translateTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setFillExtrusionTranslateTransition(options); + assertEquals(layer.getFillExtrusionTranslateTransition(), options); + } + + @Test + @UiThreadTest + public void testFillExtrusionTranslateAsConstant() { + Timber.i("fill-extrusion-translate"); + assertNotNull(layer); + assertNull(layer.getFillExtrusionTranslate().getValue()); + + // Set and Get + Float[] propertyValue = new Float[] {0f, 0f}; + layer.setProperties(fillExtrusionTranslate(propertyValue)); + assertEquals(layer.getFillExtrusionTranslate().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testFillExtrusionTranslateAnchorAsConstant() { + Timber.i("fill-extrusion-translate-anchor"); + assertNotNull(layer); + assertNull(layer.getFillExtrusionTranslateAnchor().getValue()); + + // Set and Get + String propertyValue = FILL_EXTRUSION_TRANSLATE_ANCHOR_MAP; + layer.setProperties(fillExtrusionTranslateAnchor(propertyValue)); + assertEquals(layer.getFillExtrusionTranslateAnchor().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testFillExtrusionPatternTransition() { + Timber.i("fill-extrusion-patternTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setFillExtrusionPatternTransition(options); + assertEquals(layer.getFillExtrusionPatternTransition(), options); + } + + @Test + @UiThreadTest + public void testFillExtrusionPatternAsConstant() { + Timber.i("fill-extrusion-pattern"); + assertNotNull(layer); + assertNull(layer.getFillExtrusionPattern().getValue()); + + // Set and Get + String propertyValue = "pedestrian-polygon"; + layer.setProperties(fillExtrusionPattern(propertyValue)); + assertEquals(layer.getFillExtrusionPattern().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testFillExtrusionPatternAsExpression() { + Timber.i("fill-extrusion-pattern-expression"); + assertNotNull(layer); + assertNull(layer.getFillExtrusionPattern().getExpression()); + + // Set and Get + Expression expression = string(Expression.get("undefined")); + layer.setProperties(fillExtrusionPattern(expression)); + assertEquals(layer.getFillExtrusionPattern().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testFillExtrusionHeightTransition() { + Timber.i("fill-extrusion-heightTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setFillExtrusionHeightTransition(options); + assertEquals(layer.getFillExtrusionHeightTransition(), options); + } + + @Test + @UiThreadTest + public void testFillExtrusionHeightAsConstant() { + Timber.i("fill-extrusion-height"); + assertNotNull(layer); + assertNull(layer.getFillExtrusionHeight().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(fillExtrusionHeight(propertyValue)); + assertEquals(layer.getFillExtrusionHeight().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testFillExtrusionHeightAsExpression() { + Timber.i("fill-extrusion-height-expression"); + assertNotNull(layer); + assertNull(layer.getFillExtrusionHeight().getExpression()); + + // Set and Get + Expression expression = number(Expression.get("undefined")); + layer.setProperties(fillExtrusionHeight(expression)); + assertEquals(layer.getFillExtrusionHeight().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testFillExtrusionBaseTransition() { + Timber.i("fill-extrusion-baseTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setFillExtrusionBaseTransition(options); + assertEquals(layer.getFillExtrusionBaseTransition(), options); + } + + @Test + @UiThreadTest + public void testFillExtrusionBaseAsConstant() { + Timber.i("fill-extrusion-base"); + assertNotNull(layer); + assertNull(layer.getFillExtrusionBase().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(fillExtrusionBase(propertyValue)); + assertEquals(layer.getFillExtrusionBase().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testFillExtrusionBaseAsExpression() { + Timber.i("fill-extrusion-base-expression"); + assertNotNull(layer); + assertNull(layer.getFillExtrusionBase().getExpression()); + + // Set and Get + Expression expression = number(Expression.get("undefined")); + layer.setProperties(fillExtrusionBase(expression)); + assertEquals(layer.getFillExtrusionBase().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testFillExtrusionVerticalGradientAsConstant() { + Timber.i("fill-extrusion-vertical-gradient"); + assertNotNull(layer); + assertNull(layer.getFillExtrusionVerticalGradient().getValue()); + + // Set and Get + Boolean propertyValue = true; + layer.setProperties(fillExtrusionVerticalGradient(propertyValue)); + assertEquals(layer.getFillExtrusionVerticalGradient().getValue(), propertyValue); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillLayerTest.java new file mode 100644 index 0000000000..f6e3cc8548 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillLayerTest.java @@ -0,0 +1,326 @@ +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`. + +package com.mapbox.mapboxsdk.testapp.style; + +import android.graphics.Color; +import android.support.test.annotation.UiThreadTest; +import android.support.test.runner.AndroidJUnit4; + +import com.mapbox.mapboxsdk.maps.BaseLayerTest; +import org.junit.Before; +import timber.log.Timber; + +import com.mapbox.mapboxsdk.style.expressions.Expression; +import com.mapbox.mapboxsdk.style.layers.FillLayer; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static com.mapbox.mapboxsdk.style.expressions.Expression.*; +import static org.junit.Assert.*; +import static com.mapbox.mapboxsdk.style.layers.Property.*; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*; + +import com.mapbox.mapboxsdk.style.layers.TransitionOptions; + +/** + * Basic smoke tests for FillLayer + */ +@RunWith(AndroidJUnit4.class) +public class FillLayerTest extends BaseLayerTest { + + private FillLayer layer; + + @Before + @UiThreadTest + public void beforeTest(){ + super.before(); + layer = new FillLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + setupLayer(layer); + } + + @Test + @UiThreadTest + public void testSourceId() { + Timber.i("SourceId"); + assertNotNull(layer); + assertEquals(layer.getSourceId(), "composite"); + } + + @Test + @UiThreadTest + public void testSetVisibility() { + Timber.i("Visibility"); + assertNotNull(layer); + + // Get initial + assertEquals(layer.getVisibility().getValue(), VISIBLE); + + // Set + layer.setProperties(visibility(NONE)); + assertEquals(layer.getVisibility().getValue(), NONE); + } + + @Test + @UiThreadTest + public void testSourceLayer() { + Timber.i("SourceLayer"); + assertNotNull(layer); + + // Get initial + assertEquals(layer.getSourceLayer(), "composite"); + + // Set + final String sourceLayer = "test"; + layer.setSourceLayer(sourceLayer); + assertEquals(layer.getSourceLayer(), sourceLayer); + } + + @Test + @UiThreadTest + public void testFilter() { + Timber.i("Filter"); + assertNotNull(layer); + + // Get initial + assertEquals(layer.getFilter(), null); + + // Set + Expression filter = eq(get("undefined"), literal(1.0)); + layer.setFilter(filter); + assertEquals(layer.getFilter().toString(), filter.toString()); + + // Set constant + filter = literal(true); + layer.setFilter(filter); + assertEquals(layer.getFilter().toString(), filter.toString()); + } + + + + @Test + @UiThreadTest + public void testFillAntialiasAsConstant() { + Timber.i("fill-antialias"); + assertNotNull(layer); + assertNull(layer.getFillAntialias().getValue()); + + // Set and Get + Boolean propertyValue = true; + layer.setProperties(fillAntialias(propertyValue)); + assertEquals(layer.getFillAntialias().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testFillOpacityTransition() { + Timber.i("fill-opacityTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setFillOpacityTransition(options); + assertEquals(layer.getFillOpacityTransition(), options); + } + + @Test + @UiThreadTest + public void testFillOpacityAsConstant() { + Timber.i("fill-opacity"); + assertNotNull(layer); + assertNull(layer.getFillOpacity().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(fillOpacity(propertyValue)); + assertEquals(layer.getFillOpacity().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testFillOpacityAsExpression() { + Timber.i("fill-opacity-expression"); + assertNotNull(layer); + assertNull(layer.getFillOpacity().getExpression()); + + // Set and Get + Expression expression = number(Expression.get("undefined")); + layer.setProperties(fillOpacity(expression)); + assertEquals(layer.getFillOpacity().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testFillColorTransition() { + Timber.i("fill-colorTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setFillColorTransition(options); + assertEquals(layer.getFillColorTransition(), options); + } + + @Test + @UiThreadTest + public void testFillColorAsConstant() { + Timber.i("fill-color"); + assertNotNull(layer); + assertNull(layer.getFillColor().getValue()); + + // Set and Get + String propertyValue = "rgba(255,128,0,0.7)"; + layer.setProperties(fillColor(propertyValue)); + assertEquals(layer.getFillColor().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testFillColorAsExpression() { + Timber.i("fill-color-expression"); + assertNotNull(layer); + assertNull(layer.getFillColor().getExpression()); + + // Set and Get + Expression expression = toColor(Expression.get("undefined")); + layer.setProperties(fillColor(expression)); + assertEquals(layer.getFillColor().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testFillColorAsIntConstant() { + Timber.i("fill-color"); + assertNotNull(layer); + + // Set and Get + layer.setProperties(fillColor(Color.argb(127, 255, 127, 0))); + assertEquals(layer.getFillColorAsInt(), Color.argb(127, 255, 127, 0)); + } + + @Test + @UiThreadTest + public void testFillOutlineColorTransition() { + Timber.i("fill-outline-colorTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setFillOutlineColorTransition(options); + assertEquals(layer.getFillOutlineColorTransition(), options); + } + + @Test + @UiThreadTest + public void testFillOutlineColorAsConstant() { + Timber.i("fill-outline-color"); + assertNotNull(layer); + assertNull(layer.getFillOutlineColor().getValue()); + + // Set and Get + String propertyValue = "rgba(255,128,0,0.7)"; + layer.setProperties(fillOutlineColor(propertyValue)); + assertEquals(layer.getFillOutlineColor().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testFillOutlineColorAsExpression() { + Timber.i("fill-outline-color-expression"); + assertNotNull(layer); + assertNull(layer.getFillOutlineColor().getExpression()); + + // Set and Get + Expression expression = toColor(Expression.get("undefined")); + layer.setProperties(fillOutlineColor(expression)); + assertEquals(layer.getFillOutlineColor().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testFillOutlineColorAsIntConstant() { + Timber.i("fill-outline-color"); + assertNotNull(layer); + + // Set and Get + layer.setProperties(fillOutlineColor(Color.argb(127, 255, 127, 0))); + assertEquals(layer.getFillOutlineColorAsInt(), Color.argb(127, 255, 127, 0)); + } + + @Test + @UiThreadTest + public void testFillTranslateTransition() { + Timber.i("fill-translateTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setFillTranslateTransition(options); + assertEquals(layer.getFillTranslateTransition(), options); + } + + @Test + @UiThreadTest + public void testFillTranslateAsConstant() { + Timber.i("fill-translate"); + assertNotNull(layer); + assertNull(layer.getFillTranslate().getValue()); + + // Set and Get + Float[] propertyValue = new Float[] {0f, 0f}; + layer.setProperties(fillTranslate(propertyValue)); + assertEquals(layer.getFillTranslate().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testFillTranslateAnchorAsConstant() { + Timber.i("fill-translate-anchor"); + assertNotNull(layer); + assertNull(layer.getFillTranslateAnchor().getValue()); + + // Set and Get + String propertyValue = FILL_TRANSLATE_ANCHOR_MAP; + layer.setProperties(fillTranslateAnchor(propertyValue)); + assertEquals(layer.getFillTranslateAnchor().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testFillPatternTransition() { + Timber.i("fill-patternTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setFillPatternTransition(options); + assertEquals(layer.getFillPatternTransition(), options); + } + + @Test + @UiThreadTest + public void testFillPatternAsConstant() { + Timber.i("fill-pattern"); + assertNotNull(layer); + assertNull(layer.getFillPattern().getValue()); + + // Set and Get + String propertyValue = "pedestrian-polygon"; + layer.setProperties(fillPattern(propertyValue)); + assertEquals(layer.getFillPattern().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testFillPatternAsExpression() { + Timber.i("fill-pattern-expression"); + assertNotNull(layer); + assertNull(layer.getFillPattern().getExpression()); + + // Set and Get + Expression expression = string(Expression.get("undefined")); + layer.setProperties(fillPattern(expression)); + assertEquals(layer.getFillPattern().getExpression(), expression); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/GeoJsonSourceTests.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/GeoJsonSourceTests.java new file mode 100644 index 0000000000..61086e1344 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/GeoJsonSourceTests.java @@ -0,0 +1,189 @@ +package com.mapbox.mapboxsdk.testapp.style; + +import android.support.annotation.RawRes; +import android.support.test.espresso.ViewAction; +import android.support.test.runner.AndroidJUnit4; +import android.view.View; + +import com.mapbox.geojson.Feature; +import com.mapbox.geojson.FeatureCollection; +import com.mapbox.geojson.Point; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.style.layers.CircleLayer; +import com.mapbox.mapboxsdk.style.layers.Layer; +import com.mapbox.mapboxsdk.style.sources.GeoJsonSource; +import com.mapbox.mapboxsdk.testapp.R; +import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction; +import com.mapbox.mapboxsdk.testapp.activity.EspressoTest; +import com.mapbox.mapboxsdk.testapp.utils.ResourceUtils; +import com.mapbox.mapboxsdk.testapp.utils.TestingAsyncUtils; + +import org.hamcrest.Matcher; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import timber.log.Timber; + +import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +import static org.junit.Assert.assertEquals; + +/** + * Tests for {@link GeoJsonSource} + */ +@RunWith(AndroidJUnit4.class) +public class GeoJsonSourceTests extends EspressoTest { + + @Test + public void testFeatureCollection() { + validateTestSetup(); + MapboxMapAction.invoke(mapboxMap, (uiController, mapboxMap) -> { + GeoJsonSource source = null; + try { + source = new GeoJsonSource("source", FeatureCollection + .fromJson(ResourceUtils.readRawResource(rule.getActivity(), R.raw.test_feature_collection))); + } catch (IOException exception) { + Timber.e(exception); + } + mapboxMap.getStyle().addSource(source); + mapboxMap.getStyle().addLayer(new CircleLayer("layer", source.getId())); + }); + } + + @Test + public void testPointGeometry() { + validateTestSetup(); + MapboxMapAction.invoke(mapboxMap, (uiController, mapboxMap) -> { + GeoJsonSource source = new GeoJsonSource("source", Point.fromLngLat(0d, 0d)); + mapboxMap.getStyle().addSource(source); + mapboxMap.getStyle().addLayer(new CircleLayer("layer", source.getId())); + }); + } + + @Test + public void testFeatureProperties() { + validateTestSetup(); + MapboxMapAction.invoke(mapboxMap, (uiController, mapboxMap) -> { + GeoJsonSource source = null; + try { + source = new GeoJsonSource("source", + ResourceUtils.readRawResource(rule.getActivity(), R.raw.test_feature_properties)); + } catch (IOException exception) { + Timber.e(exception); + } + mapboxMap.getStyle().addSource(source); + mapboxMap.getStyle().addLayer(new CircleLayer("layer", source.getId())); + }); + } + + @Test + public void testUpdateCoalescing() { + validateTestSetup(); + MapboxMapAction.invoke(mapboxMap, (uiController, mapboxMap) -> { + GeoJsonSource source = new GeoJsonSource("source"); + mapboxMap.getStyle().addSource(source); + mapboxMap.getStyle().addLayer(new CircleLayer("layer", source.getId())); + + source.setGeoJson(Point.fromLngLat(0, 0)); + source.setGeoJson(Point.fromLngLat(-25, -25)); + try { + source.setGeoJson(ResourceUtils.readRawResource(rule.getActivity(), R.raw.test_feature_properties)); + } catch (IOException exception) { + Timber.e(exception); + } + + source.setGeoJson(Point.fromLngLat(20, 55)); + TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView); + assertEquals(1, mapboxMap.queryRenderedFeatures( + mapboxMap.getProjection().toScreenLocation( + new LatLng(55, 20)), "layer").size()); + }); + } + + @Test + public void testClearCollectionDuringConversion() { + // https://github.com/mapbox/mapbox-gl-native/issues/14565 + validateTestSetup(); + MapboxMapAction.invoke(mapboxMap, (uiController, mapboxMap) -> { + for (int j = 0; j < 1000; j++) { + List<Feature> features = new ArrayList<>(); + for (int i = 0; i < 100; i++) { + features.add(Feature.fromGeometry(Point.fromLngLat(0, 0))); + } + mapboxMap.getStyle().addSource(new GeoJsonSource("source" + j, FeatureCollection.fromFeatures(features))); + features.clear(); + } + }); + } + + @Test + public void testPointFeature() { + testFeatureFromResource(R.raw.test_point_feature); + } + + @Test + public void testLineStringFeature() { + testFeatureFromResource(R.raw.test_line_string_feature); + } + + @Test + public void testPolygonFeature() { + testFeatureFromResource(R.raw.test_polygon_feature); + } + + @Test + public void testPolygonWithHoleFeature() { + testFeatureFromResource(R.raw.test_polygon_with_hole_feature); + } + + @Test + public void testMultiPointFeature() { + testFeatureFromResource(R.raw.test_multi_point_feature); + } + + @Test + public void testMultiLineStringFeature() { + testFeatureFromResource(R.raw.test_multi_line_string_feature); + } + + @Test + public void testMultiPolygonFeature() { + testFeatureFromResource(R.raw.test_multi_polygon_feature); + } + + protected void testFeatureFromResource(final @RawRes int resource) { + validateTestSetup(); + MapboxMapAction.invoke(mapboxMap, (uiController, mapboxMap) -> { + GeoJsonSource source = new GeoJsonSource("source"); + mapboxMap.getStyle().addSource(source); + Layer layer = new CircleLayer("layer", source.getId()); + mapboxMap.getStyle().addLayer(layer); + + try { + source.setGeoJson(Feature.fromJson(ResourceUtils.readRawResource(rule.getActivity(), resource))); + } catch (IOException exception) { + Timber.e(exception); + } + + mapboxMap.getStyle().removeLayer(layer); + mapboxMap.getStyle().removeSource(source); + }); + } + + public abstract class BaseViewAction implements ViewAction { + + @Override + public Matcher<View> getConstraints() { + return isDisplayed(); + } + + @Override + public String getDescription() { + return getClass().getSimpleName(); + } + + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/HeatmapLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/HeatmapLayerTest.java new file mode 100644 index 0000000000..21a17723db --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/HeatmapLayerTest.java @@ -0,0 +1,215 @@ +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`. + +package com.mapbox.mapboxsdk.testapp.style; + +import android.graphics.Color; +import android.support.test.annotation.UiThreadTest; +import android.support.test.runner.AndroidJUnit4; + +import com.mapbox.mapboxsdk.maps.BaseLayerTest; +import org.junit.Before; +import timber.log.Timber; + +import com.mapbox.mapboxsdk.style.expressions.Expression; +import com.mapbox.mapboxsdk.style.layers.HeatmapLayer; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static com.mapbox.mapboxsdk.style.expressions.Expression.*; +import static org.junit.Assert.*; +import static com.mapbox.mapboxsdk.style.layers.Property.*; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*; + +import com.mapbox.mapboxsdk.style.layers.TransitionOptions; + +/** + * Basic smoke tests for HeatmapLayer + */ +@RunWith(AndroidJUnit4.class) +public class HeatmapLayerTest extends BaseLayerTest { + + private HeatmapLayer layer; + + @Before + @UiThreadTest + public void beforeTest(){ + super.before(); + layer = new HeatmapLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + setupLayer(layer); + } + + @Test + @UiThreadTest + public void testSourceId() { + Timber.i("SourceId"); + assertNotNull(layer); + assertEquals(layer.getSourceId(), "composite"); + } + + @Test + @UiThreadTest + public void testSetVisibility() { + Timber.i("Visibility"); + assertNotNull(layer); + + // Get initial + assertEquals(layer.getVisibility().getValue(), VISIBLE); + + // Set + layer.setProperties(visibility(NONE)); + assertEquals(layer.getVisibility().getValue(), NONE); + } + + @Test + @UiThreadTest + public void testSourceLayer() { + Timber.i("SourceLayer"); + assertNotNull(layer); + + // Get initial + assertEquals(layer.getSourceLayer(), "composite"); + + // Set + final String sourceLayer = "test"; + layer.setSourceLayer(sourceLayer); + assertEquals(layer.getSourceLayer(), sourceLayer); + } + + @Test + @UiThreadTest + public void testFilter() { + Timber.i("Filter"); + assertNotNull(layer); + + // Get initial + assertEquals(layer.getFilter(), null); + + // Set + Expression filter = eq(get("undefined"), literal(1.0)); + layer.setFilter(filter); + assertEquals(layer.getFilter().toString(), filter.toString()); + + // Set constant + filter = literal(true); + layer.setFilter(filter); + assertEquals(layer.getFilter().toString(), filter.toString()); + } + + + + @Test + @UiThreadTest + public void testHeatmapRadiusTransition() { + Timber.i("heatmap-radiusTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setHeatmapRadiusTransition(options); + assertEquals(layer.getHeatmapRadiusTransition(), options); + } + + @Test + @UiThreadTest + public void testHeatmapRadiusAsConstant() { + Timber.i("heatmap-radius"); + assertNotNull(layer); + assertNull(layer.getHeatmapRadius().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(heatmapRadius(propertyValue)); + assertEquals(layer.getHeatmapRadius().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testHeatmapRadiusAsExpression() { + Timber.i("heatmap-radius-expression"); + assertNotNull(layer); + assertNull(layer.getHeatmapRadius().getExpression()); + + // Set and Get + Expression expression = number(Expression.get("undefined")); + layer.setProperties(heatmapRadius(expression)); + assertEquals(layer.getHeatmapRadius().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testHeatmapWeightAsConstant() { + Timber.i("heatmap-weight"); + assertNotNull(layer); + assertNull(layer.getHeatmapWeight().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(heatmapWeight(propertyValue)); + assertEquals(layer.getHeatmapWeight().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testHeatmapWeightAsExpression() { + Timber.i("heatmap-weight-expression"); + assertNotNull(layer); + assertNull(layer.getHeatmapWeight().getExpression()); + + // Set and Get + Expression expression = number(Expression.get("undefined")); + layer.setProperties(heatmapWeight(expression)); + assertEquals(layer.getHeatmapWeight().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testHeatmapIntensityTransition() { + Timber.i("heatmap-intensityTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setHeatmapIntensityTransition(options); + assertEquals(layer.getHeatmapIntensityTransition(), options); + } + + @Test + @UiThreadTest + public void testHeatmapIntensityAsConstant() { + Timber.i("heatmap-intensity"); + assertNotNull(layer); + assertNull(layer.getHeatmapIntensity().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(heatmapIntensity(propertyValue)); + assertEquals(layer.getHeatmapIntensity().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testHeatmapOpacityTransition() { + Timber.i("heatmap-opacityTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setHeatmapOpacityTransition(options); + assertEquals(layer.getHeatmapOpacityTransition(), options); + } + + @Test + @UiThreadTest + public void testHeatmapOpacityAsConstant() { + Timber.i("heatmap-opacity"); + assertNotNull(layer); + assertNull(layer.getHeatmapOpacity().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(heatmapOpacity(propertyValue)); + assertEquals(layer.getHeatmapOpacity().getValue(), propertyValue); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/HillshadeLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/HillshadeLayerTest.java new file mode 100644 index 0000000000..694348b888 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/HillshadeLayerTest.java @@ -0,0 +1,223 @@ +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`. + +package com.mapbox.mapboxsdk.testapp.style; + +import android.graphics.Color; +import android.support.test.annotation.UiThreadTest; +import android.support.test.runner.AndroidJUnit4; + +import com.mapbox.mapboxsdk.maps.BaseLayerTest; +import org.junit.Before; +import timber.log.Timber; + +import com.mapbox.mapboxsdk.style.expressions.Expression; +import com.mapbox.mapboxsdk.style.layers.HillshadeLayer; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static com.mapbox.mapboxsdk.style.expressions.Expression.*; +import static org.junit.Assert.*; +import static com.mapbox.mapboxsdk.style.layers.Property.*; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*; + +import com.mapbox.mapboxsdk.style.layers.TransitionOptions; + +/** + * Basic smoke tests for HillshadeLayer + */ +@RunWith(AndroidJUnit4.class) +public class HillshadeLayerTest extends BaseLayerTest { + + private HillshadeLayer layer; + + @Before + @UiThreadTest + public void beforeTest(){ + super.before(); + layer = new HillshadeLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + setupLayer(layer); + } + + @Test + @UiThreadTest + public void testSourceId() { + Timber.i("SourceId"); + assertNotNull(layer); + assertEquals(layer.getSourceId(), "composite"); + } + + @Test + @UiThreadTest + public void testSetVisibility() { + Timber.i("Visibility"); + assertNotNull(layer); + + // Get initial + assertEquals(layer.getVisibility().getValue(), VISIBLE); + + // Set + layer.setProperties(visibility(NONE)); + assertEquals(layer.getVisibility().getValue(), NONE); + } + + @Test + @UiThreadTest + public void testHillshadeIlluminationDirectionAsConstant() { + Timber.i("hillshade-illumination-direction"); + assertNotNull(layer); + assertNull(layer.getHillshadeIlluminationDirection().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(hillshadeIlluminationDirection(propertyValue)); + assertEquals(layer.getHillshadeIlluminationDirection().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testHillshadeIlluminationAnchorAsConstant() { + Timber.i("hillshade-illumination-anchor"); + assertNotNull(layer); + assertNull(layer.getHillshadeIlluminationAnchor().getValue()); + + // Set and Get + String propertyValue = HILLSHADE_ILLUMINATION_ANCHOR_MAP; + layer.setProperties(hillshadeIlluminationAnchor(propertyValue)); + assertEquals(layer.getHillshadeIlluminationAnchor().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testHillshadeExaggerationTransition() { + Timber.i("hillshade-exaggerationTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setHillshadeExaggerationTransition(options); + assertEquals(layer.getHillshadeExaggerationTransition(), options); + } + + @Test + @UiThreadTest + public void testHillshadeExaggerationAsConstant() { + Timber.i("hillshade-exaggeration"); + assertNotNull(layer); + assertNull(layer.getHillshadeExaggeration().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(hillshadeExaggeration(propertyValue)); + assertEquals(layer.getHillshadeExaggeration().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testHillshadeShadowColorTransition() { + Timber.i("hillshade-shadow-colorTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setHillshadeShadowColorTransition(options); + assertEquals(layer.getHillshadeShadowColorTransition(), options); + } + + @Test + @UiThreadTest + public void testHillshadeShadowColorAsConstant() { + Timber.i("hillshade-shadow-color"); + assertNotNull(layer); + assertNull(layer.getHillshadeShadowColor().getValue()); + + // Set and Get + String propertyValue = "rgba(255,128,0,0.7)"; + layer.setProperties(hillshadeShadowColor(propertyValue)); + assertEquals(layer.getHillshadeShadowColor().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testHillshadeShadowColorAsIntConstant() { + Timber.i("hillshade-shadow-color"); + assertNotNull(layer); + + // Set and Get + layer.setProperties(hillshadeShadowColor(Color.argb(127, 255, 127, 0))); + assertEquals(layer.getHillshadeShadowColorAsInt(), Color.argb(127, 255, 127, 0)); + } + + @Test + @UiThreadTest + public void testHillshadeHighlightColorTransition() { + Timber.i("hillshade-highlight-colorTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setHillshadeHighlightColorTransition(options); + assertEquals(layer.getHillshadeHighlightColorTransition(), options); + } + + @Test + @UiThreadTest + public void testHillshadeHighlightColorAsConstant() { + Timber.i("hillshade-highlight-color"); + assertNotNull(layer); + assertNull(layer.getHillshadeHighlightColor().getValue()); + + // Set and Get + String propertyValue = "rgba(255,128,0,0.7)"; + layer.setProperties(hillshadeHighlightColor(propertyValue)); + assertEquals(layer.getHillshadeHighlightColor().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testHillshadeHighlightColorAsIntConstant() { + Timber.i("hillshade-highlight-color"); + assertNotNull(layer); + + // Set and Get + layer.setProperties(hillshadeHighlightColor(Color.argb(127, 255, 127, 0))); + assertEquals(layer.getHillshadeHighlightColorAsInt(), Color.argb(127, 255, 127, 0)); + } + + @Test + @UiThreadTest + public void testHillshadeAccentColorTransition() { + Timber.i("hillshade-accent-colorTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setHillshadeAccentColorTransition(options); + assertEquals(layer.getHillshadeAccentColorTransition(), options); + } + + @Test + @UiThreadTest + public void testHillshadeAccentColorAsConstant() { + Timber.i("hillshade-accent-color"); + assertNotNull(layer); + assertNull(layer.getHillshadeAccentColor().getValue()); + + // Set and Get + String propertyValue = "rgba(255,128,0,0.7)"; + layer.setProperties(hillshadeAccentColor(propertyValue)); + assertEquals(layer.getHillshadeAccentColor().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testHillshadeAccentColorAsIntConstant() { + Timber.i("hillshade-accent-color"); + assertNotNull(layer); + + // Set and Get + layer.setProperties(hillshadeAccentColor(Color.argb(127, 255, 127, 0))); + assertEquals(layer.getHillshadeAccentColorAsInt(), Color.argb(127, 255, 127, 0)); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/ImageTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/ImageTest.kt new file mode 100644 index 0000000000..eb45ab52c6 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/ImageTest.kt @@ -0,0 +1,75 @@ +package com.mapbox.mapboxsdk.testapp.style + +import android.graphics.Bitmap +import android.graphics.drawable.BitmapDrawable +import android.support.test.runner.AndroidJUnit4 +import com.mapbox.mapboxsdk.testapp.R +import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction +import com.mapbox.mapboxsdk.testapp.activity.EspressoTest +import java.util.* +import org.junit.Assert.assertNull +import org.junit.Assert.assertTrue +import org.junit.Test +import org.junit.runner.RunWith + +/** + * CRUD tests around Image + */ +@RunWith(AndroidJUnit4::class) +class ImageTest : EspressoTest() { + + companion object { + private const val IMAGE_ID = "test.image" + } + + @Test + fun testAddGetImage() { + validateTestSetup() + MapboxMapAction.invoke(mapboxMap) { uiController, mapboxMap -> + val drawable = rule.activity.resources.getDrawable(R.drawable.ic_launcher_round) + assertTrue(drawable is BitmapDrawable) + + val bitmapSet = (drawable as BitmapDrawable).bitmap + mapboxMap.style!!.addImage(IMAGE_ID, bitmapSet) + + // adding an image requires converting the image with an asynctask + uiController.loopMainThreadForAtLeast(200) + + val bitmapGet = mapboxMap.style!!.getImage(IMAGE_ID) + assertTrue(bitmapGet!!.similarTo(bitmapSet)) + + mapboxMap.style!!.removeImage(IMAGE_ID) + assertNull(mapboxMap.style!!.getImage(IMAGE_ID)) + } + } +} + +/** + * Alternative implementation of Bitmap.sameAs #14060 + */ +fun Bitmap.similarTo(other: Bitmap): Boolean { + if (invalidConfig(other)) { + return false + } + + // Allocate arrays + val argb = IntArray(width * height) + val argbOther = IntArray(other.width * other.height) + getPixels(argb, 0, width, 0, 0, width, height) + other.getPixels(argbOther, 0, width, 0, 0, width, height) + + // Alpha channel special check + if (config == Bitmap.Config.ALPHA_8) { + // in this case we have to manually compare the alpha channel as the rest is garbage. + val length = width * height + for (i in 0 until length) { + if (argb[i] and -0x1000000 != argbOther[i] and -0x1000000) { + return false + } + } + return true + } + return Arrays.equals(argb, argbOther) +} + +fun Bitmap.invalidConfig(other: Bitmap): Boolean = this.config != other.config || this.width != other.width || this.height != other.height
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LightTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LightTest.java new file mode 100644 index 0000000000..b78a2d26e5 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LightTest.java @@ -0,0 +1,172 @@ +package com.mapbox.mapboxsdk.testapp.style; + +import android.graphics.Color; +import android.support.test.espresso.UiController; +import android.support.test.espresso.ViewAction; +import android.support.test.runner.AndroidJUnit4; +import android.view.View; + +import com.mapbox.mapboxsdk.style.light.Light; +import com.mapbox.mapboxsdk.style.expressions.Expression; +import com.mapbox.mapboxsdk.style.layers.FillExtrusionLayer; +import com.mapbox.mapboxsdk.style.layers.TransitionOptions; +import com.mapbox.mapboxsdk.style.light.Position; +import com.mapbox.mapboxsdk.testapp.R; +import com.mapbox.mapboxsdk.testapp.activity.BaseTest; +import com.mapbox.mapboxsdk.testapp.activity.style.FillExtrusionStyleTestActivity; + +import timber.log.Timber; + +import org.hamcrest.Matcher; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +import static android.support.test.espresso.matcher.ViewMatchers.withId; +import static com.mapbox.mapboxsdk.style.expressions.Expression.eq; +import static com.mapbox.mapboxsdk.style.layers.Property.ANCHOR_MAP; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillExtrusionBase; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillExtrusionColor; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillExtrusionHeight; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillExtrusionOpacity; + +import static com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke; +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; + +@RunWith(AndroidJUnit4.class) +public class LightTest extends BaseTest { + + private Light light; + + @Test + public void testAnchor() { + validateTestSetup(); + setupLight(); + Timber.i("anchor"); + invoke(mapboxMap, (uiController, mapboxMap) -> { + assertNotNull(light); + // Set and Get + light.setAnchor(ANCHOR_MAP); + assertEquals("Anchor should match", ANCHOR_MAP, light.getAnchor()); + }); + } + + @Test + public void testPositionTransition() { + validateTestSetup(); + setupLight(); + Timber.i("positionTransitionOptions"); + invoke(mapboxMap, (uiController, mapboxMap) -> { + assertNotNull(light); + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + light.setPositionTransition(options); + assertEquals("Transition options should match", options, light.getPositionTransition()); + }); + } + + @Test + public void testPosition() { + validateTestSetup(); + setupLight(); + Timber.i("position"); + invoke(mapboxMap,(uiController, mapboxMap) -> { + assertNotNull(light); + // Set and Get + Position position = new Position(1, 2, 3); + light.setPosition(position); + assertEquals("Position should match", position, light.getPosition()); + }); + } + + @Test + public void testColorTransition() { + validateTestSetup(); + setupLight(); + Timber.i("colorTransitionOptions"); + invoke(mapboxMap, (uiController, mapboxMap) -> { + assertNotNull(light); + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + light.setColorTransition(options); + assertEquals("Transition options should match", options, light.getColorTransition()); + }); + } + + @Test + public void testColor() { + validateTestSetup(); + setupLight(); + Timber.i("color"); + invoke(mapboxMap, (uiController, mapboxMap) -> { + assertNotNull(light); + // Set and Get + light.setColor("rgba(255,128,0,0.7)"); + assertEquals("Color should match", "rgba(255,128,0,0.7)", light.getColor()); + }); + } + + @Test + public void testIntensityTransition() { + validateTestSetup(); + setupLight(); + Timber.i("intensityTransitionOptions"); + invoke(mapboxMap, (uiController, mapboxMap) -> { + assertNotNull(light); + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + light.setIntensityTransition(options); + assertEquals("Transition options should match", options, light.getIntensityTransition()); + }); + } + + @Test + public void testIntensity() { + validateTestSetup(); + setupLight(); + Timber.i("intensity"); + invoke(mapboxMap, (uiController, mapboxMap) -> { + assertNotNull(light); + // Set and Get + light.setIntensity(0.3f); + assertEquals("Intensity should match", 0.3f, light.getIntensity()); + }); + } + + private void setupLight() { + onView(withId(R.id.mapView)).perform(new ViewAction() { + @Override + public Matcher<View> getConstraints() { + return isDisplayed(); + } + + @Override + public String getDescription() { + return getClass().getSimpleName(); + } + + @Override + public void perform(UiController uiController, View view) { + light = mapboxMap.getStyle().getLight(); + FillExtrusionLayer fillExtrusionLayer = new FillExtrusionLayer("3d-buildings", "composite"); + fillExtrusionLayer.setSourceLayer("building"); + fillExtrusionLayer.setFilter(eq(Expression.get("extrude"), "true")); + fillExtrusionLayer.setMinZoom(15); + fillExtrusionLayer.setProperties( + fillExtrusionColor(Color.LTGRAY), + fillExtrusionHeight(Expression.get("height")), + fillExtrusionBase(Expression.get("min_height")), + fillExtrusionOpacity(0.6f) + ); + mapboxMap.getStyle().addLayer(fillExtrusionLayer); + } + }); + } + + @Override + protected Class getActivityClass() { + return FillExtrusionStyleTestActivity.class; + } +}
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LineLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LineLayerTest.java new file mode 100644 index 0000000000..5e00890f7f --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LineLayerTest.java @@ -0,0 +1,493 @@ +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`. + +package com.mapbox.mapboxsdk.testapp.style; + +import android.graphics.Color; +import android.support.test.annotation.UiThreadTest; +import android.support.test.runner.AndroidJUnit4; + +import com.mapbox.mapboxsdk.maps.BaseLayerTest; +import org.junit.Before; +import timber.log.Timber; + +import com.mapbox.mapboxsdk.style.expressions.Expression; +import com.mapbox.mapboxsdk.style.layers.LineLayer; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static com.mapbox.mapboxsdk.style.expressions.Expression.*; +import static org.junit.Assert.*; +import static com.mapbox.mapboxsdk.style.layers.Property.*; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*; + +import com.mapbox.mapboxsdk.style.layers.TransitionOptions; + +/** + * Basic smoke tests for LineLayer + */ +@RunWith(AndroidJUnit4.class) +public class LineLayerTest extends BaseLayerTest { + + private LineLayer layer; + + @Before + @UiThreadTest + public void beforeTest(){ + super.before(); + layer = new LineLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + setupLayer(layer); + } + + @Test + @UiThreadTest + public void testSourceId() { + Timber.i("SourceId"); + assertNotNull(layer); + assertEquals(layer.getSourceId(), "composite"); + } + + @Test + @UiThreadTest + public void testSetVisibility() { + Timber.i("Visibility"); + assertNotNull(layer); + + // Get initial + assertEquals(layer.getVisibility().getValue(), VISIBLE); + + // Set + layer.setProperties(visibility(NONE)); + assertEquals(layer.getVisibility().getValue(), NONE); + } + + @Test + @UiThreadTest + public void testSourceLayer() { + Timber.i("SourceLayer"); + assertNotNull(layer); + + // Get initial + assertEquals(layer.getSourceLayer(), "composite"); + + // Set + final String sourceLayer = "test"; + layer.setSourceLayer(sourceLayer); + assertEquals(layer.getSourceLayer(), sourceLayer); + } + + @Test + @UiThreadTest + public void testFilter() { + Timber.i("Filter"); + assertNotNull(layer); + + // Get initial + assertEquals(layer.getFilter(), null); + + // Set + Expression filter = eq(get("undefined"), literal(1.0)); + layer.setFilter(filter); + assertEquals(layer.getFilter().toString(), filter.toString()); + + // Set constant + filter = literal(true); + layer.setFilter(filter); + assertEquals(layer.getFilter().toString(), filter.toString()); + } + + + + @Test + @UiThreadTest + public void testLineCapAsConstant() { + Timber.i("line-cap"); + assertNotNull(layer); + assertNull(layer.getLineCap().getValue()); + + // Set and Get + String propertyValue = LINE_CAP_BUTT; + layer.setProperties(lineCap(propertyValue)); + assertEquals(layer.getLineCap().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testLineJoinAsConstant() { + Timber.i("line-join"); + assertNotNull(layer); + assertNull(layer.getLineJoin().getValue()); + + // Set and Get + String propertyValue = LINE_JOIN_BEVEL; + layer.setProperties(lineJoin(propertyValue)); + assertEquals(layer.getLineJoin().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testLineJoinAsExpression() { + Timber.i("line-join-expression"); + assertNotNull(layer); + assertNull(layer.getLineJoin().getExpression()); + + // Set and Get + Expression expression = string(Expression.get("undefined")); + layer.setProperties(lineJoin(expression)); + assertEquals(layer.getLineJoin().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testLineMiterLimitAsConstant() { + Timber.i("line-miter-limit"); + assertNotNull(layer); + assertNull(layer.getLineMiterLimit().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(lineMiterLimit(propertyValue)); + assertEquals(layer.getLineMiterLimit().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testLineRoundLimitAsConstant() { + Timber.i("line-round-limit"); + assertNotNull(layer); + assertNull(layer.getLineRoundLimit().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(lineRoundLimit(propertyValue)); + assertEquals(layer.getLineRoundLimit().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testLineOpacityTransition() { + Timber.i("line-opacityTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setLineOpacityTransition(options); + assertEquals(layer.getLineOpacityTransition(), options); + } + + @Test + @UiThreadTest + public void testLineOpacityAsConstant() { + Timber.i("line-opacity"); + assertNotNull(layer); + assertNull(layer.getLineOpacity().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(lineOpacity(propertyValue)); + assertEquals(layer.getLineOpacity().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testLineOpacityAsExpression() { + Timber.i("line-opacity-expression"); + assertNotNull(layer); + assertNull(layer.getLineOpacity().getExpression()); + + // Set and Get + Expression expression = number(Expression.get("undefined")); + layer.setProperties(lineOpacity(expression)); + assertEquals(layer.getLineOpacity().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testLineColorTransition() { + Timber.i("line-colorTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setLineColorTransition(options); + assertEquals(layer.getLineColorTransition(), options); + } + + @Test + @UiThreadTest + public void testLineColorAsConstant() { + Timber.i("line-color"); + assertNotNull(layer); + assertNull(layer.getLineColor().getValue()); + + // Set and Get + String propertyValue = "rgba(255,128,0,0.7)"; + layer.setProperties(lineColor(propertyValue)); + assertEquals(layer.getLineColor().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testLineColorAsExpression() { + Timber.i("line-color-expression"); + assertNotNull(layer); + assertNull(layer.getLineColor().getExpression()); + + // Set and Get + Expression expression = toColor(Expression.get("undefined")); + layer.setProperties(lineColor(expression)); + assertEquals(layer.getLineColor().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testLineColorAsIntConstant() { + Timber.i("line-color"); + assertNotNull(layer); + + // Set and Get + layer.setProperties(lineColor(Color.argb(127, 255, 127, 0))); + assertEquals(layer.getLineColorAsInt(), Color.argb(127, 255, 127, 0)); + } + + @Test + @UiThreadTest + public void testLineTranslateTransition() { + Timber.i("line-translateTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setLineTranslateTransition(options); + assertEquals(layer.getLineTranslateTransition(), options); + } + + @Test + @UiThreadTest + public void testLineTranslateAsConstant() { + Timber.i("line-translate"); + assertNotNull(layer); + assertNull(layer.getLineTranslate().getValue()); + + // Set and Get + Float[] propertyValue = new Float[] {0f, 0f}; + layer.setProperties(lineTranslate(propertyValue)); + assertEquals(layer.getLineTranslate().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testLineTranslateAnchorAsConstant() { + Timber.i("line-translate-anchor"); + assertNotNull(layer); + assertNull(layer.getLineTranslateAnchor().getValue()); + + // Set and Get + String propertyValue = LINE_TRANSLATE_ANCHOR_MAP; + layer.setProperties(lineTranslateAnchor(propertyValue)); + assertEquals(layer.getLineTranslateAnchor().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testLineWidthTransition() { + Timber.i("line-widthTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setLineWidthTransition(options); + assertEquals(layer.getLineWidthTransition(), options); + } + + @Test + @UiThreadTest + public void testLineWidthAsConstant() { + Timber.i("line-width"); + assertNotNull(layer); + assertNull(layer.getLineWidth().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(lineWidth(propertyValue)); + assertEquals(layer.getLineWidth().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testLineWidthAsExpression() { + Timber.i("line-width-expression"); + assertNotNull(layer); + assertNull(layer.getLineWidth().getExpression()); + + // Set and Get + Expression expression = number(Expression.get("undefined")); + layer.setProperties(lineWidth(expression)); + assertEquals(layer.getLineWidth().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testLineGapWidthTransition() { + Timber.i("line-gap-widthTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setLineGapWidthTransition(options); + assertEquals(layer.getLineGapWidthTransition(), options); + } + + @Test + @UiThreadTest + public void testLineGapWidthAsConstant() { + Timber.i("line-gap-width"); + assertNotNull(layer); + assertNull(layer.getLineGapWidth().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(lineGapWidth(propertyValue)); + assertEquals(layer.getLineGapWidth().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testLineGapWidthAsExpression() { + Timber.i("line-gap-width-expression"); + assertNotNull(layer); + assertNull(layer.getLineGapWidth().getExpression()); + + // Set and Get + Expression expression = number(Expression.get("undefined")); + layer.setProperties(lineGapWidth(expression)); + assertEquals(layer.getLineGapWidth().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testLineOffsetTransition() { + Timber.i("line-offsetTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setLineOffsetTransition(options); + assertEquals(layer.getLineOffsetTransition(), options); + } + + @Test + @UiThreadTest + public void testLineOffsetAsConstant() { + Timber.i("line-offset"); + assertNotNull(layer); + assertNull(layer.getLineOffset().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(lineOffset(propertyValue)); + assertEquals(layer.getLineOffset().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testLineBlurTransition() { + Timber.i("line-blurTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setLineBlurTransition(options); + assertEquals(layer.getLineBlurTransition(), options); + } + + @Test + @UiThreadTest + public void testLineBlurAsConstant() { + Timber.i("line-blur"); + assertNotNull(layer); + assertNull(layer.getLineBlur().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(lineBlur(propertyValue)); + assertEquals(layer.getLineBlur().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testLineBlurAsExpression() { + Timber.i("line-blur-expression"); + assertNotNull(layer); + assertNull(layer.getLineBlur().getExpression()); + + // Set and Get + Expression expression = number(Expression.get("undefined")); + layer.setProperties(lineBlur(expression)); + assertEquals(layer.getLineBlur().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testLineDasharrayTransition() { + Timber.i("line-dasharrayTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setLineDasharrayTransition(options); + assertEquals(layer.getLineDasharrayTransition(), options); + } + + @Test + @UiThreadTest + public void testLineDasharrayAsConstant() { + Timber.i("line-dasharray"); + assertNotNull(layer); + assertNull(layer.getLineDasharray().getValue()); + + // Set and Get + Float[] propertyValue = new Float[] {}; + layer.setProperties(lineDasharray(propertyValue)); + assertEquals(layer.getLineDasharray().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testLinePatternTransition() { + Timber.i("line-patternTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setLinePatternTransition(options); + assertEquals(layer.getLinePatternTransition(), options); + } + + @Test + @UiThreadTest + public void testLinePatternAsConstant() { + Timber.i("line-pattern"); + assertNotNull(layer); + assertNull(layer.getLinePattern().getValue()); + + // Set and Get + String propertyValue = "pedestrian-polygon"; + layer.setProperties(linePattern(propertyValue)); + assertEquals(layer.getLinePattern().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testLinePatternAsExpression() { + Timber.i("line-pattern-expression"); + assertNotNull(layer); + assertNull(layer.getLinePattern().getExpression()); + + // Set and Get + Expression expression = string(Expression.get("undefined")); + layer.setProperties(linePattern(expression)); + assertEquals(layer.getLinePattern().getExpression(), expression); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RasterLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RasterLayerTest.java new file mode 100644 index 0000000000..aa50b1fe52 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RasterLayerTest.java @@ -0,0 +1,240 @@ +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`. + +package com.mapbox.mapboxsdk.testapp.style; + +import android.graphics.Color; +import android.support.test.annotation.UiThreadTest; +import android.support.test.runner.AndroidJUnit4; + +import com.mapbox.mapboxsdk.maps.BaseLayerTest; +import org.junit.Before; +import timber.log.Timber; + +import com.mapbox.mapboxsdk.style.expressions.Expression; +import com.mapbox.mapboxsdk.style.layers.RasterLayer; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static com.mapbox.mapboxsdk.style.expressions.Expression.*; +import static org.junit.Assert.*; +import static com.mapbox.mapboxsdk.style.layers.Property.*; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*; + +import com.mapbox.mapboxsdk.style.layers.TransitionOptions; + +/** + * Basic smoke tests for RasterLayer + */ +@RunWith(AndroidJUnit4.class) +public class RasterLayerTest extends BaseLayerTest { + + private RasterLayer layer; + + @Before + @UiThreadTest + public void beforeTest(){ + super.before(); + layer = new RasterLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + setupLayer(layer); + } + + @Test + @UiThreadTest + public void testSourceId() { + Timber.i("SourceId"); + assertNotNull(layer); + assertEquals(layer.getSourceId(), "composite"); + } + + @Test + @UiThreadTest + public void testSetVisibility() { + Timber.i("Visibility"); + assertNotNull(layer); + + // Get initial + assertEquals(layer.getVisibility().getValue(), VISIBLE); + + // Set + layer.setProperties(visibility(NONE)); + assertEquals(layer.getVisibility().getValue(), NONE); + } + + @Test + @UiThreadTest + public void testRasterOpacityTransition() { + Timber.i("raster-opacityTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setRasterOpacityTransition(options); + assertEquals(layer.getRasterOpacityTransition(), options); + } + + @Test + @UiThreadTest + public void testRasterOpacityAsConstant() { + Timber.i("raster-opacity"); + assertNotNull(layer); + assertNull(layer.getRasterOpacity().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(rasterOpacity(propertyValue)); + assertEquals(layer.getRasterOpacity().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testRasterHueRotateTransition() { + Timber.i("raster-hue-rotateTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setRasterHueRotateTransition(options); + assertEquals(layer.getRasterHueRotateTransition(), options); + } + + @Test + @UiThreadTest + public void testRasterHueRotateAsConstant() { + Timber.i("raster-hue-rotate"); + assertNotNull(layer); + assertNull(layer.getRasterHueRotate().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(rasterHueRotate(propertyValue)); + assertEquals(layer.getRasterHueRotate().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testRasterBrightnessMinTransition() { + Timber.i("raster-brightness-minTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setRasterBrightnessMinTransition(options); + assertEquals(layer.getRasterBrightnessMinTransition(), options); + } + + @Test + @UiThreadTest + public void testRasterBrightnessMinAsConstant() { + Timber.i("raster-brightness-min"); + assertNotNull(layer); + assertNull(layer.getRasterBrightnessMin().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(rasterBrightnessMin(propertyValue)); + assertEquals(layer.getRasterBrightnessMin().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testRasterBrightnessMaxTransition() { + Timber.i("raster-brightness-maxTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setRasterBrightnessMaxTransition(options); + assertEquals(layer.getRasterBrightnessMaxTransition(), options); + } + + @Test + @UiThreadTest + public void testRasterBrightnessMaxAsConstant() { + Timber.i("raster-brightness-max"); + assertNotNull(layer); + assertNull(layer.getRasterBrightnessMax().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(rasterBrightnessMax(propertyValue)); + assertEquals(layer.getRasterBrightnessMax().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testRasterSaturationTransition() { + Timber.i("raster-saturationTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setRasterSaturationTransition(options); + assertEquals(layer.getRasterSaturationTransition(), options); + } + + @Test + @UiThreadTest + public void testRasterSaturationAsConstant() { + Timber.i("raster-saturation"); + assertNotNull(layer); + assertNull(layer.getRasterSaturation().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(rasterSaturation(propertyValue)); + assertEquals(layer.getRasterSaturation().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testRasterContrastTransition() { + Timber.i("raster-contrastTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setRasterContrastTransition(options); + assertEquals(layer.getRasterContrastTransition(), options); + } + + @Test + @UiThreadTest + public void testRasterContrastAsConstant() { + Timber.i("raster-contrast"); + assertNotNull(layer); + assertNull(layer.getRasterContrast().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(rasterContrast(propertyValue)); + assertEquals(layer.getRasterContrast().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testRasterResamplingAsConstant() { + Timber.i("raster-resampling"); + assertNotNull(layer); + assertNull(layer.getRasterResampling().getValue()); + + // Set and Get + String propertyValue = RASTER_RESAMPLING_LINEAR; + layer.setProperties(rasterResampling(propertyValue)); + assertEquals(layer.getRasterResampling().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testRasterFadeDurationAsConstant() { + Timber.i("raster-fade-duration"); + assertNotNull(layer); + assertNull(layer.getRasterFadeDuration().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(rasterFadeDuration(propertyValue)); + assertEquals(layer.getRasterFadeDuration().getValue(), propertyValue); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RuntimeStyleTests.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RuntimeStyleTests.java new file mode 100644 index 0000000000..2d1fbf5fc4 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RuntimeStyleTests.java @@ -0,0 +1,370 @@ +package com.mapbox.mapboxsdk.testapp.style; + +import android.graphics.Color; +import android.graphics.PointF; +import android.support.test.espresso.UiController; +import android.support.test.espresso.ViewAction; +import android.support.test.runner.AndroidJUnit4; +import android.view.View; +import com.mapbox.mapboxsdk.style.layers.CannotAddLayerException; +import com.mapbox.mapboxsdk.style.layers.CircleLayer; +import com.mapbox.mapboxsdk.style.layers.FillLayer; +import com.mapbox.mapboxsdk.style.layers.Layer; +import com.mapbox.mapboxsdk.style.layers.LineLayer; +import com.mapbox.mapboxsdk.style.layers.Property; +import com.mapbox.mapboxsdk.style.layers.PropertyFactory; +import com.mapbox.mapboxsdk.style.sources.CannotAddSourceException; +import com.mapbox.mapboxsdk.style.sources.GeoJsonSource; +import com.mapbox.mapboxsdk.style.sources.RasterSource; +import com.mapbox.mapboxsdk.style.sources.Source; +import com.mapbox.mapboxsdk.style.sources.VectorSource; +import com.mapbox.mapboxsdk.testapp.R; +import com.mapbox.mapboxsdk.testapp.activity.EspressoTest; +import junit.framework.Assert; +import org.hamcrest.Matcher; +import org.junit.Test; +import org.junit.runner.RunWith; +import timber.log.Timber; + +import java.util.List; + +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +import static android.support.test.espresso.matcher.ViewMatchers.withId; +import static com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +/** + * Basic smoke tests for Layer and Source + */ +@RunWith(AndroidJUnit4.class) +public class RuntimeStyleTests extends EspressoTest { + + @Test + public void testListLayers() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new BaseViewAction() { + + @Override + public void perform(UiController uiController, View view) { + List<Layer> layers = mapboxMap.getStyle().getLayers(); + assertNotNull(layers); + assertTrue(layers.size() > 0); + for (Layer layer : layers) { + assertNotNull(layer); + } + } + + }); + } + + @Test + public void testGetAddRemoveLayer() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new AddRemoveLayerAction()); + } + + @Test + public void testAddLayerAbove() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new BaseViewAction() { + @Override + public void perform(UiController uiController, View view) { + List<Layer> layers = mapboxMap.getStyle().getLayers(); + Source source = mapboxMap.getStyle().getSources().get(0); + + // Test inserting with invalid above-id + try { + mapboxMap.getStyle().addLayerAbove( + new CircleLayer("invalid-id-layer-test", source.getId()), "no-such-layer-here-man" + ); + fail("Should have thrown exception"); + } catch (CannotAddLayerException ex) { + // Yeah + assertNotNull(ex.getMessage()); + } + + // Insert as last + CircleLayer last = new CircleLayer("this is the last one", source.getId()); + mapboxMap.getStyle().addLayerAbove(last, layers.get(layers.size() - 1).getId()); + layers = mapboxMap.getStyle().getLayers(); + assertEquals(last.getId(), layers.get(layers.size() - 1).getId()); + + // Insert + CircleLayer second = new CircleLayer("this is the second one", source.getId()); + mapboxMap.getStyle().addLayerAbove(second, layers.get(0).getId()); + layers = mapboxMap.getStyle().getLayers(); + assertEquals(second.getId(), layers.get(1).getId()); + } + }); + } + + @Test + public void testRemoveLayerAt() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new BaseViewAction() { + + @Override + public void perform(UiController uiController, View view) { + // Remove by index + Layer firstLayer = mapboxMap.getStyle().getLayers().get(0); + boolean removed = mapboxMap.getStyle().removeLayerAt(0); + assertTrue(removed); + assertNotNull(firstLayer); + + // Test remove by index bounds checks + Timber.i("Remove layer at index > size"); + assertFalse(mapboxMap.getStyle().removeLayerAt(Integer.MAX_VALUE)); + } + }); + } + + public void testAddLayerAt() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new BaseViewAction() { + @Override + public void perform(UiController uiController, View view) { + List<Layer> layers = mapboxMap.getStyle().getLayers(); + Source source = mapboxMap.getStyle().getSources().get(0); + + // Test inserting out of range + try { + mapboxMap.getStyle().addLayerAt(new CircleLayer("invalid-id-layer-test", source.getId()), layers.size()); + fail("Should have thrown exception"); + } catch (CannotAddLayerException ex) { + // Yeah + assertNotNull(ex.getMessage()); + } + + // Insert at current last position + CircleLayer last = new CircleLayer("this is the last one", source.getId()); + mapboxMap.getStyle().addLayerAt(last, layers.size() - 1); + layers = mapboxMap.getStyle().getLayers(); + assertEquals(last.getId(), layers.get(layers.size() - 2).getId()); + + // Insert at start + CircleLayer second = new CircleLayer("this is the first one", source.getId()); + mapboxMap.getStyle().addLayerAt(second, 0); + layers = mapboxMap.getStyle().getLayers(); + assertEquals(second.getId(), layers.get(0).getId()); + } + }); + } + + + @Test + public void testListSources() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new BaseViewAction() { + + @Override + public void perform(UiController uiController, View view) { + List<Source> sources = mapboxMap.getStyle().getSources(); + assertNotNull(sources); + assertTrue(sources.size() > 0); + for (Source source : sources) { + assertNotNull(source); + } + } + + }); + } + + @Test + public void testAddRemoveSource() { + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + mapboxMap.getStyle().addSource(new VectorSource("my-source", "mapbox://mapbox.mapbox-terrain-v2")); + mapboxMap.getStyle().removeSource("my-source"); + + // Add initial source + mapboxMap.getStyle().addSource(new VectorSource("my-source", "mapbox://mapbox.mapbox-terrain-v2")); + + // Remove + boolean removeOk = mapboxMap.getStyle().removeSource("my-source"); + assertTrue(removeOk); + assertNull(mapboxMap.getStyle().getLayer("my-source")); + + // Add + Source source = new VectorSource("my-source", "mapbox://mapbox.mapbox-terrain-v2"); + mapboxMap.getStyle().addSource(source); + + // Remove, preserving the reference + mapboxMap.getStyle().removeSource(source); + + // Re-add the reference... + mapboxMap.getStyle().addSource(source); + + // Ensure it's there + Assert.assertNotNull(mapboxMap.getStyle().getSource(source.getId())); + + // Test adding a duplicate source + try { + Source source2 = new VectorSource("my-source", "mapbox://mapbox.mapbox-terrain-v2"); + mapboxMap.getStyle().addSource(source2); + fail("Should not have been allowed to add a source with a duplicate id"); + } catch (CannotAddSourceException cannotAddSourceException) { + // OK + } + }); + + } + + @Test + public void testVectorSourceUrlGetter() { + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + VectorSource source = new VectorSource("my-source", "mapbox://mapbox.mapbox-terrain-v2"); + mapboxMap.getStyle().addSource(source); + assertEquals("mapbox://mapbox.mapbox-terrain-v2", source.getUri()); + }); + } + + @Test + public void testRasterSourceUrlGetter() { + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + RasterSource source = new RasterSource("my-source", "mapbox://mapbox.mapbox-terrain-v2"); + mapboxMap.getStyle().addSource(source); + assertEquals("mapbox://mapbox.mapbox-terrain-v2", source.getUri()); + }); + } + + @Test + public void testGeoJsonSourceUrlGetter() { + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + GeoJsonSource source = new GeoJsonSource("my-source"); + mapboxMap.getStyle().addSource(source); + assertNull(source.getUri()); + source.setUri("http://mapbox.com/my-file.json"); + assertEquals("http://mapbox.com/my-file.json", source.getUri()); + }); + } + + @Test + public void testRemoveSourceInUse() { + validateTestSetup(); + + onView(withId(R.id.mapView)).perform(new BaseViewAction() { + + @Override + public void perform(UiController uiController, View view) { + mapboxMap.getStyle().addSource(new VectorSource("my-source", "mapbox://mapbox.mapbox-terrain-v2")); + mapboxMap.getStyle().addLayer(new LineLayer("my-layer", "my-source")); + mapboxMap.getStyle().removeSource("my-source"); + assertNotNull(mapboxMap.getStyle().getSource("my-source")); + } + + }); + } + + @Test + public void testRemoveNonExistingSource() { + invoke(mapboxMap, (uiController, mapboxMap) -> mapboxMap.getStyle().removeSource("source")); + } + + @Test + public void testRemoveNonExistingLayer() { + invoke(mapboxMap, (uiController, mapboxMap) -> { + assertFalse(mapboxMap.getStyle().removeLayer("layer")); + assertFalse(mapboxMap.getStyle().removeLayerAt(mapboxMap.getStyle().getLayers().size() + 1)); + assertFalse(mapboxMap.getStyle().removeLayerAt(-1)); + }); + } + + @Test + public void testRemoveExistingLayer() { + invoke(mapboxMap, (uiController, mapboxMap) -> { + Layer firstLayer = mapboxMap.getStyle().getLayers().get(0); + assertTrue(mapboxMap.getStyle().removeLayer(firstLayer)); + + firstLayer = mapboxMap.getStyle().getLayers().get(0); + assertTrue(mapboxMap.getStyle().removeLayer(firstLayer.getId())); + + assertTrue(mapboxMap.getStyle().removeLayerAt(0)); + }); + } + + /** + * https://github.com/mapbox/mapbox-gl-native/issues/7973 + */ + @Test + public void testQueryRenderedFeaturesInputHandling() { + validateTestSetup(); + onView(withId(R.id.mapView)).perform(new BaseViewAction() { + + @Override + public void perform(UiController uiController, View view) { + String[] layerIds = new String[600]; + for (int i = 0; i < layerIds.length; i++) { + layerIds[i] = "layer-" + i; + } + mapboxMap.queryRenderedFeatures(new PointF(100, 100), layerIds); + } + + }); + } + + private class AddRemoveLayerAction extends BaseViewAction { + + @Override + public void perform(UiController uiController, View view) { + // Get initial + assertNotNull(mapboxMap.getStyle().getLayer("building")); + + // Remove + boolean removed = mapboxMap.getStyle().removeLayer("building"); + assertTrue(removed); + assertNull(mapboxMap.getStyle().getLayer("building")); + + // Add + FillLayer layer = new FillLayer("building", "composite"); + layer.setSourceLayer("building"); + mapboxMap.getStyle().addLayer(layer); + assertNotNull(mapboxMap.getStyle().getLayer("building")); + + // Assure the reference still works + layer.setProperties(PropertyFactory.visibility(Property.VISIBLE)); + + // Remove, preserving the reference + mapboxMap.getStyle().removeLayer(layer); + + // Property setters should still work + layer.setProperties(PropertyFactory.fillColor(Color.RED)); + + // Re-add the reference... + mapboxMap.getStyle().addLayer(layer); + + // Ensure it's there + Assert.assertNotNull(mapboxMap.getStyle().getLayer(layer.getId())); + + // Test adding a duplicate layer + try { + mapboxMap.getStyle().addLayer(new FillLayer("building", "composite")); + fail("Should not have been allowed to add a layer with a duplicate id"); + } catch (CannotAddLayerException cannotAddLayerException) { + // OK + } + } + } + + public abstract class BaseViewAction implements ViewAction { + + @Override + public Matcher<View> getConstraints() { + return isDisplayed(); + } + + @Override + public String getDescription() { + return getClass().getSimpleName(); + } + + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RuntimeStyleTimingTests.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RuntimeStyleTimingTests.java new file mode 100644 index 0000000000..4dd01d06cb --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RuntimeStyleTimingTests.java @@ -0,0 +1,27 @@ +package com.mapbox.mapboxsdk.testapp.style; + +import android.support.test.runner.AndroidJUnit4; + +import com.mapbox.mapboxsdk.testapp.activity.BaseTest; +import com.mapbox.mapboxsdk.testapp.activity.style.RuntimeStyleTimingTestActivity; + +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * Basic smoke tests for adding Layer and Source as early as possible (in onCreate) + */ +@RunWith(AndroidJUnit4.class) +public class RuntimeStyleTimingTests extends BaseTest { + + @Override + protected Class getActivityClass() { + return RuntimeStyleTimingTestActivity.class; + } + + @Test + public void testGetAddRemoveLayer() { + validateTestSetup(); + // We're good if it didn't crash + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/StyleLoaderTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/StyleLoaderTest.java new file mode 100644 index 0000000000..495b209831 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/StyleLoaderTest.java @@ -0,0 +1,59 @@ +package com.mapbox.mapboxsdk.testapp.style; + +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.testapp.R; +import com.mapbox.mapboxsdk.testapp.activity.EspressoTest; +import com.mapbox.mapboxsdk.testapp.utils.ResourceUtils; +import org.junit.Test; + +import java.io.IOException; + +import static com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke; +import static org.junit.Assert.assertEquals; + +/** + * Tests around style loading + */ +public class StyleLoaderTest extends EspressoTest { + + @Test + public void testSetGetStyleJsonString() { + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + try { + String expected = ResourceUtils.readRawResource(rule.getActivity(), R.raw.local_style); + mapboxMap.setStyle(new Style.Builder().fromJson(expected)); + String actual = mapboxMap.getStyle().getJson(); + assertEquals("Style json should match", expected, actual); + } catch (IOException exception) { + exception.printStackTrace(); + } + }); + } + + @Test + public void testDefaultStyleLoadWithActivityLifecycleChange() { + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + try { + String expected = ResourceUtils.readRawResource(rule.getActivity(), R.raw.local_style); + mapboxMap.setStyle(new Style.Builder().fromJson(expected)); + + // fake activity stop/start + MapView mapView = (MapView) rule.getActivity().findViewById(R.id.mapView); + mapView.onPause(); + mapView.onStop(); + + mapView.onStart(); + mapView.onResume(); + + String actual = mapboxMap.getStyle().getJson(); + assertEquals("Style URL should be empty", "", mapboxMap.getStyle().getUri()); + assertEquals("Style json should match", expected, actual); + } catch (IOException exception) { + exception.printStackTrace(); + } + }); + } +}
\ No newline at end of file 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 new file mode 100644 index 0000000000..c65e37019b --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerTest.java @@ -0,0 +1,1313 @@ +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`. + +package com.mapbox.mapboxsdk.testapp.style; + +import android.graphics.Color; +import android.support.test.annotation.UiThreadTest; +import android.support.test.runner.AndroidJUnit4; + +import com.mapbox.mapboxsdk.maps.BaseLayerTest; +import org.junit.Before; +import timber.log.Timber; + +import com.mapbox.mapboxsdk.style.expressions.Expression; +import com.mapbox.mapboxsdk.style.layers.SymbolLayer; +import com.mapbox.mapboxsdk.style.types.Formatted; +import com.mapbox.mapboxsdk.style.types.FormattedSection; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static com.mapbox.mapboxsdk.style.expressions.Expression.*; +import static org.junit.Assert.*; +import static com.mapbox.mapboxsdk.style.layers.Property.*; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*; + +import com.mapbox.mapboxsdk.style.layers.TransitionOptions; + +/** + * Basic smoke tests for SymbolLayer + */ +@RunWith(AndroidJUnit4.class) +public class SymbolLayerTest extends BaseLayerTest { + + private SymbolLayer layer; + + @Before + @UiThreadTest + public void beforeTest(){ + super.before(); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + setupLayer(layer); + } + + @Test + @UiThreadTest + public void testSourceId() { + Timber.i("SourceId"); + assertNotNull(layer); + assertEquals(layer.getSourceId(), "composite"); + } + + @Test + @UiThreadTest + public void testSetVisibility() { + Timber.i("Visibility"); + assertNotNull(layer); + + // Get initial + assertEquals(layer.getVisibility().getValue(), VISIBLE); + + // Set + layer.setProperties(visibility(NONE)); + assertEquals(layer.getVisibility().getValue(), NONE); + } + + @Test + @UiThreadTest + public void testSourceLayer() { + Timber.i("SourceLayer"); + assertNotNull(layer); + + // Get initial + assertEquals(layer.getSourceLayer(), "composite"); + + // Set + final String sourceLayer = "test"; + layer.setSourceLayer(sourceLayer); + assertEquals(layer.getSourceLayer(), sourceLayer); + } + + @Test + @UiThreadTest + public void testFilter() { + Timber.i("Filter"); + assertNotNull(layer); + + // Get initial + assertEquals(layer.getFilter(), null); + + // Set + Expression filter = eq(get("undefined"), literal(1.0)); + layer.setFilter(filter); + assertEquals(layer.getFilter().toString(), filter.toString()); + + // Set constant + filter = literal(true); + layer.setFilter(filter); + assertEquals(layer.getFilter().toString(), filter.toString()); + } + + + + @Test + @UiThreadTest + public void testSymbolPlacementAsConstant() { + Timber.i("symbol-placement"); + assertNotNull(layer); + assertNull(layer.getSymbolPlacement().getValue()); + + // Set and Get + String propertyValue = SYMBOL_PLACEMENT_POINT; + layer.setProperties(symbolPlacement(propertyValue)); + assertEquals(layer.getSymbolPlacement().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testSymbolSpacingAsConstant() { + Timber.i("symbol-spacing"); + assertNotNull(layer); + assertNull(layer.getSymbolSpacing().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(symbolSpacing(propertyValue)); + assertEquals(layer.getSymbolSpacing().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testSymbolAvoidEdgesAsConstant() { + Timber.i("symbol-avoid-edges"); + assertNotNull(layer); + assertNull(layer.getSymbolAvoidEdges().getValue()); + + // Set and Get + Boolean propertyValue = true; + layer.setProperties(symbolAvoidEdges(propertyValue)); + assertEquals(layer.getSymbolAvoidEdges().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testSymbolSortKeyAsConstant() { + Timber.i("symbol-sort-key"); + assertNotNull(layer); + assertNull(layer.getSymbolSortKey().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(symbolSortKey(propertyValue)); + assertEquals(layer.getSymbolSortKey().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testSymbolSortKeyAsExpression() { + Timber.i("symbol-sort-key-expression"); + assertNotNull(layer); + assertNull(layer.getSymbolSortKey().getExpression()); + + // Set and Get + Expression expression = number(Expression.get("undefined")); + layer.setProperties(symbolSortKey(expression)); + assertEquals(layer.getSymbolSortKey().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testSymbolZOrderAsConstant() { + Timber.i("symbol-z-order"); + assertNotNull(layer); + assertNull(layer.getSymbolZOrder().getValue()); + + // Set and Get + String propertyValue = SYMBOL_Z_ORDER_AUTO; + layer.setProperties(symbolZOrder(propertyValue)); + assertEquals(layer.getSymbolZOrder().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testIconAllowOverlapAsConstant() { + Timber.i("icon-allow-overlap"); + assertNotNull(layer); + assertNull(layer.getIconAllowOverlap().getValue()); + + // Set and Get + Boolean propertyValue = true; + layer.setProperties(iconAllowOverlap(propertyValue)); + assertEquals(layer.getIconAllowOverlap().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testIconIgnorePlacementAsConstant() { + Timber.i("icon-ignore-placement"); + assertNotNull(layer); + assertNull(layer.getIconIgnorePlacement().getValue()); + + // Set and Get + Boolean propertyValue = true; + layer.setProperties(iconIgnorePlacement(propertyValue)); + assertEquals(layer.getIconIgnorePlacement().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testIconOptionalAsConstant() { + Timber.i("icon-optional"); + assertNotNull(layer); + assertNull(layer.getIconOptional().getValue()); + + // Set and Get + Boolean propertyValue = true; + layer.setProperties(iconOptional(propertyValue)); + assertEquals(layer.getIconOptional().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testIconRotationAlignmentAsConstant() { + Timber.i("icon-rotation-alignment"); + assertNotNull(layer); + assertNull(layer.getIconRotationAlignment().getValue()); + + // Set and Get + String propertyValue = ICON_ROTATION_ALIGNMENT_MAP; + layer.setProperties(iconRotationAlignment(propertyValue)); + assertEquals(layer.getIconRotationAlignment().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testIconSizeAsConstant() { + Timber.i("icon-size"); + assertNotNull(layer); + assertNull(layer.getIconSize().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(iconSize(propertyValue)); + assertEquals(layer.getIconSize().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testIconSizeAsExpression() { + Timber.i("icon-size-expression"); + assertNotNull(layer); + assertNull(layer.getIconSize().getExpression()); + + // Set and Get + Expression expression = number(Expression.get("undefined")); + layer.setProperties(iconSize(expression)); + assertEquals(layer.getIconSize().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testIconTextFitAsConstant() { + Timber.i("icon-text-fit"); + assertNotNull(layer); + assertNull(layer.getIconTextFit().getValue()); + + // Set and Get + String propertyValue = ICON_TEXT_FIT_NONE; + layer.setProperties(iconTextFit(propertyValue)); + assertEquals(layer.getIconTextFit().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testIconTextFitPaddingAsConstant() { + Timber.i("icon-text-fit-padding"); + assertNotNull(layer); + assertNull(layer.getIconTextFitPadding().getValue()); + + // Set and Get + Float[] propertyValue = new Float[] {0f, 0f, 0f, 0f}; + layer.setProperties(iconTextFitPadding(propertyValue)); + assertEquals(layer.getIconTextFitPadding().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testIconImageAsConstant() { + Timber.i("icon-image"); + assertNotNull(layer); + assertNull(layer.getIconImage().getValue()); + + // Set and Get + String propertyValue = "undefined"; + layer.setProperties(iconImage(propertyValue)); + assertEquals(layer.getIconImage().getValue(), propertyValue); + + layer.setProperties(iconImage("{token}")); + assertEquals(layer.getIconImage().getExpression(), Expression.toString(Expression.get("token"))); + } + + @Test + @UiThreadTest + public void testIconImageAsExpression() { + Timber.i("icon-image-expression"); + assertNotNull(layer); + assertNull(layer.getIconImage().getExpression()); + + // Set and Get + Expression expression = string(Expression.get("undefined")); + layer.setProperties(iconImage(expression)); + assertEquals(layer.getIconImage().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testIconRotateAsConstant() { + Timber.i("icon-rotate"); + assertNotNull(layer); + assertNull(layer.getIconRotate().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(iconRotate(propertyValue)); + assertEquals(layer.getIconRotate().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testIconRotateAsExpression() { + Timber.i("icon-rotate-expression"); + assertNotNull(layer); + assertNull(layer.getIconRotate().getExpression()); + + // Set and Get + Expression expression = number(Expression.get("undefined")); + layer.setProperties(iconRotate(expression)); + assertEquals(layer.getIconRotate().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testIconPaddingAsConstant() { + Timber.i("icon-padding"); + assertNotNull(layer); + assertNull(layer.getIconPadding().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(iconPadding(propertyValue)); + assertEquals(layer.getIconPadding().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testIconKeepUprightAsConstant() { + Timber.i("icon-keep-upright"); + assertNotNull(layer); + assertNull(layer.getIconKeepUpright().getValue()); + + // Set and Get + Boolean propertyValue = true; + layer.setProperties(iconKeepUpright(propertyValue)); + assertEquals(layer.getIconKeepUpright().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testIconOffsetAsConstant() { + Timber.i("icon-offset"); + assertNotNull(layer); + assertNull(layer.getIconOffset().getValue()); + + // Set and Get + Float[] propertyValue = new Float[] {0f, 0f}; + layer.setProperties(iconOffset(propertyValue)); + assertEquals(layer.getIconOffset().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testIconAnchorAsConstant() { + Timber.i("icon-anchor"); + assertNotNull(layer); + assertNull(layer.getIconAnchor().getValue()); + + // Set and Get + String propertyValue = ICON_ANCHOR_CENTER; + layer.setProperties(iconAnchor(propertyValue)); + assertEquals(layer.getIconAnchor().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testIconAnchorAsExpression() { + Timber.i("icon-anchor-expression"); + assertNotNull(layer); + assertNull(layer.getIconAnchor().getExpression()); + + // Set and Get + Expression expression = string(Expression.get("undefined")); + layer.setProperties(iconAnchor(expression)); + assertEquals(layer.getIconAnchor().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testIconPitchAlignmentAsConstant() { + Timber.i("icon-pitch-alignment"); + assertNotNull(layer); + assertNull(layer.getIconPitchAlignment().getValue()); + + // Set and Get + String propertyValue = ICON_PITCH_ALIGNMENT_MAP; + layer.setProperties(iconPitchAlignment(propertyValue)); + assertEquals(layer.getIconPitchAlignment().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testTextPitchAlignmentAsConstant() { + Timber.i("text-pitch-alignment"); + assertNotNull(layer); + assertNull(layer.getTextPitchAlignment().getValue()); + + // Set and Get + String propertyValue = TEXT_PITCH_ALIGNMENT_MAP; + layer.setProperties(textPitchAlignment(propertyValue)); + assertEquals(layer.getTextPitchAlignment().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testTextRotationAlignmentAsConstant() { + Timber.i("text-rotation-alignment"); + assertNotNull(layer); + assertNull(layer.getTextRotationAlignment().getValue()); + + // Set and Get + String propertyValue = TEXT_ROTATION_ALIGNMENT_MAP; + layer.setProperties(textRotationAlignment(propertyValue)); + assertEquals(layer.getTextRotationAlignment().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testTextFieldAsConstant() { + Timber.i("text-field"); + assertNotNull(layer); + assertNull(layer.getTextField().getValue()); + + // Set and Get + Formatted propertyValue = new Formatted(new FormattedSection("default")); + layer.setProperties(textField("default")); + assertEquals(layer.getTextField().getValue(), propertyValue); + layer.setProperties(textField(propertyValue)); + assertEquals(layer.getTextField().getValue(), propertyValue); + + layer.setProperties(textField("{token}")); + assertEquals(layer.getTextField().getExpression(), format(Expression.formatEntry(Expression.toString(Expression.get("token"))))); + } + + @Test + @UiThreadTest + public void testTextFieldAsExpression() { + Timber.i("text-field-expression"); + assertNotNull(layer); + assertNull(layer.getTextField().getExpression()); + + // Set and Get + Expression expression = format(Expression.formatEntry(Expression.get("undefined"), FormatOption.formatFontScale(2.0), FormatOption.formatTextFont(new String[]{"Open Sans Regular", "Arial Unicode MS Regular"}))); + layer.setProperties(textField(expression)); + assertEquals(layer.getTextField().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testTextFontAsConstant() { + Timber.i("text-font"); + assertNotNull(layer); + assertNull(layer.getTextFont().getValue()); + + // Set and Get + String[] propertyValue = new String[]{"Open Sans Regular", "Arial Unicode MS Regular"}; + layer.setProperties(textFont(propertyValue)); + assertEquals(layer.getTextFont().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testTextSizeAsConstant() { + Timber.i("text-size"); + assertNotNull(layer); + assertNull(layer.getTextSize().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(textSize(propertyValue)); + assertEquals(layer.getTextSize().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testTextSizeAsExpression() { + Timber.i("text-size-expression"); + assertNotNull(layer); + assertNull(layer.getTextSize().getExpression()); + + // Set and Get + Expression expression = number(Expression.get("undefined")); + layer.setProperties(textSize(expression)); + assertEquals(layer.getTextSize().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testTextMaxWidthAsConstant() { + Timber.i("text-max-width"); + assertNotNull(layer); + assertNull(layer.getTextMaxWidth().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(textMaxWidth(propertyValue)); + assertEquals(layer.getTextMaxWidth().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testTextMaxWidthAsExpression() { + Timber.i("text-max-width-expression"); + assertNotNull(layer); + assertNull(layer.getTextMaxWidth().getExpression()); + + // Set and Get + Expression expression = number(Expression.get("undefined")); + layer.setProperties(textMaxWidth(expression)); + assertEquals(layer.getTextMaxWidth().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testTextLineHeightAsConstant() { + Timber.i("text-line-height"); + assertNotNull(layer); + assertNull(layer.getTextLineHeight().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(textLineHeight(propertyValue)); + assertEquals(layer.getTextLineHeight().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testTextLetterSpacingAsConstant() { + Timber.i("text-letter-spacing"); + assertNotNull(layer); + assertNull(layer.getTextLetterSpacing().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(textLetterSpacing(propertyValue)); + assertEquals(layer.getTextLetterSpacing().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testTextLetterSpacingAsExpression() { + Timber.i("text-letter-spacing-expression"); + assertNotNull(layer); + assertNull(layer.getTextLetterSpacing().getExpression()); + + // Set and Get + Expression expression = number(Expression.get("undefined")); + layer.setProperties(textLetterSpacing(expression)); + assertEquals(layer.getTextLetterSpacing().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testTextJustifyAsConstant() { + Timber.i("text-justify"); + assertNotNull(layer); + assertNull(layer.getTextJustify().getValue()); + + // Set and Get + String propertyValue = TEXT_JUSTIFY_AUTO; + layer.setProperties(textJustify(propertyValue)); + assertEquals(layer.getTextJustify().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testTextJustifyAsExpression() { + Timber.i("text-justify-expression"); + assertNotNull(layer); + assertNull(layer.getTextJustify().getExpression()); + + // Set and Get + Expression expression = string(Expression.get("undefined")); + layer.setProperties(textJustify(expression)); + assertEquals(layer.getTextJustify().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testTextRadialOffsetAsConstant() { + Timber.i("text-radial-offset"); + assertNotNull(layer); + assertNull(layer.getTextRadialOffset().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(textRadialOffset(propertyValue)); + assertEquals(layer.getTextRadialOffset().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testTextVariableAnchorAsConstant() { + Timber.i("text-variable-anchor"); + assertNotNull(layer); + assertNull(layer.getTextVariableAnchor().getValue()); + + // Set and Get + String[] propertyValue = new String[0]; + layer.setProperties(textVariableAnchor(propertyValue)); + assertEquals(layer.getTextVariableAnchor().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testTextAnchorAsConstant() { + Timber.i("text-anchor"); + assertNotNull(layer); + assertNull(layer.getTextAnchor().getValue()); + + // Set and Get + String propertyValue = TEXT_ANCHOR_CENTER; + layer.setProperties(textAnchor(propertyValue)); + assertEquals(layer.getTextAnchor().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testTextAnchorAsExpression() { + Timber.i("text-anchor-expression"); + assertNotNull(layer); + assertNull(layer.getTextAnchor().getExpression()); + + // Set and Get + Expression expression = string(Expression.get("undefined")); + layer.setProperties(textAnchor(expression)); + assertEquals(layer.getTextAnchor().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testTextMaxAngleAsConstant() { + Timber.i("text-max-angle"); + assertNotNull(layer); + assertNull(layer.getTextMaxAngle().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(textMaxAngle(propertyValue)); + assertEquals(layer.getTextMaxAngle().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testTextWritingModeAsConstant() { + Timber.i("text-writing-mode"); + assertNotNull(layer); + assertNull(layer.getTextWritingMode().getValue()); + + // Set and Get + String[] propertyValue = new String[0]; + layer.setProperties(textWritingMode(propertyValue)); + assertEquals(layer.getTextWritingMode().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testTextRotateAsConstant() { + Timber.i("text-rotate"); + assertNotNull(layer); + assertNull(layer.getTextRotate().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(textRotate(propertyValue)); + assertEquals(layer.getTextRotate().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testTextRotateAsExpression() { + Timber.i("text-rotate-expression"); + assertNotNull(layer); + assertNull(layer.getTextRotate().getExpression()); + + // Set and Get + Expression expression = number(Expression.get("undefined")); + layer.setProperties(textRotate(expression)); + assertEquals(layer.getTextRotate().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testTextPaddingAsConstant() { + Timber.i("text-padding"); + assertNotNull(layer); + assertNull(layer.getTextPadding().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(textPadding(propertyValue)); + assertEquals(layer.getTextPadding().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testTextKeepUprightAsConstant() { + Timber.i("text-keep-upright"); + assertNotNull(layer); + assertNull(layer.getTextKeepUpright().getValue()); + + // Set and Get + Boolean propertyValue = true; + layer.setProperties(textKeepUpright(propertyValue)); + assertEquals(layer.getTextKeepUpright().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testTextTransformAsConstant() { + Timber.i("text-transform"); + assertNotNull(layer); + assertNull(layer.getTextTransform().getValue()); + + // Set and Get + String propertyValue = TEXT_TRANSFORM_NONE; + layer.setProperties(textTransform(propertyValue)); + assertEquals(layer.getTextTransform().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testTextTransformAsExpression() { + Timber.i("text-transform-expression"); + assertNotNull(layer); + assertNull(layer.getTextTransform().getExpression()); + + // Set and Get + Expression expression = string(Expression.get("undefined")); + layer.setProperties(textTransform(expression)); + assertEquals(layer.getTextTransform().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testTextOffsetAsConstant() { + Timber.i("text-offset"); + assertNotNull(layer); + assertNull(layer.getTextOffset().getValue()); + + // Set and Get + Float[] propertyValue = new Float[] {0f, 0f}; + layer.setProperties(textOffset(propertyValue)); + assertEquals(layer.getTextOffset().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testTextAllowOverlapAsConstant() { + Timber.i("text-allow-overlap"); + assertNotNull(layer); + assertNull(layer.getTextAllowOverlap().getValue()); + + // Set and Get + Boolean propertyValue = true; + layer.setProperties(textAllowOverlap(propertyValue)); + assertEquals(layer.getTextAllowOverlap().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testTextIgnorePlacementAsConstant() { + Timber.i("text-ignore-placement"); + assertNotNull(layer); + assertNull(layer.getTextIgnorePlacement().getValue()); + + // Set and Get + Boolean propertyValue = true; + layer.setProperties(textIgnorePlacement(propertyValue)); + assertEquals(layer.getTextIgnorePlacement().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testTextOptionalAsConstant() { + Timber.i("text-optional"); + assertNotNull(layer); + assertNull(layer.getTextOptional().getValue()); + + // Set and Get + Boolean propertyValue = true; + layer.setProperties(textOptional(propertyValue)); + assertEquals(layer.getTextOptional().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testIconOpacityTransition() { + Timber.i("icon-opacityTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setIconOpacityTransition(options); + assertEquals(layer.getIconOpacityTransition(), options); + } + + @Test + @UiThreadTest + public void testIconOpacityAsConstant() { + Timber.i("icon-opacity"); + assertNotNull(layer); + assertNull(layer.getIconOpacity().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(iconOpacity(propertyValue)); + assertEquals(layer.getIconOpacity().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testIconOpacityAsExpression() { + Timber.i("icon-opacity-expression"); + assertNotNull(layer); + assertNull(layer.getIconOpacity().getExpression()); + + // Set and Get + Expression expression = number(Expression.get("undefined")); + layer.setProperties(iconOpacity(expression)); + assertEquals(layer.getIconOpacity().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testIconColorTransition() { + Timber.i("icon-colorTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setIconColorTransition(options); + assertEquals(layer.getIconColorTransition(), options); + } + + @Test + @UiThreadTest + public void testIconColorAsConstant() { + Timber.i("icon-color"); + assertNotNull(layer); + assertNull(layer.getIconColor().getValue()); + + // Set and Get + String propertyValue = "rgba(255,128,0,0.7)"; + layer.setProperties(iconColor(propertyValue)); + assertEquals(layer.getIconColor().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testIconColorAsExpression() { + Timber.i("icon-color-expression"); + assertNotNull(layer); + assertNull(layer.getIconColor().getExpression()); + + // Set and Get + Expression expression = toColor(Expression.get("undefined")); + layer.setProperties(iconColor(expression)); + assertEquals(layer.getIconColor().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testIconColorAsIntConstant() { + Timber.i("icon-color"); + assertNotNull(layer); + + // Set and Get + layer.setProperties(iconColor(Color.argb(127, 255, 127, 0))); + assertEquals(layer.getIconColorAsInt(), Color.argb(127, 255, 127, 0)); + } + + @Test + @UiThreadTest + public void testIconHaloColorTransition() { + Timber.i("icon-halo-colorTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setIconHaloColorTransition(options); + assertEquals(layer.getIconHaloColorTransition(), options); + } + + @Test + @UiThreadTest + public void testIconHaloColorAsConstant() { + Timber.i("icon-halo-color"); + assertNotNull(layer); + assertNull(layer.getIconHaloColor().getValue()); + + // Set and Get + String propertyValue = "rgba(255,128,0,0.7)"; + layer.setProperties(iconHaloColor(propertyValue)); + assertEquals(layer.getIconHaloColor().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testIconHaloColorAsExpression() { + Timber.i("icon-halo-color-expression"); + assertNotNull(layer); + assertNull(layer.getIconHaloColor().getExpression()); + + // Set and Get + Expression expression = toColor(Expression.get("undefined")); + layer.setProperties(iconHaloColor(expression)); + assertEquals(layer.getIconHaloColor().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testIconHaloColorAsIntConstant() { + Timber.i("icon-halo-color"); + assertNotNull(layer); + + // Set and Get + layer.setProperties(iconHaloColor(Color.argb(127, 255, 127, 0))); + assertEquals(layer.getIconHaloColorAsInt(), Color.argb(127, 255, 127, 0)); + } + + @Test + @UiThreadTest + public void testIconHaloWidthTransition() { + Timber.i("icon-halo-widthTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setIconHaloWidthTransition(options); + assertEquals(layer.getIconHaloWidthTransition(), options); + } + + @Test + @UiThreadTest + public void testIconHaloWidthAsConstant() { + Timber.i("icon-halo-width"); + assertNotNull(layer); + assertNull(layer.getIconHaloWidth().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(iconHaloWidth(propertyValue)); + assertEquals(layer.getIconHaloWidth().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testIconHaloWidthAsExpression() { + Timber.i("icon-halo-width-expression"); + assertNotNull(layer); + assertNull(layer.getIconHaloWidth().getExpression()); + + // Set and Get + Expression expression = number(Expression.get("undefined")); + layer.setProperties(iconHaloWidth(expression)); + assertEquals(layer.getIconHaloWidth().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testIconHaloBlurTransition() { + Timber.i("icon-halo-blurTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setIconHaloBlurTransition(options); + assertEquals(layer.getIconHaloBlurTransition(), options); + } + + @Test + @UiThreadTest + public void testIconHaloBlurAsConstant() { + Timber.i("icon-halo-blur"); + assertNotNull(layer); + assertNull(layer.getIconHaloBlur().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(iconHaloBlur(propertyValue)); + assertEquals(layer.getIconHaloBlur().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testIconHaloBlurAsExpression() { + Timber.i("icon-halo-blur-expression"); + assertNotNull(layer); + assertNull(layer.getIconHaloBlur().getExpression()); + + // Set and Get + Expression expression = number(Expression.get("undefined")); + layer.setProperties(iconHaloBlur(expression)); + assertEquals(layer.getIconHaloBlur().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testIconTranslateTransition() { + Timber.i("icon-translateTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setIconTranslateTransition(options); + assertEquals(layer.getIconTranslateTransition(), options); + } + + @Test + @UiThreadTest + public void testIconTranslateAsConstant() { + Timber.i("icon-translate"); + assertNotNull(layer); + assertNull(layer.getIconTranslate().getValue()); + + // Set and Get + Float[] propertyValue = new Float[] {0f, 0f}; + layer.setProperties(iconTranslate(propertyValue)); + assertEquals(layer.getIconTranslate().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testIconTranslateAnchorAsConstant() { + Timber.i("icon-translate-anchor"); + assertNotNull(layer); + assertNull(layer.getIconTranslateAnchor().getValue()); + + // Set and Get + String propertyValue = ICON_TRANSLATE_ANCHOR_MAP; + layer.setProperties(iconTranslateAnchor(propertyValue)); + assertEquals(layer.getIconTranslateAnchor().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testTextOpacityTransition() { + Timber.i("text-opacityTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setTextOpacityTransition(options); + assertEquals(layer.getTextOpacityTransition(), options); + } + + @Test + @UiThreadTest + public void testTextOpacityAsConstant() { + Timber.i("text-opacity"); + assertNotNull(layer); + assertNull(layer.getTextOpacity().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(textOpacity(propertyValue)); + assertEquals(layer.getTextOpacity().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testTextOpacityAsExpression() { + Timber.i("text-opacity-expression"); + assertNotNull(layer); + assertNull(layer.getTextOpacity().getExpression()); + + // Set and Get + Expression expression = number(Expression.get("undefined")); + layer.setProperties(textOpacity(expression)); + assertEquals(layer.getTextOpacity().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testTextColorTransition() { + Timber.i("text-colorTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setTextColorTransition(options); + assertEquals(layer.getTextColorTransition(), options); + } + + @Test + @UiThreadTest + public void testTextColorAsConstant() { + Timber.i("text-color"); + assertNotNull(layer); + assertNull(layer.getTextColor().getValue()); + + // Set and Get + String propertyValue = "rgba(255,128,0,0.7)"; + layer.setProperties(textColor(propertyValue)); + assertEquals(layer.getTextColor().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testTextColorAsExpression() { + Timber.i("text-color-expression"); + assertNotNull(layer); + assertNull(layer.getTextColor().getExpression()); + + // Set and Get + Expression expression = toColor(Expression.get("undefined")); + layer.setProperties(textColor(expression)); + assertEquals(layer.getTextColor().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testTextColorAsIntConstant() { + Timber.i("text-color"); + assertNotNull(layer); + + // Set and Get + layer.setProperties(textColor(Color.argb(127, 255, 127, 0))); + assertEquals(layer.getTextColorAsInt(), Color.argb(127, 255, 127, 0)); + } + + @Test + @UiThreadTest + public void testTextHaloColorTransition() { + Timber.i("text-halo-colorTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setTextHaloColorTransition(options); + assertEquals(layer.getTextHaloColorTransition(), options); + } + + @Test + @UiThreadTest + public void testTextHaloColorAsConstant() { + Timber.i("text-halo-color"); + assertNotNull(layer); + assertNull(layer.getTextHaloColor().getValue()); + + // Set and Get + String propertyValue = "rgba(255,128,0,0.7)"; + layer.setProperties(textHaloColor(propertyValue)); + assertEquals(layer.getTextHaloColor().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testTextHaloColorAsExpression() { + Timber.i("text-halo-color-expression"); + assertNotNull(layer); + assertNull(layer.getTextHaloColor().getExpression()); + + // Set and Get + Expression expression = toColor(Expression.get("undefined")); + layer.setProperties(textHaloColor(expression)); + assertEquals(layer.getTextHaloColor().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testTextHaloColorAsIntConstant() { + Timber.i("text-halo-color"); + assertNotNull(layer); + + // Set and Get + layer.setProperties(textHaloColor(Color.argb(127, 255, 127, 0))); + assertEquals(layer.getTextHaloColorAsInt(), Color.argb(127, 255, 127, 0)); + } + + @Test + @UiThreadTest + public void testTextHaloWidthTransition() { + Timber.i("text-halo-widthTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setTextHaloWidthTransition(options); + assertEquals(layer.getTextHaloWidthTransition(), options); + } + + @Test + @UiThreadTest + public void testTextHaloWidthAsConstant() { + Timber.i("text-halo-width"); + assertNotNull(layer); + assertNull(layer.getTextHaloWidth().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(textHaloWidth(propertyValue)); + assertEquals(layer.getTextHaloWidth().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testTextHaloWidthAsExpression() { + Timber.i("text-halo-width-expression"); + assertNotNull(layer); + assertNull(layer.getTextHaloWidth().getExpression()); + + // Set and Get + Expression expression = number(Expression.get("undefined")); + layer.setProperties(textHaloWidth(expression)); + assertEquals(layer.getTextHaloWidth().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testTextHaloBlurTransition() { + Timber.i("text-halo-blurTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setTextHaloBlurTransition(options); + assertEquals(layer.getTextHaloBlurTransition(), options); + } + + @Test + @UiThreadTest + public void testTextHaloBlurAsConstant() { + Timber.i("text-halo-blur"); + assertNotNull(layer); + assertNull(layer.getTextHaloBlur().getValue()); + + // Set and Get + Float propertyValue = 0.3f; + layer.setProperties(textHaloBlur(propertyValue)); + assertEquals(layer.getTextHaloBlur().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testTextHaloBlurAsExpression() { + Timber.i("text-halo-blur-expression"); + assertNotNull(layer); + assertNull(layer.getTextHaloBlur().getExpression()); + + // Set and Get + Expression expression = number(Expression.get("undefined")); + layer.setProperties(textHaloBlur(expression)); + assertEquals(layer.getTextHaloBlur().getExpression(), expression); + } + + @Test + @UiThreadTest + public void testTextTranslateTransition() { + Timber.i("text-translateTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setTextTranslateTransition(options); + assertEquals(layer.getTextTranslateTransition(), options); + } + + @Test + @UiThreadTest + public void testTextTranslateAsConstant() { + Timber.i("text-translate"); + assertNotNull(layer); + assertNull(layer.getTextTranslate().getValue()); + + // Set and Get + Float[] propertyValue = new Float[] {0f, 0f}; + layer.setProperties(textTranslate(propertyValue)); + assertEquals(layer.getTextTranslate().getValue(), propertyValue); + } + + @Test + @UiThreadTest + public void testTextTranslateAnchorAsConstant() { + Timber.i("text-translate-anchor"); + assertNotNull(layer); + assertNull(layer.getTextTranslateAnchor().getValue()); + + // Set and Get + String propertyValue = TEXT_TRANSLATE_ANCHOR_MAP; + layer.setProperties(textTranslateAnchor(propertyValue)); + assertEquals(layer.getTextTranslateAnchor().getValue(), propertyValue); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/layer.junit.ejs b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/layer.junit.ejs new file mode 100644 index 0000000000..1104cbed9d --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/layer.junit.ejs @@ -0,0 +1,195 @@ +<% + const type = locals.type; + const properties = locals.properties; +-%> +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`. + +package com.mapbox.mapboxsdk.testapp.style; + +import android.graphics.Color; +import android.support.test.annotation.UiThreadTest; +import android.support.test.runner.AndroidJUnit4; + +import com.mapbox.mapboxsdk.maps.BaseLayerTest; +import org.junit.Before; +import timber.log.Timber; + +import com.mapbox.mapboxsdk.style.expressions.Expression; +import com.mapbox.mapboxsdk.style.layers.<%- camelize(type) %>Layer; +<% if (type === 'symbol') { -%> +import com.mapbox.mapboxsdk.style.types.Formatted; +import com.mapbox.mapboxsdk.style.types.FormattedSection; +<% } -%> + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static com.mapbox.mapboxsdk.style.expressions.Expression.*; +import static org.junit.Assert.*; +import static com.mapbox.mapboxsdk.style.layers.Property.*; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*; + +import com.mapbox.mapboxsdk.style.layers.TransitionOptions; + +/** + * Basic smoke tests for <%- camelize(type) %>Layer + */ +@RunWith(AndroidJUnit4.class) +public class <%- camelize(type) %>LayerTest extends BaseLayerTest { + + private <%- camelize(type) %>Layer layer; + + @Before + @UiThreadTest + public void beforeTest(){ + super.before(); +<% if (type === 'background') { -%> + layer = new <%- camelize(type) %>Layer("my-layer"); +<% } else { -%> + layer = new <%- camelize(type) %>Layer("my-layer", "composite"); + layer.setSourceLayer("composite"); +<% } -%> + setupLayer(layer); + } +<% if (type !== 'background') { -%> + + @Test + @UiThreadTest + public void testSourceId() { + Timber.i("SourceId"); + assertNotNull(layer); + assertEquals(layer.getSourceId(), "composite"); + } +<% } -%> + + @Test + @UiThreadTest + public void testSetVisibility() { + Timber.i("Visibility"); + assertNotNull(layer); + + // Get initial + assertEquals(layer.getVisibility().getValue(), VISIBLE); + + // Set + layer.setProperties(visibility(NONE)); + assertEquals(layer.getVisibility().getValue(), NONE); + } +<% if (!(type === 'background' || type === 'raster' || type === 'hillshade')) { -%> + + @Test + @UiThreadTest + public void testSourceLayer() { + Timber.i("SourceLayer"); + assertNotNull(layer); + + // Get initial + assertEquals(layer.getSourceLayer(), "composite"); + + // Set + final String sourceLayer = "test"; + layer.setSourceLayer(sourceLayer); + assertEquals(layer.getSourceLayer(), sourceLayer); + } + + @Test + @UiThreadTest + public void testFilter() { + Timber.i("Filter"); + assertNotNull(layer); + + // Get initial + assertEquals(layer.getFilter(), null); + + // Set + Expression filter = eq(get("undefined"), literal(1.0)); + layer.setFilter(filter); + assertEquals(layer.getFilter().toString(), filter.toString()); + + // Set constant + filter = literal(true); + layer.setFilter(filter); + assertEquals(layer.getFilter().toString(), filter.toString()); + } + + +<% } -%> +<% for (const property of properties) { -%> +<% if (property['property-type'] !== 'color-ramp') { -%> +<% if (property.transition) { -%> + + @Test + @UiThreadTest + public void test<%- camelize(property.name) %>Transition() { + Timber.i("<%- property.name %>TransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.set<%- camelize(property.name) %>Transition(options); + assertEquals(layer.get<%- camelize(property.name) %>Transition(), options); + } +<% } -%> + + @Test + @UiThreadTest + public void test<%- camelize(property.name) %>AsConstant() { + Timber.i("<%- property.name %>"); + assertNotNull(layer); + assertNull(layer.get<%- camelize(property.name) %>().getValue()); + + // Set and Get + <%- propertyType(property) %> propertyValue = <%- defaultValueJava(property) %>; +<% if (property.type === 'formatted') { -%> + layer.setProperties(<%- camelizeWithLeadingLowercase(property.name) %>("default")); + assertEquals(layer.get<%- camelize(property.name) %>().getValue(), propertyValue); +<% } -%> + layer.setProperties(<%- camelizeWithLeadingLowercase(property.name) %>(propertyValue)); + assertEquals(layer.get<%- camelize(property.name) %>().getValue(), propertyValue); +<% if (property.tokens) { -%> + + layer.setProperties(<%- camelizeWithLeadingLowercase(property.name) %>("{token}")); +<% if (property.type === 'formatted') { -%> + assertEquals(layer.get<%- camelize(property.name) %>().getExpression(), <%- defaultExpressionJava(property) %>(Expression.formatEntry(Expression.toString(Expression.get("token"))))); +<% } else {-%> + assertEquals(layer.get<%- camelize(property.name) %>().getExpression(), Expression.toString(Expression.get("token"))); +<% } -%> +<% } -%> + } +<% if (property['property-type'] === 'data-driven' || property['property-type'] === 'cross-faded-data-driven') { -%> +<% if (!(property.name.endsWith("-font")||property.name.endsWith("-offset"))) { -%> + + @Test + @UiThreadTest + public void test<%- camelize(property.name) %>AsExpression() { + Timber.i("<%- property.name %>-expression"); + assertNotNull(layer); + assertNull(layer.get<%- camelize(property.name) %>().getExpression()); + + // Set and Get +<% if (property.type === 'formatted') { -%> + Expression expression = <%- defaultExpressionJava(property) %>(Expression.formatEntry(Expression.get("undefined"), FormatOption.formatFontScale(2.0), FormatOption.formatTextFont(new String[]{"Open Sans Regular", "Arial Unicode MS Regular"}))); +<% } else { -%> + Expression expression = <%- defaultExpressionJava(property) %>(Expression.get("undefined")); +<% } -%> + layer.setProperties(<%- camelizeWithLeadingLowercase(property.name) %>(expression)); + assertEquals(layer.get<%- camelize(property.name) %>().getExpression(), expression); + } +<% } -%> +<% } -%> +<% if (property.type == 'color') { -%> + + @Test + @UiThreadTest + public void test<%- camelize(property.name) %>AsIntConstant() { + Timber.i("<%- property.name %>"); + assertNotNull(layer); + + // Set and Get + layer.setProperties(<%- camelizeWithLeadingLowercase(property.name) %>(Color.argb(127, 255, 127, 0))); + assertEquals(layer.get<%- camelize(property.name) %>AsInt(), Color.argb(127, 255, 127, 0)); + } +<% } -%> +<% } -%> +<% } -%> +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/light.junit.ejs b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/light.junit.ejs new file mode 100644 index 0000000000..9bc77b202b --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/light.junit.ejs @@ -0,0 +1,132 @@ +<% + const properties = locals.properties; +-%> +package com.mapbox.mapboxsdk.testapp.style; + +import android.graphics.Color; +import android.support.test.espresso.UiController; +import android.support.test.espresso.ViewAction; +import android.support.test.runner.AndroidJUnit4; +import android.view.View; + +import com.mapbox.mapboxsdk.style.light.Light; +import com.mapbox.mapboxsdk.style.expressions.Expression; +import com.mapbox.mapboxsdk.style.layers.FillExtrusionLayer; +import com.mapbox.mapboxsdk.style.layers.TransitionOptions; +import com.mapbox.mapboxsdk.style.light.Position; +import com.mapbox.mapboxsdk.testapp.R; +import com.mapbox.mapboxsdk.testapp.activity.BaseTest; +import com.mapbox.mapboxsdk.testapp.activity.style.FillExtrusionStyleTestActivity; + +import timber.log.Timber; + +import org.hamcrest.Matcher; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +import static android.support.test.espresso.matcher.ViewMatchers.withId; +import static com.mapbox.mapboxsdk.style.expressions.Expression.eq; +import static com.mapbox.mapboxsdk.style.layers.Property.ANCHOR_MAP; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillExtrusionBase; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillExtrusionColor; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillExtrusionHeight; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillExtrusionOpacity; + +import static com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke; +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; + +@RunWith(AndroidJUnit4.class) +public class LightTest extends BaseTest { + + private Light light; +<% for (const property of properties) { -%> +<% if (property.transition) { -%> + + @Test + public void test<%- camelize(property.name) %>Transition() { + validateTestSetup(); + setupLight(); + Timber.i("<%- property.name %>TransitionOptions"); + invoke(mapboxMap, (uiController, mapboxMap) -> { + assertNotNull(light); + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + light.set<%- camelize(property.name) %>Transition(options); + assertEquals("Transition options should match", options, light.get<%- camelize(property.name) %>Transition()); + }); + } +<% } -%> +<% if (property.name == "position") { -%> + + @Test + public void test<%- camelize(property.name) %>() { + validateTestSetup(); + setupLight(); + Timber.i("<%- property.name %>"); + invoke(mapboxMap,(uiController, mapboxMap) -> { + assertNotNull(light); + // Set and Get + Position position = new Position(1, 2, 3); + light.set<%- camelize(property.name) %>(position); + assertEquals("Position should match", position, light.get<%- camelize(property.name) %>()); + }); + } +<% } else { -%> + + @Test + public void test<%- camelize(property.name) %>() { + validateTestSetup(); + setupLight(); + Timber.i("<%- property.name %>"); + invoke(mapboxMap, (uiController, mapboxMap) -> { + assertNotNull(light); + // Set and Get + light.set<%- camelize(property.name) %>(<%- defaultValueJava(property) %>); +<% if (property.name == 'color') { -%> + assertEquals("<%- camelize(property.name) %> should match", <%- defaultValueJava(property) %>, light.get<%- camelize(property.name) %>()); +<% } else { -%> + assertEquals("<%- camelize(property.name) %> should match", <%- defaultValueJava(property) %>, light.get<%- camelize(property.name) %>()); +<% } -%> + }); + } +<% } -%> +<% } -%> + + private void setupLight() { + onView(withId(R.id.mapView)).perform(new ViewAction() { + @Override + public Matcher<View> getConstraints() { + return isDisplayed(); + } + + @Override + public String getDescription() { + return getClass().getSimpleName(); + } + + @Override + public void perform(UiController uiController, View view) { + light = mapboxMap.getStyle().getLight(); + FillExtrusionLayer fillExtrusionLayer = new FillExtrusionLayer("3d-buildings", "composite"); + fillExtrusionLayer.setSourceLayer("building"); + fillExtrusionLayer.setFilter(eq(Expression.get("extrude"), "true")); + fillExtrusionLayer.setMinZoom(15); + fillExtrusionLayer.setProperties( + fillExtrusionColor(Color.LTGRAY), + fillExtrusionHeight(Expression.get("height")), + fillExtrusionBase(Expression.get("min_height")), + fillExtrusionOpacity(0.6f) + ); + mapboxMap.getStyle().addLayer(fillExtrusionLayer); + } + }); + } + + @Override + protected Class getActivityClass() { + return FillExtrusionStyleTestActivity.class; + } +}
\ No newline at end of file |