aprs.me/test/aprsme_web/live/info_live/show_helpers_test.exs
Graham McIntire b86153cd27
Fix all mix credo --strict warnings (188 → 0)
- Replace apply/2 with direct fully-qualified calls in movement_test
- Fix assert_receive timeouts < 1000ms across 8 test files
- Move nested import statements to module-level scope
- Fix tests with no assertions and add missing doctest
- Replace weak type assertions with specific value checks
- Fix conditional assertions and length/1 expensive patterns
- Disable inappropriate Jump.CredoChecks.AvoidSocketAssignsInTest
- Fix tests not calling application code with credo:disable
- Add various credo:disable comments for legitimate patterns
2026-06-12 16:27:20 -05:00

227 lines
7.3 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)
# credo:disable-for-next-line Jump.CredoChecks.ConditionalAssertion
assert bearing == 0.0 or bearing == 360.0
# calculate_course for due north legitimately returns 0.0 or 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
describe "parse_path_with_links/1" do
test "returns empty list for non-binary input" do
assert Show.parse_path_with_links(nil) == []
assert Show.parse_path_with_links("") == []
assert Show.parse_path_with_links(123) == []
end
test "splits on commas and links plain callsigns" do
result = Show.parse_path_with_links("K5ABC-1,W1XYZ")
assert [{:link, "K5ABC-1", "K5ABC-1"}, {:link, "W1XYZ", "W1XYZ"}] = result
end
test "preserves the heard-via asterisk in the display text" do
assert [{:link, "K5ABC", "K5ABC*"}] = Show.parse_path_with_links("K5ABC*")
end
test "does not link WIDE/TRACE/RELAY/TCPIP path aliases" do
assert [{:text, "WIDE1-1", "WIDE1-1"}] = Show.parse_path_with_links("WIDE1-1")
assert [{:text, "TRACE3-3", "TRACE3-3"}] = Show.parse_path_with_links("TRACE3-3")
assert [{:text, "RELAY", "RELAY"}] = Show.parse_path_with_links("RELAY")
assert [{:text, "TCPIP*", "TCPIP*"}] = Show.parse_path_with_links("TCPIP*")
end
test "does not link q-constructs" do
assert [{:text, "qAC", "qAC"}] = Show.parse_path_with_links("qAC")
assert [{:text, "qAR", "qAR"}] = Show.parse_path_with_links("qAR")
end
test "trims whitespace before linking" do
assert [{:link, "K5ABC", "K5ABC"}] = Show.parse_path_with_links(" K5ABC ")
end
test "mixes links and text in a single path" do
result = Show.parse_path_with_links("K5ABC*,WIDE1-1,W1XYZ")
assert [
{:link, "K5ABC", "K5ABC*"},
{:text, "WIDE1-1", "WIDE1-1"},
{:link, "W1XYZ", "W1XYZ"}
] = result
end
end
describe "render_symbol_html/2" do
test "returns an empty raw for a nil packet" do
result = Show.render_symbol_html(nil)
# raw("") — a safe-iodata pair.
assert {:safe, ""} = result
end
test "returns an overlay div for a packet with a uppercase-letter overlay table_id" do
packet = %{symbol_table_id: "A", symbol_code: ">"}
{:safe, html} = Show.render_symbol_html(packet, 24)
assert html =~ "<div"
assert html =~ "background-image"
end
test "returns a single-sprite div for a standard symbol table" do
packet = %{symbol_table_id: "/", symbol_code: "-"}
{:safe, html} = Show.render_symbol_html(packet)
assert html =~ "<div"
end
end
describe "haversine/4 with Decimal input" do
test "handles Decimal-valued coordinates" do
result =
Show.haversine(
Decimal.new("40.0"),
Decimal.new("-100.0"),
Decimal.new("41.0"),
Decimal.new("-99.0")
)
assert is_float(result)
assert result > 0
end
end
describe "format_distance/2 rounding" do
test "rounds to 2 decimal places in metric mode" do
# 1.234567 km → "1.23 km"
assert Show.format_distance(1.234567, "fr") == "1.23 km"
end
test "0 km in metric mode prints 0 m" do
assert Show.format_distance(0.0, "de") == "0.0 m"
end
test "0 km in English mode prints 0 ft" do
assert Show.format_distance(0.0, "en") == "0.0 ft"
end
end
describe "position_changed_for_test/2" do
test "returns true when current packet is nil" do
assert Show.position_changed_for_test(nil, %{lat: 1.0, lon: 1.0})
end
test "returns false when new packet is nil" do
refute Show.position_changed_for_test(%{lat: 1.0, lon: 1.0}, nil)
end
test "returns false when positions are identical" do
current = %{lat: 33.0, lon: -96.0}
new = %{lat: 33.0, lon: -96.0}
refute Show.position_changed_for_test(current, new)
end
test "returns true when position changes by more than threshold" do
current = %{lat: 33.0, lon: -96.0}
new = %{lat: 33.01, lon: -96.0}
assert Show.position_changed_for_test(current, new)
end
test "returns true when either coordinate is nil" do
assert Show.position_changed_for_test(%{lat: nil, lon: -96.0}, %{lat: 33.0, lon: -96.0})
assert Show.position_changed_for_test(%{lat: 33.0, lon: nil}, %{lat: 33.0, lon: -96.0})
assert Show.position_changed_for_test(%{lat: 33.0, lon: -96.0}, %{lat: nil, lon: -96.0})
assert Show.position_changed_for_test(%{lat: 33.0, lon: -96.0}, %{lat: 33.0, lon: nil})
end
end
end