aprs.me/test/parser/position_test.exs

81 lines
2.9 KiB
Elixir

defmodule Parser.PositionTest do
use ExUnit.Case, async: true
use ExUnitProperties
alias Parser.Position
alias Parser.Types.Position, as: PositionStruct
describe "parse/1" do
test "returns a Position struct for valid input" do
result = Position.parse("4903.50N/07201.75W>Test position")
assert %PositionStruct{} = result
assert result.symbol_table_id == "/"
assert result.symbol_code == ">"
assert result.comment == "Test position"
end
test "returns nil or struct with nil lat/lon for invalid input" do
for input <- ["", "invalidstring", "12345678N/123456789W"] do
result = Position.parse(input)
assert result == nil or match?(%PositionStruct{latitude: nil, longitude: nil}, result)
end
end
end
property "returns nil or struct with nil lat/lon for random invalid strings" do
check all s <- StreamData.string(:ascii, min_length: 1, max_length: 30),
not String.match?(s, ~r/^\d{4}\.\d{2}[NS][\/\\]\d{5}\.\d{2}[EW].+/) do
result = Position.parse(s)
assert result == nil or match?(%PositionStruct{latitude: nil, longitude: nil}, result)
end
end
describe "parse_aprs_position/2" do
test "parses valid APRS lat/lon strings" do
result = Position.parse_aprs_position("4903.50N", "07201.75W")
if result.latitude == nil or result.longitude == nil do
flunk("parse_aprs_position/2 returned nil for latitude or longitude")
end
assert Decimal.equal?(Decimal.round(result.latitude, 6), Decimal.new("49.058333"))
assert Decimal.equal?(Decimal.round(result.longitude, 6), Decimal.new("-72.029167"))
end
test "returns nils for invalid strings" do
assert %{latitude: nil, longitude: nil} = Position.parse_aprs_position("bad", "data")
end
end
describe "calculate_position_ambiguity/2" do
test "returns correct ambiguity for no spaces" do
assert Position.calculate_position_ambiguity("4903.50N", "07201.75W") == 0
end
test "returns correct ambiguity for one space in each string" do
assert Position.calculate_position_ambiguity("49 3.50N", "07201.7 W") == 1
end
test "returns correct ambiguity for two spaces in each string" do
assert Position.calculate_position_ambiguity("4 3.50N", "0720 .7W") == 2
end
end
describe "count_spaces/1" do
property "counts spaces correctly" do
check all s <- StreamData.string(:ascii, min_length: 0, max_length: 20) do
assert Position.count_spaces(s) == s |> String.graphemes() |> Enum.count(&(&1 == " "))
end
end
end
describe "parse_dao_extension/1" do
test "parses valid DAO extension" do
assert %{lat_dao: "A", lon_dao: "B", datum: "WGS84"} = Position.parse_dao_extension("!ABZ!")
end
test "returns nil for no DAO extension" do
assert Position.parse_dao_extension("no dao here") == nil
end
end
end