2016-10-15 16:26:56 +00:00
|
|
|
defmodule RDF.LiteralTest do
|
|
|
|
use ExUnit.Case
|
|
|
|
|
2017-04-10 01:06:20 +00:00
|
|
|
import RDF.Sigils
|
2017-04-16 21:13:39 +00:00
|
|
|
import RDF.TestLiterals
|
2017-04-10 01:06:20 +00:00
|
|
|
|
2017-04-20 21:09:55 +00:00
|
|
|
alias RDF.Literal
|
2017-03-12 13:27:52 +00:00
|
|
|
alias RDF.NS.XSD
|
|
|
|
|
2016-10-15 16:26:56 +00:00
|
|
|
doctest RDF.Literal
|
|
|
|
|
2017-04-23 21:41:29 +00:00
|
|
|
@examples %{
|
|
|
|
RDF.String => ["foo"],
|
|
|
|
RDF.Integer => [42],
|
|
|
|
RDF.Double => [3.14],
|
|
|
|
RDF.Boolean => [true, false],
|
|
|
|
}
|
2016-10-15 16:26:56 +00:00
|
|
|
|
2016-10-30 18:36:46 +00:00
|
|
|
|
2017-04-23 21:41:29 +00:00
|
|
|
describe "construction by type inference" do
|
|
|
|
Enum.each @examples, fn {datatype, example_values} ->
|
|
|
|
@tag example: %{datatype: datatype, values: example_values}
|
|
|
|
test (datatype |> Module.split |> List.last |> to_string), %{example: example} do
|
|
|
|
Enum.each example.values, fn example_value ->
|
|
|
|
assert Literal.new(example_value) == example.datatype.new(example_value)
|
|
|
|
end
|
|
|
|
end
|
2016-10-15 16:26:56 +00:00
|
|
|
end
|
|
|
|
|
2017-04-23 21:41:29 +00:00
|
|
|
test "when options without datatype given" do
|
|
|
|
assert Literal.new(true, %{}) == RDF.Boolean.new(true)
|
|
|
|
assert Literal.new(42, %{}) == RDF.Integer.new(42)
|
2017-04-20 21:09:55 +00:00
|
|
|
end
|
2016-10-30 18:36:46 +00:00
|
|
|
end
|
|
|
|
|
2017-04-23 21:41:29 +00:00
|
|
|
|
2017-04-20 21:09:55 +00:00
|
|
|
describe "typed construction" do
|
|
|
|
test "boolean" do
|
|
|
|
assert Literal.new(true, datatype: XSD.boolean) == RDF.Boolean.new(true)
|
|
|
|
assert Literal.new(false, datatype: XSD.boolean) == RDF.Boolean.new(false)
|
|
|
|
assert Literal.new("true", datatype: XSD.boolean) == RDF.Boolean.new("true")
|
|
|
|
assert Literal.new("false", datatype: XSD.boolean) == RDF.Boolean.new("false")
|
|
|
|
end
|
2016-10-30 18:36:46 +00:00
|
|
|
|
2017-04-20 21:09:55 +00:00
|
|
|
test "integer" do
|
|
|
|
assert Literal.new(42, datatype: XSD.integer) == RDF.Integer.new(42)
|
|
|
|
assert Literal.new("42", datatype: XSD.integer) == RDF.Integer.new("42")
|
|
|
|
end
|
2016-10-30 18:36:46 +00:00
|
|
|
|
2017-04-26 00:48:49 +00:00
|
|
|
test "double" do
|
|
|
|
assert Literal.new(3.14, datatype: XSD.double) == RDF.Double.new(3.14)
|
|
|
|
assert Literal.new("3.14", datatype: XSD.double) == RDF.Double.new("3.14")
|
|
|
|
end
|
|
|
|
|
2017-04-23 21:41:29 +00:00
|
|
|
test "string" do
|
|
|
|
assert Literal.new("foo", datatype: XSD.string) == RDF.String.new("foo")
|
|
|
|
end
|
2016-10-30 18:36:46 +00:00
|
|
|
|
2017-04-23 21:41:29 +00:00
|
|
|
test "unmapped/unknown datatype" do
|
2017-04-20 21:09:55 +00:00
|
|
|
literal = Literal.new("custom typed value", datatype: "http://example/dt")
|
|
|
|
assert literal.value == "custom typed value"
|
|
|
|
assert literal.datatype == ~I<http://example/dt>
|
2016-10-30 18:36:46 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
2017-04-20 21:09:55 +00:00
|
|
|
|
|
|
|
describe "language tagged construction" do
|
|
|
|
test "string literal with a language tag" do
|
2017-04-16 21:13:39 +00:00
|
|
|
literal = Literal.new("Eule", language: "de")
|
2017-04-20 21:09:55 +00:00
|
|
|
assert literal.value == "Eule"
|
2017-04-16 21:13:39 +00:00
|
|
|
assert literal.datatype == RDF.langString
|
|
|
|
assert literal.language == "de"
|
|
|
|
end
|
|
|
|
|
2017-04-20 21:09:55 +00:00
|
|
|
test "language is ignored on non-string literals" do
|
2017-04-16 21:13:39 +00:00
|
|
|
literal = Literal.new(1, language: "de")
|
2017-04-20 21:09:55 +00:00
|
|
|
assert literal.value == 1
|
2017-04-16 21:13:39 +00:00
|
|
|
assert literal.datatype == XSD.integer
|
|
|
|
refute literal.language
|
|
|
|
end
|
|
|
|
|
|
|
|
test "construction of an other than rdf:langString typed and language-tagged literal fails" do
|
|
|
|
assert_raise ArgumentError, fn ->
|
|
|
|
Literal.new("Eule", datatype: XSD.string, language: "de")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
test "construction of a rdf:langString typed literal without language fails" do
|
|
|
|
assert_raise ArgumentError, fn ->
|
|
|
|
Literal.new("Eule", datatype: RDF.langString)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-04-23 21:41:29 +00:00
|
|
|
|
2017-04-16 21:13:39 +00:00
|
|
|
describe "language" do
|
|
|
|
Enum.each literals(:all_plain_lang), fn literal ->
|
|
|
|
@tag literal: literal
|
|
|
|
test "#{inspect literal} has correct language", %{literal: literal} do
|
|
|
|
assert literal.language == "en"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
Enum.each literals(:all) -- literals(:all_plain_lang), fn literal ->
|
|
|
|
@tag literal: literal
|
2017-04-30 12:38:26 +00:00
|
|
|
test "Literal for #{literal} has no language", %{literal: literal} do
|
2017-04-16 21:13:39 +00:00
|
|
|
assert is_nil(literal.language)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
test "language get lower-cased" do
|
|
|
|
assert Literal.new("Upper", language: "EN").language == "en"
|
|
|
|
assert Literal.new("Upper", %{language: "EN"}).language == "en"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-04-23 21:41:29 +00:00
|
|
|
|
2017-04-16 21:13:39 +00:00
|
|
|
describe "datatype" do
|
|
|
|
Enum.each literals(:all_simple), fn literal ->
|
|
|
|
@tag literal: literal
|
|
|
|
test "simple literal #{inspect literal} has datatype xsd:string", %{literal: literal} do
|
|
|
|
assert literal.datatype == XSD.string
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
%{
|
|
|
|
123 => "integer",
|
|
|
|
true => "boolean",
|
|
|
|
false => "boolean",
|
|
|
|
9223372036854775807 => "integer",
|
|
|
|
3.1415 => "double",
|
|
|
|
~D[2017-04-13] => "date",
|
|
|
|
~N[2017-04-14 15:32:07] => "dateTime",
|
|
|
|
~T[01:02:03] => "time"
|
|
|
|
}
|
|
|
|
|> Enum.each(fn {value, type} ->
|
|
|
|
@tag data: %{literal: literal = Literal.new(value), type: type}
|
2017-04-30 12:38:26 +00:00
|
|
|
test "Literal for #{literal} has datatype xsd:#{type}",
|
2017-04-16 21:13:39 +00:00
|
|
|
%{data: %{literal: literal, type: type}} do
|
|
|
|
assert literal.datatype == apply(XSD, String.to_atom(type), [])
|
|
|
|
end
|
|
|
|
end)
|
|
|
|
end
|
|
|
|
|
2017-04-23 21:41:29 +00:00
|
|
|
|
2017-04-16 21:13:39 +00:00
|
|
|
describe "has_datatype?" do
|
|
|
|
Enum.each literals(~W[all_simple all_plain_lang]a), fn literal ->
|
|
|
|
@tag literal: literal
|
|
|
|
test "#{inspect literal} has no datatype", %{literal: literal} do
|
|
|
|
refute Literal.has_datatype?(literal)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
Enum.each literals(:all) -- literals(~W[all_simple all_plain_lang]a), fn literal ->
|
|
|
|
@tag literal: literal
|
2017-04-30 12:38:26 +00:00
|
|
|
test "Literal for #{literal} has a datatype", %{literal: literal} do
|
2017-04-16 21:13:39 +00:00
|
|
|
assert Literal.has_datatype?(literal)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-04-23 21:41:29 +00:00
|
|
|
|
2017-04-16 21:13:39 +00:00
|
|
|
describe "plain?" do
|
|
|
|
Enum.each literals(:all_plain), fn literal ->
|
|
|
|
@tag literal: literal
|
|
|
|
test "#{inspect literal} is plain", %{literal: literal} do
|
|
|
|
assert Literal.plain?(literal)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
Enum.each literals(:all) -- literals(:all_plain), fn literal ->
|
|
|
|
@tag literal: literal
|
2017-04-30 12:38:26 +00:00
|
|
|
test "Literal for #{literal} is not plain", %{literal: literal} do
|
2017-04-16 21:13:39 +00:00
|
|
|
refute Literal.plain?(literal)
|
|
|
|
end
|
|
|
|
end
|
2016-10-30 18:36:46 +00:00
|
|
|
end
|
|
|
|
|
2017-04-23 21:41:29 +00:00
|
|
|
|
2017-04-16 21:13:39 +00:00
|
|
|
describe "simple?" do
|
|
|
|
Enum.each literals(:all_simple), fn literal ->
|
|
|
|
@tag literal: literal
|
|
|
|
test "#{inspect literal} is simple", %{literal: literal} do
|
|
|
|
assert Literal.simple?(literal)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
Enum.each literals(:all) -- literals(:all_simple), fn literal ->
|
|
|
|
@tag literal: literal
|
2017-04-30 12:38:26 +00:00
|
|
|
test "Literal for #{literal} is not simple", %{literal: literal} do
|
2017-04-16 21:13:39 +00:00
|
|
|
refute Literal.simple?(literal)
|
|
|
|
end
|
|
|
|
end
|
2016-10-30 18:36:46 +00:00
|
|
|
end
|
|
|
|
|
2017-04-23 21:41:29 +00:00
|
|
|
|
|
|
|
describe "canonicalization" do
|
|
|
|
|
|
|
|
# for mapped/known datatypes the RDF.Datatype.Test.Case uses the general RDF.Literal.canonical function
|
|
|
|
|
|
|
|
test "an unmapped/unknown datatypes is always canonical" do
|
|
|
|
assert Literal.canonical? Literal.new("custom typed value", datatype: "http://example/dt")
|
|
|
|
end
|
|
|
|
|
|
|
|
test "for unmapped/unknown datatypes, canonicalize is a no-op" do
|
|
|
|
assert Literal.new("custom typed value", datatype: "http://example/dt") ==
|
|
|
|
Literal.canonical(Literal.new("custom typed value", datatype: "http://example/dt"))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "validation" do
|
|
|
|
|
|
|
|
# for mapped/known datatypes the RDF.Datatype.Test.Case uses the general RDF.Literal.valid? function
|
|
|
|
|
|
|
|
test "a literal with an unmapped/unknown datatype is always valid" do
|
|
|
|
assert Literal.valid? Literal.new("custom typed value", datatype: "http://example/dt")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2017-04-16 21:13:39 +00:00
|
|
|
describe "String.Chars protocol implementation" do
|
|
|
|
Enum.each values(:all_plain), fn value ->
|
|
|
|
@tag value: value
|
|
|
|
test "returns String representation of #{inspect value}", %{value: value} do
|
|
|
|
assert to_string(apply(Literal, :new, value)) == List.first(value)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
%{
|
2017-04-30 12:38:26 +00:00
|
|
|
literal(:int) => "123",
|
|
|
|
literal(:true) => "true",
|
|
|
|
literal(:false) => "false",
|
|
|
|
literal(:long) => "9223372036854775807",
|
|
|
|
literal(:double) => "3.1415",
|
|
|
|
literal(:date) => "2017-04-13",
|
|
|
|
literal(:datetime) => "2017-04-14T15:32:07Z",
|
|
|
|
literal(:naive_datetime) => "2017-04-14T15:32:07",
|
|
|
|
literal(:time) => "01:02:03"
|
2017-04-16 21:13:39 +00:00
|
|
|
}
|
|
|
|
|> Enum.each(fn {literal, rep} ->
|
|
|
|
@tag data: %{literal: literal, rep: rep}
|
2017-04-30 12:38:26 +00:00
|
|
|
test "returns String representation of Literal value #{literal}",
|
2017-04-16 21:13:39 +00:00
|
|
|
%{data: %{literal: literal, rep: rep}} do
|
|
|
|
assert to_string(literal) == rep
|
|
|
|
end
|
|
|
|
end)
|
|
|
|
|
|
|
|
end
|
2016-10-30 18:36:46 +00:00
|
|
|
|
2016-10-15 16:26:56 +00:00
|
|
|
end
|