1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
package org.terst.nav.track
import org.junit.Assert.*
import org.junit.Before
import org.junit.Test
class TrackStatsTest {
private lateinit var repo: TrackRepository
private fun pt(lat: Double, lon: Double, sog: Double = 5.0, ts: Long = 0L) =
TrackPoint(lat, lon, sog, 0.0, 0.0, 0.0, false, ts)
@Before
fun setup() {
repo = TrackRepository()
repo.startTrack()
}
@Test
fun `computeStats returns null for single point`() {
repo.addPoint(pt(41.0, -71.0, ts = 0))
assertNull(repo.computeStats())
}
@Test
fun `computeStats returns null when not recording and no points`() {
repo.stopTrack()
assertNull(repo.computeStats())
}
@Test
fun `haversineNm one degree of latitude is approximately 60 nm`() {
val d = TrackRepository.haversineNm(0.0, 0.0, 1.0, 0.0)
assertEquals(60.0, d, 0.5)
}
@Test
fun `haversineNm zero distance returns zero`() {
assertEquals(0.0, TrackRepository.haversineNm(41.0, -71.0, 41.0, -71.0), 1e-9)
}
@Test
fun `computeStats distance accumulates across legs`() {
repo.addPoint(pt(0.0, 0.0, ts = 0))
repo.addPoint(pt(1.0, 0.0, ts = 3_600_000)) // ~60 nm north
repo.addPoint(pt(1.0, 1.0, ts = 7_200_000)) // ~60 nm east at 1° lat
val stats = repo.computeStats()!!
assertTrue("Expected ~120 nm, got ${stats.distanceNm}", stats.distanceNm > 100.0)
}
@Test
fun `computeStats duration is last minus first timestamp`() {
repo.addPoint(pt(0.0, 0.0, ts = 1_000))
repo.addPoint(pt(1.0, 0.0, ts = 3_601_000))
val stats = repo.computeStats()!!
assertEquals(3_600_000L, stats.durationMs)
}
@Test
fun `computeStats avgSog is mean of all point sogs`() {
repo.addPoint(pt(0.0, 0.0, sog = 4.0, ts = 0))
repo.addPoint(pt(0.0, 0.1, sog = 6.0, ts = 1000))
val stats = repo.computeStats()!!
assertEquals(5.0, stats.avgSogKnots, 0.001)
}
@Test
fun `durationFormatted shows m_ss below one hour`() {
val stats = TrackStats(1.0, 65_000L, 5.0) // 1 min 5 sec
assertEquals("1:05", stats.durationFormatted)
}
@Test
fun `durationFormatted shows h_mm_ss above one hour`() {
val stats = TrackStats(1.0, 3_661_000L, 5.0) // 1h 1m 1s
assertEquals("1:01:01", stats.durationFormatted)
}
}
|