diff --git a/lib/rdf/star/quad.ex b/lib/rdf/star/quad.ex new file mode 100644 index 0000000..903fd0c --- /dev/null +++ b/lib/rdf/star/quad.ex @@ -0,0 +1,121 @@ +defmodule RDF.Star.Quad do + @moduledoc """ + Helper functions for RDF-star quads. + + An RDF-star quad is represented as a plain Elixir tuple consisting of four valid + RDF values for subject, predicate, object and a graph name. + As opposed to an `RDF.Quad` the subject or object can be a triple. + """ + + alias RDF.Star.Statement + alias RDF.PropertyMap + + @type t :: { + Statement.subject(), + Statement.predicate(), + Statement.object(), + Statement.graph_name() + } + + @type t_values :: {String.t(), String.t(), any, String.t()} + + @doc """ + Creates a `RDF.Star.Quad` with proper RDF-star values. + + An error is raised when the given elements are not coercible to RDF-star values. + + Note: The `RDF.quad` function is a shortcut to this function. + + ## Examples + + iex> RDF.Star.Quad.new("http://example.com/S", "http://example.com/p", 42, "http://example.com/Graph") + {~I, ~I, RDF.literal(42), ~I} + + iex> RDF.Star.Quad.new(EX.S, EX.p, 42, EX.Graph) + {RDF.iri("http://example.com/S"), RDF.iri("http://example.com/p"), RDF.literal(42), RDF.iri("http://example.com/Graph")} + + iex> RDF.Star.Quad.new(EX.S, :p, 42, EX.Graph, RDF.PropertyMap.new(p: EX.p)) + {RDF.iri("http://example.com/S"), RDF.iri("http://example.com/p"), RDF.literal(42), RDF.iri("http://example.com/Graph")} + + iex> RDF.Star.Quad.new(EX.S, :p, 42, EX.Graph, RDF.PropertyMap.new(p: EX.p)) + {RDF.iri("http://example.com/S"), RDF.iri("http://example.com/p"), RDF.literal(42), RDF.iri("http://example.com/Graph")} + + iex> RDF.Star.Quad.new({EX.S, :p, 42}, :p2, 43, EX.Graph, RDF.PropertyMap.new(p: EX.p, p2: EX.p2)) + {{~I, ~I, RDF.literal(42)}, ~I, RDF.literal(43), ~I} + + """ + @spec new( + Statement.coercible_subject(), + Statement.coercible_predicate(), + Statement.coercible_object(), + Statement.coercible_graph_name(), + PropertyMap.t() | nil + ) :: t + def new(subject, predicate, object, graph_name, property_map \\ nil) + + def new(subject, predicate, object, graph_name, nil) do + { + Statement.coerce_subject(subject), + Statement.coerce_predicate(predicate), + Statement.coerce_object(object), + Statement.coerce_graph_name(graph_name) + } + end + + def new(subject, predicate, object, graph_name, %PropertyMap{} = property_map) do + { + Statement.coerce_subject(subject, property_map), + Statement.coerce_predicate(predicate, property_map), + Statement.coerce_object(object, property_map), + Statement.coerce_graph_name(graph_name) + } + end + + @doc """ + Creates a `RDF.Star.Quad` with proper RDF-star values. + + An error is raised when the given elements are not coercible to RDF-star values. + + Note: The `RDF.quad` function is a shortcut to this function. + + ## Examples + + iex> RDF.Star.Quad.new {"http://example.com/S", "http://example.com/p", 42, "http://example.com/Graph"} + {~I, ~I, RDF.literal(42), ~I} + + iex> RDF.Star.Quad.new {EX.S, EX.p, 42, EX.Graph} + {RDF.iri("http://example.com/S"), RDF.iri("http://example.com/p"), RDF.literal(42), RDF.iri("http://example.com/Graph")} + + iex> RDF.Star.Quad.new {EX.S, EX.p, 42} + {RDF.iri("http://example.com/S"), RDF.iri("http://example.com/p"), RDF.literal(42), nil} + + iex> RDF.Star.Quad.new {EX.S, :p, 42, EX.Graph}, RDF.PropertyMap.new(p: EX.p) + {RDF.iri("http://example.com/S"), RDF.iri("http://example.com/p"), RDF.literal(42), RDF.iri("http://example.com/Graph")} + + iex> RDF.Star.Quad.new({{EX.S, :p, 42}, :p2, 43, EX.Graph}, RDF.PropertyMap.new(p: EX.p, p2: EX.p2)) + {{~I, ~I, RDF.literal(42)}, ~I, RDF.literal(43), ~I} + + """ + @spec new(Statement.coercible_t(), PropertyMap.t() | nil) :: t + def new(statement, property_map \\ nil) + + def new({subject, predicate, object, graph_name}, property_map) do + new(subject, predicate, object, graph_name, property_map) + end + + def new({subject, predicate, object}, property_map) do + new(subject, predicate, object, nil, property_map) + end + + @doc """ + Checks if the given tuple is a valid RDF quad. + + The elements of a valid RDF-star quad must be RDF terms. On the subject position + only IRIs, blank nodes and triples are allowed, while on the predicate and graph name + position only IRIs allowed. The object position can be any RDF term or triple. + """ + @spec valid?(t | any) :: boolean + def valid?(tuple) + def valid?({_, _, _, _} = quad), do: Statement.valid?(quad) + def valid?(_), do: false +end diff --git a/lib/rdf/star/statement.ex b/lib/rdf/star/statement.ex new file mode 100644 index 0000000..37f86a4 --- /dev/null +++ b/lib/rdf/star/statement.ex @@ -0,0 +1,126 @@ +defmodule RDF.Star.Statement do + @moduledoc """ + Helper functions for RDF-star statements. + + An RDF-star statement is either a `RDF.Star.Triple` or a `RDF.Star.Quad`. + """ + + alias RDF.Star.{Triple, Quad} + alias RDF.PropertyMap + + @type subject :: RDF.Statement.subject() | Triple.t() + @type predicate :: RDF.Statement.predicate() + @type object :: RDF.Statement.object() | Triple.t() + @type graph_name :: RDF.Statement.graph_name() + + @type coercible_subject :: RDF.Statement.coercible_subject() | Triple.t() + @type coercible_predicate :: RDF.Statement.coercible_predicate() + @type coercible_object :: RDF.Statement.coercible_object() | Triple.t() + @type coercible_graph_name :: RDF.Statement.coercible_graph_name() + + @type t :: Triple.t() | Quad.t() + @type coercible_t :: + {coercible_subject(), coercible_predicate(), coercible_object(), coercible_graph_name()} + | {coercible_subject(), coercible_predicate(), coercible_object()} + + @doc """ + Creates a `RDF.Star.Triple` or `RDF.Star.Quad` with proper RDF values. + + An error is raised when the given elements are not coercible to RDF values. + + Note: The `RDF.statement` function is a shortcut to this function. + + ## Examples + + iex> RDF.Star.Statement.new({EX.S, EX.p, 42}) + {RDF.iri("http://example.com/S"), RDF.iri("http://example.com/p"), RDF.literal(42)} + + iex> RDF.Star.Statement.new({EX.S, EX.p, 42, EX.Graph}) + {RDF.iri("http://example.com/S"), RDF.iri("http://example.com/p"), RDF.literal(42), RDF.iri("http://example.com/Graph")} + + iex> RDF.Star.Statement.new({EX.S, :p, 42, EX.Graph}, RDF.PropertyMap.new(p: EX.p)) + {RDF.iri("http://example.com/S"), RDF.iri("http://example.com/p"), RDF.literal(42), RDF.iri("http://example.com/Graph")} + """ + def new(tuple, property_map \\ nil) + def new({_, _, _} = tuple, property_map), do: Triple.new(tuple, property_map) + def new({_, _, _, _} = tuple, property_map), do: Quad.new(tuple, property_map) + + defdelegate new(s, p, o), to: Triple, as: :new + defdelegate new(s, p, o, g), to: Quad, as: :new + + @doc """ + Creates a `RDF.Star.Statement` tuple with proper RDF values. + + An error is raised when the given elements are not coercible to RDF values. + + ## Examples + + iex> RDF.Star.Statement.coerce {"http://example.com/S", "http://example.com/p", 42} + {~I, ~I, RDF.literal(42)} + iex> RDF.Star.Statement.coerce {"http://example.com/S", "http://example.com/p", 42, "http://example.com/Graph"} + {~I, ~I, RDF.literal(42), ~I} + """ + @spec coerce(coercible_t(), PropertyMap.t() | nil) :: Triple.t() | Quad.t() + def coerce(statement, property_map \\ nil) + def coerce({_, _, _} = triple, property_map), do: Triple.new(triple, property_map) + def coerce({_, _, _, _} = quad, property_map), do: Quad.new(quad, property_map) + + @doc false + @spec coerce_subject(coercible_subject, PropertyMap.t() | nil) :: subject + def coerce_subject(subject, property_map \\ nil) + def coerce_subject({_, _, _} = triple, property_map), do: Triple.new(triple, property_map) + def coerce_subject(subject, _), do: RDF.Statement.coerce_subject(subject) + + @doc false + @spec coerce_predicate(coercible_predicate) :: predicate + def coerce_predicate(iri), do: RDF.Statement.coerce_predicate(iri) + + @doc false + @spec coerce_predicate(coercible_predicate, PropertyMap.t()) :: predicate + def coerce_predicate(term, context), do: RDF.Statement.coerce_predicate(term, context) + + @doc false + @spec coerce_object(coercible_object, PropertyMap.t() | nil) :: object + def coerce_object(object, property_map \\ nil) + def coerce_object({_, _, _} = triple, property_map), do: Triple.new(triple, property_map) + def coerce_object(object, _), do: RDF.Statement.coerce_object(object) + + @doc false + @spec coerce_graph_name(coercible_graph_name) :: graph_name + def coerce_graph_name(iri), do: RDF.Statement.coerce_graph_name(iri) + + @doc """ + Checks if the given tuple is a valid RDF-star statement, i.e. RDF-star triple or quad. + + The elements of a valid RDF-star statement must be RDF terms. On the subject + position only IRIs, blank nodes and triples allowed, while on the predicate and graph + context position only IRIs allowed. The object position can be any RDF term or a triple. + """ + @spec valid?(Triple.t() | Quad.t() | any) :: boolean + def valid?(tuple) + + def valid?({subject, predicate, object}) do + valid_subject?(subject) && valid_predicate?(predicate) && valid_object?(object) + end + + def valid?({subject, predicate, object, graph_name}) do + valid_subject?(subject) && valid_predicate?(predicate) && valid_object?(object) && + valid_graph_name?(graph_name) + end + + def valid?(_), do: false + + @spec valid_subject?(subject | any) :: boolean + def valid_subject?({_, _, _} = triple), do: Triple.valid?(triple) + def valid_subject?(any), do: RDF.Statement.valid_subject?(any) + + @spec valid_predicate?(predicate | any) :: boolean + def valid_predicate?(any), do: RDF.Statement.valid_predicate?(any) + + @spec valid_object?(object | any) :: boolean + def valid_object?({_, _, _} = triple), do: Triple.valid?(triple) + def valid_object?(any), do: RDF.Statement.valid_object?(any) + + @spec valid_graph_name?(graph_name | any) :: boolean + def valid_graph_name?(any), do: RDF.Statement.valid_graph_name?(any) +end diff --git a/lib/rdf/star/triple.ex b/lib/rdf/star/triple.ex new file mode 100644 index 0000000..08ca8ab --- /dev/null +++ b/lib/rdf/star/triple.ex @@ -0,0 +1,104 @@ +defmodule RDF.Star.Triple do + @moduledoc """ + Helper functions for RDF-star triples. + + An RDF-star triple is represented as a plain Elixir tuple consisting of three valid + RDF values for subject, predicate and object. + As opposed to an `RDF.Triple` the subject or object can be a triple itself. + """ + + alias RDF.Star.Statement + alias RDF.PropertyMap + + @type t :: {Statement.subject(), Statement.predicate(), Statement.object()} + + @doc """ + Creates a `RDF.Star.Triple` with proper RDF-star values. + + An error is raised when the given elements are not coercible to RDF-star values. + + Note: The `RDF.triple` function is a shortcut to this function. + + ## Examples + + iex> RDF.Star.Triple.new({"http://example.com/S", "http://example.com/p", 42}, "http://example.com/p2", 43) + {{~I, ~I, RDF.literal(42)}, ~I, RDF.literal(43)} + + iex> RDF.Star.Triple.new({EX.S, EX.p, 42}, EX.p2, 43) + {{~I, ~I, RDF.literal(42)}, ~I, RDF.literal(43)} + + iex> RDF.Star.Triple.new(EX.S, EX.p, 42) + {RDF.iri("http://example.com/S"), RDF.iri("http://example.com/p"), RDF.literal(42)} + + iex> RDF.Star.Triple.new({EX.S, :p, 42}, :p2, 43, RDF.PropertyMap.new(p: EX.p, p2: EX.p2)) + {{~I, ~I, RDF.literal(42)}, ~I, RDF.literal(43)} + """ + @spec new( + Statement.coercible_subject(), + Statement.coercible_predicate(), + Statement.coercible_object(), + PropertyMap.t() | nil + ) :: t + def new(subject, predicate, object, property_map \\ nil) + + def new(subject, predicate, object, nil) do + { + Statement.coerce_subject(subject), + Statement.coerce_predicate(predicate), + Statement.coerce_object(object) + } + end + + def new(subject, predicate, object, %PropertyMap{} = property_map) do + { + Statement.coerce_subject(subject, property_map), + Statement.coerce_predicate(predicate, property_map), + Statement.coerce_object(object, property_map) + } + end + + @doc """ + Creates a `RDF.Star.Triple` with proper RDF-star values. + + An error is raised when the given elements are not coercible to RDF-star values. + + Note: The `RDF.triple` function is a shortcut to this function. + + ## Examples + + iex> RDF.Star.Triple.new {"http://example.com/S", "http://example.com/p", 42} + {~I, ~I, RDF.literal(42)} + + iex> RDF.Star.Triple.new {EX.S, EX.p, 42} + {RDF.iri("http://example.com/S"), RDF.iri("http://example.com/p"), RDF.literal(42)} + + iex> RDF.Star.Triple.new {EX.S, EX.p, 42, EX.Graph} + {RDF.iri("http://example.com/S"), RDF.iri("http://example.com/p"), RDF.literal(42)} + + iex> RDF.Star.Triple.new {EX.S, :p, 42}, RDF.PropertyMap.new(p: EX.p) + {RDF.iri("http://example.com/S"), RDF.iri("http://example.com/p"), RDF.literal(42)} + + iex> RDF.Star.Triple.new({{EX.S, :p, 42}, :p2, 43}, RDF.PropertyMap.new(p: EX.p, p2: EX.p2)) + {{~I, ~I, RDF.literal(42)}, ~I, RDF.literal(43)} + """ + @spec new(Statement.coercible_t(), PropertyMap.t() | nil) :: t + def new(statement, property_map \\ nil) + + def new({subject, predicate, object}, property_map), + do: new(subject, predicate, object, property_map) + + def new({subject, predicate, object, _}, property_map), + do: new(subject, predicate, object, property_map) + + @doc """ + Checks if the given tuple is a valid RDF-star triple. + + The elements of a valid RDF-star triple must be RDF terms. On the subject + position only IRIs, blank nodes and triples are allowed, while on the predicate + position only IRIs allowed. The object position can be any RDF term or triple. + """ + @spec valid?(t | any) :: boolean + def valid?(tuple) + def valid?({_, _, _} = triple), do: Statement.valid?(triple) + def valid?(_), do: false +end diff --git a/test/support/rdf_case.ex b/test/support/rdf_case.ex index fa1b62f..4e320d3 100644 --- a/test/support/rdf_case.ex +++ b/test/support/rdf_case.ex @@ -6,8 +6,9 @@ defmodule RDF.Test.Case do defvocab FOAF, base_iri: "http://xmlns.com/foaf/0.1/", terms: [], strict: false - alias RDF.{Dataset, Graph, Description, IRI} + alias RDF.{Dataset, Graph, Description, IRI, XSD} import RDF, only: [iri: 1] + import RDF.Sigils using do quote do @@ -45,6 +46,75 @@ defmodule RDF.Test.Case do |> IO.iodata_to_binary() end + @iri ~I + @bnode ~B + @valid_literal ~L"foo" + @invalid_literal XSD.integer("foo") + + ############################### + # RDF.Statement + + @valid_triple {RDF.iri(EX.S), EX.p(), RDF.iri(EX.O)} + def valid_triple(), do: @valid_triple + + @valid_triples [ + @valid_triple, + {@iri, @iri, @iri}, + {@bnode, @iri, @iri}, + {@iri, @iri, @bnode}, + {@bnode, @iri, @bnode}, + {@iri, @iri, @valid_literal}, + {@bnode, @iri, @valid_literal}, + {@iri, @iri, @invalid_literal}, + {@bnode, @iri, @invalid_literal} + ] + + def valid_triples(), do: @valid_triples + + @valid_star_triples [ + {@valid_triple, @iri, @iri}, + {@iri, @iri, @valid_triple} + ] + + def valid_star_triples(), do: @valid_star_triples + + @valid_quads [ + {@iri, @iri, @iri, @iri}, + {@bnode, @iri, @iri, @iri}, + {@iri, @iri, @bnode, @iri}, + {@bnode, @iri, @bnode, @iri}, + {@iri, @iri, @valid_literal, @iri}, + {@bnode, @iri, @valid_literal, @iri}, + {@iri, @iri, @invalid_literal, @iri}, + {@bnode, @iri, @invalid_literal, @iri} + ] + def valid_quads(), do: @valid_quads + + @valid_star_quads [ + {@valid_triple, @iri, @iri, @iri}, + {@iri, @iri, @valid_triple, @iri} + ] + + def valid_star_quads(), do: @valid_star_quads + + @invalid_triples [ + {@iri, @bnode, @iri}, + {@valid_literal, @iri, @iri}, + {@iri, @valid_literal, @iri} + ] + + def invalid_triples, do: @invalid_triples + + @invalid_quads [ + {@iri, @bnode, @iri, @iri}, + {@iri, @iri, @iri, @bnode}, + {@valid_literal, @iri, @iri, @iri}, + {@iri, @valid_literal, @iri, @iri}, + {@iri, @iri, @iri, @valid_literal} + ] + + def invalid_quads(), do: @invalid_quads + ############################### # RDF.Description diff --git a/test/unit/star/quad_test.exs b/test/unit/star/quad_test.exs new file mode 100644 index 0000000..18037b4 --- /dev/null +++ b/test/unit/star/quad_test.exs @@ -0,0 +1,5 @@ +defmodule RDF.Star.QuadTest do + use RDF.Test.Case + + doctest RDF.Star.Quad +end diff --git a/test/unit/star/statement_test.exs b/test/unit/star/statement_test.exs new file mode 100644 index 0000000..bc8bb4d --- /dev/null +++ b/test/unit/star/statement_test.exs @@ -0,0 +1,147 @@ +defmodule RDF.Star.StatementTest do + use RDF.Test.Case + + doctest RDF.Star.Statement + + alias RDF.Star.{Statement, Triple, Quad} + + describe "valid?/1" do + @iri ~I + @bnode ~B + @valid_literal ~L"foo" + + test "valid triples" do + Enum.each(valid_triples(), fn argument -> + assert Statement.valid?(argument) == true + assert Triple.valid?(argument) == true + refute Quad.valid?(argument) + end) + end + + test "valid RDF-star triples" do + Enum.each(valid_star_triples(), fn argument -> + assert Statement.valid?(argument) == true + assert Triple.valid?(argument) == true + refute Quad.valid?(argument) + end) + end + + test "nested RDF-star triples" do + Enum.flat_map(valid_star_triples(), fn star_triple -> + [ + {star_triple, EX.p(), EX.o()}, + {EX.s(), EX.p(), star_triple} + ] + end) + |> Enum.each(fn argument -> + assert Statement.valid?(argument) == true + assert Triple.valid?(argument) == true + refute Quad.valid?(argument) + end) + end + + test "valid RDF quads" do + Enum.each(valid_quads(), fn argument -> + assert Statement.valid?(argument) == true + assert Quad.valid?(argument) == true + refute Triple.valid?(argument) + end) + end + + test "valid RDF-star quads" do + Enum.each(valid_star_quads(), fn argument -> + assert Statement.valid?(argument) == true + assert Quad.valid?(argument) == true + refute Triple.valid?(argument) + end) + end + + test "nested RDF-star quads" do + Enum.flat_map(valid_star_triples(), fn star_triple -> + [ + {star_triple, EX.p(), EX.o(), EX.graph()}, + {EX.s(), EX.p(), star_triple, EX.graph()} + ] + end) + |> Enum.each(fn argument -> + assert Statement.valid?(argument) == true + assert Quad.valid?(argument) == true + refute Triple.valid?(argument) + end) + end + + test "with invalid RDF triples" do + Enum.each(invalid_triples(), fn argument -> + assert Statement.valid?(argument) == false + assert Triple.valid?(argument) == false + assert Quad.valid?(argument) == false + end) + end + + test "with invalid RDF-star triples" do + [ + {{@iri, @iri}, @iri, @iri}, + {{@iri, @iri, @iri, @iri}, @iri, @iri}, + {{@iri, @valid_literal, @iri}, @iri, @iri}, + {@iri, @iri, {@iri, @iri}}, + {@iri, @iri, {@iri, @valid_literal, @iri}} + ] + |> Enum.each(fn argument -> + assert Statement.valid?(argument) == false + assert Triple.valid?(argument) == false + assert Quad.valid?(argument) == false + end) + end + + test "with invalid RDF quads" do + Enum.each(invalid_quads(), fn argument -> + assert Statement.valid?(argument) == false + assert Triple.valid?(argument) == false + assert Quad.valid?(argument) == false + end) + end + + test "with invalid RDF-star quads" do + [ + {{@iri, @iri}, @iri, @iri, @iri}, + {{@iri, @iri, @iri, @iri}, @iri, @iri, @iri}, + {{@iri, @valid_literal, @iri}, @iri, @iri, @iri}, + {@iri, @iri, {@iri, @iri}, @iri}, + {@iri, @iri, {@iri, @valid_literal, @iri}, @iri} + ] + |> Enum.each(fn argument -> + assert Statement.valid?(argument) == false + assert Triple.valid?(argument) == false + assert Quad.valid?(argument) == false + end) + end + + test "with invalid statements by number of elements" do + refute Statement.valid?({@iri, @iri}) + refute Triple.valid?({@iri, @iri}) + refute Quad.valid?({@iri, @iri}) + + refute Statement.valid?({@iri, @iri, @iri, @iri, @iri}) + refute Triple.valid?({@iri, @iri, @iri, @iri, @iri}) + refute Quad.valid?({@iri, @iri, @iri, @iri, @iri}) + + refute Triple.valid?({@iri, @iri, @iri, @iri}) + refute Quad.valid?({@iri, @iri, @iri}) + end + + test "with non-tuples" do + [ + 42, + "foo", + @iri, + @bnode, + @valid_literal + ] + |> Enum.each(fn arg -> + refute Statement.valid?(arg) + refute Triple.valid?(arg) + refute Quad.valid?(arg) + end) + end + end +end diff --git a/test/unit/star/triple_test.exs b/test/unit/star/triple_test.exs new file mode 100644 index 0000000..3ac4a9d --- /dev/null +++ b/test/unit/star/triple_test.exs @@ -0,0 +1,5 @@ +defmodule RDF.Star.TripleTest do + use RDF.Test.Case + + doctest RDF.Star.Triple +end diff --git a/test/unit/statement_test.exs b/test/unit/statement_test.exs index 1550afa..0a327e9 100644 --- a/test/unit/statement_test.exs +++ b/test/unit/statement_test.exs @@ -7,32 +7,9 @@ defmodule RDF.StatementTest do @iri ~I @bnode ~B @valid_literal ~L"foo" - @invalid_literal XSD.integer("foo") - - @valid_triples [ - {@iri, @iri, @iri}, - {@bnode, @iri, @iri}, - {@iri, @iri, @bnode}, - {@bnode, @iri, @bnode}, - {@iri, @iri, @valid_literal}, - {@bnode, @iri, @valid_literal}, - {@iri, @iri, @invalid_literal}, - {@bnode, @iri, @invalid_literal} - ] - - @valid_quads [ - {@iri, @iri, @iri, @iri}, - {@bnode, @iri, @iri, @iri}, - {@iri, @iri, @bnode, @iri}, - {@bnode, @iri, @bnode, @iri}, - {@iri, @iri, @valid_literal, @iri}, - {@bnode, @iri, @valid_literal, @iri}, - {@iri, @iri, @invalid_literal, @iri}, - {@bnode, @iri, @invalid_literal, @iri} - ] test "valid triples" do - Enum.each(@valid_triples, fn argument -> + Enum.each(valid_triples(), fn argument -> assert RDF.Statement.valid?(argument) == true assert RDF.Triple.valid?(argument) == true refute RDF.Quad.valid?(argument) @@ -40,7 +17,7 @@ defmodule RDF.StatementTest do end test "valid quads" do - Enum.each(@valid_quads, fn argument -> + Enum.each(valid_quads(), fn argument -> assert RDF.Statement.valid?(argument) == true assert RDF.Quad.valid?(argument) == true refute RDF.Triple.valid?(argument) @@ -48,12 +25,7 @@ defmodule RDF.StatementTest do end test "with invalid triples" do - [ - {@iri, @bnode, @iri}, - {@valid_literal, @iri, @iri}, - {@iri, @valid_literal, @iri} - ] - |> Enum.each(fn argument -> + Enum.each(invalid_triples(), fn argument -> assert RDF.Statement.valid?(argument) == false assert RDF.Triple.valid?(argument) == false assert RDF.Quad.valid?(argument) == false @@ -61,14 +33,7 @@ defmodule RDF.StatementTest do end test "with invalid quads" do - [ - {@iri, @bnode, @iri, @iri}, - {@iri, @iri, @iri, @bnode}, - {@valid_literal, @iri, @iri, @iri}, - {@iri, @valid_literal, @iri, @iri}, - {@iri, @iri, @iri, @valid_literal} - ] - |> Enum.each(fn argument -> + Enum.each(invalid_quads(), fn argument -> assert RDF.Statement.valid?(argument) == false assert RDF.Triple.valid?(argument) == false assert RDF.Quad.valid?(argument) == false @@ -93,7 +58,8 @@ defmodule RDF.StatementTest do 42, "foo", @iri, - @bnode + @bnode, + @valid_literal ] |> Enum.each(fn arg -> refute RDF.Statement.valid?(arg)