From a43205deaad8cc5289eed97045314e876565847d Mon Sep 17 00:00:00 2001 From: Marcel Otto Date: Sun, 19 Mar 2017 14:51:28 +0100 Subject: [PATCH] json_ld: solve the list reference problem with an agent --- lib/json/ld/flattening.ex | 39 ++++++++++++++++++++++----- test/unit/flattening_test.exs | 51 +++++++++++++++++------------------ 2 files changed, 57 insertions(+), 33 deletions(-) diff --git a/lib/json/ld/flattening.ex b/lib/json/ld/flattening.ex index 304890e..216f1bb 100644 --- a/lib/json/ld/flattening.ex +++ b/lib/json/ld/flattening.ex @@ -132,16 +132,23 @@ defmodule JSON.LD.Flattening do node_map end else - # TODO: list a reference! We'll have to rewrite this to work without references - list = Map.update(list, "@list", [element], fn l -> l ++ [element] end) + append_to_list(list, element) node_map end # 5) Map.has_key?(element, "@list") -> - result = %{"@list" => []} - node_map = generate_node_map(element["@list"], node_map, node_id_map, - active_graph, active_subject, active_property, result) + {:ok, result_list} = new_list + {node_map, result} = + try do + { + generate_node_map(element["@list"], node_map, node_id_map, + active_graph, active_subject, active_property, result_list), + get_list(result_list) + } + after + terminate_list(result_list) + end if node do update_in(node_map, [active_graph, active_subject, active_property], fn nil -> [result] @@ -204,8 +211,7 @@ defmodule JSON.LD.Flattening do end) # 6.6.3) TODO: Spec fixme: specs says to add ELEMENT to @list member, should be REFERENCE else - # TODO: list a reference! We'll have to rewrite this to work without references - list = Map.update(list, "@list", [reference], fn l -> l ++ [reference] end) + append_to_list(list, reference) end end end @@ -289,4 +295,23 @@ defmodule JSON.LD.Flattening do defp deep_compare(v, v), do: true defp deep_compare(_, _), do: false + + defp new_list do + Agent.start_link fn -> %{"@list" => []} end + end + + defp terminate_list(pid) do + Agent.stop pid + end + + defp get_list(pid) do + Agent.get pid, fn list_node -> list_node end + end + + defp append_to_list(pid, element) do + Agent.update pid, fn list_node -> + Map.update(list_node, "@list", [element], fn list -> list ++ [element] end) + end + end + end diff --git a/test/unit/flattening_test.exs b/test/unit/flattening_test.exs index be4b26b..2984788 100644 --- a/test/unit/flattening_test.exs +++ b/test/unit/flattening_test.exs @@ -211,32 +211,31 @@ defmodule JSON.LD.FlatteningTest do }] """) }, -# TODO: @list don't work yet, since the reference-based implementation in the spec is not possible in Elixir -# "Test Manifest (shortened)" => %{ -# input: Poison.Parser.parse!(""" -# { -# "@id": "", -# "http://example/sequence": {"@list": [ -# { -# "@id": "#t0001", -# "http://example/name": "Keywords cannot be aliased to other keywords", -# "http://example/input": {"@id": "error-expand-0001-in.jsonld"} -# } -# ]} -# } -# """), -# output: Poison.Parser.parse!(""" -# [{ -# "@id": "", -# "http://example/sequence": [{"@list": [{"@id": "#t0001"}]}] -# }, { -# "@id": "#t0001", -# "http://example/input": [{"@id": "error-expand-0001-in.jsonld"}], -# "http://example/name": [{"@value": "Keywords cannot be aliased to other keywords"}] -# }] -# """), -# options: %{} -# }, + "Test Manifest (shortened)" => %{ + input: Poison.Parser.parse!(""" + { + "@id": "", + "http://example/sequence": {"@list": [ + { + "@id": "#t0001", + "http://example/name": "Keywords cannot be aliased to other keywords", + "http://example/input": {"@id": "error-expand-0001-in.jsonld"} + } + ]} + } + """), + output: Poison.Parser.parse!(""" + [{ + "@id": "", + "http://example/sequence": [{"@list": [{"@id": "#t0001"}]}] + }, { + "@id": "#t0001", + "http://example/input": [{"@id": "error-expand-0001-in.jsonld"}], + "http://example/name": [{"@value": "Keywords cannot be aliased to other keywords"}] + }] + """), + options: %{} + }, "@reverse bnode issue (0045)" => %{ input: Poison.Parser.parse!(""" {