Interop between RDF.IRI and XSD.AnyURI in terms of cast and equal_value?
This commit is contained in:
parent
6057749d2a
commit
00a6103e56
5 changed files with 66 additions and 16 deletions
|
@ -49,11 +49,11 @@ defmodule RDF.IRI do
|
|||
"""
|
||||
@spec new(coercible) :: t
|
||||
def new(iri)
|
||||
def new(iri) when is_binary(iri), do: %RDF.IRI{value: iri}
|
||||
def new(iri) when is_binary(iri), do: %__MODULE__{value: iri}
|
||||
def new(qname) when is_atom(qname) and qname not in [nil, true, false],
|
||||
do: Namespace.resolve_term(qname)
|
||||
def new(%URI{} = uri), do: uri |> URI.to_string |> new
|
||||
def new(%RDF.IRI{} = iri), do: iri
|
||||
def new(%__MODULE__{} = iri), do: iri
|
||||
|
||||
@doc """
|
||||
Creates a `RDF.IRI`, but checks if the given IRI is valid.
|
||||
|
@ -68,7 +68,7 @@ defmodule RDF.IRI do
|
|||
def new!(qname) when is_atom(qname) and qname not in [nil, true, false],
|
||||
do: new(qname) # since terms of a namespace are already validated
|
||||
def new!(%URI{} = uri), do: uri |> valid!() |> new()
|
||||
def new!(%RDF.IRI{} = iri), do: valid!(iri)
|
||||
def new!(%__MODULE__{} = iri), do: valid!(iri)
|
||||
|
||||
|
||||
@doc """
|
||||
|
@ -136,7 +136,7 @@ defmodule RDF.IRI do
|
|||
def absolute?(iri)
|
||||
|
||||
def absolute?(value) when is_binary(value), do: not is_nil(scheme(value))
|
||||
def absolute?(%RDF.IRI{value: value}), do: absolute?(value)
|
||||
def absolute?(%__MODULE__{value: value}), do: absolute?(value)
|
||||
def absolute?(%URI{scheme: nil}), do: false
|
||||
def absolute?(%URI{scheme: _}), do: true
|
||||
def absolute?(qname) when is_atom(qname) and qname not in [nil, true, false] do
|
||||
|
@ -198,7 +198,7 @@ defmodule RDF.IRI do
|
|||
"""
|
||||
@spec scheme(coercible) :: String.t | nil
|
||||
def scheme(iri)
|
||||
def scheme(%RDF.IRI{value: value}), do: scheme(value)
|
||||
def scheme(%__MODULE__{value: value}), do: scheme(value)
|
||||
def scheme(%URI{scheme: scheme}), do: scheme
|
||||
def scheme(qname) when is_atom(qname), do: Namespace.resolve_term(qname) |> scheme()
|
||||
def scheme(iri) when is_binary(iri) do
|
||||
|
@ -216,7 +216,7 @@ defmodule RDF.IRI do
|
|||
def parse(iri) when is_binary(iri), do: URI.parse(iri)
|
||||
def parse(qname) when is_atom(qname) and qname not in [nil, true, false],
|
||||
do: Namespace.resolve_term(qname) |> parse()
|
||||
def parse(%RDF.IRI{value: value}), do: URI.parse(value)
|
||||
def parse(%__MODULE__{value: value}), do: URI.parse(value)
|
||||
def parse(%URI{} = uri), do: uri
|
||||
|
||||
|
||||
|
@ -230,9 +230,14 @@ defmodule RDF.IRI do
|
|||
@spec equal_value?(t | RDF.Literal.t, t | RDF.Literal.t) :: boolean | nil
|
||||
def equal_value?(left, right)
|
||||
|
||||
def equal_value?(%RDF.IRI{value: left}, %RDF.IRI{value: right}),
|
||||
def equal_value?(%__MODULE__{value: left}, %__MODULE__{value: right}),
|
||||
do: left == right
|
||||
|
||||
def equal_value?(%__MODULE__{} = left, %RDF.Literal{} = right),
|
||||
do: RDF.Literal.equal_value?(right, left)
|
||||
|
||||
def equal_value?(%__MODULE__{value: left}, %URI{} = right),
|
||||
do: left == URI.to_string(right)
|
||||
|
||||
def equal_value?(_, _),
|
||||
do: nil
|
||||
|
@ -256,7 +261,7 @@ defmodule RDF.IRI do
|
|||
@spec to_string(t | module) :: String.t
|
||||
def to_string(iri)
|
||||
|
||||
def to_string(%RDF.IRI{value: value}),
|
||||
def to_string(%__MODULE__{value: value}),
|
||||
do: value
|
||||
|
||||
def to_string(qname) when is_atom(qname),
|
||||
|
|
|
@ -214,8 +214,8 @@ defmodule RDF.Literal.Datatype do
|
|||
def equal_value?(_, nil), do: nil
|
||||
def equal_value?(left, right) do
|
||||
cond do
|
||||
not RDF.literal?(right) -> equal_value?(left, Literal.coerce(right))
|
||||
not RDF.literal?(left) -> equal_value?(Literal.coerce(left), right)
|
||||
not RDF.literal?(right) and not RDF.term?(right) -> equal_value?(left, Literal.coerce(right))
|
||||
not RDF.literal?(left) and not RDF.term?(left) -> equal_value?(Literal.coerce(left), right)
|
||||
true -> do_equal_value?(left, right)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,6 +7,8 @@ defmodule RDF.XSD.AnyURI do
|
|||
|
||||
@type valid_value :: URI.t()
|
||||
|
||||
alias RDF.IRI
|
||||
|
||||
use RDF.XSD.Datatype.Primitive,
|
||||
name: "anyURI",
|
||||
id: RDF.Utils.Bootstrapping.xsd_iri("anyURI")
|
||||
|
@ -19,4 +21,19 @@ defmodule RDF.XSD.AnyURI do
|
|||
@spec elixir_mapping(any, Keyword.t()) :: value
|
||||
def elixir_mapping(%URI{} = uri, _), do: uri
|
||||
def elixir_mapping(_, _), do: @invalid_value
|
||||
|
||||
@impl RDF.Literal.Datatype
|
||||
def do_cast(%IRI{} = iri), do: new(iri.value)
|
||||
def do_cast(value), do: super(value)
|
||||
|
||||
@impl RDF.Literal.Datatype
|
||||
def do_equal_value?(literal1, literal2)
|
||||
|
||||
def do_equal_value?(%IRI{} = iri, %__MODULE__{} = any_uri),
|
||||
do: do_equal_value?(any_uri, iri)
|
||||
|
||||
def do_equal_value?(%__MODULE__{} = any_uri, %IRI{value: iri}),
|
||||
do: lexical(any_uri) == iri
|
||||
|
||||
def do_equal_value?(literal1, literal2), do: super(literal1, literal2)
|
||||
end
|
||||
|
|
|
@ -3,28 +3,33 @@ defmodule RDF.EqualityTest do
|
|||
|
||||
alias RDF.XSD
|
||||
|
||||
describe "RDF.IRI" do
|
||||
describe "RDF.IRI and XSD.AnyURI" do
|
||||
@term_equal_iris [
|
||||
{RDF.iri("http://example.com/"), RDF.iri("http://example.com/")},
|
||||
{XSD.anyURI("http://example.com/"), XSD.anyURI("http://example.com/")},
|
||||
]
|
||||
@value_equal_iris [
|
||||
{RDF.iri("http://example.com/"), XSD.anyURI("http://example.com/")},
|
||||
{XSD.anyURI("http://example.com/"), XSD.anyURI("http://example.com/")},
|
||||
]
|
||||
@unequal_iris [
|
||||
{RDF.iri("http://example.com/foo"), RDF.iri("http://example.com/bar")},
|
||||
{RDF.iri("http://example.com/foo"), XSD.anyURI("http://example.com/bar")},
|
||||
]
|
||||
@equal_iris_by_coercion []
|
||||
@unequal_iris_by_coercion []
|
||||
@equal_iris_by_coercion [
|
||||
{RDF.iri("http://example.com/"), URI.parse("http://example.com/")},
|
||||
{XSD.anyURI("http://example.com/"), URI.parse("http://example.com/")},
|
||||
]
|
||||
@unequal_iris_by_coercion [
|
||||
{RDF.iri("http://example.com/foo"), URI.parse("http://example.com/bar")},
|
||||
{XSD.anyURI("http://example.com/foo"), URI.parse("http://example.com/bar")},
|
||||
]
|
||||
@incomparable_iris [
|
||||
{RDF.iri("http://example.com/"), XSD.string("http://example.com/")},
|
||||
{XSD.anyURI("http://example.com/"), XSD.string("http://example.com/")},
|
||||
]
|
||||
|
||||
test "term equality", do: assert_term_equal(@term_equal_iris)
|
||||
@tag skip: "TODO: finish value equality of XSD.AnyURI"
|
||||
test "value equality", do: assert_value_equal(@value_equal_iris)
|
||||
@tag skip: "TODO: finish value equality of XSD.AnyURI"
|
||||
test "inequality", do: assert_unequal(@unequal_iris)
|
||||
test "coerced value equality", do: assert_coerced_equal(@equal_iris_by_coercion)
|
||||
test "coerced value inequality", do: assert_coerced_unequal(@unequal_iris_by_coercion)
|
||||
|
|
|
@ -11,4 +11,27 @@ defmodule RDF.XSD.AnyURITest do
|
|||
{URI.parse("http://example.com/foo"), nil, "http://example.com/foo"}
|
||||
},
|
||||
invalid: [42, 3.14, true, false]
|
||||
|
||||
|
||||
describe "cast/1" do
|
||||
test "casting an anyURI returns the input as it is" do
|
||||
assert XSD.anyURI("http://example.com/") |> XSD.AnyURI.cast() ==
|
||||
XSD.anyURI("http://example.com/")
|
||||
end
|
||||
|
||||
test "casting an RDF.IRI" do
|
||||
assert RDF.iri("http://example.com/") |> XSD.AnyURI.cast() ==
|
||||
XSD.anyURI("http://example.com/")
|
||||
end
|
||||
|
||||
test "with coercible value" do
|
||||
assert URI.parse("http://example.com/") |> XSD.AnyURI.cast() ==
|
||||
XSD.anyURI("http://example.com/")
|
||||
end
|
||||
|
||||
test "with non-coercible value" do
|
||||
assert XSD.string("http://example.com/") |> XSD.AnyURI.cast() == nil
|
||||
assert XSD.AnyURI.cast(make_ref()) == nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue