Fix RDF.Datatype.cast/1 implementations when casting from strings

This commit is contained in:
Marcel Otto 2018-09-14 17:02:04 +02:00
parent 584d87a49c
commit a51e2a0dec
12 changed files with 52 additions and 18 deletions

View file

@ -210,6 +210,14 @@ defmodule RDF.Datatype do
def equal_value?(_, _), do: nil
def validate_cast(%Literal{} = literal) do
if valid?(literal), do: literal
end
def validate_cast(_), do: nil
defoverridable [
build_literal_by_value: 2,
build_literal_by_lexical: 2,

View file

@ -39,6 +39,7 @@ defmodule RDF.Boolean do
literal.value
|> new()
|> canonical()
|> validate_cast()
is_xsd_decimal(datatype) ->
!Decimal.equal?(literal.value, 0)

View file

@ -81,6 +81,7 @@ defmodule RDF.DateTime do
is_xsd_string(datatype) ->
literal.value
|> new()
|> validate_cast()
true ->
nil

View file

@ -85,6 +85,7 @@ defmodule RDF.Decimal do
literal.value
|> new()
|> canonical()
|> validate_cast()
is_number(literal.value) and (is_xsd_integer(datatype) or
is_xsd_double(datatype) or is_xsd_float(datatype)) ->

View file

@ -113,6 +113,7 @@ defmodule RDF.Double do
literal.value
|> new()
|> canonical()
|> validate_cast()
is_xsd_decimal(datatype) ->
literal.value

View file

@ -36,10 +36,10 @@ defmodule RDF.Integer do
new(1)
is_xsd_string(datatype) ->
case Integer.parse(literal.value) do
{value, _} -> new(value)
_ -> nil
end
literal.value
|> new()
|> canonical()
|> validate_cast()
is_xsd_decimal(datatype) ->
literal.value

View file

@ -51,7 +51,7 @@ defmodule RDF.BooleanTest do
assert RDF.false |> RDF.Boolean.cast() == RDF.false
end
test "casting a string" do
test "casting a string with a value from the lexical value space of xsd:boolean" do
assert RDF.string("true") |> RDF.Boolean.cast() == RDF.true
assert RDF.string("tRuE") |> RDF.Boolean.cast() == RDF.true
assert RDF.string("1") |> RDF.Boolean.cast() == RDF.true
@ -61,6 +61,10 @@ defmodule RDF.BooleanTest do
assert RDF.string("0") |> RDF.Boolean.cast() == RDF.false
end
test "casting a string with a value not in the lexical value space of xsd:boolean" do
assert RDF.string("foo") |> RDF.Boolean.cast() == nil
end
test "casting an integer" do
assert RDF.integer(0) |> RDF.Boolean.cast() == RDF.false
assert RDF.integer(1) |> RDF.Boolean.cast() == RDF.true

View file

@ -129,7 +129,7 @@ defmodule RDF.DateTimeTest do
RDF.date_time("2010-01-01T12:34:56")
end
test "casting a string" do
test "casting a string with a value from the lexical value space of xsd:dateTime" do
assert RDF.string("2010-01-01T12:34:56") |> RDF.DateTime.cast() ==
RDF.date_time("2010-01-01T12:34:56")
assert RDF.string("2010-01-01T12:34:56Z") |> RDF.DateTime.cast() ==
@ -138,6 +138,11 @@ defmodule RDF.DateTimeTest do
RDF.date_time("2010-01-01T12:34:56+01:00")
end
test "casting a string with a value not in the lexical value space of xsd:dateTime" do
assert RDF.string("string") |> RDF.DateTime.cast() == nil
assert RDF.string("02010-01-01T00:00:00") |> RDF.DateTime.cast() == nil
end
test "casting a date" do
assert RDF.date("2010-01-01") |> RDF.DateTime.cast() ==
RDF.date_time("2010-01-01T00:00:00")
@ -154,8 +159,8 @@ defmodule RDF.DateTimeTest do
end
test "with literals of unsupported datatypes" do
assert RDF.false |> RDF.DateTime.cast() == nil
assert RDF.integer(1) |> RDF.DateTime.cast() == nil
assert RDF.false |> RDF.DateTime.cast() == nil
assert RDF.integer(1) |> RDF.DateTime.cast() == nil
assert RDF.decimal(3.14) |> RDF.DateTime.cast() == nil
end
end

View file

@ -78,11 +78,15 @@ defmodule RDF.DecimalTest do
assert RDF.false |> RDF.Decimal.cast() == RDF.decimal(0.0)
end
test "casting a string" do
test "casting a string with a value from the lexical value space of xsd:decimal" do
assert RDF.string("0") |> RDF.Decimal.cast() == RDF.decimal(0)
assert RDF.string("3.14") |> RDF.Decimal.cast() == RDF.decimal(3.14)
end
test "casting a string with a value not in the lexical value space of xsd:decimal" do
assert RDF.string("foo") |> RDF.Decimal.cast() == nil
end
test "casting an integer" do
assert RDF.integer(0) |> RDF.Decimal.cast() == RDF.decimal(0.0)
assert RDF.integer(42) |> RDF.Decimal.cast() == RDF.decimal(42.0)

View file

@ -71,12 +71,16 @@ defmodule RDF.DoubleTest do
assert RDF.false |> RDF.Double.cast() == RDF.double(0.0)
end
test "casting a string" do
test "casting a string with a value from the lexical value space of xsd:double" do
assert RDF.string("1.0") |> RDF.Double.cast() == RDF.double("1.0E0")
assert RDF.string("3.14") |> RDF.Double.cast() == RDF.double("3.14E0")
assert RDF.string("3.14E0") |> RDF.Double.cast() == RDF.double("3.14E0")
end
test "casting a string with a value not in the lexical value space of xsd:double" do
assert RDF.string("foo") |> RDF.Double.cast() == nil
end
test "casting an integer" do
assert RDF.integer(0) |> RDF.Double.cast() == RDF.double(0.0)
assert RDF.integer(42) |> RDF.Double.cast() == RDF.double(42.0)

View file

@ -27,10 +27,14 @@ defmodule RDF.IntegerTest do
assert RDF.true |> RDF.Integer.cast() == RDF.integer(1)
end
test "casting a string" do
test "casting a string with a value from the lexical value space of xsd:integer" do
assert RDF.string("0") |> RDF.Integer.cast() == RDF.integer(0)
assert RDF.string("042") |> RDF.Integer.cast() == RDF.integer(42)
assert RDF.string("3.14") |> RDF.Integer.cast() == RDF.integer(3)
end
test "casting a string with a value not in the lexical value space of xsd:integer" do
assert RDF.string("foo") |> RDF.Integer.cast() == nil
assert RDF.string("3.14") |> RDF.Integer.cast() == nil
end
test "casting an decimal" do

View file

@ -95,11 +95,11 @@ defmodule RDF.StringTest do
end
test "casting a date" do
assert RDF.date(~D[2000-01-01]) |> RDF.String.cast() == RDF.string("2000-01-01")
assert RDF.date("2000-01-01") |> RDF.String.cast() == RDF.string("2000-01-01")
assert RDF.date(~D[2000-01-01]) |> RDF.String.cast() == RDF.string("2000-01-01")
assert RDF.date("2000-01-01") |> RDF.String.cast() == RDF.string("2000-01-01")
assert RDF.date("2000-01-01+00:00") |> RDF.String.cast() == RDF.string("2000-01-01Z")
assert RDF.date("2000-01-01+01:00") |> RDF.String.cast() == RDF.string("2000-01-01+01:00")
assert RDF.date("0001-01-01") |> RDF.String.cast() == RDF.string("0001-01-01")
assert RDF.date("0001-01-01") |> RDF.String.cast() == RDF.string("0001-01-01")
unless Version.compare(System.version(), "1.7.2") == :lt do
assert RDF.date("-0001-01-01") |> RDF.String.cast() == RDF.string("-0001-01-01")
end
@ -118,9 +118,10 @@ defmodule RDF.StringTest do
end
test "with invalid literals" do
assert RDF.integer(3.14) |> RDF.Integer.cast() == nil
assert RDF.decimal("NAN") |> RDF.Integer.cast() == nil
assert RDF.double(true) |> RDF.Integer.cast() == nil
assert RDF.integer(3.14) |> RDF.String.cast() == nil
assert RDF.decimal("NAN") |> RDF.String.cast() == nil
assert RDF.double(true) |> RDF.String.cast() == nil
end
end
end