diff options
| author | Claudomator Agent <agent@claudomator> | 2026-03-15 03:44:25 +0000 |
|---|---|---|
| committer | Peter Stone <thepeterstone@gmail.com> | 2026-03-25 04:54:31 +0000 |
| commit | 826d56ede2c59cad19748f61d8b5d75d08a702d9 (patch) | |
| tree | 6cdb3bbcc50ba6fc3a5c4f1ec077b6a1fa4a8384 /android-app/app/src/test/kotlin/org/terst | |
| parent | c943c22954132b21f3067b526b3c13f3300113dd (diff) | |
feat: add harmonic tide height predictions (Section 3.2 / 4.2)
Implement offline harmonic tide prediction as specified in COMPONENT_DESIGN.md:
- TideConstituent: name, speedDegPerHour, amplitudeMeters, phaseDeg
- TidePrediction: timestampMs, heightMeters
- TideStation: id, name, lat, lon, datumOffsetMeters, constituents
- HarmonicTideCalculator: predictHeight(), predictRange(), findHighLow()
Formula: h(t) = Z0 + Σ [ Hi × cos( ωi × (t − t0) − φi ) ]
- 15 unit tests covering all calculation paths
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'android-app/app/src/test/kotlin/org/terst')
| -rw-r--r-- | android-app/app/src/test/kotlin/org/terst/nav/data/model/TideModelTest.kt | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/android-app/app/src/test/kotlin/org/terst/nav/data/model/TideModelTest.kt b/android-app/app/src/test/kotlin/org/terst/nav/data/model/TideModelTest.kt new file mode 100644 index 0000000..0a6f4bb --- /dev/null +++ b/android-app/app/src/test/kotlin/org/terst/nav/data/model/TideModelTest.kt @@ -0,0 +1,56 @@ +package com.example.androidapp.data.model + +import org.junit.Assert.* +import org.junit.Test + +class TideModelTest { + + @Test + fun `TideConstituent holds all fields`() { + val c = TideConstituent("M2", 28.9841042, 0.85, 120.0) + assertEquals("M2", c.name) + assertEquals(28.9841042, c.speedDegPerHour, 1e-7) + assertEquals(0.85, c.amplitudeMeters, 1e-9) + assertEquals(120.0, c.phaseDeg, 1e-9) + } + + @Test + fun `TidePrediction holds timestamp and height`() { + val p = TidePrediction(1_700_000_000_000L, 2.34) + assertEquals(1_700_000_000_000L, p.timestampMs) + assertEquals(2.34, p.heightMeters, 1e-9) + } + + @Test + fun `TidePrediction data class equality`() { + val p1 = TidePrediction(1_000L, 1.5) + val p2 = TidePrediction(1_000L, 1.5) + assertEquals(p1, p2) + } + + @Test + fun `TideStation holds all fields and constituents`() { + val c = TideConstituent("K1", 15.0410686, 0.3, 45.0) + val station = TideStation( + id = "9447130", + name = "Seattle, WA", + lat = 47.602, + lon = -122.339, + datumOffsetMeters = 1.8, + constituents = listOf(c) + ) + assertEquals("9447130", station.id) + assertEquals("Seattle, WA", station.name) + assertEquals(47.602, station.lat, 1e-9) + assertEquals(-122.339, station.lon, 1e-9) + assertEquals(1.8, station.datumOffsetMeters, 1e-9) + assertEquals(1, station.constituents.size) + assertEquals("K1", station.constituents[0].name) + } + + @Test + fun `TideStation with empty constituents is valid`() { + val station = TideStation("test", "Test", 0.0, 0.0, 0.0, emptyList()) + assertTrue(station.constituents.isEmpty()) + } +} |
