Add coverage tests for MixUnused.Analyzer and HistoricalLoader edge cases

This commit is contained in:
Graham McIntire 2026-05-08 13:09:24 -05:00
parent aa809976ab
commit b2a1d8e7e9
No known key found for this signature in database
GPG key ID: F4ABF488E6029E59
2 changed files with 151 additions and 0 deletions

View file

@ -444,6 +444,109 @@ defmodule AprsmeWeb.MapLive.HistoricalLoaderTest do
end
end
describe "low zoom heat map path with string-keyed packet ids" do
test "string-keyed :id packet uses get_packet_key string-key clause" do
now = DateTime.utc_now()
Mox.stub(Aprsme.PacketsMock, :get_recent_packets, fn _opts ->
[
%{
"id" => "str-keyed-1",
"sender" => "STR-1",
"callsign" => "STR-1",
"received_at" => now,
"lat" => 33.0,
"lon" => -96.0,
has_position: true,
symbol_table_id: "/",
symbol_code: ">",
path: ""
}
]
end)
socket =
build_socket(%{
map_bounds: %{north: 34.0, south: 32.0, east: -95.0, west: -97.0},
map_zoom: 5,
historical_loading: true,
loading_generation: 1,
total_batches: 3
})
result = HistoricalLoader.load_historical_batch(socket, 0, nil)
# The string-keyed id was placed into historical_packets via the
# get_packet_key/1 string-key clause.
assert is_map(result.assigns.historical_packets)
end
end
describe "very zoomed out (zoom < 5) get_loading_params_for_zoom fallback" do
test "zoom 2 uses the catch-all params {50, 5}" do
Mox.stub(Aprsme.PacketsMock, :get_recent_packets, fn _opts -> [] end)
socket =
build_socket(%{
map_bounds: %{north: 34.0, south: 32.0, east: -95.0, west: -97.0},
map_zoom: 2,
loading_generation: 0
})
result = HistoricalLoader.start_progressive_historical_loading(socket)
# Catch-all clause produces 5 batches.
assert result.assigns.total_batches == 5
end
end
describe "apply_memory_limit pruning path" do
test "exceeds @max_historical_packets and triggers prune_oldest_packets" do
now = DateTime.utc_now()
# Pre-populate historical_packets with > 5000 entries (the cap).
historical_packets =
for i <- 1..5_001, into: %{} do
{to_string(i),
%{
id: "old-#{i}",
received_at: DateTime.add(now, -i, :second),
lat: 33.0,
lon: -96.0
}}
end
Mox.stub(Aprsme.PacketsMock, :get_recent_packets, fn _opts ->
[
%{
id: "newcomer",
sender: "NEW-1",
base_callsign: "NEW",
ssid: "1",
lat: 33.5,
lon: -96.5,
has_position: true,
symbol_table_id: "/",
symbol_code: ">",
received_at: now,
path: ""
}
]
end)
socket =
build_socket(%{
map_bounds: %{north: 34.0, south: 32.0, east: -95.0, west: -97.0},
map_zoom: 5,
historical_loading: true,
historical_packets: historical_packets,
loading_generation: 1,
total_batches: 3
})
result = HistoricalLoader.load_historical_batch(socket, 0, nil)
# After pruning, the historical_packets size should be <= 5000.
assert map_size(result.assigns.historical_packets) <= 5_000
end
end
describe "schedules next batch when not final" do
test "saturated batch with more rows triggers maybe_schedule_next_batch" do
now = DateTime.utc_now()

View file

@ -103,5 +103,53 @@ defmodule MixUnused.AnalyzerTest do
result = Analyzer.analyze(app: :no_such_app_for_real)
assert result == []
end
test "honors :compile_path option pointing to an empty directory" do
tmp = Path.join(System.tmp_dir!(), "mu_empty_#{System.unique_integer([:positive])}")
File.mkdir_p!(tmp)
try do
result = Analyzer.analyze(compile_path: tmp)
assert result == []
after
File.rm_rf(tmp)
end
end
test "honors :compile_path option pointing to a non-existent directory" do
result = Analyzer.analyze(compile_path: "/nonexistent/path/for/test/#{System.unique_integer([:positive])}")
assert result == []
end
test "exclude with both module atoms and MFA tuples filters both kinds" do
[first, second | _] = Analyzer.analyze()
excluded =
Analyzer.analyze(exclude: [first.module, {second.module, second.name, second.arity}])
refute Enum.any?(excluded, &(&1.module == first.module))
refute Enum.any?(
excluded,
&(&1.module == second.module and &1.name == second.name and &1.arity == second.arity)
)
end
end
describe "format/1 with grouped multiple-modules and missing line metadata" do
test "formats a mix of present and missing line numbers" do
entries = [
%{module: A, name: :one, arity: 1, file: "lib/a.ex", line: 5},
%{module: A, name: :two, arity: 0, file: "lib/a.ex", line: nil},
%{module: B, name: :three, arity: 2, file: nil, line: nil}
]
out = Analyzer.format(entries)
assert out =~ "A"
assert out =~ "B"
assert out =~ "lib/a.ex:5"
assert out =~ "(lib/a.ex)"
assert out =~ "(?)"
end
end
end