react-native-brouter 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -0
- package/README.md +125 -0
- package/android/build.gradle +110 -0
- package/android/generated/java/com/jhotadhari/reactnative/brouter/NativeBRouterSpec.java +39 -0
- package/android/generated/jni/CMakeLists.txt +28 -0
- package/android/generated/jni/RNBRouterSpec-generated.cpp +32 -0
- package/android/generated/jni/RNBRouterSpec.h +31 -0
- package/android/generated/jni/react/renderer/components/RNBRouterSpec/RNBRouterSpecJSI.h +38 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/AndroidManifestNew.xml +2 -0
- package/android/src/main/aidl/btools/routingapp/IBRouterService.aidl +47 -0
- package/android/src/main/java/com/jhotadhari/reactnative/brouter/BRouterClient.java +205 -0
- package/android/src/main/java/com/jhotadhari/reactnative/brouter/BRouterError.java +38 -0
- package/android/src/main/java/com/jhotadhari/reactnative/brouter/BRouterModule.java +135 -0
- package/android/src/main/java/com/jhotadhari/reactnative/brouter/BRouterPackage.kt +33 -0
- package/android/src/main/java/com/jhotadhari/reactnative/brouter/BRouterServiceConnection.java +54 -0
- package/android/src/main/java/com/jhotadhari/reactnative/brouter/ParamMapper.java +174 -0
- package/android/src/test/java/com/jhotadhari/reactnative/brouter/BRouterClientTest.java +247 -0
- package/android/src/test/java/com/jhotadhari/reactnative/brouter/BRouterErrorTest.java +48 -0
- package/android/src/test/java/com/jhotadhari/reactnative/brouter/BRouterModuleTest.java +137 -0
- package/android/src/test/java/com/jhotadhari/reactnative/brouter/ParamMapperTest.java +279 -0
- package/lib/module/NativeBRouter.js +5 -0
- package/lib/module/NativeBRouter.js.map +1 -0
- package/lib/module/geojson/index.js +235 -0
- package/lib/module/geojson/index.js.map +1 -0
- package/lib/module/index.js +297 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/release.config.d.ts +11 -0
- package/lib/typescript/release.config.d.ts.map +1 -0
- package/lib/typescript/src/NativeBRouter.d.ts +9 -0
- package/lib/typescript/src/NativeBRouter.d.ts.map +1 -0
- package/lib/typescript/src/geojson/index.d.ts +122 -0
- package/lib/typescript/src/geojson/index.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +13 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +93 -0
- package/lib/typescript/src/types.d.ts.map +1 -0
- package/package.json +159 -0
- package/react-native.config.js +12 -0
- package/src/NativeBRouter.ts +8 -0
- package/src/geojson/index.ts +371 -0
- package/src/index.tsx +344 -0
- package/src/types.ts +112 -0
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
package com.jhotadhari.reactnative.brouter;
|
|
2
|
+
|
|
3
|
+
import static org.junit.Assert.*;
|
|
4
|
+
import static org.mockito.Mockito.*;
|
|
5
|
+
|
|
6
|
+
import android.content.Context;
|
|
7
|
+
import android.os.Bundle;
|
|
8
|
+
import android.os.IBinder;
|
|
9
|
+
|
|
10
|
+
import btools.routingapp.IBRouterService;
|
|
11
|
+
|
|
12
|
+
import org.junit.Before;
|
|
13
|
+
import org.junit.Test;
|
|
14
|
+
import org.mockito.MockedStatic;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Unit tests for {@link BRouterClient} lifecycle.
|
|
18
|
+
*
|
|
19
|
+
* <p>These tests mock {@link BRouterServiceConnection#connect} so they
|
|
20
|
+
* don't need a real Android environment.
|
|
21
|
+
*/
|
|
22
|
+
public class BRouterClientTest {
|
|
23
|
+
|
|
24
|
+
private Context mockContext;
|
|
25
|
+
|
|
26
|
+
@Before
|
|
27
|
+
public void setUp() {
|
|
28
|
+
mockContext = mock(Context.class);
|
|
29
|
+
when(mockContext.getApplicationContext()).thenReturn(mockContext);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// ── Construction ───────────────────────────────────────────────
|
|
33
|
+
|
|
34
|
+
@Test
|
|
35
|
+
public void constructorStoresContextAndTimeout() {
|
|
36
|
+
BRouterClient client = new BRouterClient(mockContext, 2000);
|
|
37
|
+
|
|
38
|
+
assertFalse(client.isConnected());
|
|
39
|
+
// Timeout stored internally — verified implicitly by connect()
|
|
40
|
+
// behavior in tests below.
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// ── connect() ──────────────────────────────────────────────────
|
|
44
|
+
|
|
45
|
+
@Test
|
|
46
|
+
public void connectReturnsNullWhenServiceUnavailable() {
|
|
47
|
+
// BRouterServiceConnection.connect returns null when BRouter
|
|
48
|
+
// app is not installed — simulate that.
|
|
49
|
+
try (MockedStatic<BRouterServiceConnection> mockedStatic =
|
|
50
|
+
mockStatic(BRouterServiceConnection.class)) {
|
|
51
|
+
|
|
52
|
+
mockedStatic.when(() ->
|
|
53
|
+
BRouterServiceConnection.connect(any(Context.class))
|
|
54
|
+
).thenReturn(null);
|
|
55
|
+
|
|
56
|
+
BRouterClient client = new BRouterClient(mockContext, 500);
|
|
57
|
+
IBRouterService service = client.connect();
|
|
58
|
+
|
|
59
|
+
assertNull(service);
|
|
60
|
+
assertFalse(client.isConnected());
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@Test
|
|
65
|
+
public void connectReturnsServiceWhenAvailable() {
|
|
66
|
+
BRouterServiceConnection mockConn = mock(BRouterServiceConnection.class);
|
|
67
|
+
IBRouterService mockService = mock(IBRouterService.class);
|
|
68
|
+
IBinder mockBinder = mock(IBinder.class);
|
|
69
|
+
|
|
70
|
+
when(mockConn.getBRouterService()).thenReturn(mockService);
|
|
71
|
+
when(mockService.asBinder()).thenReturn(mockBinder);
|
|
72
|
+
when(mockBinder.isBinderAlive()).thenReturn(true);
|
|
73
|
+
|
|
74
|
+
try (MockedStatic<BRouterServiceConnection> mockedStatic =
|
|
75
|
+
mockStatic(BRouterServiceConnection.class)) {
|
|
76
|
+
|
|
77
|
+
mockedStatic.when(() ->
|
|
78
|
+
BRouterServiceConnection.connect(any(Context.class))
|
|
79
|
+
).thenReturn(mockConn);
|
|
80
|
+
|
|
81
|
+
BRouterClient client = new BRouterClient(mockContext, 500);
|
|
82
|
+
IBRouterService service = client.connect();
|
|
83
|
+
|
|
84
|
+
assertNotNull(service);
|
|
85
|
+
assertEquals(mockService, service);
|
|
86
|
+
assertTrue(client.isConnected());
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// ── getService() ───────────────────────────────────────────────
|
|
91
|
+
|
|
92
|
+
@Test
|
|
93
|
+
public void getServiceReconnectsWhenBinderDead() {
|
|
94
|
+
BRouterServiceConnection mockConn1 = mock(BRouterServiceConnection.class);
|
|
95
|
+
BRouterServiceConnection mockConn2 = mock(BRouterServiceConnection.class);
|
|
96
|
+
IBRouterService mockService1 = mock(IBRouterService.class);
|
|
97
|
+
IBRouterService mockService2 = mock(IBRouterService.class);
|
|
98
|
+
IBinder mockBinder1 = mock(IBinder.class);
|
|
99
|
+
IBinder mockBinder2 = mock(IBinder.class);
|
|
100
|
+
|
|
101
|
+
when(mockConn1.getBRouterService()).thenReturn(mockService1);
|
|
102
|
+
when(mockService1.asBinder()).thenReturn(mockBinder1);
|
|
103
|
+
when(mockBinder1.isBinderAlive()).thenReturn(true);
|
|
104
|
+
|
|
105
|
+
when(mockConn2.getBRouterService()).thenReturn(mockService2);
|
|
106
|
+
when(mockService2.asBinder()).thenReturn(mockBinder2);
|
|
107
|
+
when(mockBinder2.isBinderAlive()).thenReturn(true);
|
|
108
|
+
|
|
109
|
+
try (MockedStatic<BRouterServiceConnection> mockedStatic =
|
|
110
|
+
mockStatic(BRouterServiceConnection.class)) {
|
|
111
|
+
|
|
112
|
+
// First connect succeeds
|
|
113
|
+
mockedStatic.when(() ->
|
|
114
|
+
BRouterServiceConnection.connect(any(Context.class))
|
|
115
|
+
).thenReturn(mockConn1);
|
|
116
|
+
|
|
117
|
+
BRouterClient client = new BRouterClient(mockContext, 500);
|
|
118
|
+
IBRouterService svc = client.getService();
|
|
119
|
+
assertEquals(mockService1, svc);
|
|
120
|
+
|
|
121
|
+
// Now simulate binder death
|
|
122
|
+
when(mockBinder1.isBinderAlive()).thenReturn(false);
|
|
123
|
+
|
|
124
|
+
// Second connect call should get a new connection
|
|
125
|
+
mockedStatic.when(() ->
|
|
126
|
+
BRouterServiceConnection.connect(any(Context.class))
|
|
127
|
+
).thenReturn(mockConn2);
|
|
128
|
+
|
|
129
|
+
svc = client.getService();
|
|
130
|
+
assertEquals(mockService2, svc);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// ── getRoute() ─────────────────────────────────────────────────
|
|
135
|
+
|
|
136
|
+
@Test
|
|
137
|
+
public void getRouteCallsServiceGetTrackFromParams() throws Exception {
|
|
138
|
+
BRouterServiceConnection mockConn = mock(BRouterServiceConnection.class);
|
|
139
|
+
IBRouterService mockService = mock(IBRouterService.class);
|
|
140
|
+
IBinder mockBinder = mock(IBinder.class);
|
|
141
|
+
|
|
142
|
+
when(mockConn.getBRouterService()).thenReturn(mockService);
|
|
143
|
+
when(mockService.asBinder()).thenReturn(mockBinder);
|
|
144
|
+
when(mockBinder.isBinderAlive()).thenReturn(true);
|
|
145
|
+
when(mockService.getTrackFromParams(any(Bundle.class)))
|
|
146
|
+
.thenReturn("<gpx>track</gpx>");
|
|
147
|
+
|
|
148
|
+
try (MockedStatic<BRouterServiceConnection> mockedStatic =
|
|
149
|
+
mockStatic(BRouterServiceConnection.class)) {
|
|
150
|
+
|
|
151
|
+
mockedStatic.when(() ->
|
|
152
|
+
BRouterServiceConnection.connect(any(Context.class))
|
|
153
|
+
).thenReturn(mockConn);
|
|
154
|
+
|
|
155
|
+
BRouterClient client = new BRouterClient(mockContext, 500);
|
|
156
|
+
Bundle params = new Bundle();
|
|
157
|
+
params.putString("lonlats", "10,20|30,40");
|
|
158
|
+
|
|
159
|
+
String result = client.getRoute(params);
|
|
160
|
+
|
|
161
|
+
assertEquals("<gpx>track</gpx>", result);
|
|
162
|
+
verify(mockService).getTrackFromParams(params);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
@Test
|
|
167
|
+
public void getRouteThrowsWhenServiceUnavailable() throws Exception {
|
|
168
|
+
try (MockedStatic<BRouterServiceConnection> mockedStatic =
|
|
169
|
+
mockStatic(BRouterServiceConnection.class)) {
|
|
170
|
+
|
|
171
|
+
mockedStatic.when(() ->
|
|
172
|
+
BRouterServiceConnection.connect(any(Context.class))
|
|
173
|
+
).thenReturn(null);
|
|
174
|
+
|
|
175
|
+
BRouterClient client = new BRouterClient(mockContext, 500);
|
|
176
|
+
try {
|
|
177
|
+
client.getRoute(new Bundle());
|
|
178
|
+
fail("Expected IllegalStateException");
|
|
179
|
+
} catch (IllegalStateException e) {
|
|
180
|
+
assertEquals(BRouterError.SERVICE_NOT_INSTALLED, e.getMessage());
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
@Test
|
|
186
|
+
public void getLastErrorReturnsCodeAfterFailedConnect() {
|
|
187
|
+
try (MockedStatic<BRouterServiceConnection> mockedStatic =
|
|
188
|
+
mockStatic(BRouterServiceConnection.class)) {
|
|
189
|
+
|
|
190
|
+
mockedStatic.when(() ->
|
|
191
|
+
BRouterServiceConnection.connect(any(Context.class))
|
|
192
|
+
).thenReturn(null);
|
|
193
|
+
|
|
194
|
+
BRouterClient client = new BRouterClient(mockContext, 500);
|
|
195
|
+
IBRouterService service = client.connect();
|
|
196
|
+
|
|
197
|
+
assertNull(service);
|
|
198
|
+
assertEquals(BRouterError.SERVICE_NOT_INSTALLED, client.getLastError());
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
@Test
|
|
203
|
+
public void getConnectTimeoutMsReturnsStoredValue() {
|
|
204
|
+
BRouterClient client = new BRouterClient(mockContext, 2000);
|
|
205
|
+
assertEquals(2000, client.getConnectTimeoutMs());
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// ── disconnect() ───────────────────────────────────────────────
|
|
209
|
+
|
|
210
|
+
@Test
|
|
211
|
+
public void disconnectClearsConnection() {
|
|
212
|
+
BRouterServiceConnection mockConn = mock(BRouterServiceConnection.class);
|
|
213
|
+
IBRouterService mockService = mock(IBRouterService.class);
|
|
214
|
+
IBinder mockBinder = mock(IBinder.class);
|
|
215
|
+
|
|
216
|
+
when(mockConn.getBRouterService()).thenReturn(mockService);
|
|
217
|
+
when(mockService.asBinder()).thenReturn(mockBinder);
|
|
218
|
+
when(mockBinder.isBinderAlive()).thenReturn(true);
|
|
219
|
+
|
|
220
|
+
try (MockedStatic<BRouterServiceConnection> mockedStatic =
|
|
221
|
+
mockStatic(BRouterServiceConnection.class)) {
|
|
222
|
+
|
|
223
|
+
mockedStatic.when(() ->
|
|
224
|
+
BRouterServiceConnection.connect(any(Context.class))
|
|
225
|
+
).thenReturn(mockConn);
|
|
226
|
+
|
|
227
|
+
BRouterClient client = new BRouterClient(mockContext, 500);
|
|
228
|
+
client.connect();
|
|
229
|
+
assertTrue(client.isConnected());
|
|
230
|
+
|
|
231
|
+
client.disconnect();
|
|
232
|
+
assertFalse(client.isConnected());
|
|
233
|
+
|
|
234
|
+
// Verify unbind was called
|
|
235
|
+
verify(mockConn).disconnect(any(Context.class));
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
@Test
|
|
240
|
+
public void disconnectIsIdempotent() {
|
|
241
|
+
BRouterClient client = new BRouterClient(mockContext, 500);
|
|
242
|
+
// Should not throw
|
|
243
|
+
client.disconnect();
|
|
244
|
+
client.disconnect();
|
|
245
|
+
assertFalse(client.isConnected());
|
|
246
|
+
}
|
|
247
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
package com.jhotadhari.reactnative.brouter;
|
|
2
|
+
|
|
3
|
+
import static org.junit.Assert.*;
|
|
4
|
+
|
|
5
|
+
import org.junit.Test;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Unit tests for {@link BRouterError}.
|
|
9
|
+
*/
|
|
10
|
+
public class BRouterErrorTest {
|
|
11
|
+
|
|
12
|
+
@Test
|
|
13
|
+
public void constantsAreDistinct() {
|
|
14
|
+
assertEquals("SERVICE_NOT_INSTALLED", BRouterError.SERVICE_NOT_INSTALLED);
|
|
15
|
+
assertEquals("SERVICE_UNAVAILABLE", BRouterError.SERVICE_UNAVAILABLE);
|
|
16
|
+
assertEquals("CONNECTION_TIMEOUT", BRouterError.CONNECTION_TIMEOUT);
|
|
17
|
+
assertEquals("ROUTING_TIMEOUT", BRouterError.ROUTING_TIMEOUT);
|
|
18
|
+
assertEquals("INVALID_PARAMS", BRouterError.INVALID_PARAMS);
|
|
19
|
+
assertEquals("ROUTING_FAILED", BRouterError.ROUTING_FAILED);
|
|
20
|
+
assertEquals("UNKNOWN", BRouterError.UNKNOWN);
|
|
21
|
+
|
|
22
|
+
// Sanity: all codes are different
|
|
23
|
+
String[] codes = {
|
|
24
|
+
BRouterError.SERVICE_NOT_INSTALLED,
|
|
25
|
+
BRouterError.SERVICE_UNAVAILABLE,
|
|
26
|
+
BRouterError.CONNECTION_TIMEOUT,
|
|
27
|
+
BRouterError.ROUTING_TIMEOUT,
|
|
28
|
+
BRouterError.INVALID_PARAMS,
|
|
29
|
+
BRouterError.ROUTING_FAILED,
|
|
30
|
+
BRouterError.UNKNOWN,
|
|
31
|
+
};
|
|
32
|
+
for (int i = 0; i < codes.length; i++) {
|
|
33
|
+
for (int j = i + 1; j < codes.length; j++) {
|
|
34
|
+
assertNotEquals(
|
|
35
|
+
"Error codes should be distinct: " + codes[i],
|
|
36
|
+
codes[i],
|
|
37
|
+
codes[j]
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@Test
|
|
44
|
+
public void constructorIsPrivate() {
|
|
45
|
+
// Verify the utility class exists and is usable
|
|
46
|
+
assertNotNull(BRouterError.INVALID_PARAMS);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
package com.jhotadhari.reactnative.brouter;
|
|
2
|
+
|
|
3
|
+
import static org.junit.Assert.*;
|
|
4
|
+
import static org.mockito.Mockito.*;
|
|
5
|
+
|
|
6
|
+
import android.os.Bundle;
|
|
7
|
+
|
|
8
|
+
import com.facebook.react.bridge.Promise;
|
|
9
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
10
|
+
import com.facebook.react.bridge.ReadableArray;
|
|
11
|
+
import com.facebook.react.bridge.ReadableMap;
|
|
12
|
+
|
|
13
|
+
import org.junit.Before;
|
|
14
|
+
import org.junit.Test;
|
|
15
|
+
|
|
16
|
+
public class BRouterModuleTest {
|
|
17
|
+
|
|
18
|
+
private ReactApplicationContext mockReactContext;
|
|
19
|
+
private BRouterClient mockClient;
|
|
20
|
+
|
|
21
|
+
@Before
|
|
22
|
+
public void setUp() {
|
|
23
|
+
mockReactContext = mock( ReactApplicationContext.class );
|
|
24
|
+
when( mockReactContext.getApplicationContext() ).thenReturn( mockReactContext );
|
|
25
|
+
mockClient = mock( BRouterClient.class );
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
private BRouterModule createSpy() {
|
|
29
|
+
BRouterModule module = new BRouterModule( mockReactContext );
|
|
30
|
+
BRouterModule spy = spy( module );
|
|
31
|
+
doReturn( mockClient ).when( spy ).getClient( any( ReadableMap.class ) );
|
|
32
|
+
return spy;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
private ReadableMap validParams() {
|
|
36
|
+
ReadableArray arr = mock( ReadableArray.class );
|
|
37
|
+
when( arr.size() ).thenReturn( 2 );
|
|
38
|
+
when( arr.getDouble( 0 ) ).thenReturn( 10.0 );
|
|
39
|
+
when( arr.getDouble( 1 ) ).thenReturn( 30.0 );
|
|
40
|
+
|
|
41
|
+
ReadableArray lats = mock( ReadableArray.class );
|
|
42
|
+
when( lats.size() ).thenReturn( 2 );
|
|
43
|
+
when( lats.getDouble( 0 ) ).thenReturn( 20.0 );
|
|
44
|
+
when( lats.getDouble( 1 ) ).thenReturn( 40.0 );
|
|
45
|
+
|
|
46
|
+
ReadableMap params = mock( ReadableMap.class );
|
|
47
|
+
when( params.hasKey( "lonlats" ) ).thenReturn( true );
|
|
48
|
+
when( params.getString( "lonlats" ) ).thenReturn( "10,20|30,40" );
|
|
49
|
+
when( params.hasKey( "lats" ) ).thenReturn( true );
|
|
50
|
+
when( params.getArray( "lats" ) ).thenReturn( lats );
|
|
51
|
+
when( params.hasKey( "lons" ) ).thenReturn( true );
|
|
52
|
+
when( params.getArray( "lons" ) ).thenReturn( arr );
|
|
53
|
+
|
|
54
|
+
return params;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@Test
|
|
58
|
+
public void rejectsWhenLonlatsMissing() {
|
|
59
|
+
BRouterModule spy = createSpy();
|
|
60
|
+
ReadableMap params = mock( ReadableMap.class );
|
|
61
|
+
Promise mp = mock( Promise.class );
|
|
62
|
+
spy.getRoute( params, mp );
|
|
63
|
+
verify( mp ).reject( BRouterError.INVALID_PARAMS, "At least 2 waypoints are required" );
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
@Test
|
|
67
|
+
public void rejectsWhenServiceUnavailable() throws Exception {
|
|
68
|
+
when( mockClient.getRoute( any( Bundle.class ) ) )
|
|
69
|
+
.thenThrow( new IllegalStateException( BRouterError.SERVICE_UNAVAILABLE ) );
|
|
70
|
+
BRouterModule spy = createSpy();
|
|
71
|
+
Promise mp = mock( Promise.class );
|
|
72
|
+
spy.getRoute( validParams(), mp );
|
|
73
|
+
verify( mp ).reject( eq( BRouterError.SERVICE_UNAVAILABLE ), anyString() );
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
@Test
|
|
77
|
+
public void rejectsWhenServiceNotInstalled() throws Exception {
|
|
78
|
+
when( mockClient.getRoute( any( Bundle.class ) ) )
|
|
79
|
+
.thenThrow( new IllegalStateException( BRouterError.SERVICE_NOT_INSTALLED ) );
|
|
80
|
+
BRouterModule spy = createSpy();
|
|
81
|
+
Promise mp = mock( Promise.class );
|
|
82
|
+
spy.getRoute( validParams(), mp );
|
|
83
|
+
verify( mp ).reject( eq( BRouterError.SERVICE_NOT_INSTALLED ), anyString() );
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
@Test
|
|
87
|
+
public void rejectsWhenConnectionTimeout() throws Exception {
|
|
88
|
+
when( mockClient.getRoute( any( Bundle.class ) ) )
|
|
89
|
+
.thenThrow( new IllegalStateException( BRouterError.CONNECTION_TIMEOUT ) );
|
|
90
|
+
BRouterModule spy = createSpy();
|
|
91
|
+
Promise mp = mock( Promise.class );
|
|
92
|
+
spy.getRoute( validParams(), mp );
|
|
93
|
+
verify( mp ).reject( eq( BRouterError.CONNECTION_TIMEOUT ), anyString() );
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
@Test
|
|
97
|
+
public void resolvesWithTrackOnSuccess() throws Exception {
|
|
98
|
+
when( mockClient.getRoute( any( Bundle.class ) ) ).thenReturn( "<gpx>track</gpx>" );
|
|
99
|
+
BRouterModule spy = createSpy();
|
|
100
|
+
Promise mp = mock( Promise.class );
|
|
101
|
+
spy.getRoute( validParams(), mp );
|
|
102
|
+
verify( mp ).resolve( "<gpx>track</gpx>" );
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
@Test
|
|
106
|
+
public void rejectsWhenRouteReturnsNull() throws Exception {
|
|
107
|
+
when( mockClient.getRoute( any( Bundle.class ) ) ).thenReturn( null );
|
|
108
|
+
BRouterModule spy = createSpy();
|
|
109
|
+
Promise mp = mock( Promise.class );
|
|
110
|
+
spy.getRoute( validParams(), mp );
|
|
111
|
+
verify( mp ).reject( eq( BRouterError.ROUTING_FAILED ), anyString() );
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
@Test
|
|
115
|
+
public void rejectsOnUnexpectedException() throws Exception {
|
|
116
|
+
when( mockClient.getRoute( any( Bundle.class ) ) )
|
|
117
|
+
.thenThrow( new RuntimeException( "Boom" ) );
|
|
118
|
+
BRouterModule spy = createSpy();
|
|
119
|
+
Promise mp = mock( Promise.class );
|
|
120
|
+
spy.getRoute( validParams(), mp );
|
|
121
|
+
verify( mp ).reject( eq( BRouterError.UNKNOWN ), anyString() );
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
@Test
|
|
125
|
+
public void invalidateDisconnectsClient() {
|
|
126
|
+
// Use a subclass that injects the mock client directly into the field
|
|
127
|
+
BRouterModule module = new BRouterModule( mockReactContext ) {
|
|
128
|
+
{
|
|
129
|
+
// Set via the package-private field (same package in test)
|
|
130
|
+
this.client = mockClient;
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
module.invalidate();
|
|
135
|
+
verify( mockClient ).disconnect();
|
|
136
|
+
}
|
|
137
|
+
}
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
package com.jhotadhari.reactnative.brouter;
|
|
2
|
+
|
|
3
|
+
import static org.junit.Assert.*;
|
|
4
|
+
import static org.mockito.Mockito.*;
|
|
5
|
+
|
|
6
|
+
import android.os.Bundle;
|
|
7
|
+
|
|
8
|
+
import com.facebook.react.bridge.ReadableArray;
|
|
9
|
+
import com.facebook.react.bridge.ReadableMap;
|
|
10
|
+
import com.facebook.react.bridge.ReadableMapKeySetIterator;
|
|
11
|
+
import com.facebook.react.bridge.ReadableType;
|
|
12
|
+
|
|
13
|
+
import org.junit.Test;
|
|
14
|
+
import org.mockito.ArgumentCaptor;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Unit tests for {@link ParamMapper}.
|
|
18
|
+
*/
|
|
19
|
+
public class ParamMapperTest {
|
|
20
|
+
|
|
21
|
+
@Test
|
|
22
|
+
public void mapsLonlats() {
|
|
23
|
+
ReadableMap params = mock(ReadableMap.class);
|
|
24
|
+
when(params.hasKey("lonlats")).thenReturn(true);
|
|
25
|
+
when(params.getString("lonlats")).thenReturn("10,20|30,40");
|
|
26
|
+
|
|
27
|
+
Bundle b = mock(Bundle.class);
|
|
28
|
+
|
|
29
|
+
ParamMapper.toBundle(params, b);
|
|
30
|
+
|
|
31
|
+
verify(b).putString("lonlats", "10,20|30,40");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@Test
|
|
35
|
+
public void mapsLatsArray() {
|
|
36
|
+
ReadableArray lats = mock(ReadableArray.class);
|
|
37
|
+
when(lats.size()).thenReturn(2);
|
|
38
|
+
when(lats.getDouble(0)).thenReturn(20.0);
|
|
39
|
+
when(lats.getDouble(1)).thenReturn(40.0);
|
|
40
|
+
|
|
41
|
+
ReadableMap params = mock(ReadableMap.class);
|
|
42
|
+
when(params.hasKey("lats")).thenReturn(true);
|
|
43
|
+
when(params.getArray("lats")).thenReturn(lats);
|
|
44
|
+
|
|
45
|
+
Bundle b = mock(Bundle.class);
|
|
46
|
+
ParamMapper.toBundle(params, b);
|
|
47
|
+
|
|
48
|
+
ArgumentCaptor<double[]> captor = ArgumentCaptor.forClass(double[].class);
|
|
49
|
+
verify(b).putDoubleArray(eq("lats"), captor.capture());
|
|
50
|
+
assertEquals(20.0, captor.getValue()[0], 0.001);
|
|
51
|
+
assertEquals(40.0, captor.getValue()[1], 0.001);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@Test
|
|
55
|
+
public void mapsStraightIndices() {
|
|
56
|
+
ReadableMap params = mock(ReadableMap.class);
|
|
57
|
+
when(params.hasKey("straight")).thenReturn(true);
|
|
58
|
+
when(params.getString("straight")).thenReturn("1,3");
|
|
59
|
+
|
|
60
|
+
Bundle b = mock(Bundle.class);
|
|
61
|
+
ParamMapper.toBundle(params, b);
|
|
62
|
+
|
|
63
|
+
verify(b).putString("straight", "1,3");
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
@Test
|
|
67
|
+
public void mapsProfile() {
|
|
68
|
+
ReadableMap params = mock(ReadableMap.class);
|
|
69
|
+
when(params.hasKey("profile")).thenReturn(true);
|
|
70
|
+
when(params.getString("profile")).thenReturn("trekking");
|
|
71
|
+
|
|
72
|
+
Bundle b = mock(Bundle.class);
|
|
73
|
+
ParamMapper.toBundle(params, b);
|
|
74
|
+
|
|
75
|
+
verify(b).putString("profile", "trekking");
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
@Test
|
|
79
|
+
public void mapsVehicleToV() {
|
|
80
|
+
ReadableMap params = mock(ReadableMap.class);
|
|
81
|
+
when(params.hasKey("v")).thenReturn(true);
|
|
82
|
+
when(params.getString("v")).thenReturn("bicycle");
|
|
83
|
+
|
|
84
|
+
Bundle b = mock(Bundle.class);
|
|
85
|
+
ParamMapper.toBundle(params, b);
|
|
86
|
+
|
|
87
|
+
verify(b).putString("v", "bicycle");
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
@Test
|
|
91
|
+
public void mapsFast() {
|
|
92
|
+
ReadableMap params = mock(ReadableMap.class);
|
|
93
|
+
when(params.hasKey("fast")).thenReturn(true);
|
|
94
|
+
when(params.getInt("fast")).thenReturn(1);
|
|
95
|
+
|
|
96
|
+
Bundle b = mock(Bundle.class);
|
|
97
|
+
ParamMapper.toBundle(params, b);
|
|
98
|
+
|
|
99
|
+
verify(b).putInt("fast", 1);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
@Test
|
|
103
|
+
public void mapsTrackFormat() {
|
|
104
|
+
ReadableMap params = mock(ReadableMap.class);
|
|
105
|
+
when(params.hasKey("trackFormat")).thenReturn(true);
|
|
106
|
+
when(params.getString("trackFormat")).thenReturn("json");
|
|
107
|
+
|
|
108
|
+
Bundle b = mock(Bundle.class);
|
|
109
|
+
ParamMapper.toBundle(params, b);
|
|
110
|
+
|
|
111
|
+
verify(b).putString("trackFormat", "json");
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
@Test
|
|
115
|
+
public void mapsAlternativeidx() {
|
|
116
|
+
ReadableMap params = mock(ReadableMap.class);
|
|
117
|
+
when(params.hasKey("alternativeidx")).thenReturn(true);
|
|
118
|
+
when(params.getInt("alternativeidx")).thenReturn(2);
|
|
119
|
+
|
|
120
|
+
Bundle b = mock(Bundle.class);
|
|
121
|
+
ParamMapper.toBundle(params, b);
|
|
122
|
+
|
|
123
|
+
verify(b).putInt("alternativeidx", 2);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
@Test
|
|
127
|
+
public void mapsExportWaypoints() {
|
|
128
|
+
ReadableMap params = mock(ReadableMap.class);
|
|
129
|
+
when(params.hasKey("exportWaypoints")).thenReturn(true);
|
|
130
|
+
when(params.getInt("exportWaypoints")).thenReturn(1);
|
|
131
|
+
|
|
132
|
+
Bundle b = mock(Bundle.class);
|
|
133
|
+
ParamMapper.toBundle(params, b);
|
|
134
|
+
|
|
135
|
+
verify(b).putInt("exportWaypoints", 1);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
@Test
|
|
139
|
+
public void mapsTurnInstructionFormat() {
|
|
140
|
+
ReadableMap params = mock(ReadableMap.class);
|
|
141
|
+
when(params.hasKey("turnInstructionFormat")).thenReturn(true);
|
|
142
|
+
when(params.getString("turnInstructionFormat")).thenReturn("osmand");
|
|
143
|
+
|
|
144
|
+
Bundle b = mock(Bundle.class);
|
|
145
|
+
ParamMapper.toBundle(params, b);
|
|
146
|
+
|
|
147
|
+
verify(b).putString("turnInstructionFormat", "osmand");
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
@Test
|
|
151
|
+
public void mapsTimode() {
|
|
152
|
+
ReadableMap params = mock(ReadableMap.class);
|
|
153
|
+
when(params.hasKey("timode")).thenReturn(true);
|
|
154
|
+
when(params.getInt("timode")).thenReturn(3);
|
|
155
|
+
|
|
156
|
+
Bundle b = mock(Bundle.class);
|
|
157
|
+
ParamMapper.toBundle(params, b);
|
|
158
|
+
|
|
159
|
+
verify(b).putInt("timode", 3);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
@Test
|
|
163
|
+
public void mapsHeading() {
|
|
164
|
+
ReadableMap params = mock(ReadableMap.class);
|
|
165
|
+
when(params.hasKey("heading")).thenReturn(true);
|
|
166
|
+
when(params.getDouble("heading")).thenReturn(90.5);
|
|
167
|
+
|
|
168
|
+
Bundle b = mock(Bundle.class);
|
|
169
|
+
ParamMapper.toBundle(params, b);
|
|
170
|
+
|
|
171
|
+
verify(b).putDouble("heading", 90.5);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
@Test
|
|
175
|
+
public void mapsEngineMode() {
|
|
176
|
+
ReadableMap params = mock(ReadableMap.class);
|
|
177
|
+
when(params.hasKey("engineMode")).thenReturn(true);
|
|
178
|
+
when(params.getInt("engineMode")).thenReturn(2);
|
|
179
|
+
|
|
180
|
+
Bundle b = mock(Bundle.class);
|
|
181
|
+
ParamMapper.toBundle(params, b);
|
|
182
|
+
|
|
183
|
+
verify(b).putInt("engineMode", 2);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
@Test
|
|
187
|
+
public void mapsMaxRunningTime() {
|
|
188
|
+
ReadableMap params = mock(ReadableMap.class);
|
|
189
|
+
when(params.hasKey("maxRunningTime")).thenReturn(true);
|
|
190
|
+
when(params.getInt("maxRunningTime")).thenReturn(120);
|
|
191
|
+
|
|
192
|
+
Bundle b = mock(Bundle.class);
|
|
193
|
+
ParamMapper.toBundle(params, b);
|
|
194
|
+
|
|
195
|
+
verify(b).putString("maxRunningTime", "120");
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
@Test
|
|
199
|
+
public void mapsPathToFileResult() {
|
|
200
|
+
ReadableMap params = mock(ReadableMap.class);
|
|
201
|
+
when(params.hasKey("pathToFileResult")).thenReturn(true);
|
|
202
|
+
when(params.getString("pathToFileResult")).thenReturn("/sdcard/route.gpx");
|
|
203
|
+
|
|
204
|
+
Bundle b = mock(Bundle.class);
|
|
205
|
+
ParamMapper.toBundle(params, b);
|
|
206
|
+
|
|
207
|
+
verify(b).putString("pathToFileResult", "/sdcard/route.gpx");
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
@Test
|
|
211
|
+
public void mapsAcceptCompressedResult() {
|
|
212
|
+
ReadableMap params = mock(ReadableMap.class);
|
|
213
|
+
when(params.hasKey("acceptCompressedResult")).thenReturn(true);
|
|
214
|
+
when(params.getBoolean("acceptCompressedResult")).thenReturn(true);
|
|
215
|
+
|
|
216
|
+
Bundle b = mock(Bundle.class);
|
|
217
|
+
ParamMapper.toBundle(params, b);
|
|
218
|
+
|
|
219
|
+
verify(b).putBoolean("acceptCompressedResult", true);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
@Test
|
|
223
|
+
public void mapsExtraParams() {
|
|
224
|
+
ReadableMap extra = mock(ReadableMap.class);
|
|
225
|
+
ReadableMapKeySetIterator mockIterator = mock(ReadableMapKeySetIterator.class);
|
|
226
|
+
when(mockIterator.hasNextKey()).thenReturn(true, false);
|
|
227
|
+
when(mockIterator.nextKey()).thenReturn("key1");
|
|
228
|
+
when(extra.keySetIterator()).thenReturn(mockIterator);
|
|
229
|
+
when(extra.getType("key1")).thenReturn(ReadableType.String);
|
|
230
|
+
when(extra.getString("key1")).thenReturn("value1");
|
|
231
|
+
|
|
232
|
+
ReadableMap params = mock(ReadableMap.class);
|
|
233
|
+
when(params.hasKey("extraParams")).thenReturn(true);
|
|
234
|
+
when(params.getMap("extraParams")).thenReturn(extra);
|
|
235
|
+
|
|
236
|
+
Bundle b = mock(Bundle.class);
|
|
237
|
+
ParamMapper.toBundle(params, b);
|
|
238
|
+
|
|
239
|
+
ArgumentCaptor<Bundle> captor = ArgumentCaptor.forClass(Bundle.class);
|
|
240
|
+
verify(b).putBundle(eq("extraParams"), captor.capture());
|
|
241
|
+
assertNotNull(captor.getValue());
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
@Test
|
|
245
|
+
public void mapsNogos() {
|
|
246
|
+
ReadableMap params = mock(ReadableMap.class);
|
|
247
|
+
when(params.hasKey("nogos")).thenReturn(true);
|
|
248
|
+
when(params.getString("nogos")).thenReturn("15,25,500|35,45,1000,2");
|
|
249
|
+
|
|
250
|
+
Bundle b = mock(Bundle.class);
|
|
251
|
+
ParamMapper.toBundle(params, b);
|
|
252
|
+
|
|
253
|
+
verify(b).putString("nogos", "15,25,500|35,45,1000,2");
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
@Test
|
|
257
|
+
public void mapsPolylines() {
|
|
258
|
+
ReadableMap params = mock(ReadableMap.class);
|
|
259
|
+
when(params.hasKey("polylines")).thenReturn(true);
|
|
260
|
+
when(params.getString("polylines")).thenReturn("15,25,16,26");
|
|
261
|
+
|
|
262
|
+
Bundle b = mock(Bundle.class);
|
|
263
|
+
ParamMapper.toBundle(params, b);
|
|
264
|
+
|
|
265
|
+
verify(b).putString("polylines", "15,25,16,26");
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
@Test
|
|
269
|
+
public void mapsPois() {
|
|
270
|
+
ReadableMap params = mock(ReadableMap.class);
|
|
271
|
+
when(params.hasKey("pois")).thenReturn(true);
|
|
272
|
+
when(params.getString("pois")).thenReturn("15,25,Cafe");
|
|
273
|
+
|
|
274
|
+
Bundle b = mock(Bundle.class);
|
|
275
|
+
ParamMapper.toBundle(params, b);
|
|
276
|
+
|
|
277
|
+
verify(b).putString("pois", "15,25,Cafe");
|
|
278
|
+
}
|
|
279
|
+
}
|