diff --git a/lib/rdf/prefix_map.ex b/lib/rdf/prefix_map.ex index c8b7f2e..b672583 100644 --- a/lib/rdf/prefix_map.ex +++ b/lib/rdf/prefix_map.ex @@ -38,10 +38,20 @@ defmodule RDF.PrefixMap do do: normalize({String.to_atom(prefix), namespace}) defp normalize({prefix, namespace}) when is_binary(namespace), - do: normalize({prefix, IRI.new(namespace)}) + do: normalize({prefix, IRI.new(namespace)}) - defp normalize({prefix, _}), - do: raise("Invalid prefix on PrefixMap: #{inspect(prefix)}}") + defp normalize({prefix, namespace}) when is_atom(namespace) do + if function_exported?(namespace, :__base_iri__, 0) do + normalize({prefix, apply(namespace, :__base_iri__, [])}) + else + raise ArgumentError, + "Invalid prefix mapping for #{inspect(prefix)}, #{inspect(namespace)} is not a vocabulary namespace" + end + end + + defp normalize({prefix, namespace}), + do: + raise(ArgumentError, "Invalid prefix mapping: #{inspect(prefix)} => #{inspect(namespace)}") @doc """ Adds a prefix mapping the given `RDF.PrefixMap`. @@ -92,7 +102,8 @@ defmodule RDF.PrefixMap do {:ok, %__MODULE__{map: Map.merge(map1, map2)}} else conflicts -> - {:error, "conflicting prefix mappings: #{conflicts |> Stream.map(&inspect/1) |> Enum.join(", ")}"} + {:error, + "conflicting prefix mappings: #{conflicts |> Stream.map(&inspect/1) |> Enum.join(", ")}"} end end diff --git a/test/unit/prefix_map_test.exs b/test/unit/prefix_map_test.exs index 872cab0..0b67dcf 100644 --- a/test/unit/prefix_map_test.exs +++ b/test/unit/prefix_map_test.exs @@ -20,6 +20,11 @@ defmodule RDF.PrefixMapTest do ex3: @ex_ns3 }} + @example4 %PrefixMap{map: %{ + ex1: @ex_ns1, + ex: RDF.iri(EX.__base_iri__) + }} + test "new/0" do assert PrefixMap.new() == %PrefixMap{} end @@ -38,6 +43,13 @@ defmodule RDF.PrefixMapTest do ex2: "http://example.com/bar#" ) == @example2 end + + test "when the IRI namespace is given as a RDF.Vocabulary.Namespace" do + assert PrefixMap.new( + ex1: "http://example.com/foo/", + ex: EX + ) == @example4 + end end describe "add/3" do @@ -45,14 +57,24 @@ defmodule RDF.PrefixMapTest do assert PrefixMap.add(@example1, :ex2, @ex_ns2) == {:ok, @example2} end - test "with the prefix is given as a string" do + test "when the prefix is given as a string" do assert PrefixMap.add(@example1, "ex2", @ex_ns2) == {:ok, @example2} end - test "with the IRI namespace is given as a string" do + test "when the IRI namespace is given as a string" do assert PrefixMap.add(@example1, :ex2, "http://example.com/bar#") == {:ok, @example2} end + test "when the IRI namespace is given as a RDF.Vocabulary.Namespace" do + assert PrefixMap.add(@example1, :ex, EX) == {:ok, @example4} + end + + test "when the IRI namespace is given as an atom" do + assert_raise ArgumentError, "Invalid prefix mapping for :ex, :foo is not a vocabulary namespace", fn -> + PrefixMap.add(@example1, :ex, :foo) + end + end + test "when a mapping of the given prefix to the same namespace already exists" do assert PrefixMap.add(@example2, :ex2, "http://example.com/bar#") == {:ok, @example2} end