diff --git a/lib/rdf/iri.ex b/lib/rdf/iri.ex index 0c143c4..3d4e5ed 100644 --- a/lib/rdf/iri.ex +++ b/lib/rdf/iri.ex @@ -31,7 +31,8 @@ defmodule RDF.IRI do """ def new(iri) def new(iri) when is_binary(iri), do: %RDF.IRI{value: iri} - def new(qname) when is_atom(qname), do: Namespace.resolve_term(qname) + def new(qname) when is_atom(qname) and not qname 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 @@ -44,7 +45,8 @@ defmodule RDF.IRI do """ def new!(iri) def new!(iri) when is_binary(iri), do: iri |> valid!() |> new() - def new!(qname) when is_atom(qname), do: new(qname) # since terms of a namespace are already validated + def new!(qname) when is_atom(qname) and not qname 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) @@ -90,11 +92,18 @@ defmodule RDF.IRI do """ def absolute?(iri) - def absolute?(%RDF.IRI{value: value}), do: absolute?(value) - def absolute?(qname) when is_atom(qname), do: Namespace.resolve_term(qname) |> absolute?() - def absolute?(%URI{scheme: nil}), do: false - def absolute?(%URI{scheme: _}), do: true - def absolute?(value), do: not is_nil(scheme(value)) + def absolute?(value) when is_binary(value), do: not is_nil(scheme(value)) + def absolute?(%RDF.IRI{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 not qname in [nil, true, false] do + try do + qname |> Namespace.resolve_term |> absolute?() + rescue + _ -> false + end + end + def absolute?(_), do: false @doc """ @@ -157,7 +166,11 @@ defmodule RDF.IRI do iex> RDF.IRI.scheme("not an iri") nil """ - def scheme(iri) do + def scheme(iri) + def scheme(%RDF.IRI{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 with [_, scheme] <- Regex.run(@scheme_regex, iri) do scheme end @@ -169,7 +182,8 @@ defmodule RDF.IRI do """ def parse(iri) def parse(iri) when is_binary(iri), do: URI.parse(iri) |> empty_fragment_shim(iri) - def parse(qname) when is_atom(qname), do: Namespace.resolve_term(qname) |> parse() + def parse(qname) when is_atom(qname) and not qname in [nil, true, false], + do: Namespace.resolve_term(qname) |> parse() def parse(%RDF.IRI{value: value}), do: URI.parse(value) |> empty_fragment_shim(value) def parse(%URI{} = uri), do: uri diff --git a/test/unit/iri_test.exs b/test/unit/iri_test.exs index ded8bd9..86881ea 100644 --- a/test/unit/iri_test.exs +++ b/test/unit/iri_test.exs @@ -53,6 +53,16 @@ defmodule RDF.IRITest do test "with a resolvable atom" do assert IRI.new(EX.Foo) == %IRI{value: "http://example.com/#Foo"} end + + test "with a non-resolvable atom" do + assert_raise RDF.Namespace.UndefinedTermError, fn -> IRI.new(Foo.Bar) end + end + + test "with Elixirs special atoms" do + assert_raise FunctionClauseError, fn -> IRI.new(true) end + assert_raise FunctionClauseError, fn -> IRI.new(false) end + assert_raise FunctionClauseError, fn -> IRI.new(nil) end + end end @@ -83,6 +93,16 @@ defmodule RDF.IRITest do end end) end + + test "with a non-resolvable atom" do + assert_raise RDF.Namespace.UndefinedTermError, fn -> IRI.new!(Foo.Bar) end + end + + test "with Elixirs special atoms" do + assert_raise FunctionClauseError, fn -> IRI.new!(true) end + assert_raise FunctionClauseError, fn -> IRI.new!(false) end + assert_raise FunctionClauseError, fn -> IRI.new!(nil) end + end end @@ -97,6 +117,13 @@ defmodule RDF.IRITest do assert IRI.valid!(EX.Foo) == EX.Foo end + test "with a non-resolvable atom" do + assert_raise RDF.IRI.InvalidError, fn -> IRI.valid!(true) == false end + assert_raise RDF.IRI.InvalidError, fn -> IRI.valid!(false) == false end + assert_raise RDF.IRI.InvalidError, fn -> IRI.valid!(nil) == false end + assert_raise RDF.IRI.InvalidError, fn -> IRI.valid!(Foo.Bar) == false end + end + test "with relative iris" do Enum.each(relative_iris(), fn relative_iri -> assert_raise RDF.IRI.InvalidError, fn -> @@ -127,6 +154,13 @@ defmodule RDF.IRITest do assert IRI.valid?(EX.Foo) == true end + test "with a non-resolvable atom" do + assert IRI.valid?(true) == false + assert IRI.valid?(false) == false + assert IRI.valid?(nil) == false + assert IRI.valid?(Foo.Bar) == false + end + test "with relative iris" do Enum.each(relative_iris(), fn relative_iri -> assert IRI.valid?(relative_iri) == false @@ -153,6 +187,13 @@ defmodule RDF.IRITest do assert IRI.absolute?(EX.Foo) == true end + test "with a non-resolvable atom" do + assert IRI.absolute?(true) == false + assert IRI.absolute?(false) == false + assert IRI.absolute?(nil) == false + assert IRI.absolute?(Foo.Bar) == false + end + test "with relative iris" do Enum.each(relative_iris(), fn relative_iri -> assert IRI.absolute?(relative_iri) == false @@ -258,6 +299,12 @@ defmodule RDF.IRITest do refute IRI.parse(invalid_iri) end) end + + test "with Elixirs special atoms" do + assert_raise FunctionClauseError, fn -> IRI.parse(true) end + assert_raise FunctionClauseError, fn -> IRI.parse(false) end + assert_raise FunctionClauseError, fn -> IRI.parse(nil) end + end end