- 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%.
102 lines
2.9 KiB
Elixir
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
|