json_ld: JSON-LD expansions test suite and various expansion fixes

but still 5 tests failing
This commit is contained in:
Marcel Otto 2017-03-24 23:25:12 +01:00
parent 4cc0680fbf
commit 949a4a0f31
5 changed files with 39 additions and 22 deletions

View file

@ -15,35 +15,34 @@ defmodule JSON.LD.Context do
def create(%{"@context" => json_ld_context}, options),
do: new(options) |> update(json_ld_context)
do: new(options) |> update(json_ld_context, [], options)
def update(active, local, remote \\ [])
def update(active, local, remote \\ [], options \\ %JSON.LD.Options{})
def update(%JSON.LD.Context{} = active, local, remote) when is_list(local) do
def update(%JSON.LD.Context{} = active, local, remote, options) when is_list(local) do
Enum.reduce local, active, fn (local, result) ->
do_update(result, local, remote)
do_update(result, local, remote, options)
end
end
# 2) If local context is not an array, set it to an array containing only local context.
def update(%JSON.LD.Context{} = active, local, remote) do
update(active, [local], remote)
def update(%JSON.LD.Context{} = active, local, remote, options) do
update(active, [local], remote, options)
end
# 3.1) If context is null, set result to a newly-initialized active context and continue with the next context. The base IRI of the active context is set to the IRI of the currently being processed document (which might be different from the currently being processed context), if available; otherwise to null. If set, the base option of a JSON-LD API Implementation overrides the base IRI.
defp do_update(%JSON.LD.Context{} = active, nil, remote) do
# TODO: "If set, the base option of a JSON-LD API Implementation overrides the base IRI."
JSON.LD.Context.new(base: active.base_iri)
defp do_update(%JSON.LD.Context{} = active, nil, remote, options) do
JSON.LD.Context.new(base: JSON.LD.Options.new(options).base || active.base_iri)
end
# 3.2) If context is a string, [it's interpreted as a remote context]
defp do_update(%JSON.LD.Context{} = active, local, remote) when is_binary(local) do
defp do_update(%JSON.LD.Context{} = active, local, remote, options) when is_binary(local) do
# TODO: fetch remote context and call recursively with remote updated
end
# 3.4) - 3.8)
defp do_update(%JSON.LD.Context{} = active, local, remote) when is_map(local) do
defp do_update(%JSON.LD.Context{} = active, local, remote, _) when is_map(local) do
with {base, local} <- Map.pop(local, "@base", false),
{vocab, local} <- Map.pop(local, "@vocab", false),
{language, local} <- Map.pop(local, "@language", false) do
@ -56,7 +55,7 @@ defmodule JSON.LD.Context do
end
# 3.3) If context is not a JSON object, an invalid local context error has been detected and processing is aborted.
defp do_update(_, local, _),
defp do_update(_, local, _, _),
do: raise JSON.LD.InvalidLocalContextError,
message: "#{inspect local} is not a valid @context value"

View file

@ -72,7 +72,7 @@ defmodule JSON.LD.Expansion do
when is_map(element) do
# 5)
if Map.has_key?(element, "@context") do
active_context = JSON.LD.Context.update(active_context, Map.get(element, "@context"))
active_context = JSON.LD.Context.update(active_context, Map.get(element, "@context"), [], options)
end
# 6) and 7)
result = element
@ -206,7 +206,6 @@ defmodule JSON.LD.Expansion do
# 7.5) Otherwise, if key's container mapping in active context is @language and value is a JSON object then value is expanded from a language map as follows:
is_map(value) && term_def && term_def.container_mapping == "@language" ->
value
# |> IO.inspect(label: "value")
|> Enum.sort_by(fn {language, _} -> language end)
|> Enum.reduce([], fn ({language, language_value}, language_map_result) ->
language_map_result ++ (
@ -225,7 +224,6 @@ defmodule JSON.LD.Expansion do
end)
)
# |> IO.inspect(label: "result")
end)
# 7.6)
is_map(value) && term_def && term_def.container_mapping == "@index" ->
@ -327,7 +325,8 @@ defmodule JSON.LD.Expansion do
do: result = nil
# 12) If active property is null or @graph, drop free-floating values as follows:
if active_property in [nil, "@graph"] and (
# Spec FIXME: Due to case 10) we might land with a list here; other implementations deal with that, by just returning in step 10)
if is_map(result) and active_property in [nil, "@graph"] and (
Enum.empty?(result) or
Map.has_key?(result, "@value") or Map.has_key?(result, "@list") or
(map_size(result) == 1 and Map.has_key?(result, "@id"))),
@ -349,7 +348,8 @@ defmodule JSON.LD.Expansion do
Details at <http://json-ld.org/spec/latest/json-ld-api/#value-expansion>
"""
def expand_value(active_context, active_property, value) do
with term_def when term_def != nil <- active_context.term_defs[active_property] do
with term_def = Map.get(active_context.term_defs, active_property,
%JSON.LD.Context.TermDefinition{}) do
cond do
term_def.type_mapping == "@id" ->
%{"@id" => expand_iri(value, active_context, true, false)}
@ -370,8 +370,6 @@ defmodule JSON.LD.Expansion do
true ->
%{"@value" => value}
end
else
_ -> %{"@value" => value}
end
end

View file

@ -30,8 +30,8 @@ defmodule JSON.LD.IRIExpansion do
result = cond do
# 3) If vocab is true and the active context has a term definition for value, return the associated IRI mapping.
vocab && (term_def = active_context.term_defs[value]) ->
term_def.iri_mapping
vocab && Map.has_key?(active_context.term_defs, value) ->
(term_def = active_context.term_defs[value]) && term_def.iri_mapping
# 4) If value contains a colon (:), it is either an absolute IRI, a compact IRI, or a blank node identifier
String.contains?(value, ":") ->
case compact_iri_parts(value) do

View file

@ -0,0 +1,21 @@
defmodule JSON.LD.TestSuite.ExpandTest do
use ExUnit.Case, async: false
import JSON.LD.TestSuite
setup_all do
[base_iri: manifest("expand")["baseIri"]]
end
test_cases("expand")
|> Enum.each(fn %{"name" => name, "input" => input} = test_case ->
@tag :test_suite
@tag :expand_test_suite
@tag data: test_case
test "#{input}: #{name}",
%{data: %{"input" => input, "expect" => output} = test_case, base_iri: base_iri} do
assert JSON.LD.expand(j(input), test_case_options(test_case, base_iri)) == j(output)
end
end)
end

View file

@ -911,7 +911,6 @@ defmodule JSON.LD.ExpansionTest do
"ex:integer" => %{"@type" => "xsd:integer"},
"ex:double" => %{"@type" => "xsd:double"},
"ex:boolean" => %{"@type" => "xsd:boolean"},
"@language" => "en"
})
%{example_context: context}
end