1+ package com.mapbox.navigation.core.trip.service
2+
3+ import android.util.Log
4+ import androidx.test.ext.junit.runners.AndroidJUnit4
5+ import androidx.test.platform.app.InstrumentationRegistry
6+ import com.mapbox.api.directions.v5.models.DirectionsRoute
7+ import com.mapbox.common.LogConfiguration
8+ import com.mapbox.common.LoggingLevel
9+ import com.mapbox.navigation.base.options.NavigationOptions
10+ import com.mapbox.navigation.base.route.NavigationRoute
11+ import com.mapbox.navigation.base.route.RouterOrigin
12+ import com.mapbox.navigation.base.route.toNavigationRoute
13+ import com.mapbox.navigation.core.MapboxNavigationProvider
14+ import com.mapbox.navigation.core.navigator.toFixLocation
15+ import com.mapbox.navigation.core.replay.history.ReplayEventUpdateLocation
16+ import com.mapbox.navigation.core.replay.mapToLocation
17+ import com.mapbox.navigation.core.replay.route.ReplayRouteMapper
18+ import com.mapbox.navigation.core.test.R
19+ import com.mapbox.navigation.navigator.internal.MapboxNativeNavigator
20+ import com.mapbox.navigation.navigator.internal.MapboxNativeNavigatorImpl
21+ import com.mapbox.navigator.NavigationStatus
22+ import com.mapbox.navigator.NavigationStatusOrigin
23+ import com.mapbox.navigator.NavigatorObserver
24+ import com.mapbox.navigator.RouteState
25+ import com.mapbox.navigator.SetRoutesReason
26+ import kotlinx.coroutines.Dispatchers
27+ import kotlinx.coroutines.ExperimentalCoroutinesApi
28+ import kotlinx.coroutines.async
29+ import kotlinx.coroutines.channels.awaitClose
30+ import kotlinx.coroutines.flow.Flow
31+ import kotlinx.coroutines.flow.callbackFlow
32+ import kotlinx.coroutines.flow.collect
33+ import kotlinx.coroutines.flow.filter
34+ import kotlinx.coroutines.flow.first
35+ import kotlinx.coroutines.flow.map
36+ import kotlinx.coroutines.launch
37+ import kotlinx.coroutines.runBlocking
38+ import org.junit.Assert.assertEquals
39+ import org.junit.Assert.assertTrue
40+ import org.junit.Test
41+ import org.junit.runner.RunWith
42+
43+ @RunWith(AndroidJUnit4 ::class )
44+ class ArtificialDriverTest {
45+
46+ @Test
47+ fun testFollowingRoute () = runBlocking<Unit >(Dispatchers .Main ) {
48+ LogConfiguration .setLoggingLevel(LoggingLevel .DEBUG )
49+ getNativeNavigator { nativeNavigator ->
50+ val testRoute = getTestRoute()
51+ val replayRouteMapper = ReplayRouteMapper ()
52+ val events = replayRouteMapper.mapDirectionsRouteGeometry(testRoute.directionsRoute)
53+ val result = nativeNavigator.setRoutes(testRoute, reason = SetRoutesReason .NEW_ROUTE )
54+ assertTrue(" result is $result " , result.isValue)
55+ val states = mutableListOf<NavigationStatus >()
56+ val statusTracking = launch {
57+ nativeNavigator.statusUpdates().collect {
58+ states.add(it.second)
59+ }
60+ }
61+ for (event in events.filterIsInstance<ReplayEventUpdateLocation >()) {
62+ val location = event.location.mapToLocation(event.eventTimestamp)
63+ assertTrue(nativeNavigator.updateLocation(location.toFixLocation()))
64+ }
65+ statusTracking.cancel()
66+ assertTrue(states.all { it.routeState == RouteState .TRACKING || it.routeState == RouteState .COMPLETE })
67+ }
68+ }
69+
70+ @OptIn(ExperimentalCoroutinesApi ::class )
71+ fun MapboxNativeNavigator.statusUpdates (): Flow <Pair <NavigationStatusOrigin , NavigationStatus >> {
72+ return callbackFlow {
73+ val observer = NavigatorObserver { origin, status ->
74+ Log .d(" vadzim-debug" , " $origin , $status " )
75+ this .trySend(Pair (origin, status))
76+ }
77+ addNavigatorObserver(observer)
78+ awaitClose {
79+ removeNavigatorObserver(observer)
80+ }
81+ }
82+ }
83+
84+ private suspend fun getNativeNavigator (block : suspend (MapboxNativeNavigator ) -> Unit ) {
85+ val context = InstrumentationRegistry .getInstrumentation().targetContext
86+ val mapboxNavigation = MapboxNavigationProvider .create(
87+ NavigationOptions .Builder (context)
88+ .accessToken(context.getString(R .string.mapbox_access_token))
89+ .build()
90+ )
91+ block(MapboxNativeNavigatorImpl )
92+ mapboxNavigation.onDestroy()
93+ }
94+
95+ private fun getTestRoute (): NavigationRoute {
96+ val context = InstrumentationRegistry .getInstrumentation().targetContext
97+ return DirectionsRoute .fromJson(
98+ context.resources.openRawResource(R .raw.multileg_route)
99+ .readBytes().decodeToString()
100+ ).toNavigationRoute(RouterOrigin .Custom ())
101+ }
102+ }
0 commit comments