Change RDF.Description.new/2 to take initial data via the :init option

This commit is contained in:
Marcel Otto 2020-09-25 16:07:37 +02:00
parent bcf024647e
commit 20a69964c7
13 changed files with 395 additions and 304 deletions

View file

@ -4,6 +4,7 @@ All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/) and
[Keep a CHANGELOG](http://keepachangelog.com).
## Unreleased
### Added
@ -14,6 +15,13 @@ This project adheres to [Semantic Versioning](http://semver.org/) and
- for consistency reasons the internal `:id` struct field of `RDF.BlankNode` was renamed
to `:value`
- `RDF.Description.new` now requires the `subject` to be passed always as first argument;
if you want to add some initial data this must be done with the `:init` option
[Compare v0.8.2...HEAD](https://github.com/rdf-elixir/rdf-ex/compare/v0.8.2...HEAD)
## 0.8.2 - 2020-09-21

View file

@ -232,7 +232,7 @@ defmodule RDF do
defdelegate quad(s, p, o, g), to: Quad, as: :new
defdelegate quad(tuple), to: Quad, as: :new
defdelegate description(arg), to: Description, as: :new
defdelegate description(subject, opts \\ []), to: Description, as: :new
defdelegate graph(), to: Graph, as: :new
defdelegate graph(arg), to: Graph, as: :new

View file

@ -27,28 +27,54 @@ defmodule RDF.Description do
@type input ::
Triple.coercible_t()
| {Statement.coercible_predicate(),
Statement.coercible_object() | [Statement.coercible_object()]}
| {
Statement.coercible_predicate(),
Statement.coercible_object() | [Statement.coercible_object()]
}
| %{
Statement.coercible_predicate() =>
Statement.coercible_object() | [Statement.coercible_object()]
}
| [
Triple.coercible_t()
| {Statement.coercible_predicate(),
Statement.coercible_object() | [Statement.coercible_object()]}
| {
Statement.coercible_predicate(),
Statement.coercible_object() | [Statement.coercible_object()]
}
| t
]
| t
@doc """
Creates an empty `RDF.Description` about the given subject.
Creates an `RDF.Description` about the given subject.
The created `RDF.Description` can be initialized with any form of data which
`add/2` understands with the `:init` option. Additionally a function returning
the initialization data in any of these forms can be as the `:init` value.
## Examples
RDF.Description.new(EX.S)
RDF.Description.new(EX.S, init: {EX.S, EX.p, EX.O})
RDF.Description.new(EX.S, init: {EX.p, [EX.O1, EX.O2]})
RDF.Description.new(EX.S, init: [{EX.p1, EX.O1}, {EX.p2, EX.O2}])
RDF.Description.new(EX.S, init: RDF.Description.new(EX.S, init: {EX.P, EX.O}))
RDF.Description.new(EX.S, init: fn -> {EX.p, EX.O} end)
"""
@spec new(Statement.coercible_subject() | Triple.coercible_t() | t) :: t
def new(subject)
def new(%__MODULE__{} = description), do: new(description.subject)
def new({subject, predicate, object}), do: new(subject) |> add({predicate, object})
def new(subject), do: %__MODULE__{subject: coerce_subject(subject)}
@spec new(Statement.coercible_subject() | t, keyword) :: t
def new(subject, opts \\ [])
def new(%__MODULE__{} = description, opts), do: new(description.subject, opts)
def new(subject, opts) do
%__MODULE__{subject: coerce_subject(subject)}
|> init(Keyword.get(opts, :init))
end
defp init(description, nil), do: description
defp init(description, fun) when is_function(fun), do: add(description, fun.())
defp init(description, data), do: add(description, data)
@doc """
Returns the subject IRI or blank node of a description.
@ -72,10 +98,12 @@ defmodule RDF.Description do
## Examples
iex> RDF.Description.new({EX.S, EX.P1, EX.O1}) |> RDF.Description.add({EX.P2, EX.O2})
RDF.Description.new(EX.S) |> RDF.Description.add([{EX.P1, EX.O1}, {EX.P2, EX.O2}])
iex> RDF.Description.new({EX.S, EX.P, EX.O1}) |> RDF.Description.add({EX.P, [EX.O2, EX.O3]})
RDF.Description.new(EX.S) |> RDF.Description.add([{EX.P, EX.O1}, {EX.P, EX.O2}, {EX.P, EX.O3}])
iex> RDF.Description.new(EX.S, init: {EX.P1, EX.O1})
...> |> RDF.Description.add({EX.P2, EX.O2})
RDF.Description.new(EX.S, init: [{EX.P1, EX.O1}, {EX.P2, EX.O2}])
iex> RDF.Description.new(EX.S, init: {EX.P, EX.O1})
...> |> RDF.Description.add({EX.P, [EX.O2, EX.O3]})
RDF.Description.new(EX.S, init: [{EX.P, EX.O1}, {EX.P, EX.O2}, {EX.P, EX.O3}])
"""
@spec add(t, input, keyword) :: t
@ -148,8 +176,9 @@ defmodule RDF.Description do
## Examples
iex> RDF.Description.put(RDF.Description.new({EX.S, EX.P, EX.O1}), {EX.P, EX.O2})
RDF.Description.new({EX.S, EX.P, EX.O2})
iex> RDF.Description.new(EX.S, init: {EX.P, EX.O1})
...> |> RDF.Description.put({EX.P, EX.O2})
RDF.Description.new(EX.S, init: {EX.P, EX.O2})
"""
@spec put(t, input, keyword) :: t
@ -286,12 +315,12 @@ defmodule RDF.Description do
## Examples
iex> RDF.Description.new({EX.S, EX.p, EX.O}) |> RDF.Description.fetch(EX.p)
iex> RDF.Description.new(EX.S, init: {EX.p, EX.O}) |> RDF.Description.fetch(EX.p)
{:ok, [RDF.iri(EX.O)]}
iex> RDF.Description.new(EX.S) |> RDF.Description.add([{EX.P, EX.O1}, {EX.P, EX.O2}]) |>
...> RDF.Description.fetch(EX.P)
iex> RDF.Description.new(EX.S, init: [{EX.P, EX.O1}, {EX.P, EX.O2}])
...> |> RDF.Description.fetch(EX.P)
{:ok, [RDF.iri(EX.O1), RDF.iri(EX.O2)]}
iex> RDF.Description.fetch(RDF.Description.new(EX.S), EX.foo)
iex> RDF.Description.new(EX.S) |> RDF.Description.fetch(EX.foo)
:error
"""
@impl Access
@ -309,11 +338,11 @@ defmodule RDF.Description do
## Examples
iex> RDF.Description.get(RDF.Description.new({EX.S, EX.P, EX.O}), EX.P)
iex> RDF.Description.new(EX.S, init: {EX.P, EX.O}) |> RDF.Description.get(EX.P)
[RDF.iri(EX.O)]
iex> RDF.Description.get(RDF.Description.new(EX.S), EX.foo)
iex> RDF.Description.new(EX.S) |> RDF.Description.get(EX.foo)
nil
iex> RDF.Description.get(RDF.Description.new(EX.S), EX.foo, :bar)
iex> RDF.Description.new(EX.S) |> RDF.Description.get(EX.foo, :bar)
:bar
"""
@spec get(t, Statement.coercible_predicate(), any) :: [Statement.object()] | any
@ -331,9 +360,9 @@ defmodule RDF.Description do
## Examples
iex> RDF.Description.first(RDF.Description.new({EX.S, EX.P, EX.O}), EX.P)
iex> RDF.Description.new(EX.S, init: {EX.P, EX.O}) |> RDF.Description.first(EX.P)
RDF.iri(EX.O)
iex> RDF.Description.first(RDF.Description.new(EX.S), EX.foo)
iex> RDF.Description.new(EX.S) |> RDF.Description.first(EX.foo)
nil
"""
@spec first(t, Statement.coercible_predicate()) :: Statement.object() | nil
@ -357,12 +386,12 @@ defmodule RDF.Description do
## Examples
iex> RDF.Description.new({EX.S, EX.p, EX.O}) |>
...> RDF.Description.update(EX.p, fn objects -> [EX.O2 | objects] end)
RDF.Description.new(EX.S) |> RDF.Description.add([{EX.p, EX.O}, {EX.p, EX.O2}])
iex> RDF.Description.new(EX.S) |>
...> RDF.Description.update(EX.p, EX.O, fn _ -> EX.O2 end)
RDF.Description.new({EX.S, EX.p, EX.O})
iex> RDF.Description.new(EX.S, init: {EX.p, EX.O})
...> |> RDF.Description.update(EX.p, fn objects -> [EX.O2 | objects] end)
RDF.Description.new(EX.S, init: [{EX.p, EX.O}, {EX.p, EX.O2}])
iex> RDF.Description.new(EX.S)
...> |> RDF.Description.update(EX.p, EX.O, fn _ -> EX.O2 end)
RDF.Description.new(EX.S, init: {EX.p, EX.O})
"""
@spec update(
@ -409,15 +438,15 @@ defmodule RDF.Description do
## Examples
iex> RDF.Description.new({EX.S, EX.P, EX.O}) |>
...> RDF.Description.get_and_update(EX.P, fn current_objects ->
...> {current_objects, EX.NEW}
...> end)
{[RDF.iri(EX.O)], RDF.Description.new({EX.S, EX.P, EX.NEW})}
iex> RDF.Graph.new([{EX.S, EX.P1, EX.O1}, {EX.S, EX.P2, EX.O2}]) |>
...> RDF.Graph.description(EX.S) |>
...> RDF.Description.get_and_update(EX.P1, fn _ -> :pop end)
{[RDF.iri(EX.O1)], RDF.Description.new({EX.S, EX.P2, EX.O2})}
iex> RDF.Description.new(EX.S, init: {EX.P, EX.O})
...> |> RDF.Description.get_and_update(EX.P, fn current_objects ->
...> {current_objects, EX.New}
...> end)
{[RDF.iri(EX.O)], RDF.Description.new(EX.S, init: {EX.P, EX.New})}
iex> RDF.Graph.new([{EX.S, EX.P1, EX.O1}, {EX.S, EX.P2, EX.O2}])
...> |> RDF.Graph.description(EX.S)
...> |> RDF.Description.get_and_update(EX.P1, fn _ -> :pop end)
{[RDF.iri(EX.O1)], RDF.Description.new(EX.S, init: {EX.P2, EX.O2})}
"""
@impl Access
@spec get_and_update(
@ -466,10 +495,12 @@ defmodule RDF.Description do
## Examples
iex> RDF.Description.pop(RDF.Description.new({EX.S, EX.P, EX.O}), EX.P)
iex> RDF.Description.new(EX.S, init: {EX.P, EX.O})
...> |> RDF.Description.pop(EX.P)
{[RDF.iri(EX.O)], RDF.Description.new(EX.S)}
iex> RDF.Description.pop(RDF.Description.new({EX.S, EX.P, EX.O}), EX.Missing)
{nil, RDF.Description.new({EX.S, EX.P, EX.O})}
iex> RDF.Description.new(EX.S, init: {EX.P, EX.O})
...> |> RDF.Description.pop(EX.Missing)
{nil, RDF.Description.new(EX.S, init: {EX.P, EX.O})}
"""
@impl Access
def pop(description = %__MODULE__{subject: subject, predications: predications}, predicate) do
@ -487,11 +518,11 @@ defmodule RDF.Description do
## Examples
iex> RDF.Description.new(EX.S1) |> RDF.Description.add([
iex> RDF.Description.new(EX.S1, init: [
...> {EX.p1, EX.O1},
...> {EX.p2, EX.O2},
...> {EX.p2, EX.O3}]) |>
...> RDF.Description.predicates
...> {EX.p2, EX.O3}])
...> |> RDF.Description.predicates()
MapSet.new([EX.p1, EX.p2])
"""
@spec predicates(t) :: MapSet.t()
@ -505,13 +536,13 @@ defmodule RDF.Description do
## Examples
iex> RDF.Description.new(EX.S1) |> RDF.Description.add([
iex> RDF.Description.new(EX.S1, init: [
...> {EX.p1, EX.O1},
...> {EX.p2, EX.O2},
...> {EX.p3, EX.O2},
...> {EX.p4, RDF.bnode(:bnode)},
...> {EX.p3, "foo"}
...> ]) |> RDF.Description.objects
...> {EX.p3, "foo"}])
...> |> RDF.Description.objects()
MapSet.new([RDF.iri(EX.O1), RDF.iri(EX.O2), RDF.bnode(:bnode)])
"""
@spec objects(t) :: MapSet.t()
@ -537,13 +568,13 @@ defmodule RDF.Description do
## Examples
iex> RDF.Description.new(EX.S1) |> RDF.Description.add([
iex> RDF.Description.new(EX.S1, init: [
...> {EX.p1, EX.O1},
...> {EX.p2, EX.O2},
...> {EX.p1, EX.O2},
...> {EX.p2, RDF.bnode(:bnode)},
...> {EX.p3, "foo"}
...> ]) |> RDF.Description.resources
...> {EX.p3, "foo"}])
...> |> RDF.Description.resources()
MapSet.new([RDF.iri(EX.O1), RDF.iri(EX.O2), RDF.bnode(:bnode), EX.p1, EX.p2, EX.p3])
"""
@spec resources(t) :: MapSet.t()
@ -600,9 +631,11 @@ defmodule RDF.Description do
## Examples
iex> RDF.Description.new({EX.S1, EX.p1, EX.O1}) |> RDF.Description.describes?(EX.S1)
iex> RDF.Description.new(EX.S1, init: {EX.p1, EX.O1})
...> |> RDF.Description.describes?(EX.S1)
true
iex> RDF.Description.new({EX.S1, EX.p1, EX.O1}) |> RDF.Description.describes?(EX.S2)
iex> RDF.Description.new(EX.S1, init: {EX.p1, EX.O1})
...> |> RDF.Description.describes?(EX.S2)
false
"""
@spec describes?(t, Statement.subject()) :: boolean
@ -623,13 +656,11 @@ defmodule RDF.Description do
## Examples
iex> {~I<http://example.com/S>, ~I<http://example.com/p>, ~L"Foo"}
...> |> RDF.Description.new()
iex> RDF.Description.new(~I<http://example.com/S>, init: {~I<http://example.com/p>, ~L"Foo"})
...> |> RDF.Description.values()
%{"http://example.com/p" => ["Foo"]}
iex> {~I<http://example.com/S>, ~I<http://example.com/p>, ~L"Foo"}
...> |> RDF.Description.new()
iex> RDF.Description.new(~I<http://example.com/S>, init: {~I<http://example.com/p>, ~L"Foo"})
...> |> RDF.Description.values(fn
...> {:predicate, predicate} ->
...> predicate

View file

@ -47,7 +47,7 @@ defmodule RDF.Diff do
## Examples
iex> RDF.Diff.diff(
...> RDF.description({EX.S1, EX.p1, [EX.O1, EX.O2]}),
...> RDF.description(EX.S1, init: {EX.S1, EX.p1, [EX.O1, EX.O2]}),
...> RDF.graph([
...> {EX.S1, EX.p1, [EX.O2, EX.O3]},
...> {EX.S2, EX.p2, EX.O4}

View file

@ -428,17 +428,20 @@ defmodule RDF.Graph do
## Examples
iex> RDF.Graph.new({EX.S, EX.p, EX.O}) |>
...> RDF.Graph.update(EX.S,
...> fn description -> Description.add(description, {EX.p, EX.O2}) end)
iex> RDF.Graph.new({EX.S, EX.p, EX.O})
...> |> RDF.Graph.update(EX.S,
...> fn description -> Description.add(description, {EX.p, EX.O2})
...> end)
RDF.Graph.new([{EX.S, EX.p, EX.O}, {EX.S, EX.p, EX.O2}])
iex> RDF.Graph.new({EX.S, EX.p, EX.O}) |>
...> RDF.Graph.update(EX.S,
...> fn _ -> Description.new({EX.S2, EX.p2, EX.O2}) end)
iex> RDF.Graph.new({EX.S, EX.p, EX.O})
...> |> RDF.Graph.update(EX.S,
...> fn _ -> Description.new(EX.S2, init: {EX.p2, EX.O2})
...> end)
RDF.Graph.new([{EX.S, EX.p2, EX.O2}])
iex> RDF.Graph.new() |>
...> RDF.Graph.update(EX.S, Description.new({EX.S, EX.p, EX.O}),
...> fn description -> Description.add(description, {EX.p, EX.O2}) end)
iex> RDF.Graph.new()
...> |> RDF.Graph.update(EX.S, Description.new(EX.S, init: {EX.p, EX.O}),
...> fn description -> Description.add(description, {EX.p, EX.O2})
...> end)
RDF.Graph.new([{EX.S, EX.p, EX.O}])
"""
@ -454,7 +457,7 @@ defmodule RDF.Graph do
case get(graph, subject) do
nil ->
if initial do
add(graph, Description.new(subject) |> Description.add(initial))
add(graph, Description.new(subject, init: initial))
else
graph
end
@ -469,7 +472,7 @@ defmodule RDF.Graph do
new_description ->
graph
|> delete_subjects(subject)
|> add(Description.new(subject) |> Description.add(new_description))
|> add(Description.new(subject, init: new_description))
end
end
end
@ -481,10 +484,10 @@ defmodule RDF.Graph do
## Examples
iex> RDF.Graph.new([{EX.S1, EX.P1, EX.O1}, {EX.S2, EX.P2, EX.O2}]) |>
...> RDF.Graph.fetch(EX.S1)
{:ok, RDF.Description.new({EX.S1, EX.P1, EX.O1})}
iex> RDF.Graph.fetch(RDF.Graph.new, EX.foo)
iex> RDF.Graph.new([{EX.S1, EX.P1, EX.O1}, {EX.S2, EX.P2, EX.O2}])
...> |> RDF.Graph.fetch(EX.S1)
{:ok, RDF.Description.new(EX.S1, init: {EX.P1, EX.O1})}
iex> RDF.Graph.new() |> RDF.Graph.fetch(EX.foo)
:error
"""
@ -525,12 +528,12 @@ defmodule RDF.Graph do
## Examples
iex> RDF.Graph.new([{EX.S1, EX.P1, EX.O1}, {EX.S2, EX.P2, EX.O2}]) |>
...> RDF.Graph.get(EX.S1)
RDF.Description.new({EX.S1, EX.P1, EX.O1})
iex> RDF.Graph.get(RDF.Graph.new, EX.Foo)
iex> RDF.Graph.new([{EX.S1, EX.P1, EX.O1}, {EX.S2, EX.P2, EX.O2}])
...> |> RDF.Graph.get(EX.S1)
RDF.Description.new(EX.S1, init: {EX.P1, EX.O1})
iex> RDF.Graph.new() |> RDF.Graph.get(EX.Foo)
nil
iex> RDF.Graph.get(RDF.Graph.new, EX.Foo, :bar)
iex> RDF.Graph.new() |> RDF.Graph.get(EX.Foo, :bar)
:bar
"""
@ -629,10 +632,10 @@ defmodule RDF.Graph do
## Examples
iex> RDF.Graph.new([{EX.S1, EX.P1, EX.O1}, {EX.S2, EX.P2, EX.O2}]) |>
...> RDF.Graph.pop(EX.S1)
{RDF.Description.new({EX.S1, EX.P1, EX.O1}), RDF.Graph.new({EX.S2, EX.P2, EX.O2})}
iex> RDF.Graph.pop(RDF.Graph.new({EX.S, EX.P, EX.O}), EX.Missing)
iex> RDF.Graph.new([{EX.S1, EX.P1, EX.O1}, {EX.S2, EX.P2, EX.O2}])
...> |> RDF.Graph.pop(EX.S1)
{RDF.Description.new(EX.S1, init: {EX.P1, EX.O1}), RDF.Graph.new({EX.S2, EX.P2, EX.O2})}
iex> RDF.Graph.new({EX.S, EX.P, EX.O}) |> RDF.Graph.pop(EX.Missing)
{nil, RDF.Graph.new({EX.S, EX.P, EX.O})}
"""
@ -656,8 +659,8 @@ defmodule RDF.Graph do
iex> RDF.Graph.new([
...> {EX.S1, EX.p1, EX.O1},
...> {EX.S2, EX.p2, EX.O2},
...> {EX.S1, EX.p2, EX.O3}]) |>
...> RDF.Graph.subject_count
...> {EX.S1, EX.p2, EX.O3}])
...> |> RDF.Graph.subject_count()
2
"""
@ -673,8 +676,8 @@ defmodule RDF.Graph do
iex> RDF.Graph.new([
...> {EX.S1, EX.p1, EX.O1},
...> {EX.S2, EX.p2, EX.O2},
...> {EX.S1, EX.p2, EX.O3}]) |>
...> RDF.Graph.triple_count
...> {EX.S1, EX.p2, EX.O3}])
...> |> RDF.Graph.triple_count()
3
"""
@ -693,8 +696,8 @@ defmodule RDF.Graph do
iex> RDF.Graph.new([
...> {EX.S1, EX.p1, EX.O1},
...> {EX.S2, EX.p2, EX.O2},
...> {EX.S1, EX.p2, EX.O3}]) |>
...> RDF.Graph.subjects
...> {EX.S1, EX.p2, EX.O3}])
...> |> RDF.Graph.subjects()
MapSet.new([RDF.iri(EX.S1), RDF.iri(EX.S2)])
"""
def subjects(%__MODULE__{descriptions: descriptions}),
@ -708,8 +711,8 @@ defmodule RDF.Graph do
iex> RDF.Graph.new([
...> {EX.S1, EX.p1, EX.O1},
...> {EX.S2, EX.p2, EX.O2},
...> {EX.S1, EX.p2, EX.O3}]) |>
...> RDF.Graph.predicates
...> {EX.S1, EX.p2, EX.O3}])
...> |> RDF.Graph.predicates()
MapSet.new([EX.p1, EX.p2])
"""
def predicates(%__MODULE__{descriptions: descriptions}) do
@ -732,8 +735,8 @@ defmodule RDF.Graph do
...> {EX.S2, EX.p2, EX.O2},
...> {EX.S3, EX.p1, EX.O2},
...> {EX.S4, EX.p2, RDF.bnode(:bnode)},
...> {EX.S5, EX.p3, "foo"}
...> ]) |> RDF.Graph.objects
...> {EX.S5, EX.p3, "foo"}])
...> |> RDF.Graph.objects()
MapSet.new([RDF.iri(EX.O1), RDF.iri(EX.O2), RDF.bnode(:bnode)])
"""
def objects(%__MODULE__{descriptions: descriptions}) do
@ -753,8 +756,8 @@ defmodule RDF.Graph do
...> {EX.S1, EX.p1, EX.O1},
...> {EX.S2, EX.p1, EX.O2},
...> {EX.S2, EX.p2, RDF.bnode(:bnode)},
...> {EX.S3, EX.p1, "foo"}
...> ]) |> RDF.Graph.resources
...> {EX.S3, EX.p1, "foo"}])
...> |> RDF.Graph.resources()
MapSet.new([RDF.iri(EX.S1), RDF.iri(EX.S2), RDF.iri(EX.S3),
RDF.iri(EX.O1), RDF.iri(EX.O2), RDF.bnode(:bnode), EX.p1, EX.p2])
"""
@ -775,8 +778,8 @@ defmodule RDF.Graph do
iex> RDF.Graph.new([
...> {EX.S1, EX.p1, EX.O1},
...> {EX.S2, EX.p2, EX.O2},
...> {EX.S1, EX.p2, EX.O3}
...> ]) |> RDF.Graph.triples
...> {EX.S1, EX.p2, EX.O3}])
...> |> RDF.Graph.triples()
[{RDF.iri(EX.S1), RDF.iri(EX.p1), RDF.iri(EX.O1)},
{RDF.iri(EX.S1), RDF.iri(EX.p2), RDF.iri(EX.O3)},
{RDF.iri(EX.S2), RDF.iri(EX.p2), RDF.iri(EX.O2)}]
@ -829,22 +832,20 @@ defmodule RDF.Graph do
## Examples
iex> [
iex> RDF.Graph.new([
...> {~I<http://example.com/S1>, ~I<http://example.com/p>, ~L"Foo"},
...> {~I<http://example.com/S2>, ~I<http://example.com/p>, RDF.XSD.integer(42)}
...> ]
...> |> RDF.Graph.new()
...> ])
...> |> RDF.Graph.values()
%{
"http://example.com/S1" => %{"http://example.com/p" => ["Foo"]},
"http://example.com/S2" => %{"http://example.com/p" => [42]}
}
iex> [
iex> RDF.Graph.new([
...> {~I<http://example.com/S1>, ~I<http://example.com/p>, ~L"Foo"},
...> {~I<http://example.com/S2>, ~I<http://example.com/p>, RDF.XSD.integer(42)}
...> ]
...> |> RDF.Graph.new()
...> ])
...> |> RDF.Graph.values(fn
...> {:predicate, predicate} ->
...> predicate

View file

@ -22,7 +22,7 @@ defmodule RDF.Serialization.Format do
`RDF.Serialization.Encoder` and a `RDF.Serialization.Decoder` for the format.
By default it is assumed that these are defined in `Encoder` and `Decoder`
moduler under the `RDF.Serialization.Format` module of the format, i.e. in the
modules under the `RDF.Serialization.Format` module of the format, i.e. in the
example above in `SomeFormat.Encoder` and `SomeFormat.Decoder`. If you want
them in another module, you'll have to override the `encoder/0` and/or
`decoder/0` functions in your `RDF.Serialization.Format` module.

View file

@ -171,8 +171,7 @@ defmodule RDF.Vocabulary.Namespace do
end
def unquote(term)(subject, object) do
Description.new(subject)
|> Description.add({unquote(Macro.escape(iri)), object})
Description.new(subject, init: {unquote(Macro.escape(iri)), object})
end
# Is there a better way to support multiple objects via arguments?

View file

@ -51,22 +51,22 @@ defmodule RDF.DataTest do
end
test "merge of a description with different subject", %{description: description} do
assert RDF.Data.merge(description, Description.new({EX.Other, EX.p1(), EX.O3})) ==
assert RDF.Data.merge(description, Description.new(EX.Other, init: {EX.p1(), EX.O3})) ==
Graph.new(description) |> Graph.add({EX.Other, EX.p1(), EX.O3})
end
test "merge of a description with same subject", %{description: description} do
assert RDF.Data.merge(description, Description.new({EX.S, EX.p1(), EX.O3})) ==
assert RDF.Data.merge(description, Description.new(EX.S, init: {EX.p1(), EX.O3})) ==
Description.add(description, {EX.S, EX.p1(), EX.O3})
end
test "merge of a graph", %{graph: graph} do
assert RDF.Data.merge(Description.new({EX.Other, EX.p1(), EX.O3}), graph) ==
assert RDF.Data.merge(Description.new(EX.Other, init: {EX.p1(), EX.O3}), graph) ==
Graph.add(graph, {EX.Other, EX.p1(), EX.O3})
end
test "merge of a dataset", %{dataset: dataset} do
assert RDF.Data.merge(Description.new({EX.Other, EX.p1(), EX.O3}), dataset) ==
assert RDF.Data.merge(Description.new(EX.Other, init: {EX.p1(), EX.O3}), dataset) ==
Dataset.add(dataset, {EX.Other, EX.p1(), EX.O3})
end
@ -207,10 +207,10 @@ defmodule RDF.DataTest do
end
test "merge of a description", %{graph: graph} do
assert RDF.Data.merge(graph, Description.new({EX.Other, EX.p1(), EX.O3})) ==
assert RDF.Data.merge(graph, Description.new(EX.Other, init: {EX.p1(), EX.O3})) ==
Graph.add(graph, {EX.Other, EX.p1(), EX.O3})
assert RDF.Data.merge(graph, Description.new({EX.S, EX.p1(), EX.O3})) ==
assert RDF.Data.merge(graph, Description.new(EX.S, init: {EX.p1(), EX.O3})) ==
Graph.add(graph, {EX.S, EX.p1(), EX.O3})
end
@ -375,7 +375,7 @@ defmodule RDF.DataTest do
end
test "merge of a description", %{dataset: dataset} do
assert RDF.Data.merge(dataset, Description.new({EX.Other, EX.p1(), EX.O3})) ==
assert RDF.Data.merge(dataset, Description.new(EX.Other, init: {EX.p1(), EX.O3})) ==
Dataset.add(dataset, {EX.Other, EX.p1(), EX.O3})
end

View file

@ -97,14 +97,18 @@ defmodule RDF.DatasetTest do
test "creating a named dataset with an initial description" do
ds =
Dataset.new(Description.new({EX.Subject, EX.predicate(), EX.Object}), name: EX.DatasetName)
Description.new(EX.Subject, init: {EX.predicate(), EX.Object})
|> Dataset.new(name: EX.DatasetName)
assert named_dataset?(ds, iri(EX.DatasetName))
assert dataset_includes_statement?(ds, {EX.Subject, EX.predicate(), EX.Object})
end
test "creating an unnamed dataset with an initial description" do
ds = Dataset.new(Description.new({EX.Subject, EX.predicate(), EX.Object}))
ds =
Description.new(EX.Subject, init: {EX.predicate(), EX.Object})
|> Dataset.new()
assert unnamed_dataset?(ds)
assert dataset_includes_statement?(ds, {EX.Subject, EX.predicate(), EX.Object})
end
@ -340,18 +344,25 @@ defmodule RDF.DatasetTest do
ds =
Dataset.add(
dataset(),
Description.new(EX.Subject1)
|> RDF.Description.add([
{EX.predicate1(), EX.Object1},
{EX.predicate2(), EX.Object2}
]),
Description.new(EX.Subject1,
init: [
{EX.predicate1(), EX.Object1},
{EX.predicate2(), EX.Object2}
]
),
nil
)
assert dataset_includes_statement?(ds, {EX.Subject1, EX.predicate1(), EX.Object1})
assert dataset_includes_statement?(ds, {EX.Subject1, EX.predicate2(), EX.Object2})
ds = Dataset.add(ds, Description.new({EX.Subject1, EX.predicate3(), EX.Object3}), EX.Graph)
ds =
Dataset.add(
ds,
Description.new(EX.Subject1, init: {EX.predicate3(), EX.Object3}),
EX.Graph
)
assert Enum.count(ds) == 3
assert dataset_includes_statement?(ds, {EX.Subject1, EX.predicate1(), EX.Object1})
assert dataset_includes_statement?(ds, {EX.Subject1, EX.predicate2(), EX.Object2})
@ -579,9 +590,9 @@ defmodule RDF.DatasetTest do
test "a list of Descriptions" do
ds =
Dataset.add(dataset(), [
Description.new({EX.Subject1, EX.predicate1(), EX.Object1}),
Description.new({EX.Subject2, EX.predicate2(), EX.Object2}),
Description.new({EX.Subject1, EX.predicate3(), EX.Object3})
Description.new(EX.Subject1, init: {EX.predicate1(), EX.Object1}),
Description.new(EX.Subject2, init: {EX.predicate2(), EX.Object2}),
Description.new(EX.Subject1, init: {EX.predicate3(), EX.Object3})
])
assert dataset_includes_statement?(ds, {EX.Subject1, EX.predicate1(), EX.Object1})
@ -592,9 +603,9 @@ defmodule RDF.DatasetTest do
Dataset.add(
ds,
[
Description.new({EX.Subject1, EX.predicate1(), EX.Object1}),
Description.new({EX.Subject2, EX.predicate2(), EX.Object2}),
Description.new({EX.Subject1, EX.predicate3(), EX.Object3})
Description.new(EX.Subject1, init: {EX.predicate1(), EX.Object1}),
Description.new(EX.Subject2, init: {EX.predicate2(), EX.Object2}),
Description.new(EX.Subject1, init: {EX.predicate3(), EX.Object3})
],
EX.Graph
)
@ -828,15 +839,16 @@ defmodule RDF.DatasetTest do
test "multiple statements with a Description",
%{dataset1: dataset1, dataset2: dataset2} do
assert Dataset.delete(dataset1, Description.new({EX.S1, EX.p1(), EX.O1})) == Dataset.new()
assert Dataset.delete(dataset1, Description.new(EX.S1, init: {EX.p1(), EX.O1})) ==
Dataset.new()
assert Dataset.delete(dataset1, Description.new({EX.S1, EX.p1(), EX.O1}), EX.Graph) ==
assert Dataset.delete(dataset1, Description.new(EX.S1, init: {EX.p1(), EX.O1}), EX.Graph) ==
dataset1
assert Dataset.delete(dataset2, Description.new({EX.S2, EX.p2(), EX.O2}), EX.Graph) ==
assert Dataset.delete(dataset2, Description.new(EX.S2, init: {EX.p2(), EX.O2}), EX.Graph) ==
dataset1
assert Dataset.delete(dataset2, Description.new({EX.S1, EX.p1(), EX.O1})) ==
assert Dataset.delete(dataset2, Description.new(EX.S1, init: {EX.p1(), EX.O1})) ==
Dataset.new({EX.S2, EX.p2(), EX.O2, EX.Graph})
end

View file

@ -32,6 +32,36 @@ defmodule RDF.DescriptionTest do
assert description_of_subject(new_description, iri(EX.Subject))
refute description_includes_predication(new_description, {EX.predicate(), iri(EX.Object)})
end
test "with init data" do
desc = Description.new(EX.Subject, init: {EX.Subject, EX.predicate(), EX.Object})
assert description_of_subject(desc, iri(EX.Subject))
assert description_includes_predication(desc, {EX.predicate(), iri(EX.Object)})
desc =
Description.new(
EX.Subject,
init: [
{EX.Subject, EX.predicate1(), EX.Object1},
{EX.Subject, EX.predicate2(), EX.Object2}
]
)
assert description_of_subject(desc, iri(EX.Subject))
assert description_includes_predication(desc, {EX.predicate1(), iri(EX.Object1)})
assert description_includes_predication(desc, {EX.predicate2(), iri(EX.Object2)})
other_desc = Description.new(EX.Subject2, init: {EX.Subject2, EX.predicate(), EX.Object})
desc = Description.new(EX.Subject, init: other_desc)
assert description_of_subject(desc, iri(EX.Subject))
assert description_includes_predication(desc, {EX.predicate(), iri(EX.Object)})
end
test "with an initializer function" do
desc = Description.new(EX.Subject, init: fn -> {EX.Subject, EX.predicate(), EX.Object} end)
assert description_of_subject(desc, iri(EX.Subject))
assert description_includes_predication(desc, {EX.predicate(), iri(EX.Object)})
end
end
test "subject/1" do
@ -171,14 +201,21 @@ defmodule RDF.DescriptionTest do
test "with another description" do
desc =
description([{EX.predicate1(), EX.Object1}, {EX.predicate2(), EX.Object2}])
|> Description.add(Description.new({EX.Other, EX.predicate3(), EX.Object3}))
|> Description.add(
Description.new(EX.Other, init: {EX.Other, EX.predicate3(), EX.Object3})
)
assert description_of_subject(desc, iri(EX.Subject))
assert description_includes_predication(desc, {EX.predicate1(), iri(EX.Object1)})
assert description_includes_predication(desc, {EX.predicate2(), iri(EX.Object2)})
assert description_includes_predication(desc, {EX.predicate3(), iri(EX.Object3)})
desc = Description.add(desc, Description.new({EX.Other, EX.predicate1(), EX.Object4}))
desc =
Description.add(
desc,
Description.new(EX.Other, init: {EX.Other, EX.predicate1(), EX.Object4})
)
assert description_includes_predication(desc, {EX.predicate1(), iri(EX.Object1)})
assert description_includes_predication(desc, {EX.predicate2(), iri(EX.Object2)})
assert description_includes_predication(desc, {EX.predicate3(), iri(EX.Object3)})
@ -307,7 +344,7 @@ defmodule RDF.DescriptionTest do
assert Description.put(
desc,
Description.new({EX.Other, EX.predicate(), iri(EX.Object)})
Description.new(EX.Other, init: {EX.Other, EX.predicate(), iri(EX.Object)})
) == desc
end
@ -322,15 +359,16 @@ defmodule RDF.DescriptionTest do
setup do
{:ok,
empty_description: Description.new(EX.S),
description1: Description.new({EX.S, EX.p(), EX.O}),
description2: Description.new({EX.S, EX.p(), [EX.O1, EX.O2]}),
description1: Description.new(EX.S, init: {EX.S, EX.p(), EX.O}),
description2: Description.new(EX.S, init: {EX.S, EX.p(), [EX.O1, EX.O2]}),
description3:
Description.new(EX.S)
|> Description.add([
{EX.p1(), [EX.O1, EX.O2]},
{EX.p2(), EX.O3},
{EX.p3(), [~B<foo>, ~L"bar"]}
])}
Description.new(EX.S,
init: [
{EX.p1(), [EX.O1, EX.O2]},
{EX.p2(), EX.O3},
{EX.p3(), [~B<foo>, ~L"bar"]}
]
)}
end
test "a single statement as a predicate-object tuple",
@ -343,7 +381,7 @@ defmodule RDF.DescriptionTest do
assert Description.delete(description1, {EX.p(), EX.O}) == empty_description
assert Description.delete(description2, {EX.p(), EX.O2}) ==
Description.new({EX.S, EX.p(), EX.O1})
Description.new(EX.S, init: {EX.S, EX.p(), EX.O1})
end
test "a single statement as a subject-predicate-object tuple and the proper description subject",
@ -356,7 +394,7 @@ defmodule RDF.DescriptionTest do
assert Description.delete(description1, {EX.S, EX.p(), EX.O}) == empty_description
assert Description.delete(description2, {EX.S, EX.p(), EX.O2}) ==
Description.new({EX.S, EX.p(), EX.O1})
Description.new(EX.S, init: {EX.S, EX.p(), EX.O1})
end
test "a single statement as a subject-predicate-object tuple and another description subject",
@ -390,7 +428,7 @@ defmodule RDF.DescriptionTest do
{EX.p1(), EX.O1},
{EX.p2(), [EX.O2, EX.O3]},
{EX.S, EX.p3(), [~B<foo>, ~L"bar"]}
]) == Description.new({EX.S, EX.p1(), EX.O2})
]) == Description.new(EX.S, init: {EX.S, EX.p1(), EX.O2})
end
test "multiple statements with a map of predications",
@ -401,7 +439,7 @@ defmodule RDF.DescriptionTest do
EX.p1() => EX.O1,
EX.p2() => [EX.O2, EX.O3],
EX.p3() => [~B<foo>, ~L"bar"]
}) == Description.new({EX.S, EX.p1(), EX.O2})
}) == Description.new(EX.S, init: {EX.S, EX.p1(), EX.O2})
end
test "multiple statements with another description",
@ -414,13 +452,14 @@ defmodule RDF.DescriptionTest do
assert Description.delete(
description3,
Description.new(EX.S)
|> Description.add(%{
EX.p1() => EX.O1,
EX.p2() => [EX.O2, EX.O3],
EX.p3() => [~B<foo>, ~L"bar"]
})
) == Description.new({EX.S, EX.p1(), EX.O2})
Description.new(EX.S,
init: %{
EX.p1() => EX.O1,
EX.p2() => [EX.O2, EX.O3],
EX.p3() => [~B<foo>, ~L"bar"]
}
)
) == Description.new(EX.S, init: {EX.S, EX.p1(), EX.O2})
end
end
@ -428,13 +467,14 @@ defmodule RDF.DescriptionTest do
setup do
{:ok,
empty_description: Description.new(EX.S),
description1: Description.new({EX.S, EX.p(), [EX.O1, EX.O2]}),
description1: Description.new(EX.S, init: {EX.S, EX.p(), [EX.O1, EX.O2]}),
description2:
Description.new(EX.S)
|> Description.add([
{EX.P1, [EX.O1, EX.O2]},
{EX.p2(), [~B<foo>, ~L"bar"]}
])}
Description.new(EX.S,
init: [
{EX.P1, [EX.O1, EX.O2]},
{EX.p2(), [~B<foo>, ~L"bar"]}
]
)}
end
test "a single property",
@ -446,7 +486,7 @@ defmodule RDF.DescriptionTest do
assert Description.delete_predicates(description1, EX.p()) == empty_description
assert Description.delete_predicates(description2, EX.P1) ==
Description.new({EX.S, EX.p2(), [~B<foo>, ~L"bar"]})
Description.new(EX.S, init: {EX.S, EX.p2(), [~B<foo>, ~L"bar"]})
end
test "a list of properties",
@ -464,18 +504,18 @@ defmodule RDF.DescriptionTest do
describe "update/4" do
test "list values returned from the update function become new coerced objects of the predicate" do
assert Description.new({EX.S, EX.P, [EX.O1, EX.O2]})
assert Description.new(EX.S, init: {EX.S, EX.P, [EX.O1, EX.O2]})
|> Description.update(
EX.P,
fn [_object | other] -> [EX.O3 | other] end
) ==
Description.new({EX.S, EX.P, [EX.O3, EX.O2]})
Description.new(EX.S, init: {EX.S, EX.P, [EX.O3, EX.O2]})
end
test "single values returned from the update function becomes new object of the predicate" do
assert Description.new({EX.S, EX.P, [EX.O1, EX.O2]})
assert Description.new(EX.S, init: {EX.S, EX.P, [EX.O1, EX.O2]})
|> Description.update(EX.P, fn _ -> EX.O3 end) ==
Description.new({EX.S, EX.P, EX.O3})
Description.new(EX.S, init: {EX.S, EX.P, EX.O3})
end
test "returning an empty list or nil from the update function causes a removal of the predications" do
@ -495,12 +535,10 @@ defmodule RDF.DescriptionTest do
test "when the property is not present the initial object value is added for the predicate and the update function not called" do
fun = fn _ -> raise "should not be called" end
assert Description.new(EX.S)
|> Description.update(EX.P, EX.O, fun) ==
Description.new({EX.S, EX.P, EX.O})
assert Description.new(EX.S) |> Description.update(EX.P, EX.O, fun) ==
Description.new(EX.S, init: {EX.S, EX.P, EX.O})
assert Description.new(EX.S)
|> Description.update(EX.P, fun) ==
assert Description.new(EX.S) |> Description.update(EX.P, fun) ==
Description.new(EX.S)
end
end
@ -508,21 +546,19 @@ defmodule RDF.DescriptionTest do
test "pop" do
assert Description.pop(Description.new(EX.S)) == {nil, Description.new(EX.S)}
{triple, desc} = Description.new({EX.S, EX.p(), EX.O}) |> Description.pop()
{triple, desc} = Description.new(EX.S, init: {EX.S, EX.p(), EX.O}) |> Description.pop()
assert {iri(EX.S), iri(EX.p()), iri(EX.O)} == triple
assert Enum.count(desc.predications) == 0
{{subject, predicate, _}, desc} =
Description.new(EX.S)
|> Description.add([{EX.S, EX.p(), EX.O1}, {EX.S, EX.p(), EX.O2}])
Description.new(EX.S, init: [{EX.S, EX.p(), EX.O1}, {EX.S, EX.p(), EX.O2}])
|> Description.pop()
assert {subject, predicate} == {iri(EX.S), iri(EX.p())}
assert Enum.count(desc.predications) == 1
{{subject, _, _}, desc} =
Description.new(EX.S)
|> Description.add([{EX.S, EX.p1(), EX.O1}, {EX.S, EX.p2(), EX.O2}])
Description.new(EX.S, init: [{EX.S, EX.p1(), EX.O1}, {EX.S, EX.p2(), EX.O2}])
|> Description.pop()
assert subject == iri(EX.S)
@ -531,12 +567,13 @@ defmodule RDF.DescriptionTest do
test "include?/2" do
desc =
Description.new(EX.S)
|> Description.add([
{EX.p1(), [EX.O1, EX.O2]},
{EX.p2(), EX.O3},
{EX.p3(), [~B<foo>, ~L"bar"]}
])
Description.new(EX.S,
init: [
{EX.p1(), [EX.O1, EX.O2]},
{EX.p2(), EX.O3},
{EX.p3(), [~B<foo>, ~L"bar"]}
]
)
assert Description.include?(desc, {EX.p1(), EX.O2})
assert Description.include?(desc, {EX.p1(), [EX.O1, EX.O2]})
@ -545,8 +582,7 @@ defmodule RDF.DescriptionTest do
assert Description.include?(
desc,
Description.new(EX.S)
|> Description.add(%{EX.p1() => [EX.O1, EX.O2], EX.p2() => EX.O3})
Description.new(EX.S, init: %{EX.p1() => [EX.O1, EX.O2], EX.p2() => EX.O3})
)
refute Description.include?(desc, {EX.p4(), EX.O1})
@ -557,7 +593,7 @@ defmodule RDF.DescriptionTest do
test "values/1" do
assert Description.new(EX.s()) |> Description.values() == %{}
assert Description.new({EX.s(), EX.p(), ~L"Foo"}) |> Description.values() ==
assert Description.new(EX.s(), init: {EX.s(), EX.p(), ~L"Foo"}) |> Description.values() ==
%{RDF.Term.value(EX.p()) => ["Foo"]}
end
@ -572,63 +608,59 @@ defmodule RDF.DescriptionTest do
assert Description.new(EX.s()) |> Description.values(mapping) == %{}
assert Description.new({EX.s(), EX.p(), ~L"Foo"}) |> Description.values(mapping) ==
assert Description.new(EX.s(), init: {EX.s(), EX.p(), ~L"Foo"}) |> Description.values(mapping) ==
%{p: ["Foo"]}
end
describe "take/2" do
test "with a non-empty property list" do
assert Description.new(EX.S)
|> Description.add([{EX.S, EX.p1(), EX.O1}, {EX.S, EX.p2(), EX.O2}])
assert Description.new(EX.S, init: [{EX.S, EX.p1(), EX.O1}, {EX.S, EX.p2(), EX.O2}])
|> Description.take([EX.p2(), EX.p3()]) ==
Description.new({EX.S, EX.p2(), EX.O2})
Description.new(EX.S, init: {EX.S, EX.p2(), EX.O2})
end
test "with an empty property list" do
assert Description.new(EX.S)
|> Description.add([{EX.S, EX.p1(), EX.O1}, {EX.S, EX.p2(), EX.O2}])
assert Description.new(EX.S, init: [{EX.S, EX.p1(), EX.O1}, {EX.S, EX.p2(), EX.O2}])
|> Description.take([]) == Description.new(EX.S)
end
test "with nil" do
assert Description.new(EX.S)
|> Description.add([{EX.S, EX.p1(), EX.O1}, {EX.S, EX.p2(), EX.O2}])
assert Description.new(EX.S, init: [{EX.S, EX.p1(), EX.O1}, {EX.S, EX.p2(), EX.O2}])
|> Description.take(nil) ==
Description.new(EX.S)
|> Description.add([{EX.S, EX.p1(), EX.O1}, {EX.S, EX.p2(), EX.O2}])
Description.new(EX.S, init: [{EX.S, EX.p1(), EX.O1}, {EX.S, EX.p2(), EX.O2}])
end
end
test "equal/2" do
assert Description.new({EX.S, EX.p(), EX.O})
|> Description.equal?(Description.new({EX.S, EX.p(), EX.O}))
assert Description.new(EX.S, init: {EX.S, EX.p(), EX.O})
|> Description.equal?(Description.new(EX.S, init: {EX.S, EX.p(), EX.O}))
refute Description.new({EX.S, EX.p(), EX.O})
|> Description.equal?(Description.new({EX.S, EX.p(), EX.O2}))
refute Description.new(EX.S, init: {EX.S, EX.p(), EX.O})
|> Description.equal?(Description.new(EX.S, init: {EX.S, EX.p(), EX.O2}))
end
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
assert Enum.count(Description.new(EX.S, init: {EX.S, EX.p(), EX.O})) == 1
assert Enum.count(
Description.new(EX.S)
|> Description.add([{EX.S, EX.p(), EX.O1}, {EX.S, EX.p(), EX.O2}])
Description.new(EX.S, init: [{EX.S, EX.p(), EX.O1}, {EX.S, EX.p(), EX.O2}])
) == 2
end
test "Enum.member?" do
refute Enum.member?(Description.new(EX.S), {iri(EX.S), EX.p(), iri(EX.O)})
assert Enum.member?(Description.new({EX.S, EX.p(), EX.O}), {EX.S, EX.p(), EX.O})
assert Enum.member?(Description.new(EX.S, init: {EX.S, EX.p(), EX.O}), {EX.S, EX.p(), EX.O})
desc =
Description.new(EX.Subject)
|> Description.add([
{EX.Subject, EX.predicate1(), EX.Object1},
{EX.Subject, EX.predicate2(), EX.Object2},
{EX.predicate2(), EX.Object3}
])
Description.new(EX.Subject,
init: [
{EX.Subject, EX.predicate1(), EX.Object1},
{EX.Subject, EX.predicate2(), EX.Object2},
{EX.predicate2(), EX.Object3}
]
)
assert Enum.member?(desc, {EX.Subject, EX.predicate1(), EX.Object1})
assert Enum.member?(desc, {EX.Subject, EX.predicate2(), EX.Object2})
@ -638,12 +670,13 @@ defmodule RDF.DescriptionTest do
test "Enum.reduce" do
desc =
Description.new(EX.Subject)
|> Description.add([
{EX.Subject, EX.predicate1(), EX.Object1},
{EX.Subject, EX.predicate2(), EX.Object2},
{EX.predicate2(), EX.Object3}
])
Description.new(EX.Subject,
init: [
{EX.Subject, EX.predicate1(), EX.Object1},
{EX.Subject, EX.predicate2(), EX.Object2},
{EX.predicate2(), EX.Object3}
]
)
assert desc ==
Enum.reduce(desc, description(), fn triple, acc ->
@ -660,7 +693,7 @@ defmodule RDF.DescriptionTest do
}
assert Enum.into(map, Description.new(EX.Subject)) ==
Description.new(EX.Subject) |> Description.add(map)
Description.new(EX.Subject, init: map)
end
test "with a list of triples" do
@ -670,8 +703,7 @@ defmodule RDF.DescriptionTest do
]
assert Enum.into(triples, Description.new(EX.Subject)) ==
Description.new(EX.Subject)
|> Description.add(triples)
Description.new(EX.Subject, init: triples)
end
test "with a list of predicate-object pairs" do
@ -681,8 +713,7 @@ defmodule RDF.DescriptionTest do
]
assert Enum.into(pairs, Description.new(EX.Subject)) ==
Description.new(EX.Subject)
|> Description.add(pairs)
Description.new(EX.Subject, init: pairs)
end
test "with a list of lists" do
@ -692,8 +723,7 @@ defmodule RDF.DescriptionTest do
]
assert Enum.into(lists, Description.new(EX.Subject)) ==
Description.new(EX.Subject)
|> Description.add(Enum.map(lists, &List.to_tuple/1))
Description.new(EX.Subject, init: Enum.map(lists, &List.to_tuple/1))
end
end
@ -701,24 +731,29 @@ defmodule RDF.DescriptionTest do
test "access with the [] operator" do
assert Description.new(EX.Subject)[EX.predicate()] == nil
assert Description.new({EX.Subject, EX.predicate(), EX.Object})[EX.predicate()] == [
assert Description.new(EX.Subject, init: {EX.Subject, EX.predicate(), EX.Object})[
EX.predicate()
] == [
iri(EX.Object)
]
assert Description.new({EX.Subject, EX.Predicate, EX.Object})[EX.Predicate] == [
assert Description.new(EX.Subject, init: {EX.Subject, EX.Predicate, EX.Object})[
EX.Predicate
] == [
iri(EX.Object)
]
assert Description.new({EX.Subject, EX.predicate(), EX.Object})[
assert Description.new(EX.Subject, init: {EX.Subject, EX.predicate(), EX.Object})[
"http://example.com/predicate"
] == [iri(EX.Object)]
assert (Description.new(EX.Subject)
|> Description.add([
{EX.Subject, EX.predicate1(), EX.Object1},
{EX.Subject, EX.predicate1(), EX.Object2},
{EX.Subject, EX.predicate2(), EX.Object3}
]))[EX.predicate1()] ==
assert Description.new(EX.Subject,
init: [
{EX.Subject, EX.predicate1(), EX.Object1},
{EX.Subject, EX.predicate1(), EX.Object2},
{EX.Subject, EX.predicate2(), EX.Object3}
]
)[EX.predicate1()] ==
[iri(EX.Object1), iri(EX.Object2)]
end
end

View file

@ -15,7 +15,7 @@ defmodule RDF.DiffTest do
assert Diff.new(additions: Graph.new(), deletions: Graph.new()) ==
%Diff{additions: Graph.new(), deletions: Graph.new()}
description = Description.new({EX.S, EX.p(), EX.O1})
description = Description.new(EX.S, init: {EX.p(), EX.O1})
graph = Graph.new({EX.S, EX.p(), EX.O2})
assert Diff.new(additions: description, deletions: graph) ==
@ -30,8 +30,8 @@ defmodule RDF.DiffTest do
end
test "with two descriptions with different subjects" do
description1 = Description.new({EX.S1, EX.p(), EX.O})
description2 = Description.new({EX.S2, EX.p(), EX.O})
description1 = Description.new(EX.S1, init: {EX.p(), EX.O})
description2 = Description.new(EX.S2, init: {EX.p(), EX.O})
assert Diff.diff(description1, description2) ==
Diff.new(
@ -41,7 +41,7 @@ defmodule RDF.DiffTest do
end
test "with two descriptions when the second description has additional statements" do
description1 = Description.new({EX.S, EX.p(), EX.O})
description1 = Description.new(EX.S, init: {EX.p(), EX.O})
description2 =
description1
@ -61,7 +61,7 @@ defmodule RDF.DiffTest do
end
test "with two descriptions when the first description has additional statements" do
description1 = Description.new({EX.S, EX.p(), EX.O})
description1 = Description.new(EX.S, init: {EX.p(), EX.O})
description2 =
description1

View file

@ -84,16 +84,18 @@ defmodule RDF.GraphTest do
test "creating a named graph with an initial description" do
g =
Graph.new(Description.new({EX.Subject, EX.predicate(), EX.Object}),
name: EX.GraphName
)
Description.new(EX.Subject, init: {EX.predicate(), EX.Object})
|> Graph.new(name: EX.GraphName)
assert named_graph?(g, iri(EX.GraphName))
assert graph_includes_statement?(g, {EX.Subject, EX.predicate(), EX.Object})
end
test "creating an unnamed graph with an initial description" do
g = Graph.new(Description.new({EX.Subject, EX.predicate(), EX.Object}))
g =
Description.new(EX.Subject, init: {EX.predicate(), EX.Object})
|> Graph.new()
assert unnamed_graph?(g)
assert graph_includes_statement?(g, {EX.Subject, EX.predicate(), EX.Object})
end
@ -226,7 +228,8 @@ defmodule RDF.GraphTest do
assert graph_includes_statement?(g, {EX.Subject1, EX.predicate1(), EX.Object1})
assert graph_includes_statement?(g, {EX.Subject1, EX.predicate2(), EX.Object2})
g = Graph.add(g, Description.new({EX.Subject1, EX.predicate3(), EX.Object3}))
g = Graph.add(g, Description.new(EX.Subject1, init: {EX.predicate3(), EX.Object3}))
assert graph_includes_statement?(g, {EX.Subject1, EX.predicate1(), EX.Object1})
assert graph_includes_statement?(g, {EX.Subject1, EX.predicate2(), EX.Object2})
assert graph_includes_statement?(g, {EX.Subject1, EX.predicate3(), EX.Object3})
@ -235,9 +238,9 @@ defmodule RDF.GraphTest do
test "a list of Descriptions" do
g =
Graph.add(graph(), [
Description.new({EX.Subject1, EX.predicate1(), EX.Object1}),
Description.new({EX.Subject2, EX.predicate2(), EX.Object2}),
Description.new({EX.Subject1, EX.predicate3(), EX.Object3})
Description.new(EX.Subject1, init: {EX.predicate1(), EX.Object1}),
Description.new(EX.Subject2, init: {EX.predicate2(), EX.Object2}),
Description.new(EX.Subject1, init: {EX.predicate3(), EX.Object3})
])
assert graph_includes_statement?(g, {EX.Subject1, EX.predicate1(), EX.Object1})
@ -462,10 +465,10 @@ defmodule RDF.GraphTest do
|> Description.add([{EX.p(), EX.O}, {EX.p2(), EX.O2}])
) == Graph.new()
assert Graph.delete(graph2, Description.new({EX.S, EX.p(), [EX.O1, EX.O2]})) ==
assert Graph.delete(graph2, Description.new(EX.S, init: {EX.p(), [EX.O1, EX.O2]})) ==
Graph.new(name: EX.Graph)
assert Graph.delete(graph3, Description.new({EX.S3, EX.p3(), ~B<foo>})) ==
assert Graph.delete(graph3, Description.new(EX.S3, init: {EX.p3(), ~B<foo>})) ==
Graph.new([
{EX.S1, EX.p1(), [EX.O1, EX.O2]},
{EX.S2, EX.p2(), EX.O3},
@ -480,9 +483,7 @@ defmodule RDF.GraphTest do
assert Graph.delete(
graph2,
Graph.new({EX.S, EX.p(), [EX.O1, EX.O3]},
name: EX.Graph
)
Graph.new({EX.S, EX.p(), [EX.O1, EX.O3]}, name: EX.Graph)
) ==
Graph.new({EX.S, EX.p(), EX.O2}, name: EX.Graph)
@ -531,8 +532,8 @@ defmodule RDF.GraphTest do
describe "update/4" do
test "a description returned from the update function becomes new description of the subject" do
old_description = Description.new({EX.S2, EX.p2(), EX.O3})
new_description = Description.new({EX.S2, EX.p(), EX.O})
old_description = Description.new(EX.S2, init: {EX.p2(), EX.O3})
new_description = Description.new(EX.S2, init: {EX.p(), EX.O})
assert Graph.new([
{EX.S1, EX.p1(), [EX.O1, EX.O2]},
@ -546,8 +547,8 @@ defmodule RDF.GraphTest do
end
test "a description with another subject returned from the update function becomes new description of the subject" do
old_description = Description.new({EX.S2, EX.p2(), EX.O3})
new_description = Description.new({EX.S2, EX.p(), EX.O})
old_description = Description.new(EX.S2, init: {EX.p2(), EX.O3})
new_description = Description.new(EX.S2, init: {EX.p(), EX.O})
assert Graph.new([
{EX.S1, EX.p1(), [EX.O1, EX.O2]},
@ -556,7 +557,7 @@ defmodule RDF.GraphTest do
|> Graph.update(
EX.S2,
fn ^old_description ->
Description.new(EX.S3) |> Description.add(new_description)
Description.new(EX.S3, init: new_description)
end
) ==
Graph.new([
@ -566,7 +567,7 @@ defmodule RDF.GraphTest do
end
test "a value returned from the update function becomes new coerced description of the subject" do
old_description = Description.new({EX.S2, EX.p2(), EX.O3})
old_description = Description.new(EX.S2, init: {EX.p2(), EX.O3})
new_description = {EX.p(), [EX.O1, EX.O2]}
assert Graph.new([
@ -874,7 +875,7 @@ defmodule RDF.GraphTest do
assert Graph.new()[EX.Subject] == nil
assert Graph.new({EX.S, EX.p(), EX.O})[EX.S] ==
Description.new({EX.S, EX.p(), EX.O})
Description.new(EX.S, init: {EX.p(), EX.O})
end
end
end

View file

@ -282,21 +282,21 @@ defmodule RDF.Vocabulary.NamespaceTest do
assert Example.__ENV__() == ~I<http://example.com/ex#__ENV__>
assert Example.__CALLER__() == ~I<http://example.com/ex#__CALLER__>
assert Example.nil(EX.S, 1) == RDF.description({EX.S, Example.nil(), 1})
assert Example.true(EX.S, 1) == RDF.description({EX.S, Example.true(), 1})
assert Example.false(EX.S, 1) == RDF.description({EX.S, Example.false(), 1})
assert Example.do(EX.S, 1) == RDF.description({EX.S, Example.do(), 1})
assert Example.end(EX.S, 1) == RDF.description({EX.S, Example.end(), 1})
assert Example.else(EX.S, 1) == RDF.description({EX.S, Example.else(), 1})
assert Example.try(EX.S, 1) == RDF.description({EX.S, Example.try(), 1})
assert Example.rescue(EX.S, 1) == RDF.description({EX.S, Example.rescue(), 1})
assert Example.catch(EX.S, 1) == RDF.description({EX.S, Example.catch(), 1})
assert Example.after(EX.S, 1) == RDF.description({EX.S, Example.after(), 1})
assert Example.not(EX.S, 1) == RDF.description({EX.S, Example.not(), 1})
assert Example.cond(EX.S, 1) == RDF.description({EX.S, Example.cond(), 1})
assert Example.inbits(EX.S, 1) == RDF.description({EX.S, Example.inbits(), 1})
assert Example.inlist(EX.S, 1) == RDF.description({EX.S, Example.inlist(), 1})
assert Example.receive(EX.S, 1) == RDF.description({EX.S, Example.receive(), 1})
assert Example.nil(EX.S, 1) == RDF.description(EX.S, init: {EX.S, Example.nil(), 1})
assert Example.true(EX.S, 1) == RDF.description(EX.S, init: {EX.S, Example.true(), 1})
assert Example.false(EX.S, 1) == RDF.description(EX.S, init: {EX.S, Example.false(), 1})
assert Example.do(EX.S, 1) == RDF.description(EX.S, init: {EX.S, Example.do(), 1})
assert Example.end(EX.S, 1) == RDF.description(EX.S, init: {EX.S, Example.end(), 1})
assert Example.else(EX.S, 1) == RDF.description(EX.S, init: {EX.S, Example.else(), 1})
assert Example.try(EX.S, 1) == RDF.description(EX.S, init: {EX.S, Example.try(), 1})
assert Example.rescue(EX.S, 1) == RDF.description(EX.S, init: {EX.S, Example.rescue(), 1})
assert Example.catch(EX.S, 1) == RDF.description(EX.S, init: {EX.S, Example.catch(), 1})
assert Example.after(EX.S, 1) == RDF.description(EX.S, init: {EX.S, Example.after(), 1})
assert Example.not(EX.S, 1) == RDF.description(EX.S, init: {EX.S, Example.not(), 1})
assert Example.cond(EX.S, 1) == RDF.description(EX.S, init: {EX.S, Example.cond(), 1})
assert Example.inbits(EX.S, 1) == RDF.description(EX.S, init: {EX.S, Example.inbits(), 1})
assert Example.inlist(EX.S, 1) == RDF.description(EX.S, init: {EX.S, Example.inlist(), 1})
assert Example.receive(EX.S, 1) == RDF.description(EX.S, init: {EX.S, Example.receive(), 1})
end
describe "defvocab with invalid terms" do
@ -885,7 +885,7 @@ defmodule RDF.Vocabulary.NamespaceTest do
alias TestNS.EX
assert Example._foo() == ~I<http://example.com/ex#_foo>
assert Example._foo(EX.S, 1) == RDF.description({EX.S, Example._foo(), 1})
assert Example._foo(EX.S, 1) == RDF.description(EX.S, init: {EX.S, Example._foo(), 1})
end
end
@ -966,7 +966,7 @@ defmodule RDF.Vocabulary.NamespaceTest do
alias TestNS.{EX, EXS}
test "one statement with a strict property term" do
assert EXS.foo(EX.S, EX.O) == Description.new({EX.S, EXS.foo(), EX.O})
assert EXS.foo(EX.S, EX.O) == Description.new(EX.S, init: {EXS.foo(), EX.O})
end
test "multiple statements with strict property terms and one object" do
@ -976,7 +976,7 @@ defmodule RDF.Vocabulary.NamespaceTest do
|> EXS.bar(EX.O2)
assert description ==
Description.new(EX.S) |> Description.add([{EXS.foo(), EX.O1}, {EXS.bar(), EX.O2}])
Description.new(EX.S, init: [{EXS.foo(), EX.O1}, {EXS.bar(), EX.O2}])
end
test "multiple statements with strict property terms and multiple objects in a list" do
@ -986,13 +986,14 @@ defmodule RDF.Vocabulary.NamespaceTest do
|> EXS.bar([EX.O3, EX.O4])
assert description ==
Description.new(EX.S)
|> Description.add([
{EXS.foo(), EX.O1},
{EXS.foo(), EX.O2},
{EXS.bar(), EX.O3},
{EXS.bar(), EX.O4}
])
Description.new(EX.S,
init: [
{EXS.foo(), EX.O1},
{EXS.foo(), EX.O2},
{EXS.bar(), EX.O3},
{EXS.bar(), EX.O4}
]
)
end
test "multiple statements with strict property terms and multiple objects as arguments" do
@ -1002,18 +1003,19 @@ defmodule RDF.Vocabulary.NamespaceTest do
|> EXS.bar(EX.O3, EX.O4, EX.O5)
assert description ==
Description.new(EX.S)
|> Description.add([
{EXS.foo(), EX.O1},
{EXS.foo(), EX.O2},
{EXS.bar(), EX.O3},
{EXS.bar(), EX.O4},
{EXS.bar(), EX.O5}
])
Description.new(EX.S,
init: [
{EXS.foo(), EX.O1},
{EXS.foo(), EX.O2},
{EXS.bar(), EX.O3},
{EXS.bar(), EX.O4},
{EXS.bar(), EX.O5}
]
)
end
test "one statement with a non-strict property term" do
assert EX.p(EX.S, EX.O) == Description.new({EX.S, EX.p(), EX.O})
assert EX.p(EX.S, EX.O) == Description.new(EX.S, init: {EX.p(), EX.O})
end
test "multiple statements with non-strict property terms and one object" do
@ -1023,7 +1025,7 @@ defmodule RDF.Vocabulary.NamespaceTest do
|> EX.p2(EX.O2)
assert description ==
Description.new(EX.S) |> Description.add([{EX.p1(), EX.O1}, {EX.p2(), EX.O2}])
Description.new(EX.S, init: [{EX.p1(), EX.O1}, {EX.p2(), EX.O2}])
end
test "multiple statements with non-strict property terms and multiple objects in a list" do
@ -1033,13 +1035,14 @@ defmodule RDF.Vocabulary.NamespaceTest do
|> EX.p2([EX.O3, EX.O4])
assert description ==
Description.new(EX.S)
|> Description.add([
{EX.p1(), EX.O1},
{EX.p1(), EX.O2},
{EX.p2(), EX.O3},
{EX.p2(), EX.O4}
])
Description.new(EX.S,
init: [
{EX.p1(), EX.O1},
{EX.p1(), EX.O2},
{EX.p2(), EX.O3},
{EX.p2(), EX.O4}
]
)
end
test "multiple statements with non-strict property terms and multiple objects as arguments" do
@ -1049,13 +1052,14 @@ defmodule RDF.Vocabulary.NamespaceTest do
|> EX.p2(EX.O3, EX.O4)
assert description ==
Description.new(EX.S)
|> Description.add([
{EX.p1(), EX.O1},
{EX.p1(), EX.O2},
{EX.p2(), EX.O3},
{EX.p2(), EX.O4}
])
Description.new(EX.S,
init: [
{EX.p1(), EX.O1},
{EX.p1(), EX.O2},
{EX.p2(), EX.O3},
{EX.p2(), EX.O4}
]
)
end
end