summaryrefslogtreecommitdiff
path: root/test-runner/src/test/kotlin/org/terst/nav/track/TrackStatsTest.kt
blob: 7bce0a23abe737e7911206a4fc17a08cf3a763b9 (plain)
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)
    }
}