Support more values for the :base_iri in defvocab
This commit is contained in:
parent
9449fce988
commit
f8517de119
3 changed files with 45 additions and 20 deletions
10
CHANGELOG.md
10
CHANGELOG.md
|
@ -18,15 +18,21 @@ The generated namespaces are much more flexible now and compile faster.
|
|||
|
||||
### Changed
|
||||
|
||||
- The `:base_iri` specified in `defvocab` can now be given in any form supported
|
||||
by `RDF.IRI.new/1`. There are also no longer restrictions on the expression
|
||||
of this value. While previously the value had to be provided as a literal value,
|
||||
now any expression returning a value accepted by `RDF.IRI.new/1` can be given
|
||||
(e.g. function calls, module attributes etc.).
|
||||
The `:base_iri` also no longer has to end with a `/` or `#`.
|
||||
- Aliases on a `RDF.Vocabulary.Namespace` can now be specified directly in the
|
||||
`:terms` list
|
||||
`:terms` list.
|
||||
- When defining an alias for a term of vocabulary which would be invalid as an
|
||||
Elixir term, the original term is now implicitly ignored and won't any longer
|
||||
be returned by the `__terms__/0` function of a `RDF.Vocabulary.Namespace`.
|
||||
- `RDF.Data.merge/2` and `RDF.Data.equal?/2` are now commutative, i.e. structs
|
||||
which implement the `RDF.Data` protocol can be given also as the second argument
|
||||
(previously custom structs with `RDF.Data` protocol implementations always
|
||||
had to be given as the first argument)
|
||||
had to be given as the first argument).
|
||||
- several performance improvements
|
||||
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ defmodule RDF.Vocabulary.Namespace do
|
|||
the `RDF.NS` module.
|
||||
"""
|
||||
|
||||
alias RDF.{Description, Graph, Dataset, Vocabulary, Namespace}
|
||||
alias RDF.{Description, Graph, Dataset, Vocabulary, Namespace, IRI}
|
||||
|
||||
import RDF.Vocabulary.Namespace.{TermMapping, CaseValidation}
|
||||
import RDF.Vocabulary, only: [term_to_iri: 2, extract_terms: 2]
|
||||
|
@ -254,14 +254,25 @@ defmodule RDF.Vocabulary.Namespace do
|
|||
end
|
||||
end
|
||||
|
||||
defp normalize_base_uri(base_uri) do
|
||||
unless is_binary(base_uri) and String.ends_with?(base_uri, ~w[/ # .]) do
|
||||
raise RDF.Namespace.InvalidVocabBaseIRIError, "invalid base IRI: #{inspect(base_uri)}"
|
||||
else
|
||||
defp normalize_base_uri(%IRI{} = base_iri), do: IRI.to_string(base_iri)
|
||||
|
||||
defp normalize_base_uri(base_uri) when is_binary(base_uri) do
|
||||
if IRI.valid?(base_uri) do
|
||||
base_uri
|
||||
else
|
||||
raise RDF.Namespace.InvalidVocabBaseIRIError, "invalid base IRI: #{inspect(base_uri)}"
|
||||
end
|
||||
end
|
||||
|
||||
defp normalize_base_uri(base_uri) do
|
||||
base_uri |> IRI.new() |> normalize_base_uri()
|
||||
rescue
|
||||
[Namespace.UndefinedTermError, IRI.InvalidError, FunctionClauseError] ->
|
||||
reraise RDF.Namespace.InvalidVocabBaseIRIError,
|
||||
"invalid base IRI: #{inspect(base_uri)}",
|
||||
__STACKTRACE__
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec vocabulary_namespace?(module) :: boolean
|
||||
def vocabulary_namespace?(name) do
|
||||
|
|
|
@ -42,6 +42,15 @@ defmodule RDF.Vocabulary.NamespaceTest do
|
|||
base_iri: "http://example.com/strict#",
|
||||
terms: ~w[foo bar]
|
||||
|
||||
@base_iri "http://example.com/"
|
||||
defvocab ExampleWithBaseFromModuleAttribute,
|
||||
base_iri: @base_iri,
|
||||
terms: ~w[foo Bar]a
|
||||
|
||||
defvocab ExampleWithBaseFromIRI,
|
||||
base_iri: ~I<http://example.com/>,
|
||||
terms: ~w[foo Bar]a
|
||||
|
||||
defvocab ExampleFromGraph,
|
||||
base_iri: "http://example.com/from_graph#",
|
||||
data:
|
||||
|
@ -139,18 +148,6 @@ defmodule RDF.Vocabulary.NamespaceTest do
|
|||
end
|
||||
end
|
||||
|
||||
test "when the base_iri doesn't end with '/' or '#', an error is raised" do
|
||||
assert_raise RDF.Namespace.InvalidVocabBaseIRIError, fn ->
|
||||
defmodule NSWithInvalidBaseIRI1 do
|
||||
use RDF.Vocabulary.Namespace
|
||||
|
||||
defvocab Example,
|
||||
base_iri: "http://example.com/base_iri4",
|
||||
terms: []
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test "when the base_iri isn't a valid IRI, an error is raised" do
|
||||
assert_raise RDF.Namespace.InvalidVocabBaseIRIError, fn ->
|
||||
defmodule NSWithInvalidBaseIRI2 do
|
||||
|
@ -957,9 +954,13 @@ defmodule RDF.Vocabulary.NamespaceTest do
|
|||
test "__base_iri__ returns the base_iri" do
|
||||
alias TestNS.ExampleFromGraph, as: HashVocab
|
||||
alias TestNS.ExampleFromNTriplesFile, as: SlashVocab
|
||||
alias TestNS.ExampleWithBaseFromModuleAttribute, as: BaseFromModuleAttribute
|
||||
alias TestNS.ExampleWithBaseFromIRI, as: BaseFromIRI
|
||||
|
||||
assert HashVocab.__base_iri__() == "http://example.com/from_graph#"
|
||||
assert SlashVocab.__base_iri__() == "http://example.com/from_ntriples/"
|
||||
assert BaseFromModuleAttribute.__base_iri__() == "http://example.com/"
|
||||
assert BaseFromIRI.__base_iri__() == "http://example.com/"
|
||||
end
|
||||
|
||||
test "__iris__ returns all IRIs of the vocabulary" do
|
||||
|
@ -1040,7 +1041,9 @@ defmodule RDF.Vocabulary.NamespaceTest do
|
|||
EXS,
|
||||
ExampleFromGraph,
|
||||
ExampleFromNTriplesFile,
|
||||
StrictExampleFromTerms
|
||||
StrictExampleFromTerms,
|
||||
ExampleWithBaseFromIRI,
|
||||
ExampleWithBaseFromModuleAttribute
|
||||
}
|
||||
|
||||
test "undefined terms" do
|
||||
|
@ -1088,12 +1091,17 @@ defmodule RDF.Vocabulary.NamespaceTest do
|
|||
|
||||
assert StrictExampleFromTerms.foo() == ~I<http://example.com/strict_from_terms#foo>
|
||||
assert RDF.iri(StrictExampleFromTerms.foo()) == ~I<http://example.com/strict_from_terms#foo>
|
||||
|
||||
assert ExampleWithBaseFromIRI.foo() == ~I<http://example.com/foo>
|
||||
assert ExampleWithBaseFromModuleAttribute.foo() == ~I<http://example.com/foo>
|
||||
end
|
||||
|
||||
test "capitalized terms" do
|
||||
assert RDF.iri(ExampleFromGraph.Bar) == ~I<http://example.com/from_graph#Bar>
|
||||
assert RDF.iri(ExampleFromNTriplesFile.Bar) == ~I<http://example.com/from_ntriples/Bar>
|
||||
assert RDF.iri(StrictExampleFromTerms.Bar) == ~I<http://example.com/strict_from_terms#Bar>
|
||||
assert RDF.iri(ExampleWithBaseFromIRI.Bar) == ~I<http://example.com/Bar>
|
||||
assert RDF.iri(ExampleWithBaseFromModuleAttribute.Bar) == ~I<http://example.com/Bar>
|
||||
end
|
||||
|
||||
test "terms starting with an underscore" do
|
||||
|
|
Loading…
Reference in a new issue