terms in a vocabulary namespace can be ignored

This commit is contained in:
Marcel Otto 2017-06-21 23:28:23 +02:00
parent 1ce89e7ad4
commit 02202b49a7
2 changed files with 176 additions and 3 deletions

View file

@ -39,9 +39,11 @@ defmodule RDF.Vocabulary.Namespace do
IO.puts("Compiling vocabulary namespace for #{base_uri} may take some time")
end
ignored_terms = ignored_terms!(opts)
terms =
terms
|> term_mapping!(opts)
|> Map.drop(MapSet.to_list(ignored_terms))
|> validate_terms!(opts)
|> validate_case!(data, base_uri, opts)
case_separated_terms = group_terms_by_case(terms)
@ -68,6 +70,8 @@ defmodule RDF.Vocabulary.Namespace do
@terms unquote(Macro.escape(terms))
def __terms__, do: @terms |> Map.keys
@ignored_terms unquote(Macro.escape(ignored_terms))
@doc """
Returns all known URIs of the vocabulary.
"""
@ -85,7 +89,8 @@ defmodule RDF.Vocabulary.Namespace do
def __resolve_term__(term) do
case @terms[term] do
nil ->
if @strict do
# TODO: Why does this MapSet.member? call produce a warning? It does NOT always yield the same result!
if @strict or MapSet.member?(@ignored_terms, term) do
raise RDF.Namespace.UndefinedTermError,
"undefined term #{term} in strict vocabulary #{__MODULE__}"
else
@ -100,11 +105,19 @@ defmodule RDF.Vocabulary.Namespace do
if not @strict do
def unquote(:"$handle_undefined_function")(term, []) do
term_to_uri(@base_uri, term)
if MapSet.member?(@ignored_terms, term) do
raise UndefinedFunctionError
else
term_to_uri(@base_uri, term)
end
end
def unquote(:"$handle_undefined_function")(term, [subject | objects]) do
RDF.Description.new(subject, term_to_uri(@base_uri, term), objects)
if MapSet.member?(@ignored_terms, term) do
raise UndefinedFunctionError
else
RDF.Description.new(subject, term_to_uri(@base_uri, term), objects)
end
end
end
end
@ -417,6 +430,20 @@ defmodule RDF.Vocabulary.Namespace do
end
defp ignored_terms!(opts) do
# TODO: find an alternative to Code.eval_quoted - We want to support that the terms can be given as sigils ...
with terms = Keyword.get(opts, :ignore, []) do
{terms, _ } = Code.eval_quoted(terms, [], rdf_data_env())
terms
|> Enum.map(fn
term when is_atom(term) -> term
term when is_binary(term) -> String.to_atom(term)
term -> raise RDF.Namespace.InvalidTermError, inspect(term)
end)
|> MapSet.new
end
end
defp filename!(opts) do
if filename = Keyword.get(opts, :file) do
cond do

View file

@ -340,6 +340,152 @@ defmodule RDF.Vocabulary.NamespaceTest do
end
describe "defvocab ignore terms" do
defmodule NSWithIgnoredTerms do
use RDF.Vocabulary.Namespace
defvocab ExampleIgnoredLowercasedTerm,
base_uri: "http://example.com/",
data: RDF.Graph.new([
{~I<http://example.com/foo>, ~I<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>, ~I<http://www.w3.org/1999/02/22-rdf-syntax-ns#Property>},
{~I<http://example.com/Bar>, ~I<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>, ~I<http://www.w3.org/2000/01/rdf-schema#Resource>}
]),
ignore: ["foo"]
defvocab ExampleIgnoredCapitalizedTerm,
base_uri: "http://example.com/",
data: RDF.Dataset.new([
{~I<http://example.com/foo>, ~I<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>, ~I<http://www.w3.org/1999/02/22-rdf-syntax-ns#Property>},
{~I<http://example.com/Bar>, ~I<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>, ~I<http://www.w3.org/2000/01/rdf-schema#Resource>, ~I<http://example.com/from_dataset#Graph>}
]),
ignore: ~w[Bar]
defvocab ExampleIgnoredLowercasedTermWithAlias,
base_uri: "http://example.com/",
terms: ~w[foo Bar],
alias: [Foo: "foo"],
ignore: ~w[foo]a
defvocab ExampleIgnoredCapitalizedTermWithAlias,
base_uri: "http://example.com/",
terms: ~w[foo Bar],
alias: [bar: "Bar"],
ignore: ~w[Bar]a
defvocab ExampleIgnoredLowercasedAlias,
base_uri: "http://example.com/",
terms: ~w[foo Bar],
alias: [bar: "Bar"],
ignore: ~w[bar]a
defvocab ExampleIgnoredCapitalizedAlias,
base_uri: "http://example.com/",
terms: ~w[foo Bar],
alias: [Foo: "foo"],
ignore: ~w[Foo]a
defvocab ExampleIgnoredNonStrictLowercasedTerm,
base_uri: "http://example.com/",
terms: ~w[],
strict: false,
ignore: ~w[foo]a
defvocab ExampleIgnoredNonStrictCapitalizedTerm,
base_uri: "http://example.com/",
terms: ~w[],
strict: false,
ignore: ~w[Bar]a
end
test "resolution of ignored lowercased term on a strict vocab fails" do
alias NSWithIgnoredTerms.ExampleIgnoredLowercasedTerm
assert ExampleIgnoredLowercasedTerm.__terms__ == [:Bar]
assert_raise UndefinedFunctionError, fn -> ExampleIgnoredLowercasedTerm.foo end
end
test "resolution of ignored capitalized term on a strict vocab fails" do
alias NSWithIgnoredTerms.ExampleIgnoredCapitalizedTerm
assert ExampleIgnoredCapitalizedTerm.__terms__ == [:foo]
assert_raise RDF.Namespace.UndefinedTermError, fn ->
RDF.uri(ExampleIgnoredCapitalizedTerm.Bar)
end
end
test "resolution of ignored lowercased term with alias on a strict vocab fails" do
alias NSWithIgnoredTerms.ExampleIgnoredLowercasedTermWithAlias
assert ExampleIgnoredLowercasedTermWithAlias.__terms__ == [:Bar, :Foo]
assert_raise UndefinedFunctionError, fn -> ExampleIgnoredLowercasedTermWithAlias.foo end
assert RDF.uri(ExampleIgnoredLowercasedTermWithAlias.Foo) == ~I<http://example.com/foo>
end
test "resolution of ignored capitalized term with alias on a strict vocab fails" do
alias NSWithIgnoredTerms.ExampleIgnoredCapitalizedTermWithAlias
assert ExampleIgnoredCapitalizedTermWithAlias.__terms__ == [:bar, :foo]
assert_raise RDF.Namespace.UndefinedTermError, fn ->
RDF.uri(ExampleIgnoredCapitalizedTermWithAlias.Bar)
end
assert RDF.uri(ExampleIgnoredCapitalizedTermWithAlias.bar) == ~I<http://example.com/Bar>
end
test "resolution of ignored lowercased alias on a strict vocab fails" do
alias NSWithIgnoredTerms.ExampleIgnoredLowercasedAlias
assert ExampleIgnoredLowercasedAlias.__terms__ == [:Bar, :foo]
assert RDF.uri(ExampleIgnoredLowercasedAlias.Bar) == ~I<http://example.com/Bar>
assert_raise UndefinedFunctionError, fn ->
RDF.uri(ExampleIgnoredLowercasedAlias.bar)
end
end
test "resolution of ignored capitalized alias on a strict vocab fails" do
alias NSWithIgnoredTerms.ExampleIgnoredCapitalizedAlias
assert ExampleIgnoredCapitalizedAlias.__terms__ == [:Bar, :foo]
assert RDF.uri(ExampleIgnoredCapitalizedAlias.foo) == ~I<http://example.com/foo>
assert_raise RDF.Namespace.UndefinedTermError, fn ->
RDF.uri(ExampleIgnoredCapitalizedAlias.Foo)
end
end
test "resolution of ignored lowercased term on a non-strict vocab fails" do
alias NSWithIgnoredTerms.ExampleIgnoredNonStrictLowercasedTerm
assert_raise UndefinedFunctionError, fn ->
ExampleIgnoredNonStrictLowercasedTerm.foo
end
end
test "resolution of ignored capitalized term on a non-strict vocab fails" do
alias NSWithIgnoredTerms.ExampleIgnoredNonStrictCapitalizedTerm
assert_raise RDF.Namespace.UndefinedTermError, fn ->
RDF.uri(ExampleIgnoredNonStrictCapitalizedTerm.Bar)
end
end
test "ignored terms with invalid characters do not raise anything" do
defmodule IgnoredTermWithInvalidCharacters do
use RDF.Vocabulary.Namespace
defvocab Example,
base_uri: "http://example.com/",
terms: ~w[foo-bar],
ignore: ~w[foo-bar]a
end
end
test "ignored terms with case violations do not raise anything" do
defmodule IgnoredTermWithInvalidCharacters do
use RDF.Vocabulary.Namespace
defvocab Example,
base_uri: "http://example.com/",
data: RDF.Dataset.new([
{~I<http://example.com/Foo>, ~I<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>, ~I<http://www.w3.org/1999/02/22-rdf-syntax-ns#Property>},
{~I<http://example.com/bar>, ~I<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>, ~I<http://www.w3.org/2000/01/rdf-schema#Resource>, ~I<http://example.com/from_dataset#Graph>}
]),
case_violations: :fail,
ignore: ~w[Foo bar]a
end
end
end
test "__base_uri__ returns the base_uri" do
alias TestNS.ExampleFromGraph, as: HashVocab
alias TestNS.ExampleFromNTriplesFile, as: SlashVocab