prop/test/microwaveprop/buildings/parser_test.exs
Graham McIntire 079346a1b9
Some checks failed
Build and Push / Build and Push Docker Image (push) Failing after 4m38s
fix: resolve all 281 credo issues across source and test files
- F-level (228): replace length/1 with Enum.count_until/2 or pattern
  matching; convert Enum.flat_map+if to Enum.filter+Enum.map; fix
  identity case in narr_client
- W-level (46): normalize dual atom/string key access in weather_layers,
  beacon_measurements, surface, skewt_live, contact_live/show; add
  :data_provider and weather-map assigns to ignored_assigns in credo
  config (consumed by child components credo can't trace); remove
  weak is_list assertion; remove explicit assert_receive timeout
- R-level (6): replace 'This module provides...' moduledocs with
  meaningful descriptions
- Also fix 4 compile-connected xref issues by deferring
  BandConfig.band_options() from module attribute to runtime

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-29 09:04:21 -05:00

181 lines
4.8 KiB
Elixir

defmodule Microwaveprop.Buildings.ParserTest do
use ExUnit.Case, async: true
alias Microwaveprop.Buildings.Parser
describe "parse_tile/1" do
test "parses a single Polygon feature" do
path =
create_gz(%{
"type" => "Feature",
"properties" => %{"height" => 15.0},
"geometry" => %{
"type" => "Polygon",
"coordinates" => [
[
[-97.0, 32.9],
[-97.0, 33.0],
[-96.9, 33.0],
[-96.9, 32.9],
[-97.0, 32.9]
]
]
}
})
records = path |> Parser.parse_tile() |> Enum.to_list()
assert Enum.count_until(records, 2) == 1
rec = hd(records)
assert rec.height_m == 15.0
assert rec.centroid_lat > 32.9
assert rec.centroid_lat < 33.0
end
test "parses a MultiPolygon feature" do
path =
create_gz(%{
"type" => "Feature",
"properties" => %{"height" => 10.0},
"geometry" => %{
"type" => "MultiPolygon",
"coordinates" => [
[
[
[-97.0, 32.9],
[-97.0, 33.0],
[-96.9, 33.0],
[-96.9, 32.9],
[-97.0, 32.9]
]
]
]
}
})
records = path |> Parser.parse_tile() |> Enum.to_list()
assert Enum.count_until(records, 2) == 1
assert hd(records).height_m == 10.0
end
test "drops features with height -1.0 (unknown)" do
path =
create_gz(%{
"type" => "Feature",
"properties" => %{"height" => -1.0},
"geometry" => %{
"type" => "Polygon",
"coordinates" => [
[
[-97.0, 32.9],
[-97.0, 33.0],
[-96.9, 33.0],
[-96.9, 32.9],
[-97.0, 32.9]
]
]
}
})
records = path |> Parser.parse_tile() |> Enum.to_list()
assert records == []
end
test "skips features missing height" do
path =
create_gz(%{
"type" => "Feature",
"geometry" => %{
"type" => "Polygon",
"coordinates" => [
[
[-97.0, 32.9],
[-97.0, 33.0],
[-96.9, 33.0],
[-96.9, 32.9],
[-97.0, 32.9]
]
]
}
})
records = path |> Parser.parse_tile() |> Enum.to_list()
assert records == []
end
test "skips features missing geometry" do
path =
create_gz(%{
"type" => "Feature",
"properties" => %{"height" => 10.0}
})
records = path |> Parser.parse_tile() |> Enum.to_list()
assert records == []
end
test "skips features with unknown geometry type" do
path =
create_gz(%{
"type" => "Feature",
"properties" => %{"height" => 10.0},
"geometry" => %{
"type" => "Point",
"coordinates" => [-97.0, 32.9]
}
})
records = path |> Parser.parse_tile() |> Enum.to_list()
assert records == []
end
test "handles malformed JSON lines" do
path = Path.join(System.tmp_dir!(), "bad_#{System.unique_integer([:positive])}.csv.gz")
File.write!(path, "not json\n", [:compressed])
on_exit(fn -> File.rm(path) end)
records = path |> Parser.parse_tile() |> Enum.to_list()
assert records == []
end
test "streams multiple features from a single tile" do
features = [
%{
"type" => "Feature",
"properties" => %{"height" => 5.0},
"geometry" => %{
"type" => "Polygon",
"coordinates" => [[[-97.0, 33.0], [-97.0, 33.001], [-96.999, 33.001], [-96.999, 33.0], [-97.0, 33.0]]]
}
},
%{
"type" => "Feature",
"properties" => %{"height" => 20.0},
"geometry" => %{
"type" => "Polygon",
"coordinates" => [[[-96.8, 32.7], [-96.8, 32.701], [-96.799, 32.701], [-96.799, 32.7], [-96.8, 32.7]]]
}
}
]
path = create_gz_lines(features)
records = path |> Parser.parse_tile() |> Enum.to_list()
assert Enum.count_until(records, 3) == 2
heights = Enum.map(records, & &1.height_m)
assert 5.0 in heights
assert 20.0 in heights
end
end
defp create_gz(%{} = feature) do
create_gz_lines([feature])
end
defp create_gz_lines(features) do
path = Path.join(System.tmp_dir!(), "parser_test_#{System.unique_integer([:positive])}.csv.gz")
body = Enum.map_join(features, "\n", &Jason.encode!/1) <> "\n"
File.write!(path, body, [:compressed])
on_exit(fn -> File.rm(path) end)
path
end
end