Fix graph addition of triples with an empty object list
This commit is contained in:
parent
8dcd949d24
commit
ca724d0300
4 changed files with 44 additions and 31 deletions
|
@ -16,6 +16,12 @@ This project adheres to [Semantic Versioning](http://semver.org/) and
|
|||
- The inspect string of `RDF.Description` now includes the subject separately, so
|
||||
it can be seen also when the description is empty.
|
||||
|
||||
### Fixed
|
||||
|
||||
- When triples with an empty object list where added to an `RDF.Graph`, it
|
||||
included empty descriptions, which lead to inconsistent behaviour
|
||||
(for example it would be counted in `RDF.Graph.subject_count/1`).
|
||||
|
||||
|
||||
[Compare v0.11.0...HEAD](https://github.com/rdf-elixir/rdf-ex/compare/v0.11.0...HEAD)
|
||||
|
||||
|
|
|
@ -18,8 +18,6 @@ defmodule RDF.Graph do
|
|||
alias RDF.{Description, IRI, PrefixMap, PropertyMap}
|
||||
alias RDF.Star.Statement
|
||||
|
||||
import RDF.Utils
|
||||
|
||||
@type graph_description :: %{Statement.subject() => Description.t()}
|
||||
|
||||
@type t :: %__MODULE__{
|
||||
|
@ -192,20 +190,21 @@ defmodule RDF.Graph do
|
|||
@spec add(t, input, keyword) :: t
|
||||
def add(graph, input, opts \\ [])
|
||||
|
||||
def add(%__MODULE__{} = graph, {subject, predications}, opts),
|
||||
do: do_add(graph, RDF.coerce_subject(subject), predications, opts)
|
||||
|
||||
def add(%__MODULE__{} = graph, {subject, _, _} = triple, opts),
|
||||
do: do_add(graph, RDF.coerce_subject(subject), triple, opts)
|
||||
|
||||
def add(graph, {subject, predicate, object, _}, opts),
|
||||
do: add(graph, {subject, predicate, object}, opts)
|
||||
|
||||
def add(%__MODULE__{} = graph, %Description{} = description, opts) do
|
||||
if Description.count(description) > 0 do
|
||||
do_add(graph, description.subject, description, opts)
|
||||
else
|
||||
def add(%__MODULE__{descriptions: descriptions} = graph, %Description{} = description, opts) do
|
||||
if Enum.empty?(description) do
|
||||
graph
|
||||
else
|
||||
%__MODULE__{
|
||||
graph
|
||||
| descriptions:
|
||||
Map.update(
|
||||
descriptions,
|
||||
description.subject,
|
||||
description,
|
||||
&Description.add(&1, description, opts)
|
||||
)
|
||||
}
|
||||
|> RDF.Star.Graph.handle_addition_annotations(description, opts)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -234,26 +233,19 @@ defmodule RDF.Graph do
|
|||
|> Enum.reduce(graph, &add(&2, &1, opts))
|
||||
end
|
||||
|
||||
def add(%__MODULE__{} = graph, {subject, predications}, opts),
|
||||
do: add(graph, Description.new(subject, Keyword.put(opts, :init, predications)), opts)
|
||||
|
||||
def add(%__MODULE__{} = graph, {subject, _, _} = triple, opts),
|
||||
do: add(graph, Description.new(subject, Keyword.put(opts, :init, triple)), opts)
|
||||
|
||||
def add(graph, {subject, predicate, object, _}, opts),
|
||||
do: add(graph, {subject, predicate, object}, opts)
|
||||
|
||||
def add(graph, input, opts) when is_list(input) or (is_map(input) and not is_struct(input)) do
|
||||
Enum.reduce(input, graph, &add(&2, &1, opts))
|
||||
end
|
||||
|
||||
defp do_add(%__MODULE__{descriptions: descriptions} = graph, subject, statements, opts) do
|
||||
%__MODULE__{
|
||||
graph
|
||||
| descriptions:
|
||||
lazy_map_update(
|
||||
descriptions,
|
||||
subject,
|
||||
# when new: create and initialize description with statements
|
||||
fn -> Description.new(subject, Keyword.put(opts, :init, statements)) end,
|
||||
# when update: merge statements description
|
||||
fn description -> Description.add(description, statements, opts) end
|
||||
)
|
||||
}
|
||||
|> RDF.Star.Graph.handle_addition_annotations({subject, statements}, opts)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Adds statements to a `RDF.Graph` overwriting existing statements with the subjects given in the `input` data.
|
||||
|
||||
|
|
|
@ -124,6 +124,11 @@ defmodule RDF.DescriptionTest do
|
|||
assert description_includes_predication(desc, {EX.p(), iri(EX.O2)})
|
||||
end
|
||||
|
||||
test "with a predicate-object tuple and an empty list of objects" do
|
||||
assert Description.add(description(), {EX.p(), []}) ==
|
||||
description()
|
||||
end
|
||||
|
||||
test "with a list of predicate-object tuples" do
|
||||
desc =
|
||||
Description.add(description(), [
|
||||
|
|
|
@ -74,6 +74,10 @@ defmodule RDF.GraphTest do
|
|||
assert graph_includes_statement?(g, {EX.Subject, EX.predicate(), EX.Object2})
|
||||
end
|
||||
|
||||
test "initial triples with an empty object list" do
|
||||
assert Graph.new({EX.Subject, EX.predicate(), []}) == Graph.new()
|
||||
end
|
||||
|
||||
test "creating a named graph with an initial description" do
|
||||
g =
|
||||
Description.new(EX.Subject, init: {EX.predicate(), EX.Object})
|
||||
|
@ -336,6 +340,12 @@ defmodule RDF.GraphTest do
|
|||
assert graph_includes_statement?(g, {EX.S2, EX.P2, EX.O2})
|
||||
end
|
||||
|
||||
test "empty object list" do
|
||||
assert Graph.add(graph(), {EX.S, EX.P, []}) == graph()
|
||||
graph = Graph.new({EX.S, EX.P, EX.O})
|
||||
assert Graph.add(graph, {EX.S, EX.P, []}) == graph
|
||||
end
|
||||
|
||||
test "a mixed list" do
|
||||
g =
|
||||
Graph.new([{EX.S1, EX.p1(), EX.O1}, {EX.S2, EX.p2(), EX.O2}, {EX.S1, EX.p3(), EX.O3}])
|
||||
|
|
Loading…
Reference in a new issue