aprs.me/test/aprsme_web/live/info_live/show_helpers_test.exs
Graham McIntire 35bd098b30
refactor: more pattern matching + drop unreachable get_field_value clause
- Aprsme.Packet.put_phg_fields: dispatch on the shape of the phg value
  (map / 4-char binary / anything else) via put_phg_fields_for/2.
- Aprsme.Packet.get_field_value: remove the catch-all nil clause. After
  the put_phg_fields refactor, dialyzer can prove every call site passes
  a map and flagged the fallback as unreachable — so it's gone, and
  a future mistyped caller now fails loudly instead of silently.
- LogSanitizer.sanitize_map: extract redact_field/2 for readability.
- DeviceIdentification.pattern_matches?: match_pattern/3 dispatched on
  String.contains?/2 keeps the rescue tight around the regex path.
- InfoLive.Show: get_received_at pattern-matches on key shape;
  format_distance splits locale × range via four format_*_distance
  helpers; calculate_course pipes through normalize_bearing/1.

Adds 15 tests exercising the InfoLive.Show helpers (imperial vs. metric
formatting, cardinal bearings, haversine symmetry, Decimal inputs).
Coverage 67.43 → 67.72%.
2026-04-23 14:09:53 -05:00

102 lines
2.9 KiB
Elixir

defmodule AprsmeWeb.InfoLive.ShowHelpersTest do
use ExUnit.Case, async: true
alias AprsmeWeb.InfoLive.Show
describe "format_distance/2 with English locale (imperial)" do
test "uses feet for distances under a mile" do
# 0.5 km → ~0.31 miles → ~1641 ft
result = Show.format_distance(0.5, "en")
assert result =~ "ft"
refute result =~ "mi"
end
test "uses miles for distances >= 1 mile" do
# 10 km → ~6.21 miles
result = Show.format_distance(10.0, "en")
assert result =~ "mi"
refute result =~ "ft"
end
test "default locale is English" do
assert Show.format_distance(10.0) =~ "mi"
end
end
describe "format_distance/2 with non-English locale (metric)" do
test "uses meters for distances under 1 km" do
result = Show.format_distance(0.5, "de")
assert result =~ "m"
refute result =~ "km"
end
test "uses km for longer distances" do
result = Show.format_distance(5.0, "fr")
assert result =~ "km"
end
test "handles multiple metric locales" do
for loc <- ["es", "de", "fr", "ja"] do
assert Show.format_distance(10.0, loc) =~ "km"
end
end
end
describe "calculate_course/4" do
test "returns 0 (or 360) for due north" do
# From (0,0) to (1,0) — moving north.
bearing = Show.calculate_course(0.0, 0.0, 1.0, 0.0)
assert bearing == 0.0 or bearing == 360.0
end
test "returns ~90 for due east" do
# From (0,0) to (0,1) — moving east.
bearing = Show.calculate_course(0.0, 0.0, 0.0, 1.0)
assert_in_delta bearing, 90.0, 0.5
end
test "returns ~180 for due south" do
bearing = Show.calculate_course(1.0, 0.0, 0.0, 0.0)
assert_in_delta bearing, 180.0, 0.5
end
test "returns ~270 for due west" do
bearing = Show.calculate_course(0.0, 1.0, 0.0, 0.0)
assert_in_delta bearing, 270.0, 0.5
end
test "always returns a value in 0..360" do
for {lat1, lon1, lat2, lon2} <- [
{0.0, 0.0, 45.0, 45.0},
{10.0, 20.0, -10.0, -20.0},
{0.0, 0.0, 0.0, -1.0}
] do
b = Show.calculate_course(lat1, lon1, lat2, lon2)
assert b >= 0
assert b <= 360
end
end
test "accepts Decimal inputs" do
result = Show.calculate_course(Decimal.new("0.0"), Decimal.new("0.0"), Decimal.new("1.0"), Decimal.new("0.0"))
assert is_float(result)
end
end
describe "haversine/4" do
test "returns 0 for identical points" do
assert Show.haversine(40.0, -100.0, 40.0, -100.0) == 0.0
end
test "is symmetric" do
a = Show.haversine(40.0, -100.0, 41.0, -99.0)
b = Show.haversine(41.0, -99.0, 40.0, -100.0)
assert_in_delta a, b, 0.001
end
test "returns positive distance for distinct points" do
d = Show.haversine(40.0, -100.0, 41.0, -99.0)
assert d > 0
end
end
end