From a86e90b034078b870b44333bb2982c395e114c9c Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Tue, 31 Jan 2023 15:32:13 -0600 Subject: [PATCH] more tests for the parser --- .formatter.exs | 2 +- lib/parser.ex | 3 +- mix.exs | 4 +- mix.lock | 2 + test/parser/parser_test.exs | 94 +++++++++++++++++++++++++++++++++++-- 5 files changed, 97 insertions(+), 8 deletions(-) diff --git a/.formatter.exs b/.formatter.exs index ef8840c..011a477 100644 --- a/.formatter.exs +++ b/.formatter.exs @@ -1,5 +1,5 @@ [ - import_deps: [:ecto, :ecto_sql, :phoenix], + import_deps: [:ecto, :ecto_sql, :phoenix, :stream_data], subdirectories: ["priv/*/migrations"], plugins: [Phoenix.LiveView.HTMLFormatter], inputs: ["*.{heex,ex,exs}", "{config,lib,test}/**/*.{heex,ex,exs}", "priv/*/seeds.exs"] diff --git a/lib/parser.ex b/lib/parser.ex index d075ec0..7f1ff67 100644 --- a/lib/parser.ex +++ b/lib/parser.ex @@ -39,7 +39,7 @@ defmodule Parser do # {:ok, file} = File.open("/home/graham/badpackets.txt", [:append]) # IO.binwrite(file, message <> "\n\n") # File.close(file) - {:error, "PARSE ERROR"} + {:error, :invalid_packet} end end @@ -275,6 +275,7 @@ defmodule Parser do end def parse_mic_e(destination_field, information_field) do + # Logger.debug("MIC-E: " <> destination_field <> " :: " <> information_field) # Mic-E is kind of a nutty compression scheme, APRS packs additional # information into the destination field when Mic-E encoding is used. # No other aprs packets use the destination field this way as far as i know. diff --git a/mix.exs b/mix.exs index 7ff20a7..de70d3f 100644 --- a/mix.exs +++ b/mix.exs @@ -65,11 +65,13 @@ defmodule Aprs.MixProject do {:telemetry_poller, "~> 1.0"}, {:esbuild, "~> 0.5", runtime: Mix.env() == :dev}, {:tailwind, "~> 0.1.8", runtime: Mix.env() == :dev}, - {:credo, "~> 1.6.2", only: [:dev, :test], runtime: false}, {:dialyxir, "~> 1.0", only: :dev, runtime: false}, {:excoveralls, "~> 0.15.3", only: :test, runtime: false}, {:exvcr, "~> 0.13.4", only: :test}, {:floki, ">= 0.30.0", only: :test}, + {:credo, "~> 1.6.2", only: [:dev, :test], runtime: false}, + {:faker, "~> 0.17.0", only: [:dev, :test]}, + {:stream_data, "~> 0.5", only: [:dev, :test]}, {:mix_test_watch, "~> 1.1", only: [:dev, :test]}, {:sobelow, "~> 0.8", only: :dev} ] diff --git a/mix.lock b/mix.lock index 5246f24..abf16a7 100644 --- a/mix.lock +++ b/mix.lock @@ -23,6 +23,7 @@ "exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm", "32e95820a97cffea67830e91514a2ad53b888850442d6d395f53a1ac60c82e07"}, "expo": {:hex, :expo, "0.3.0", "13127c1d5f653b2927f2616a4c9ace5ae372efd67c7c2693b87fd0fdc30c6feb", [:mix], [], "hexpm", "fb3cd4bf012a77bc1608915497dae2ff684a06f0fa633c7afa90c4d72b881823"}, "exvcr": {:hex, :exvcr, "0.13.4", "68efca5ae04a909b29a9e137338a7033642898033c7a938a5faec545bfc5a38e", [:mix], [{:exactor, "~> 2.2", [hex: :exactor, repo: "hexpm", optional: false]}, {:exjsx, "~> 4.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:finch, "~> 0.8", [hex: :finch, repo: "hexpm", optional: true]}, {:httpoison, "~> 1.0", [hex: :httpoison, repo: "hexpm", optional: true]}, {:httpotion, "~> 3.1", [hex: :httpotion, repo: "hexpm", optional: true]}, {:ibrowse, "4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:meck, "~> 0.8", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "42920a59bdeef34001f8c2305a57d68b29d8a2e7aa1877bb35a75034b9f9904a"}, + "faker": {:hex, :faker, "0.17.0", "671019d0652f63aefd8723b72167ecdb284baf7d47ad3a82a15e9b8a6df5d1fa", [:mix], [], "hexpm", "a7d4ad84a93fd25c5f5303510753789fc2433ff241bf3b4144d3f6f291658a6a"}, "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"}, "finch": {:hex, :finch, "0.14.0", "619bfdee18fc135190bf590356c4bf5d5f71f916adb12aec94caa3fa9267a4bc", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: false]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.6", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "5459acaf18c4fdb47a8c22fb3baff5d8173106217c8e56c5ba0b93e66501a8dd"}, "floki": {:hex, :floki, "0.34.0", "002d0cc194b48794d74711731db004fafeb328fe676976f160685262d43706a8", [:mix], [], "hexpm", "9c3a9f43f40dde00332a589bd9d389b90c1f518aef500364d00636acc5ebc99c"}, @@ -62,6 +63,7 @@ "ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"}, "sobelow": {:hex, :sobelow, "0.11.1", "23438964486f8112b41e743bbfd402da3e5b296fdc9eacab29914b79c48916dd", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "9897363a7eff96f4809304a90aad819e2ad5e5d24db547af502885146746a53c"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"}, + "stream_data": {:hex, :stream_data, "0.5.0", "b27641e58941685c75b353577dc602c9d2c12292dd84babf506c2033cd97893e", [:mix], [], "hexpm", "012bd2eec069ada4db3411f9115ccafa38540a3c78c4c0349f151fc761b9e271"}, "swoosh": {:hex, :swoosh, "1.9.1", "0a5d7bf9954eb41d7e55525bc0940379982b090abbaef67cd8e1fd2ed7f8ca1a", [:mix], [{:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:ex_aws, "~> 2.1", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "76dffff3ffcab80f249d5937a592eaef7cc49ac6f4cdd27e622868326ed6371e"}, "tailwind": {:hex, :tailwind, "0.1.9", "25ba09d42f7bfabe170eb67683a76d6ec2061952dc9bd263a52a99ba3d24bd4d", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "9213f87709c458aaec313bb5f2df2b4d2cedc2b630e4ae821bf3c54c47a56d0b"}, "telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"}, diff --git a/test/parser/parser_test.exs b/test/parser/parser_test.exs index 11652e4..b9c79fb 100644 --- a/test/parser/parser_test.exs +++ b/test/parser/parser_test.exs @@ -10,14 +10,11 @@ defmodule Parser.ParserTest do end test "mic_e convert digits" do - sut = Parser.parse_mic_e_digit("0") - assert sut == [0, 0, nil] + assert Parser.parse_mic_e_digit("0") == [0, 0, nil] end test "mic_e convert destination field" do - sut = Parser.parse_mic_e_destination("T7SYWP") - - assert sut == %{ + assert Parser.parse_mic_e_destination("T7SYWP") == %{ lat_degrees: 47, lat_minutes: 39, lat_fractional: 70, @@ -59,4 +56,91 @@ defmodule Parser.ParserTest do Parser.parse(aprs_message) end + + describe "parse/1" do + test "with invalid packet" do + assert {:error, :invalid_packet} = Parser.parse("invalid packet") + end + end + + describe "parse_callsign/1" do + test "callsign with ssid" do + assert Parser.parse_callsign("W5ISP-1") == ["W5ISP", "1"] + end + + test "callsign without ssid" do + assert Parser.parse_callsign("W5ISP") == ["W5ISP", nil] + end + end + + describe "parse_datatype/1" do + test "position" do + %{ + ":" => :message, + ">" => :status, + "!" => :position, + "/" => :timestamped_position, + "=" => :position_with_message, + "@" => :timestamped_position_with_message, + ";" => :object, + "`" => :mic_e, + "'" => :mic_e_old, + "_" => :weather, + "T" => :telemetry, + "$" => :raw_gps_ultimeter, + "<" => :station_capabilities, + "?" => :query, + "{" => :user_defined, + "}" => :third_party_traffic, + "" => :unknown_datatype + } + |> Enum.each(fn {key, value} -> + assert Parser.parse_datatype(key) == value + end) + end + end + + describe "parse_manufacturer/3" do + test "with any manufacturer" do + [ + %{matcher: [" ", nil, nil], result: "Original MIC-E"}, + %{matcher: [">", nil, "="], result: "Kenwood TH-D72"}, + %{matcher: [">", nil, "^"], result: "Kenwood TH-D74"}, + %{matcher: [">", nil, nil], result: "Kenwood TH-D74A"}, + %{matcher: ["]", nil, "="], result: "Kenwood DM-710"}, + %{matcher: ["]", nil, nil], result: "Kenwood DM-700"}, + %{matcher: ["`", "_", " "], result: "Yaesu VX-8"}, + %{matcher: ["`", "_", "\""], result: "Yaesu FTM-350"}, + %{matcher: ["`", "_", "#"], result: "Yaesu VX-8G"}, + %{matcher: ["`", "_", "$"], result: "Yaesu FT1D"}, + %{matcher: ["`", "_", "%"], result: "Yaesu FTM-400DR"}, + %{matcher: ["`", "_", ")"], result: "Yaesu FTM-100D"}, + %{matcher: ["`", "_", "("], result: "Yaesu FT2D"}, + %{matcher: ["`", " ", "X"], result: "AP510"}, + %{matcher: ["`", nil, nil], result: "Mic-Emsg"}, + %{matcher: ["'", "|", "3"], result: "Byonics TinyTrack3"}, + %{matcher: ["'", "|", "4"], result: "Byonics TinyTrack4"}, + %{matcher: ["'", ":", "4"], result: "SCS GmbH & Co. P4dragon DR-7400 modems"}, + %{matcher: ["'", ":", "8"], result: "SCS GmbH & Co. P4dragon DR-7800 modems"}, + %{matcher: ["'", nil, nil], result: "McTrackr"}, + %{matcher: [nil, "\"", nil], result: "Hamhud ?"}, + %{matcher: [nil, "/", nil], result: "Argent ?"}, + %{matcher: [nil, "^", nil], result: "HinzTec anyfrog"}, + %{matcher: [nil, "*", nil], result: "APOZxx www.KissOZ.dk Tracker. OZ1EKD and OZ7HVO"}, + %{matcher: [nil, "~", nil], result: "Other"}, + %{matcher: [nil, nil, nil], result: :unknown_manufacturer} + ] + |> Enum.each(fn %{matcher: [s1, s2, s3], result: result} -> + assert Parser.parse_manufacturer(s1, s2, s3) == result + end) + end + end + + describe "parse_mic_e/2" do + test "with valid mic-e" do + # `|J!l4^\k/]"6?}= + mic_e_position = <<96, 124, 74, 33, 108, 52, 94, 107, 47, 93, 34, 54, 63, 125, 61>> + assert %Parser.Types.MicE{} = Parser.parse_mic_e("SS0Y1S", mic_e_position) + end + end end