rdf-ex/test/unit/query/builder_test.exs

252 lines
7.7 KiB
Elixir
Raw Normal View History

2020-06-11 22:19:31 +00:00
defmodule RDF.Query.BuilderTest do
2020-06-12 01:23:20 +00:00
use RDF.Query.Test.Case
2020-06-09 23:13:01 +00:00
2020-06-12 01:23:20 +00:00
alias RDF.Query.Builder
2020-06-09 23:13:01 +00:00
describe "bgp/1" do
2020-06-09 23:13:01 +00:00
test "empty triple pattern" do
2020-06-12 01:23:20 +00:00
assert Builder.bgp([]) == ok_bgp_struct([])
2020-06-09 23:13:01 +00:00
end
test "one triple pattern doesn't require list brackets" do
2020-06-29 08:37:42 +00:00
assert Builder.bgp({EX.s(), EX.p(), EX.o()}) ==
ok_bgp_struct([{EX.s(), EX.p(), EX.o()}])
2020-06-09 23:13:01 +00:00
end
test "variables" do
2020-06-29 08:37:42 +00:00
assert Builder.bgp([{:s?, :p?, :o?}]) == ok_bgp_struct([{:s, :p, :o}])
2020-06-09 23:13:01 +00:00
end
test "blank nodes" do
2020-06-11 22:19:31 +00:00
assert Builder.bgp([{RDF.bnode("s"), RDF.bnode("p"), RDF.bnode("o")}]) ==
2020-06-29 08:37:42 +00:00
ok_bgp_struct([{RDF.bnode("s"), RDF.bnode("p"), RDF.bnode("o")}])
2020-06-09 23:13:01 +00:00
end
test "blank nodes as atoms" do
2020-06-11 22:19:31 +00:00
assert Builder.bgp([{:_s, :_p, :_o}]) ==
2020-06-29 08:37:42 +00:00
ok_bgp_struct([{RDF.bnode("s"), RDF.bnode("p"), RDF.bnode("o")}])
2020-06-09 23:13:01 +00:00
end
test "variable notation has precedence over blank node notation" do
2020-06-29 08:37:42 +00:00
assert Builder.bgp([{:_s?, :_p?, :_o?}]) == ok_bgp_struct([{:_s, :_p, :_o}])
2020-06-09 23:13:01 +00:00
end
test "IRIs" do
2020-06-29 08:37:42 +00:00
assert Builder.bgp([
{
RDF.iri("http://example.com/s"),
RDF.iri("http://example.com/p"),
RDF.iri("http://example.com/o")
}
]) == ok_bgp_struct([{EX.s(), EX.p(), EX.o()}])
2020-06-09 23:13:01 +00:00
2020-06-29 08:37:42 +00:00
assert Builder.bgp([
{
~I<http://example.com/s>,
~I<http://example.com/p>,
~I<http://example.com/o>
}
]) == ok_bgp_struct([{EX.s(), EX.p(), EX.o()}])
2020-06-09 23:13:01 +00:00
2020-06-29 08:37:42 +00:00
assert Builder.bgp([{EX.s(), EX.p(), EX.o()}]) ==
ok_bgp_struct([{EX.s(), EX.p(), EX.o()}])
2020-06-09 23:13:01 +00:00
end
test "vocabulary term atoms" do
2020-06-11 22:19:31 +00:00
assert Builder.bgp([{EX.S, EX.P, EX.O}]) ==
2020-06-29 08:37:42 +00:00
ok_bgp_struct([{RDF.iri(EX.S), RDF.iri(EX.P), RDF.iri(EX.O)}])
2020-06-09 23:13:01 +00:00
end
test "special :a atom for rdf:type" do
2020-06-11 22:19:31 +00:00
assert Builder.bgp([{EX.S, :a, EX.O}]) ==
2020-06-29 08:37:42 +00:00
ok_bgp_struct([{RDF.iri(EX.S), RDF.type(), RDF.iri(EX.O)}])
2020-06-09 23:13:01 +00:00
end
test "URIs" do
2020-06-29 08:37:42 +00:00
assert Builder.bgp([
{
URI.parse("http://example.com/s"),
URI.parse("http://example.com/p"),
URI.parse("http://example.com/o")
}
]) == ok_bgp_struct([{EX.s(), EX.p(), EX.o()}])
2020-06-09 23:13:01 +00:00
end
test "literals" do
2020-06-29 08:37:42 +00:00
assert Builder.bgp([{EX.s(), EX.p(), ~L"foo"}]) ==
ok_bgp_struct([{EX.s(), EX.p(), ~L"foo"}])
2020-06-09 23:13:01 +00:00
end
test "values coercible to literals" do
2020-06-29 08:37:42 +00:00
assert Builder.bgp([{EX.s(), EX.p(), "foo"}]) ==
ok_bgp_struct([{EX.s(), EX.p(), ~L"foo"}])
assert Builder.bgp([{EX.s(), EX.p(), 42}]) ==
ok_bgp_struct([{EX.s(), EX.p(), RDF.literal(42)}])
assert Builder.bgp([{EX.s(), EX.p(), true}]) ==
ok_bgp_struct([{EX.s(), EX.p(), XSD.true()}])
2020-06-09 23:13:01 +00:00
end
test "literals on non-object positions" do
2020-06-29 08:37:42 +00:00
assert {:error, %RDF.Query.InvalidError{}} = Builder.bgp([{~L"foo", EX.p(), ~L"bar"}])
2020-06-09 23:13:01 +00:00
end
test "multiple triple patterns" do
2020-06-11 22:19:31 +00:00
assert Builder.bgp([
2020-06-29 08:37:42 +00:00
{EX.S, EX.p(), :o?},
{:o?, EX.p2(), 42}
2020-06-09 23:13:01 +00:00
]) ==
2020-06-29 08:37:42 +00:00
ok_bgp_struct([
{RDF.iri(EX.S), EX.p(), :o},
{:o, EX.p2(), RDF.literal(42)}
])
2020-06-09 23:13:01 +00:00
end
test "multiple objects to the same subject-predicate" do
result =
ok_bgp_struct([
{EX.s(), EX.p(), EX.o1()},
{EX.s(), EX.p(), EX.o2()}
])
2020-06-29 08:37:42 +00:00
assert Builder.bgp([{EX.s(), EX.p(), [EX.o1(), EX.o2()]}]) == result
assert Builder.bgp({EX.s(), EX.p(), [EX.o1(), EX.o2()]}) == result
2020-06-29 08:37:42 +00:00
assert Builder.bgp({EX.s(), EX.p(), [:o?, false, 42, "foo"]}) ==
2020-06-29 08:37:42 +00:00
ok_bgp_struct([
{EX.s(), EX.p(), :o},
{EX.s(), EX.p(), XSD.false()},
{EX.s(), EX.p(), RDF.literal(42)},
{EX.s(), EX.p(), RDF.literal("foo")}
])
2020-06-09 23:13:01 +00:00
end
test "multiple predicate-object pairs to the same subject" do
result =
ok_bgp_struct([
{EX.s(), EX.p1(), EX.o1()},
{EX.s(), EX.p2(), EX.o2()}
])
2020-06-29 08:37:42 +00:00
assert Builder.bgp([
{
EX.s(),
[
{EX.p1(), EX.o1()},
{EX.p2(), EX.o2()}
]
2020-06-29 08:37:42 +00:00
}
]) == result
2020-06-29 08:37:42 +00:00
assert Builder.bgp([
{
EX.s(),
[
{:a, :o?},
{EX.p1(), [42, 3.14]},
{EX.p2(), ["foo", true]}
]
2020-06-29 08:37:42 +00:00
}
]) ==
ok_bgp_struct([
{EX.s(), RDF.type(), :o},
{EX.s(), EX.p1(), RDF.literal(42)},
{EX.s(), EX.p1(), RDF.literal(3.14)},
{EX.s(), EX.p2(), RDF.literal("foo")},
{EX.s(), EX.p2(), XSD.true()}
])
assert Builder.bgp([{EX.s(), {EX.p(), EX.o()}}]) ==
2020-06-29 08:37:42 +00:00
ok_bgp_struct([{EX.s(), EX.p(), EX.o()}])
2020-06-09 23:13:01 +00:00
end
test "triple patterns with maps" do
assert Builder.bgp(%{
EX.S => {EX.p(), :o?},
o?: [
{EX.p2(), 42},
{EX.p3(), "foo"}
]
}) ==
ok_bgp_struct([
{RDF.iri(EX.S), EX.p(), :o},
{:o, EX.p2(), RDF.literal(42)},
{:o, EX.p3(), RDF.literal("foo")}
])
assert Builder.bgp(%{
EX.s() => %{
:a => :o1?,
:p? => :o2?,
EX.p1() => [42, 3.14],
EX.p2() => ["foo", true]
}
}) ==
ok_bgp_struct([
{EX.s(), RDF.type(), :o1},
{EX.s(), :p, :o2},
{EX.s(), EX.p1(), RDF.literal(42)},
{EX.s(), EX.p1(), RDF.literal(3.14)},
{EX.s(), EX.p2(), RDF.literal("foo")},
{EX.s(), EX.p2(), XSD.true()}
])
assert Builder.bgp([
%{EX.S => {EX.p(), :o?}},
{EX.S2, EX.p(), :o?}
]) ==
ok_bgp_struct([
{RDF.iri(EX.S), EX.p(), :o},
{RDF.iri(EX.S2), EX.p(), :o}
])
end
test "triple patterns with descriptions" do
assert Builder.bgp([
EX.p(~B"s", EX.O),
{:_s, :p?, :o?}
]) ==
ok_bgp_struct([
{~B"s", EX.p(), RDF.iri(EX.O)},
{~B"s", :p, :o}
])
end
2020-06-09 23:13:01 +00:00
end
2020-06-12 00:53:29 +00:00
describe "path/2" do
test "element count == 3" do
2020-06-29 08:37:42 +00:00
assert Builder.path([EX.s(), EX.p(), EX.o()]) == ok_bgp_struct([{EX.s(), EX.p(), EX.o()}])
assert Builder.path([:s?, :p?, :o?]) == ok_bgp_struct([{:s, :p, :o}])
2020-06-12 00:53:29 +00:00
end
test "element count > 3" do
2020-06-29 08:37:42 +00:00
assert Builder.path([EX.s(), EX.p1(), EX.p2(), EX.o()]) ==
ok_bgp_struct([
{EX.s(), EX.p1(), RDF.bnode("0")},
{RDF.bnode("0"), EX.p2(), EX.o()}
])
2020-06-12 00:53:29 +00:00
assert Builder.path([:s?, :p1?, :p2?, :o?]) ==
2020-06-29 08:37:42 +00:00
ok_bgp_struct([
2020-06-12 00:53:29 +00:00
{:s, :p1, RDF.bnode("0")},
2020-06-29 08:37:42 +00:00
{RDF.bnode("0"), :p2, :o}
])
2020-06-12 00:53:29 +00:00
end
test "element count < 3" do
2020-06-29 08:37:42 +00:00
assert {:error, %RDF.Query.InvalidError{}} = Builder.path([EX.s(), EX.p()])
assert {:error, %RDF.Query.InvalidError{}} = Builder.path([EX.s()])
2020-06-12 00:53:29 +00:00
assert {:error, %RDF.Query.InvalidError{}} = Builder.path([])
end
test "with_elements: true" do
2020-06-29 08:37:42 +00:00
assert Builder.path([EX.s(), EX.p1(), EX.p2(), :o?], with_elements: true) ==
ok_bgp_struct([
{EX.s(), EX.p1(), :el0},
{:el0, EX.p2(), :o}
])
2020-06-12 00:53:29 +00:00
end
end
2020-06-09 23:13:01 +00:00
end