Audit issue #22 speed-pipeline test coverage, fill the real GPX-replay distance gap #103
No reviewers
Labels
No labels
area:companion
area:docs
area:shared
area:tooling
area:watchapp
blocker
kind:chore
kind:feature
kind:spike
kind:test
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
robert/PedalPebble!103
Loading…
Reference in a new issue
No description provided.
Delete branch "area/speed-pipeline-coverage-audit"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #22.
Audit result: most of #22 was already satisfied tonight
Read #22's acceptance criteria against what #100/#101/#102 (issues #69/#17/#19) and #99 (#18) actually shipped before writing anything. Five of six criteria are already real, passing coverage — no duplicate tests added for any of them:
SpeedPipelineTest.kt:"onGpsFix falls back to a position-delta (distance/dt) speed when the fix carries no platform speed, smoothed over the ~3 s window","onGpsFix's reported speed clamps to exactly zero once StopDetector confirms a stop", and the synthetic stop-and-go traffic-light scenario test.WheelSpeedTrackerTest.kt:"a revolution-count rollover across two samples still yields a correct, positive delta","an event-time rollover across two samples still yields the correct elapsed time","both counters rolling over on the same pair of samples still yields a correct delta", plus property-basedcheckAllfuzzing ofuint32Delta/uint16Deltaover their full ranges. Confirmed real, not assumed.SpeedPipelineTest.kt:"onGpsFix rejects a fix past the accuracy threshold..."and"onGpsFix rejects a fix with unknown (NaN) accuracy too...".SpeedPipelineTest.kt: the wheel-live/GPS-dropped tests,"a disconnect immediately hands speed sourcing back to GPS...", and the no-source case via"currentReport is NoSignal before any sample has ever arrived"/"currentReport flips to NoSignal once neither source has reported for SIGNAL_TIMEOUT_NANOS...". Confirmed real, not assumed.companion/core/src/test/including the new one below;./gradlew :companion:core:testconfirms it.The one real gap this PR fills
"Distance accumulation tested against a known GPX with a hand-checked total" had a real gap:
RealWorldFixtureTest.kt(from #38/#6, PR #95) tests the ~119 km komoot fixture throughGpxImporter/computeRouteMetrics— the import-time route-metrics path. That is a different code path fromSpeedPipeline.onGpsFix's live-ride, one-fix-at-a-time distance accumulation this issue is actually about (the accuracy gate, has-speed-vs-fallback, and smoothing this issue names).New:
companion/core/src/test/kotlin/de/butzei/pedalpebble/core/location/SpeedPipelineGpxReplayTest.kt. It:<trkpt>sequence directly (2795 points), deliberately bypassingGpxImporter's RDP simplification so it replays the exact same raw-point basisRealWorldFixtureTest's ~119,020 m ground truth was independently computed over (plain haversine over the raw file).SpeedPipeline.onGpsFixone at a time, using the point's own real recorded<time>(not a synthetic fixed cadence — komoot's actual interval varies ~0.1-160 s) and a fixed 6.0 m accuracy (mid of a realistic 5-8 m phone GPS accuracy; the file carries no accuracy field).movingDistanceMeterslands within 50 m of ~119,020 m, and thatrejectedFixCount == 0.Measured result: 119,020.28649817174 m vs. the ~119,020.29 m ground truth — a difference of about 3.5 mm. The 50 m tolerance is deliberately tight and is justified, not padded: a standalone Python re-implementation of the exact
SpeedPipeline/StopDetectoralgorithm over this fixture found zero confirmed-stop events anywhere in the ride (no two consecutive raw points are ever slower than the 0.8 m/s stop threshold apart), soStopDetectornever leaves its initialMOVINGstate and every position delta counts toward moving distance — for this specific fixture, "moving distance" and "raw total distance" are the same quantity, not merely close ones. A fixture with real recorded stops would need a substantially wider tolerance; this one doesn't, and the test's own KDoc says so.Test run
Real Android SDK/JDK 21 toolchain, not hand-reviewed.
Claude-Session: https://claude.ai/code/session_01DAoXbRmJUf2uxNYBfdAXPt