diff --git a/lib/rdf/description.ex b/lib/rdf/description.ex index 1721cb8..bb1bd8d 100644 --- a/lib/rdf/description.ex +++ b/lib/rdf/description.ex @@ -29,6 +29,8 @@ defmodule RDF.Description do do: %RDF.Description{subject: Triple.convert_subject(subject)} def new(subject, predicate, objects), do: new(subject) |> add(predicate, objects) + def new(subject, description = %RDF.Description{}), + do: new(subject) |> add(description) @doc """ @@ -80,6 +82,12 @@ defmodule RDF.Description do end end + def add(%RDF.Description{subject: subject, predications: predications}, + %RDF.Description{predications: other_predications}) do + merged_predications = Map.merge predications, other_predications, + fn (_, objects, other_objects) -> Map.merge(objects, other_objects) end + %RDF.Description{subject: subject, predications: merged_predications} + end @doc """ Puts objects to a predicate of a `RDF.Description`, overwriting all existing objects. @@ -115,6 +123,9 @@ defmodule RDF.Description do iex> RDF.Description.new({EX.S, EX.P1, EX.O1}) |> ...> RDF.Description.put([{EX.P2, EX.O2}, {EX.S, EX.P2, EX.O3}, {EX.P1, EX.O4}]) RDF.Description.new([{EX.S, EX.P1, EX.O4}, {EX.S, EX.P2, EX.O2}, {EX.S, EX.P2, EX.O3}]) + iex> RDF.Description.new({EX.S, EX.P, EX.O1}) |> + ...> RDF.Description.put(RDF.Description.new(EX.S, EX.P, [EX.O1, EX.O2])) + RDF.Description.new([{EX.S, EX.P, EX.O1}, {EX.S, EX.P, EX.O2}]) """ def put(description, statements) @@ -143,6 +154,13 @@ defmodule RDF.Description do put(desc, predicate, objects) end) end + def put(%RDF.Description{subject: subject, predications: predications}, + %RDF.Description{predications: other_predications}) do + merged_predications = Map.merge predications, other_predications, + fn (_, _, other_objects) -> other_objects end + %RDF.Description{subject: subject, predications: merged_predications} + end + @doc """ Fetches the objects for the given predicate of a Description. diff --git a/test/unit/description_test.exs b/test/unit/description_test.exs index d81f971..b4a69c7 100644 --- a/test/unit/description_test.exs +++ b/test/unit/description_test.exs @@ -66,6 +66,13 @@ defmodule RDF.DescriptionTest do assert description_includes_predication(desc, {EX.predicate, literal("bar")}) end + test "creating a description from another description" do + desc1 = Description.new({EX.Other, EX.predicate, EX.Object}) + desc2 = Description.new(EX.Subject, desc1) + assert description_of_subject(desc2, uri(EX.Subject)) + assert description_includes_predication(desc2, {EX.predicate, uri(EX.Object)}) + end + describe "add" do test "a predicate-object-pair of proper RDF terms" do assert Description.add(description, EX.predicate, uri(EX.Object)) @@ -137,6 +144,26 @@ defmodule RDF.DescriptionTest do refute description_includes_predication(desc, {EX.predicate, uri(EX.Object3)}) end + + test "another description" do + desc = + description + |> Description.add([{EX.predicate1, EX.Object1}, + {EX.predicate2, EX.Object2}]) + |> Description.add(Description.new({EX.Other, EX.predicate3, EX.Object3})) + + assert description_of_subject(desc, uri(EX.Subject)) + assert description_includes_predication(desc, {EX.predicate1, uri(EX.Object1)}) + assert description_includes_predication(desc, {EX.predicate2, uri(EX.Object2)}) + assert description_includes_predication(desc, {EX.predicate3, uri(EX.Object3)}) + + desc = Description.add(desc, Description.new({EX.Other, EX.predicate1, EX.Object4})) + assert description_includes_predication(desc, {EX.predicate1, uri(EX.Object1)}) + assert description_includes_predication(desc, {EX.predicate2, uri(EX.Object2)}) + assert description_includes_predication(desc, {EX.predicate3, uri(EX.Object3)}) + assert description_includes_predication(desc, {EX.predicate1, uri(EX.Object4)}) + end + test "duplicates are ignored" do desc = Description.add(description, {EX.predicate, EX.Object}) assert Description.add(desc, {EX.predicate, EX.Object}) == desc @@ -177,7 +204,7 @@ defmodule RDF.DescriptionTest do assert Enum.count(desc.predications) == 1 end - describe "Enumerable implementation" do + describe "Enumerable protocol" do test "Enum.count" do assert Enum.count(Description.new EX.foo) == 0 assert Enum.count(Description.new {EX.S, EX.p, EX.O}) == 1