From 72d1f411368cbf732c3e8286a4781c313234fa5f Mon Sep 17 00:00:00 2001 From: Ivan Habunek Date: Sun, 20 Sep 2020 21:11:36 +0200 Subject: [PATCH] Add route master validation --- lib/triglav/zet/validator.ex | 60 +++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 8 deletions(-) diff --git a/lib/triglav/zet/validator.ex b/lib/triglav/zet/validator.ex index a8858ae..02eeb57 100644 --- a/lib/triglav/zet/validator.ex +++ b/lib/triglav/zet/validator.ex @@ -23,13 +23,13 @@ defmodule Triglav.Zet.Validator do end @spec validate_route(Route.t(), [Relation.t()]) :: [error] - def validate_route(_route, relations) do + def validate_route(route, relations) do [ validate_has_route_master(relations), validate_has_relations(relations), validate_routes_are_contained_in_route_master(relations), validate_routes_master_route_has_no_unknown_members(relations), - Enum.map(relations, &validate_route_master_naming/1), + Enum.map(relations, &validate_route_master(route, &1)), Enum.map(relations, &validate_route_naming/1) ] |> List.flatten() @@ -89,20 +89,64 @@ defmodule Triglav.Zet.Validator do end end - defp validate_route_master_naming(%Relation{} = rel) do - if is_route_master(rel) and has_tags(rel, ["name", "ref", "route_master"]) do - name = get_tag(rel, "name") - ref = get_tag(rel, "ref") - type = get_tag(rel, "route_master") + defp validate_route_master(%Route{} = route, %Relation{type: "route_master"} = rel) do + [ + validate_route_master_naming(rel), + validate_route_master_required_tags(rel), + validate_route_master_allowed_tags(rel), + validate_route_master_tag(route, rel) + ] + end + + defp validate_route_master(_, _), do: nil + + defp validate_route_master_naming(relation) do + if has_tags(relation, ["name", "ref", "route_master"]) do + name = get_tag(relation, "name") + ref = get_tag(relation, "ref") + type = get_tag(relation, "route_master") expected = "#{String.capitalize(type)} #{ref}" if name != expected do - {rel, "Expected name: '#{expected}', actual name: '#{name}'"} + {relation, "Expected name: '#{expected}', actual name: '#{name}'"} end end end + defp validate_route_master_required_tags(relation) do + required_tags = MapSet.new(["type", "route_master", "ref", "name", "operator"]) + existing_tags = MapSet.new(Map.keys(relation.tags)) + missing_tags = MapSet.difference(required_tags, existing_tags) + + if MapSet.size(missing_tags) > 0 do + {relation, "Missing required tags: #{Enum.join(missing_tags, ", ")}"} + end + end + + defp validate_route_master_allowed_tags(relation) do + allowed_tags = MapSet.new(["type", "route_master", "ref", "name", "operator", "network"]) + existing_tags = MapSet.new(Map.keys(relation.tags)) + unknown_tags = MapSet.difference(existing_tags, allowed_tags) + + if MapSet.size(unknown_tags) > 0 do + {relation, "Unknown tags: #{Enum.join(unknown_tags, ", ")}"} + end + end + + # Relations [type=route_master] must have [route_master=bus] or [route_master=tram]. + defp validate_route_master_tag(route, relation) do + actual = get_tag(relation, "route_master") + expected = case route.type do + 0 -> "tram" + 3 -> "bus" + end + + if !is_nil(actual) and actual != expected do + {relation, "Invalid tag: [route_master=#{actual}], expected: [route_master=#{expected}]"} + end + end + defp validate_route_naming(%Relation{} = rel) do if is_route(rel) and has_tags(rel, ["name", "ref", "route", "from", "to"]) do name = get_tag(rel, "name") -- 2.34.2