Files
maptool/test/test_track_stats.rb
T
randy 105651f005
CI / check (push) Successful in 41s
CI / deploy (push) Successful in 15s
Add activity type and a click-to-open track profile panel
Track properties gain activity_type (FIT: sport enum from the
session/sport message, Garmin's own table; GPX: <trk><type> passed
through as-is) alongside the existing distance/elevation/duration.

Clicking a track line now opens a bottom panel with a chart per
metric the track actually has (elevation always; speed/cadence/heart
rate only when present — FIT's record fields or GPX's device
extensions). TrackStats.build_profile computes cumulative distance
the same way for both formats so they're directly comparable. One
pointermove listener drives a synchronized crosshair across every
chart, a single tooltip listing all series, and a map marker at the
hovered point's position — hovering the chart shows where on the
track that moment was.
2026-09-07 13:38:49 +02:00

58 lines
2.2 KiB
Ruby

require_relative "test_helper"
require "maptool/track_stats"
class TrackStatsTest < Minitest::Test
def test_computes_distance_and_elevation_gain_ignoring_descents
# A right-angle path (equirectangular approximation is accurate enough
# at this scale to just assert "nonzero, roughly plausible") with a
# climb-then-descend elevation profile, so both distance and
# elevation-gain have a real value to check against.
points = [
[17.0, 48.0, 100],
[17.001, 48.0, 150], # +50m gain
[17.001, 48.001, 120], # descent — not subtracted
]
times = [Time.utc(2026, 1, 1, 0, 0, 0), nil, Time.utc(2026, 1, 1, 0, 10, 0)]
stats = Maptool::TrackStats.compute(points, times: times)
assert_operator stats["distance_meters"], :>, 100
assert_equal 50.0, stats["elevation_gain_meters"]
assert_equal 600, stats["duration_secs"]
assert_equal 3, stats["point_count"]
end
def test_nil_elevation_gain_and_duration_when_data_is_missing
stats = Maptool::TrackStats.compute([[17.0, 48.0], [17.0, 48.0]], times: [])
assert_nil stats["elevation_gain_meters"]
assert_nil stats["duration_secs"]
end
def test_single_point_has_zero_distance
stats = Maptool::TrackStats.compute([[17.0, 48.0]])
assert_equal 0.0, stats["distance_meters"]
end
def test_build_profile_has_cumulative_distance_elevation_and_extras
points = [[17.0, 48.0, 100], [17.001, 48.0, 150]]
extras = [{ heart_rate_bpm: 120 }, { heart_rate_bpm: 130, cadence_rpm: 80 }]
profile = Maptool::TrackStats.build_profile(points, extras: extras)
assert_equal 2, profile.size
assert_equal 0.0, profile[0]["distance_meters"]
assert_equal 100, profile[0]["elevation_meters"]
assert_equal 120, profile[0]["heart_rate_bpm"]
assert_nil profile[0]["cadence_rpm"]
assert_operator profile[1]["distance_meters"], :>, 0
assert_equal 80, profile[1]["cadence_rpm"]
assert_equal [17.001, 48.0], [profile[1]["lon"], profile[1]["lat"]]
end
def test_build_profile_extras_default_to_nil_when_shorter_than_coordinates
profile = Maptool::TrackStats.build_profile([[17.0, 48.0], [17.001, 48.0]], extras: [])
assert_nil profile[0]["heart_rate_bpm"]
assert_nil profile[1]["speed_mps"]
end
end