json_ld: JSON-LD toRdf test suite and various fixes

This commit is contained in:
Marcel Otto 2017-04-14 13:38:38 +02:00
parent f714a02d1d
commit d72791bcd5
3 changed files with 125 additions and 23 deletions

View file

@ -70,8 +70,12 @@ defmodule JSON.LD.Decoder do
rdf_graph
end
end)
Dataset.add(dataset, rdf_graph,
if Enum.empty?(rdf_graph) do
dataset
else
Dataset.add(dataset, rdf_graph,
if(graph_name == "@default", do: nil, else: graph_name))
end
else
dataset
end
@ -134,21 +138,56 @@ defmodule JSON.LD.Decoder do
end
defp list_to_rdf(list, node_id_map) do
list
|> Enum.reverse
|> Enum.reduce({[], RDF.NS.RDF.nil}, fn (item, {list_triples, last}) ->
case object_to_rdf(item) do
nil -> {list_triples, last}
object ->
with bnode = node_to_rdf(generate_blank_node_id(node_id_map)) do
{
[{bnode, RDF.NS.RDF.first, object},
{bnode, RDF.NS.RDF.rest, last } | list_triples],
bnode
}
end
end
end)
{list_triples, first, last} =
list
|> Enum.reduce({[], nil, nil}, fn (item, {list_triples, first, last}) ->
case object_to_rdf(item) do
nil -> {list_triples, first, last}
object ->
with bnode = node_to_rdf(generate_blank_node_id(node_id_map)) do
if last do
{
list_triples ++
[{last, RDF.NS.RDF.rest, bnode},
{bnode, RDF.NS.RDF.first, object}],
first,
bnode
}
else
{
list_triples ++ [{bnode, RDF.NS.RDF.first, object}],
bnode,
bnode
}
end
end
end
end)
if last do
{list_triples ++ [{last, RDF.NS.RDF.rest, RDF.NS.RDF.nil}], first}
else
{[], RDF.NS.RDF.nil}
end
end
# This is a much nicer and faster version, but the blank node numbering is reversed.
# Although this isn't relevant, I prefer to be more spec conform (for now).
# defp list_to_rdf(list, node_id_map) do
# list
# |> Enum.reverse
# |> Enum.reduce({[], RDF.NS.RDF.nil}, fn (item, {list_triples, last}) ->
# case object_to_rdf(item) do
# nil -> {list_triples, last}
# object ->
# with bnode = node_to_rdf(generate_blank_node_id(node_id_map)) do
# {
# [{bnode, RDF.NS.RDF.first, object},
# {bnode, RDF.NS.RDF.rest, last } | list_triples],
# bnode
# }
# end
# end
# end)
# end
end

View file

@ -0,0 +1,63 @@
defmodule JSON.LD.TestSuite.ToRdfTest do
use ExUnit.Case, async: false
import JSON.LD.TestSuite
import RDF.Sigils
setup_all do
[base_iri: manifest("toRdf")["baseIri"]]
end
test_cases("toRdf")
# TODO: finish literal implementation
# |> Enum.filter(fn %{"@id" => id} -> id in ~w[#t0022] end)
# |> Enum.filter(fn %{"@id" => id} -> id in ~w[#t0035] end)
# |> Enum.filter(fn %{"@id" => id} -> id in ~w[#t0071] end)
# |> Enum.filter(fn %{"@id" => id} -> id in ~w[#t0101] end)
# TODO: Ordering problems
# |> Enum.filter(fn %{"@id" => id} -> id in ~w[#t0118] end)
# TODO: Fixed in Elixir 1.5
# |> Enum.filter(fn %{"@id" => id} -> id in ~w[#t0069] end)
# |> Enum.filter(fn %{"@id" => id} -> id in ~w[#t0102] end)
|> Enum.each(fn %{"name" => name, "input" => input} = test_case ->
if input in ~w[toRdf-0022-in.jsonld toRdf-0035-in.jsonld toRdf-0071-in.jsonld toRdf-0101-in.jsonld] do
@tag skip: "finish literal implementation"
end
if input in ~w[toRdf-0069-in.jsonld toRdf-0102-in.jsonld] do
@tag skip: """
probably caused by a bug in Elixirs URI.merge which should be fixed with Elixir 1.5
https://github.com/elixir-lang/elixir/pull/5780
"""
end
if input in ~w[toRdf-0118-in.jsonld] do
@tag skip: """
Actually an isomorphic graph is generated, but due to different ordering
during expansion the generated blank nodes are named different.
"""
end
@tag :test_suite
@tag :to_rdf_test_suite
@tag data: test_case
test "#{input}: #{name}",
%{data: %{"input" => input, "expect" => output} = test_case, base_iri: base_iri} do
# This requires a special handling, since the N-Quad ouput file is not valid, by using blank nodes as predicates
if input == "toRdf-0118-in.jsonld" do
assert JSON.LD.read_file!(file(input), test_case_options(test_case, base_iri)) ==
RDF.Dataset.new([
{RDF.bnode("b0"), ~I<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>, RDF.bnode("b0")},
{RDF.bnode("b0"), RDF.bnode("b0"), "plain value"},
{RDF.bnode("b0"), RDF.bnode("b0"), ~I<http://json-ld.org/test-suite/tests/relativeIri>},
{RDF.bnode("b0"), RDF.bnode("b0"), RDF.bnode("b0")},
{RDF.bnode("b0"), RDF.bnode("b0"), RDF.bnode("b1")},
{RDF.bnode("b0"), RDF.bnode("b0"), RDF.bnode("b2")},
{RDF.bnode("b0"), RDF.bnode("b0"), RDF.bnode("b3")},
{RDF.bnode("b1"), RDF.bnode("b0"), "term"},
{RDF.bnode("b2"), RDF.bnode("b0"), "termId"},
])
else
assert JSON.LD.read_file!(file(input), test_case_options(test_case, base_iri)) ==
RDF.NQuads.read_file!(file(output))
end
end
end)
end

View file

@ -3,7 +3,7 @@ defmodule JSON.LD.DecoderTest do
doctest JSON.LD.Decoder
alias RDF.{Dataset, Graph}
alias RDF.Dataset
alias RDF.NS
alias RDF.NS.{XSD, RDFS}
@ -19,7 +19,7 @@ defmodule JSON.LD.DecoderTest do
test "an empty JSON document is deserialized to an empty graph" do
assert JSON.LD.Decoder.decode!("{}") == Dataset.new(Graph.new)
assert JSON.LD.Decoder.decode!("{}") == Dataset.new
end
describe "unnamed nodes" do
@ -378,11 +378,11 @@ defmodule JSON.LD.DecoderTest do
"foaf:knows": {"@list": ["Manu Sporny", "Dave Longley"]}
}),
[
{~I<http://greggkellogg.net/foaf#me>, ~I<http://xmlns.com/foaf/0.1/knows>, RDF.bnode("b1")},
{RDF.bnode("b1"), NS.RDF.first, RDF.literal("Manu Sporny")},
{RDF.bnode("b1"), NS.RDF.rest, RDF.bnode("b0")},
{RDF.bnode("b0"), NS.RDF.first, RDF.literal("Dave Longley")},
{RDF.bnode("b0"), NS.RDF.rest, NS.RDF.nil},
{~I<http://greggkellogg.net/foaf#me>, ~I<http://xmlns.com/foaf/0.1/knows>, RDF.bnode("b0")},
{RDF.bnode("b0"), NS.RDF.first, RDF.literal("Manu Sporny")},
{RDF.bnode("b0"), NS.RDF.rest, RDF.bnode("b1")},
{RDF.bnode("b1"), NS.RDF.first, RDF.literal("Dave Longley")},
{RDF.bnode("b1"), NS.RDF.rest, NS.RDF.nil},
]
},
}