core: Description DSL

This commit is contained in:
Marcel Otto 2017-05-25 13:34:42 +02:00
parent 9105ef3a49
commit 88d260ac1e
2 changed files with 126 additions and 2 deletions

View file

@ -99,9 +99,18 @@ defmodule RDF.Vocabulary.Namespace do
term_to_uri(@base_uri, term)
end
def unquote(:"$handle_undefined_function")(term, args) do
def unquote(:"$handle_undefined_function")(term, []) do
term_to_uri(@base_uri, term)
end
def unquote(:"$handle_undefined_function")(term,
[%RDF.Description{} = description | objects]) do
RDF.Description.add(description, term_to_uri(@base_uri, term), objects)
end
def unquote(:"$handle_undefined_function")(term, [subject | objects]) do
RDF.Description.new(subject, term_to_uri(@base_uri, term), objects)
end
end
Module.delete_attribute(__MODULE__, :tmp_uri)
@ -170,6 +179,7 @@ defmodule RDF.Vocabulary.Namespace do
defmacro define_vocab_terms(terms, base_uri) do
Enum.map terms, fn term ->
name = String.to_atom(term)
# TODO: Why does this way of precompiling the URI not work? We're getting an "invalid quoted expression: %URI{...}"
# uri = term_to_uri(base_uri, term)
# quote bind_quoted: [uri: Macro.escape(uri), term: String.to_atom(term)] do
@ -182,7 +192,27 @@ defmodule RDF.Vocabulary.Namespace do
quote do
@tmp_uri term_to_uri(@base_uri, unquote(term))
@doc "<#{@tmp_uri}>"
def unquote(term |> String.to_atom)(), do: @tmp_uri
def unquote(name)(), do: @tmp_uri
@doc "`RDF.Description` builder for <#{@tmp_uri}>"
def unquote(name)(subject, object)
def unquote(name)(%RDF.Description{} = description, object) do
RDF.Description.add(description, @tmp_uri, object)
end
def unquote(name)(subject, object) do
RDF.Description.new(subject, @tmp_uri, object)
end
def unquote(name)(subject, o1, o2),
do: unquote(name)(subject, [o1, o2])
def unquote(name)(subject, o1, o2, o3),
do: unquote(name)(subject, [o1, o2, o3])
def unquote(name)(subject, o1, o2, o3, o4),
do: unquote(name)(subject, [o1, o2, o3, o4])
def unquote(name)(subject, o1, o2, o3, o4, o5),
do: unquote(name)(subject, [o1, o2, o3, o4, o5])
end
end
end

View file

@ -3,9 +3,20 @@ defmodule RDF.Vocabulary.NamespaceTest do
doctest RDF.Vocabulary.Namespace
alias RDF.Description
defmodule TestNS do
use RDF.Vocabulary.Namespace
defvocab EX,
base_uri: "http://example.com/",
terms: ~w[], strict: false
defvocab EXS,
base_uri: "http://example.com/strict#",
terms: ~w[foo bar]
defvocab Example1,
base_uri: "http://example.com/example1#",
data: RDF.Graph.new([
@ -168,4 +179,87 @@ defmodule RDF.Vocabulary.NamespaceTest do
end
end
describe "Description DSL" do
alias TestNS.{EX, EXS}
test "one statement with a strict property term" do
assert EXS.foo(EX.S, EX.O) == Description.new(EX.S, EXS.foo, EX.O)
end
test "multiple statements with strict property terms and one object" do
description =
EX.S
|> EXS.foo(EX.O1)
|> EXS.bar(EX.O2)
assert description == Description.new(EX.S, [{EXS.foo, EX.O1}, {EXS.bar, EX.O2}])
end
test "multiple statements with strict property terms and multiple objects in a list" do
description =
EX.S
|> EXS.foo([EX.O1, EX.O2])
|> EXS.bar([EX.O3, EX.O4])
assert description == Description.new(EX.S, [
{EXS.foo, EX.O1},
{EXS.foo, EX.O2},
{EXS.bar, EX.O3},
{EXS.bar, EX.O4}
])
end
test "multiple statements with strict property terms and multiple objects as arguments" do
description =
EX.S
|> EXS.foo(EX.O1, EX.O2)
|> EXS.bar(EX.O3, EX.O4, EX.O5)
assert description == Description.new(EX.S, [
{EXS.foo, EX.O1},
{EXS.foo, EX.O2},
{EXS.bar, EX.O3},
{EXS.bar, EX.O4},
{EXS.bar, EX.O5}
])
end
test "one statement with a non-strict property term" do
assert EX.p(EX.S, EX.O) == Description.new(EX.S, EX.p, EX.O)
end
test "multiple statements with non-strict property terms and one object" do
description =
EX.S
|> EX.p1(EX.O1)
|> EX.p2(EX.O2)
assert description == Description.new(EX.S, [{EX.p1, EX.O1}, {EX.p2, EX.O2}])
end
test "multiple statements with non-strict property terms and multiple objects in a list" do
description =
EX.S
|> EX.p1([EX.O1, EX.O2])
|> EX.p2([EX.O3, EX.O4])
assert description == Description.new(EX.S, [
{EX.p1, EX.O1},
{EX.p1, EX.O2},
{EX.p2, EX.O3},
{EX.p2, EX.O4}
])
end
test "multiple statements with non-strict property terms and multiple objects as arguments" do
description =
EX.S
|> EX.p1(EX.O1, EX.O2)
|> EX.p2(EX.O3, EX.O4)
assert description == Description.new(EX.S, [
{EX.p1, EX.O1},
{EX.p1, EX.O2},
{EX.p2, EX.O3},
{EX.p2, EX.O4}
])
end
end
end