Move base IRI coercion from PrefixMap into new RDF.IRI.coerce_base/1

- and extend it to also support terms from vocabulary namespaces
This commit is contained in:
Marcel Otto 2019-08-08 22:26:07 +02:00
parent 65374303d4
commit fe49c0e431
5 changed files with 64 additions and 16 deletions

View file

@ -13,6 +13,8 @@ This project adheres to [Semantic Versioning](http://semver.org/) and
option on `RDF.Graph.new` or the the new functions `RDF.Graph.set_base_iri/2`
and `RDF.Graph.clear_base_iri/1`
- `RDF.Graph.clear_metadata/1` which clears the base IRI and the prefixes
- `RDF.IRI.coerce_base/1` which coerces base IRIs; as opposed to `RDF.IRI.new/1`
it also accepts bare `RDF.Vocabulary.Namespace` modules
### Changed
@ -24,6 +26,8 @@ This project adheres to [Semantic Versioning](http://semver.org/) and
- from the `base_iri` field of the given graph
- from the `RDF.default_base_iri` returning the one from the application
configuration
- `RDF.PrefixMap.new` and `RDF.PrefixMap.add` now also terms from
`RDF.Vocabulary.Namespace`s as namespaces
[Compare v0.6.1...HEAD](https://github.com/marcelotto/rdf-ex/compare/v0.6.1...HEAD)

View file

@ -65,6 +65,25 @@ defmodule RDF.IRI do
def new!(%RDF.IRI{} = iri), do: valid!(iri)
@doc """
Coerces an IRI serving as a base IRI.
As opposed to `new/1` this also accepts bare `RDF.Vocabulary.Namespace` modules
and uses the base IRI from their definition.
"""
def coerce_base(base_iri)
def coerce_base(module) when is_atom(module) do
if RDF.Vocabulary.Namespace.vocabulary_namespace?(module) do
apply(module, :__base_iri__, [])
|> new()
else
new(module)
end
end
def coerce_base(base_iri), do: new(base_iri)
@doc """
Returns the given value unchanged if it's a valid IRI, otherwise raises an exception.

View file

@ -33,24 +33,12 @@ defmodule RDF.PrefixMap do
map |> Map.new() |> new()
end
defp normalize({prefix, %IRI{} = namespace}) when is_atom(prefix),
do: {prefix, namespace}
defp normalize({prefix, namespace}) when is_atom(prefix),
do: {prefix, IRI.coerce_base(namespace)}
defp normalize({prefix, namespace}) when is_binary(prefix),
do: normalize({String.to_atom(prefix), namespace})
defp normalize({prefix, namespace}) when is_binary(namespace),
do: normalize({prefix, IRI.new(namespace)})
defp normalize({prefix, namespace}) when is_atom(namespace) do
if RDF.Vocabulary.Namespace.vocabulary_namespace?(namespace) 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)}")

View file

@ -106,6 +106,44 @@ defmodule RDF.IRITest do
end
describe "coerce_base/1" do
test "with a string" do
assert IRI.coerce_base("http://example.com/") == IRI.new("http://example.com/")
end
test "with a RDF.IRI" do
assert IRI.coerce_base(IRI.new("http://example.com/")) == IRI.new("http://example.com/")
end
test "with a URI" do
assert IRI.coerce_base(URI.parse("http://example.com/")) ==
IRI.new(URI.parse("http://example.com/"))
end
test "with a resolvable atom" do
assert IRI.coerce_base(EX.Foo) == IRI.new(EX.Foo)
end
test "with a non-resolvable atom" do
assert_raise RDF.Namespace.UndefinedTermError, fn -> IRI.coerce_base(Foo.Bar) end
end
test "with Elixirs special atoms" do
assert_raise FunctionClauseError, fn -> IRI.coerce_base(true) end
assert_raise FunctionClauseError, fn -> IRI.coerce_base(false) end
assert_raise FunctionClauseError, fn -> IRI.coerce_base(nil) end
end
test "with a RDF.Vocabulary.Namespace module" do
assert IRI.coerce_base(EX) == IRI.new(EX.__base_iri__)
end
test "with a RDF.Vocabulary.Namespace module which is not loaded yet" do
assert IRI.coerce_base(RDF.NS.SKOS) == ~I<http://www.w3.org/2004/02/skos/core#>
end
end
describe "valid!/1" do
test "with valid iris" do
Enum.each(valid_iris(), fn valid_iri ->
@ -277,7 +315,6 @@ defmodule RDF.IRITest do
end
end
describe "parse/1" do
test "with absolute and relative iris" do
Enum.each(absolute_iris() ++ relative_iris(), fn iri ->

View file

@ -80,7 +80,7 @@ defmodule RDF.PrefixMapTest do
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 ->
assert_raise RDF.Namespace.UndefinedTermError, "foo is not a term on a RDF.Namespace", fn ->
PrefixMap.add(@example1, :ex, :foo)
end
end