@kafitra/react-native-live-tracking 0.1.0
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 +21 -0
- package/README.md +396 -0
- package/android/build.gradle +71 -0
- package/android/gradle.properties +7 -0
- package/android/src/main/AndroidManifest.xml +40 -0
- package/android/src/main/java/com/livetracking/LiveTrackingModuleImpl.kt +728 -0
- package/android/src/main/java/com/livetracking/LiveTrackingPackage.kt +16 -0
- package/android/src/main/java/com/livetracking/location/LocationEngine.kt +93 -0
- package/android/src/main/java/com/livetracking/network/NetworkListener.kt +127 -0
- package/android/src/main/java/com/livetracking/optimizer/ActivityRecognitionHandler.kt +248 -0
- package/android/src/main/java/com/livetracking/optimizer/MotionSleepManager.kt +130 -0
- package/android/src/main/java/com/livetracking/permissions/PermissionHandler.kt +145 -0
- package/android/src/main/java/com/livetracking/queue/QueueEngine.kt +167 -0
- package/android/src/main/java/com/livetracking/queue/QueuedLocation.kt +16 -0
- package/android/src/main/java/com/livetracking/queue/TrackingDatabase.kt +239 -0
- package/android/src/main/java/com/livetracking/receiver/BootReceiver.kt +53 -0
- package/android/src/main/java/com/livetracking/service/TrackingForegroundService.kt +145 -0
- package/android/src/main/java/com/livetracking/sync/FirebaseSyncEngine.kt +277 -0
- package/android/src/main/java/com/livetracking/sync/LocationDataPoint.kt +31 -0
- package/android/src/main/java/com/livetracking/sync/SyncEngineController.kt +220 -0
- package/android/src/main/java/com/livetracking/sync/SyncTargetConfig.kt +20 -0
- package/android/src/main/java/com/livetracking/sync/TargetHandler.kt +601 -0
- package/android/src/newarch/java/com/livetracking/LiveTrackingModule.kt +64 -0
- package/android/src/oldarch/java/com/livetracking/LiveTrackingModule.kt +70 -0
- package/android/src/test/java/com/livetracking/BackoffCalculationTest.kt +216 -0
- package/android/src/test/java/com/livetracking/BatchAccumulatorTest.kt +391 -0
- package/android/src/test/java/com/livetracking/BootReceiverTest.kt +247 -0
- package/android/src/test/java/com/livetracking/FirebaseSyncEngineTest.kt +337 -0
- package/android/src/test/java/com/livetracking/LocationEngineTest.kt +202 -0
- package/android/src/test/java/com/livetracking/MotionSleepManagerTest.kt +420 -0
- package/android/src/test/java/com/livetracking/OfflineQueueTest.kt +462 -0
- package/android/src/test/java/com/livetracking/PermissionHandlerTest.kt +200 -0
- package/android/src/test/java/com/livetracking/QueueEngineTest.kt +335 -0
- package/android/src/test/java/com/livetracking/SyncEngineControllerTest.kt +855 -0
- package/ios/ActivityRecognitionHandler.swift +196 -0
- package/ios/BackgroundModeHelper.swift +132 -0
- package/ios/FirebaseSyncEngine.swift +276 -0
- package/ios/LiveTracking-Bridging-Header.h +2 -0
- package/ios/LiveTracking.m +37 -0
- package/ios/LiveTracking.swift +773 -0
- package/ios/LocationDataPoint.swift +56 -0
- package/ios/LocationEngine.swift +160 -0
- package/ios/MotionSleepManager.swift +151 -0
- package/ios/NetworkListener.swift +105 -0
- package/ios/OfflineQueueManager.swift +503 -0
- package/ios/PermissionHandler.swift +148 -0
- package/ios/QueueEngine.swift +249 -0
- package/ios/SyncEngineController.swift +396 -0
- package/ios/SyncTargetConfig.swift +36 -0
- package/ios/TargetHandler.swift +715 -0
- package/ios/Tests/ActivityRecognitionHandlerTests.swift +259 -0
- package/ios/Tests/FirebaseSyncEngineTests.swift +303 -0
- package/ios/Tests/LocationEngineTests.swift +244 -0
- package/ios/Tests/MotionSleepManagerTests.swift +355 -0
- package/ios/Tests/NetworkListenerTests.swift +188 -0
- package/ios/Tests/OfflineQueueFlushTests.swift +375 -0
- package/ios/Tests/PermissionHandlerTests.swift +238 -0
- package/ios/Tests/QueueEngineTests.swift +346 -0
- package/ios/TrackingCleanup.swift +93 -0
- package/ios/TrackingNotificationManager.swift +187 -0
- package/lib/commonjs/EventEmitter.js +113 -0
- package/lib/commonjs/EventEmitter.js.map +1 -0
- package/lib/commonjs/LiveTracking.js +134 -0
- package/lib/commonjs/LiveTracking.js.map +1 -0
- package/lib/commonjs/NativeLiveTracking.js +21 -0
- package/lib/commonjs/NativeLiveTracking.js.map +1 -0
- package/lib/commonjs/filters/distanceTimeFilter.js +63 -0
- package/lib/commonjs/filters/distanceTimeFilter.js.map +1 -0
- package/lib/commonjs/index.js +103 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/serialization/locationSerializer.js +51 -0
- package/lib/commonjs/serialization/locationSerializer.js.map +1 -0
- package/lib/commonjs/types.js +77 -0
- package/lib/commonjs/types.js.map +1 -0
- package/lib/commonjs/utils/distance.js +63 -0
- package/lib/commonjs/utils/distance.js.map +1 -0
- package/lib/commonjs/utils/retry.js +80 -0
- package/lib/commonjs/utils/retry.js.map +1 -0
- package/lib/commonjs/validation.js +463 -0
- package/lib/commonjs/validation.js.map +1 -0
- package/lib/module/EventEmitter.js +105 -0
- package/lib/module/EventEmitter.js.map +1 -0
- package/lib/module/LiveTracking.js +127 -0
- package/lib/module/LiveTracking.js.map +1 -0
- package/lib/module/NativeLiveTracking.js +16 -0
- package/lib/module/NativeLiveTracking.js.map +1 -0
- package/lib/module/filters/distanceTimeFilter.js +58 -0
- package/lib/module/filters/distanceTimeFilter.js.map +1 -0
- package/lib/module/index.js +32 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/serialization/locationSerializer.js +45 -0
- package/lib/module/serialization/locationSerializer.js.map +1 -0
- package/lib/module/types.js +94 -0
- package/lib/module/types.js.map +1 -0
- package/lib/module/utils/distance.js +56 -0
- package/lib/module/utils/distance.js.map +1 -0
- package/lib/module/utils/retry.js +72 -0
- package/lib/module/utils/retry.js.map +1 -0
- package/lib/module/validation.js +456 -0
- package/lib/module/validation.js.map +1 -0
- package/lib/typescript/EventEmitter.d.ts +65 -0
- package/lib/typescript/EventEmitter.d.ts.map +1 -0
- package/lib/typescript/LiveTracking.d.ts +23 -0
- package/lib/typescript/LiveTracking.d.ts.map +1 -0
- package/lib/typescript/NativeLiveTracking.d.ts +25 -0
- package/lib/typescript/NativeLiveTracking.d.ts.map +1 -0
- package/lib/typescript/filters/distanceTimeFilter.d.ts +44 -0
- package/lib/typescript/filters/distanceTimeFilter.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +21 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/serialization/locationSerializer.d.ts +39 -0
- package/lib/typescript/serialization/locationSerializer.d.ts.map +1 -0
- package/lib/typescript/types.d.ts +217 -0
- package/lib/typescript/types.d.ts.map +1 -0
- package/lib/typescript/utils/distance.d.ts +38 -0
- package/lib/typescript/utils/distance.d.ts.map +1 -0
- package/lib/typescript/utils/retry.d.ts +60 -0
- package/lib/typescript/utils/retry.d.ts.map +1 -0
- package/lib/typescript/validation.d.ts +26 -0
- package/lib/typescript/validation.d.ts.map +1 -0
- package/package.json +126 -0
- package/react-native-live-tracking.podspec +47 -0
- package/src/EventEmitter.ts +118 -0
- package/src/LiveTracking.ts +159 -0
- package/src/NativeLiveTracking.ts +29 -0
- package/src/filters/distanceTimeFilter.ts +75 -0
- package/src/index.ts +51 -0
- package/src/serialization/locationSerializer.ts +57 -0
- package/src/types.ts +252 -0
- package/src/utils/distance.ts +68 -0
- package/src/utils/retry.ts +75 -0
- package/src/validation.ts +552 -0
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
package com.livetracking
|
|
2
|
+
|
|
3
|
+
import com.livetracking.queue.QueuedLocation
|
|
4
|
+
import com.livetracking.queue.QueuedLocationDao
|
|
5
|
+
import io.mockk.*
|
|
6
|
+
import org.junit.Assert.*
|
|
7
|
+
import org.junit.Before
|
|
8
|
+
import org.junit.Test
|
|
9
|
+
import java.util.UUID
|
|
10
|
+
import java.util.concurrent.ExecutorService
|
|
11
|
+
import java.util.concurrent.Executors
|
|
12
|
+
import java.util.concurrent.Future
|
|
13
|
+
import java.util.concurrent.Callable
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Unit tests for QueueEngine and QueuedLocation.
|
|
17
|
+
*
|
|
18
|
+
* NOTE: QueueEngine depends on Room Database (TrackingDatabase) which requires Android Context.
|
|
19
|
+
* These tests verify:
|
|
20
|
+
* - QueuedLocation data class structure and field correctness
|
|
21
|
+
* - UUID generation for unique IDs
|
|
22
|
+
* - Executor-based background threading pattern
|
|
23
|
+
* - DAO interface contract
|
|
24
|
+
*
|
|
25
|
+
* Full Room database integration tests (insert, query, delete) require instrumented tests
|
|
26
|
+
* (androidTest) running on a device or emulator with a real or in-memory Room database.
|
|
27
|
+
*/
|
|
28
|
+
class QueueEngineTest {
|
|
29
|
+
|
|
30
|
+
private lateinit var mockDao: QueuedLocationDao
|
|
31
|
+
private lateinit var executor: ExecutorService
|
|
32
|
+
|
|
33
|
+
@Before
|
|
34
|
+
fun setup() {
|
|
35
|
+
mockDao = mockk(relaxed = true)
|
|
36
|
+
executor = Executors.newSingleThreadExecutor()
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// --- QueuedLocation Data Class Tests ---
|
|
40
|
+
|
|
41
|
+
@Test
|
|
42
|
+
fun `QueuedLocation has all required fields`() {
|
|
43
|
+
val location = QueuedLocation(
|
|
44
|
+
id = "test-id-123",
|
|
45
|
+
latitude = 37.7749,
|
|
46
|
+
longitude = -122.4194,
|
|
47
|
+
timestamp = 1700000000000L,
|
|
48
|
+
accuracy = 5.0f,
|
|
49
|
+
speed = 2.5f,
|
|
50
|
+
altitude = 100.0,
|
|
51
|
+
bearing = 180.0f,
|
|
52
|
+
createdAt = 1700000000100L
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
assertEquals("test-id-123", location.id)
|
|
56
|
+
assertEquals(37.7749, location.latitude, 0.0001)
|
|
57
|
+
assertEquals(-122.4194, location.longitude, 0.0001)
|
|
58
|
+
assertEquals(1700000000000L, location.timestamp)
|
|
59
|
+
assertEquals(5.0f, location.accuracy, 0.01f)
|
|
60
|
+
assertEquals(2.5f, location.speed!!, 0.01f)
|
|
61
|
+
assertEquals(100.0, location.altitude!!, 0.01)
|
|
62
|
+
assertEquals(180.0f, location.bearing!!, 0.01f)
|
|
63
|
+
assertEquals(1700000000100L, location.createdAt)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
@Test
|
|
67
|
+
fun `QueuedLocation allows nullable speed`() {
|
|
68
|
+
val location = QueuedLocation(
|
|
69
|
+
id = "test-id",
|
|
70
|
+
latitude = 0.0,
|
|
71
|
+
longitude = 0.0,
|
|
72
|
+
timestamp = 0L,
|
|
73
|
+
accuracy = 0.0f,
|
|
74
|
+
speed = null,
|
|
75
|
+
altitude = null,
|
|
76
|
+
bearing = null,
|
|
77
|
+
createdAt = 0L
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
assertNull(location.speed)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
@Test
|
|
84
|
+
fun `QueuedLocation allows nullable altitude`() {
|
|
85
|
+
val location = QueuedLocation(
|
|
86
|
+
id = "test-id",
|
|
87
|
+
latitude = 0.0,
|
|
88
|
+
longitude = 0.0,
|
|
89
|
+
timestamp = 0L,
|
|
90
|
+
accuracy = 0.0f,
|
|
91
|
+
speed = 1.0f,
|
|
92
|
+
altitude = null,
|
|
93
|
+
bearing = null,
|
|
94
|
+
createdAt = 0L
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
assertNull(location.altitude)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
@Test
|
|
101
|
+
fun `QueuedLocation allows nullable bearing`() {
|
|
102
|
+
val location = QueuedLocation(
|
|
103
|
+
id = "test-id",
|
|
104
|
+
latitude = 0.0,
|
|
105
|
+
longitude = 0.0,
|
|
106
|
+
timestamp = 0L,
|
|
107
|
+
accuracy = 0.0f,
|
|
108
|
+
speed = 1.0f,
|
|
109
|
+
altitude = 50.0,
|
|
110
|
+
bearing = null,
|
|
111
|
+
createdAt = 0L
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
assertNull(location.bearing)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
@Test
|
|
118
|
+
fun `QueuedLocation data class supports equality`() {
|
|
119
|
+
val loc1 = QueuedLocation(
|
|
120
|
+
id = "same-id",
|
|
121
|
+
latitude = 1.0,
|
|
122
|
+
longitude = 2.0,
|
|
123
|
+
timestamp = 100L,
|
|
124
|
+
accuracy = 5.0f,
|
|
125
|
+
speed = null,
|
|
126
|
+
altitude = null,
|
|
127
|
+
bearing = null,
|
|
128
|
+
createdAt = 200L
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
val loc2 = QueuedLocation(
|
|
132
|
+
id = "same-id",
|
|
133
|
+
latitude = 1.0,
|
|
134
|
+
longitude = 2.0,
|
|
135
|
+
timestamp = 100L,
|
|
136
|
+
accuracy = 5.0f,
|
|
137
|
+
speed = null,
|
|
138
|
+
altitude = null,
|
|
139
|
+
bearing = null,
|
|
140
|
+
createdAt = 200L
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
assertEquals(loc1, loc2)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
@Test
|
|
147
|
+
fun `QueuedLocation data class supports copy`() {
|
|
148
|
+
val original = QueuedLocation(
|
|
149
|
+
id = "original-id",
|
|
150
|
+
latitude = 1.0,
|
|
151
|
+
longitude = 2.0,
|
|
152
|
+
timestamp = 100L,
|
|
153
|
+
accuracy = 5.0f,
|
|
154
|
+
speed = null,
|
|
155
|
+
altitude = null,
|
|
156
|
+
bearing = null,
|
|
157
|
+
createdAt = 200L
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
val copy = original.copy(latitude = 99.0)
|
|
161
|
+
|
|
162
|
+
assertEquals("original-id", copy.id)
|
|
163
|
+
assertEquals(99.0, copy.latitude, 0.0001)
|
|
164
|
+
assertEquals(2.0, copy.longitude, 0.0001)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// --- UUID Generation Tests ---
|
|
168
|
+
|
|
169
|
+
@Test
|
|
170
|
+
fun `UUID randomUUID generates unique IDs`() {
|
|
171
|
+
val ids = (1..100).map { UUID.randomUUID().toString() }.toSet()
|
|
172
|
+
assertEquals(100, ids.size) // All 100 should be unique
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
@Test
|
|
176
|
+
fun `UUID randomUUID generates valid UUID format`() {
|
|
177
|
+
val uuid = UUID.randomUUID().toString()
|
|
178
|
+
// UUID format: 8-4-4-4-12 hex characters
|
|
179
|
+
val uuidRegex = Regex("^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$")
|
|
180
|
+
assertTrue("UUID should match standard format: $uuid", uuidRegex.matches(uuid))
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
@Test
|
|
184
|
+
fun `UUID is used as primary key for QueuedLocation`() {
|
|
185
|
+
val id = UUID.randomUUID().toString()
|
|
186
|
+
val location = QueuedLocation(
|
|
187
|
+
id = id,
|
|
188
|
+
latitude = 0.0,
|
|
189
|
+
longitude = 0.0,
|
|
190
|
+
timestamp = System.currentTimeMillis(),
|
|
191
|
+
accuracy = 0.0f,
|
|
192
|
+
speed = null,
|
|
193
|
+
altitude = null,
|
|
194
|
+
bearing = null,
|
|
195
|
+
createdAt = System.currentTimeMillis()
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
assertNotNull(location.id)
|
|
199
|
+
assertTrue(location.id.isNotEmpty())
|
|
200
|
+
assertEquals(36, location.id.length) // UUID string length is always 36
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// --- Executor Background Thread Tests ---
|
|
204
|
+
|
|
205
|
+
@Test
|
|
206
|
+
fun `executor submits tasks and returns Future`() {
|
|
207
|
+
val future: Future<String> = executor.submit(Callable { "result" })
|
|
208
|
+
assertEquals("result", future.get())
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
@Test
|
|
212
|
+
fun `executor runs tasks on background thread`() {
|
|
213
|
+
val mainThread = Thread.currentThread()
|
|
214
|
+
var taskThread: Thread? = null
|
|
215
|
+
|
|
216
|
+
val future = executor.submit(Callable {
|
|
217
|
+
taskThread = Thread.currentThread()
|
|
218
|
+
"done"
|
|
219
|
+
})
|
|
220
|
+
future.get() // Wait for completion
|
|
221
|
+
|
|
222
|
+
assertNotNull(taskThread)
|
|
223
|
+
assertNotEquals(mainThread, taskThread)
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
@Test
|
|
227
|
+
fun `executor processes tasks sequentially with single thread`() {
|
|
228
|
+
val singleThreadExecutor = Executors.newSingleThreadExecutor()
|
|
229
|
+
val executionOrder = mutableListOf<Int>()
|
|
230
|
+
|
|
231
|
+
val futures = (1..5).map { index ->
|
|
232
|
+
singleThreadExecutor.submit(Callable {
|
|
233
|
+
executionOrder.add(index)
|
|
234
|
+
index
|
|
235
|
+
})
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Wait for all to complete
|
|
239
|
+
futures.forEach { it.get() }
|
|
240
|
+
|
|
241
|
+
assertEquals(listOf(1, 2, 3, 4, 5), executionOrder)
|
|
242
|
+
singleThreadExecutor.shutdown()
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// --- DAO Interface Contract Tests ---
|
|
246
|
+
|
|
247
|
+
@Test
|
|
248
|
+
fun `QueuedLocationDao insert is called with correct location`() {
|
|
249
|
+
val location = QueuedLocation(
|
|
250
|
+
id = "test-id",
|
|
251
|
+
latitude = 37.0,
|
|
252
|
+
longitude = -122.0,
|
|
253
|
+
timestamp = 1000L,
|
|
254
|
+
accuracy = 5.0f,
|
|
255
|
+
speed = null,
|
|
256
|
+
altitude = null,
|
|
257
|
+
bearing = null,
|
|
258
|
+
createdAt = 2000L
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
mockDao.insert(location)
|
|
262
|
+
|
|
263
|
+
verify(exactly = 1) { mockDao.insert(location) }
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
@Test
|
|
267
|
+
fun `QueuedLocationDao getOldestBatch respects limit parameter`() {
|
|
268
|
+
val batch = listOf(
|
|
269
|
+
QueuedLocation("1", 0.0, 0.0, 100L, 5.0f, null, null, null, 100L),
|
|
270
|
+
QueuedLocation("2", 0.0, 0.0, 200L, 5.0f, null, null, null, 200L)
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
every { mockDao.getOldestBatch(10) } returns batch
|
|
274
|
+
|
|
275
|
+
val result = mockDao.getOldestBatch(10)
|
|
276
|
+
|
|
277
|
+
assertEquals(2, result.size)
|
|
278
|
+
verify { mockDao.getOldestBatch(10) }
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
@Test
|
|
282
|
+
fun `QueuedLocationDao deleteByIds accepts list of IDs`() {
|
|
283
|
+
val ids = listOf("id-1", "id-2", "id-3")
|
|
284
|
+
|
|
285
|
+
mockDao.deleteByIds(ids)
|
|
286
|
+
|
|
287
|
+
verify(exactly = 1) { mockDao.deleteByIds(ids) }
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
@Test
|
|
291
|
+
fun `QueuedLocationDao getCount returns integer`() {
|
|
292
|
+
every { mockDao.getCount() } returns 42
|
|
293
|
+
|
|
294
|
+
val count = mockDao.getCount()
|
|
295
|
+
|
|
296
|
+
assertEquals(42, count)
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// --- Enqueue Pattern Tests ---
|
|
300
|
+
|
|
301
|
+
@Test
|
|
302
|
+
fun `enqueue pattern creates QueuedLocation with UUID and current time`() {
|
|
303
|
+
val beforeTime = System.currentTimeMillis()
|
|
304
|
+
|
|
305
|
+
val location = QueuedLocation(
|
|
306
|
+
id = UUID.randomUUID().toString(),
|
|
307
|
+
latitude = 37.7749,
|
|
308
|
+
longitude = -122.4194,
|
|
309
|
+
timestamp = 1700000000000L,
|
|
310
|
+
accuracy = 10.0f,
|
|
311
|
+
speed = 5.0f,
|
|
312
|
+
altitude = 50.0,
|
|
313
|
+
bearing = 90.0f,
|
|
314
|
+
createdAt = System.currentTimeMillis()
|
|
315
|
+
)
|
|
316
|
+
|
|
317
|
+
val afterTime = System.currentTimeMillis()
|
|
318
|
+
|
|
319
|
+
// Verify UUID format
|
|
320
|
+
assertTrue(location.id.length == 36)
|
|
321
|
+
|
|
322
|
+
// Verify createdAt is approximately now
|
|
323
|
+
assertTrue(location.createdAt >= beforeTime)
|
|
324
|
+
assertTrue(location.createdAt <= afterTime)
|
|
325
|
+
|
|
326
|
+
// Verify passed parameters are stored correctly
|
|
327
|
+
assertEquals(37.7749, location.latitude, 0.0001)
|
|
328
|
+
assertEquals(-122.4194, location.longitude, 0.0001)
|
|
329
|
+
assertEquals(1700000000000L, location.timestamp)
|
|
330
|
+
assertEquals(10.0f, location.accuracy, 0.01f)
|
|
331
|
+
assertEquals(5.0f, location.speed!!, 0.01f)
|
|
332
|
+
assertEquals(50.0, location.altitude!!, 0.01)
|
|
333
|
+
assertEquals(90.0f, location.bearing!!, 0.01f)
|
|
334
|
+
}
|
|
335
|
+
}
|