defmodule Microwaveprop.Rover.RoadProximityTest do use ExUnit.Case, async: true alias Microwaveprop.Rover.RoadProximity describe "road_distances/3" do test "returns distances when segments are available" do cells = [%{lat: 33.0, lon: -97.0}] bbox = %{"south" => 32.5, "north" => 33.5, "west" => -98.0, "east" => -96.0} # One segment 0.5 deg (~55 km) from the cell fetch = fn _bbox -> {:ok, [{{33.0, -96.5}, {33.0, -96.0}}]} end {:ok, distances} = RoadProximity.road_distances(cells, bbox, fetch: fetch) assert map_size(distances) > 0 assert Map.has_key?(distances, {33.0, -97.0}) assert distances[{33.0, -97.0}] > 0 end test "returns nanometres for point exactly on the road" do cells = [%{lat: 33.0, lon: -97.0}] bbox = %{"south" => 32.5, "north" => 33.5, "west" => -98.0, "east" => -96.0} # Segment passes through the cell point fetch = fn _bbox -> {:ok, [{{33.0, -98.0}, {33.0, -96.0}}]} end {:ok, distances} = RoadProximity.road_distances(cells, bbox, fetch: fetch) assert_in_delta distances[{33.0, -97.0}], 0.0, 0.001 end test "returns {:error, :no_roads} when no segments found" do cells = [%{lat: 33.0, lon: -97.0}] bbox = %{"south" => 32.5, "north" => 33.5, "west" => -98.0, "east" => -96.0} assert {:error, :no_roads} = RoadProximity.road_distances(cells, bbox, fetch: fn _ -> {:ok, []} end) end test "propagates fetch errors" do cells = [%{lat: 33.0, lon: -97.0}] bbox = %{"south" => 32.5, "north" => 33.5, "west" => -98.0, "east" => -96.0} assert {:error, :overpass_timeout} = RoadProximity.road_distances(cells, bbox, fetch: fn _ -> {:error, :overpass_timeout} end) end test "multiple cells each get their nearest road distance" do cells = [ %{lat: 33.0, lon: -97.0}, %{lat: 33.5, lon: -97.0}, %{lat: 34.0, lon: -97.0} ] bbox = %{"south" => 32.5, "north" => 34.5, "west" => -98.0, "east" => -96.0} # Road runs east-west at lat=33.0 fetch = fn _bbox -> {:ok, [{{33.0, -98.0}, {33.0, -96.0}}]} end {:ok, distances} = RoadProximity.road_distances(cells, bbox, fetch: fetch) # Cell at lat=33.0 is ON the road, lat=33.5 is ~55 km north, lat=34.0 is ~111 km north assert distances[{33.0, -97.0}] < distances[{33.5, -97.0}] assert distances[{33.5, -97.0}] < distances[{34.0, -97.0}] end test "segments_from_elements excludes non-way or short geometry" do # Tested implicitly through road_distances with injected fetch. # The internal segments_from_elements/1 is exercised by: # road_distances -> fetch -> {:ok, segments} # where segments are directly provided. {:ok, distances} = RoadProximity.road_distances( [%{lat: 33.0, lon: -97.0}], %{"west" => -100, "east" => -95, "south" => 32, "north" => 35}, fetch: fn _ -> {:ok, [{{33.0, -98.0}, {33.0, -96.0}}]} end ) assert map_size(distances) == 1 end end end