package com.mapbox.mapboxsdk.maps import android.graphics.Bitmap import android.graphics.drawable.ShapeDrawable import com.mapbox.mapboxsdk.constants.MapboxConstants import com.mapbox.mapboxsdk.style.layers.SymbolLayer import com.mapbox.mapboxsdk.style.layers.TransitionOptions import com.mapbox.mapboxsdk.style.sources.GeoJsonSource import io.mockk.every import io.mockk.mockk import io.mockk.spyk import io.mockk.verify import org.junit.Assert import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner @RunWith(RobolectricTestRunner::class) class StyleTest { private lateinit var mapboxMap: MapboxMap private lateinit var nativeMapView: NativeMapView @Before fun setup() { nativeMapView = mockk() mapboxMap = MapboxMap(nativeMapView, null, null, null, null, null) every { nativeMapView.styleUrl = any() } answers {} every { nativeMapView.styleJson = any() } answers {} every { nativeMapView.addLayerBelow(any(), any()) } answers {} every { nativeMapView.addLayerAbove(any(), any()) } answers {} every { nativeMapView.addLayerAt(any(), any()) } answers {} every { nativeMapView.addSource(any()) } answers {} every { nativeMapView.addImages(any()) } answers {} every { nativeMapView.transitionOptions = any() } answers {} every { nativeMapView.isDestroyed } returns false mapboxMap.injectLocationComponent(spyk()) } @Test fun testFromUrl() { val builder = Style.Builder().fromUrl(Style.MAPBOX_STREETS) mapboxMap.setStyle(builder) verify(exactly = 1) { nativeMapView.styleUrl = Style.MAPBOX_STREETS } } @Test fun testFromJson() { val builder = Style.Builder().fromJson("{}") mapboxMap.setStyle(builder) verify(exactly = 1) { nativeMapView.styleJson = "{}" } } @Test fun testEmptyBuilder() { val builder = Style.Builder() mapboxMap.setStyle(builder) verify(exactly = 1) { nativeMapView.styleJson = "{}" } } @Test fun testWithLayer() { val layer = mockk() every { layer.id } returns "1" val builder = Style.Builder().withLayer(layer) mapboxMap.setStyle(builder) mapboxMap.onFinishLoadingStyle() verify(exactly = 1) { nativeMapView.addLayerBelow(layer, MapboxConstants.LAYER_ID_ANNOTATIONS) } } @Test fun testWithLayerAbove() { val layer = mockk() every { layer.id } returns "1" val builder = Style.Builder().withLayerAbove(layer, "id") mapboxMap.setStyle(builder) mapboxMap.onFinishLoadingStyle() verify(exactly = 1) { nativeMapView.addLayerAbove(layer, "id") } } @Test fun testWithLayerBelow() { val layer = mockk() every { layer.id } returns "1" val builder = Style.Builder().withLayerBelow(layer, "id") mapboxMap.setStyle(builder) mapboxMap.onFinishLoadingStyle() verify(exactly = 1) { nativeMapView.addLayerBelow(layer, "id") } } @Test fun testWithLayerAt() { val layer = mockk() every { layer.id } returns "1" val builder = Style.Builder().withLayerAt(layer, 1) mapboxMap.setStyle(builder) mapboxMap.onFinishLoadingStyle() verify(exactly = 1) { nativeMapView.addLayerAt(layer, 1) } } @Test fun testWithSource() { val source = mockk() every { source.id } returns "1" val builder = Style.Builder().withSource(source) mapboxMap.setStyle(builder) mapboxMap.onFinishLoadingStyle() verify(exactly = 1) { nativeMapView.addSource(source) } } @Test fun testWithTransitionOptions() { val transitionOptions = TransitionOptions(100, 200) val builder = Style.Builder().withTransition(transitionOptions) mapboxMap.setStyle(builder) mapboxMap.onFinishLoadingStyle() verify(exactly = 1) { nativeMapView.transitionOptions = transitionOptions } } @Test fun testWithFromLoadingSource() { val source = mockk() every { source.id } returns "1" val builder = Style.Builder().fromUrl(Style.MAPBOX_STREETS).withSource(source) mapboxMap.setStyle(builder) verify(exactly = 1) { nativeMapView.styleUrl = Style.MAPBOX_STREETS } mapboxMap.notifyStyleLoaded() verify(exactly = 1) { nativeMapView.addSource(source) } } @Test fun testWithFromLoadingLayer() { val layer = mockk() every { layer.id } returns "1" val builder = Style.Builder().fromUrl(Style.MAPBOX_STREETS).withLayer(layer) mapboxMap.setStyle(builder) verify(exactly = 1) { nativeMapView.styleUrl = Style.MAPBOX_STREETS } mapboxMap.notifyStyleLoaded() verify(exactly = 1) { nativeMapView.addLayerBelow(layer, MapboxConstants.LAYER_ID_ANNOTATIONS) } } @Test fun testWithFromLoadingLayerAt() { val layer = mockk() every { layer.id } returns "1" val builder = Style.Builder().fromUrl(Style.MAPBOX_STREETS).withLayerAt(layer, 1) mapboxMap.setStyle(builder) verify(exactly = 1) { nativeMapView.styleUrl = Style.MAPBOX_STREETS } mapboxMap.notifyStyleLoaded() verify(exactly = 1) { nativeMapView.addLayerAt(layer, 1) } } @Test fun testWithFromLoadingLayerBelow() { val layer = mockk() every { layer.id } returns "1" val builder = Style.Builder().fromUrl(Style.MAPBOX_STREETS).withLayerBelow(layer, "below") mapboxMap.setStyle(builder) verify(exactly = 1) { nativeMapView.styleUrl = Style.MAPBOX_STREETS } mapboxMap.notifyStyleLoaded() verify(exactly = 1) { nativeMapView.addLayerBelow(layer, "below") } } @Test fun testWithFromLoadingLayerAbove() { val layer = mockk() every { layer.id } returns "1" val builder = Style.Builder().fromUrl(Style.MAPBOX_STREETS).withLayerBelow(layer, "below") mapboxMap.setStyle(builder) verify(exactly = 1) { nativeMapView.styleUrl = Style.MAPBOX_STREETS } mapboxMap.notifyStyleLoaded() verify(exactly = 1) { nativeMapView.addLayerBelow(layer, "below") } } @Test fun testWithFromLoadingTransitionOptions() { val transitionOptions = TransitionOptions(100, 200) val builder = Style.Builder().fromUrl(Style.MAPBOX_STREETS).withTransition(transitionOptions) mapboxMap.setStyle(builder) verify(exactly = 1) { nativeMapView.styleUrl = Style.MAPBOX_STREETS } mapboxMap.notifyStyleLoaded() verify(exactly = 1) { nativeMapView.transitionOptions = transitionOptions } } @Test fun testFromCallback() { val callback = mockk() every { callback.onStyleLoaded(any()) } answers {} val builder = Style.Builder().fromUrl(Style.MAPBOX_STREETS) mapboxMap.setStyle(builder, callback) verify(exactly = 1) { nativeMapView.styleUrl = Style.MAPBOX_STREETS } mapboxMap.notifyStyleLoaded() verify(exactly = 1) { callback.onStyleLoaded(any()) } } @Test fun testWithCallback() { val callback = mockk() every { callback.onStyleLoaded(any()) } answers {} val source = mockk() every { source.id } returns "1" val builder = Style.Builder().withSource(source) mapboxMap.setStyle(builder, callback) mapboxMap.onFinishLoadingStyle() verify(exactly = 1) { nativeMapView.addSource(source) } verify(exactly = 1) { callback.onStyleLoaded(any()) } } @Test fun testGetAsyncWith() { val callback = mockk() every { callback.onStyleLoaded(any()) } answers {} mapboxMap.getStyle(callback) val source = mockk() every { source.id } returns "1" val builder = Style.Builder().withSource(source) mapboxMap.setStyle(builder) mapboxMap.onFinishLoadingStyle() verify(exactly = 1) { nativeMapView.addSource(source) } verify(exactly = 1) { callback.onStyleLoaded(any()) } } @Test fun testGetAsyncFrom() { val callback = mockk() every { callback.onStyleLoaded(any()) } answers {} mapboxMap.getStyle(callback) val source = mockk() every { source.id } returns "1" val builder = Style.Builder().fromJson("{}") mapboxMap.setStyle(builder) verify(exactly = 1) { nativeMapView.styleJson = "{}" } mapboxMap.notifyStyleLoaded() verify(exactly = 1) { callback.onStyleLoaded(any()) } } @Test fun testGetAsyncWithFrom() { val callback = mockk() every { callback.onStyleLoaded(any()) } answers {} mapboxMap.getStyle(callback) val source = mockk() every { source.id } returns "1" val builder = Style.Builder().fromUrl(Style.MAPBOX_STREETS).withSource(source) mapboxMap.setStyle(builder) verify(exactly = 1) { nativeMapView.styleUrl = Style.MAPBOX_STREETS } mapboxMap.notifyStyleLoaded() verify(exactly = 1) { nativeMapView.addSource(source) } verify(exactly = 1) { callback.onStyleLoaded(any()) } } @Test fun testGetNullStyle() { Assert.assertNull(mapboxMap.style) } @Test fun testGetNullWhileLoading() { val transitionOptions = TransitionOptions(100, 200) val builder = Style.Builder().fromUrl(Style.MAPBOX_STREETS).withTransition(transitionOptions) mapboxMap.setStyle(builder) Assert.assertNull(mapboxMap.style) mapboxMap.notifyStyleLoaded() Assert.assertNotNull(mapboxMap.style) } @Test fun testNotReinvokeSameListener() { val callback = mockk() every { callback.onStyleLoaded(any()) } answers {} mapboxMap.getStyle(callback) val source = mockk() every { source.id } returns "1" val builder = Style.Builder().fromJson("{}") mapboxMap.setStyle(builder) verify(exactly = 1) { nativeMapView.styleJson = "{}" } mapboxMap.notifyStyleLoaded() mapboxMap.setStyle(Style.MAPBOX_STREETS) verify(exactly = 1) { callback.onStyleLoaded(any()) } } @Test(expected = IllegalStateException::class) fun testIllegalStateExceptionWithStyleReload() { val builder = Style.Builder().fromUrl(Style.MAPBOX_STREETS) mapboxMap.setStyle(builder) mapboxMap.notifyStyleLoaded() val style = mapboxMap.style mapboxMap.setStyle(Style.Builder().fromUrl(Style.DARK)) style!!.addLayer(mockk()) } @Test fun testAddImage() { val bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888) val builder = Style.Builder().fromUrl(Style.SATELLITE).withImage("id", bitmap) mapboxMap.setStyle(builder) verify(exactly = 1) { nativeMapView.styleUrl = Style.SATELLITE } verify(exactly = 0) { nativeMapView.addImages(any()) } mapboxMap.notifyStyleLoaded() verify(exactly = 1) { nativeMapView.addImages(any()) } } @Test fun testAddDrawable() { val drawable = ShapeDrawable() drawable.intrinsicHeight = 10 drawable.intrinsicWidth = 10 val builder = Style.Builder().fromUrl(Style.SATELLITE).withImage("id", drawable) mapboxMap.setStyle(builder) verify(exactly = 1) { nativeMapView.styleUrl = Style.SATELLITE } verify(exactly = 0) { nativeMapView.addImages(any()) } mapboxMap.notifyStyleLoaded() verify(exactly = 1) { nativeMapView.addImages(any()) } } }