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
|
### 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
|
- 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
|
- 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
|
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`.
|
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
|
- `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
|
which implement the `RDF.Data` protocol can be given also as the second argument
|
||||||
(previously custom structs with `RDF.Data` protocol implementations always
|
(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
|
- several performance improvements
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ defmodule RDF.Vocabulary.Namespace do
|
||||||
the `RDF.NS` module.
|
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.Namespace.{TermMapping, CaseValidation}
|
||||||
import RDF.Vocabulary, only: [term_to_iri: 2, extract_terms: 2]
|
import RDF.Vocabulary, only: [term_to_iri: 2, extract_terms: 2]
|
||||||
|
@ -254,14 +254,25 @@ defmodule RDF.Vocabulary.Namespace do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp normalize_base_uri(base_uri) do
|
defp normalize_base_uri(%IRI{} = base_iri), do: IRI.to_string(base_iri)
|
||||||
unless is_binary(base_uri) and String.ends_with?(base_uri, ~w[/ # .]) do
|
|
||||||
raise RDF.Namespace.InvalidVocabBaseIRIError, "invalid base IRI: #{inspect(base_uri)}"
|
defp normalize_base_uri(base_uri) when is_binary(base_uri) do
|
||||||
else
|
if IRI.valid?(base_uri) do
|
||||||
base_uri
|
base_uri
|
||||||
|
else
|
||||||
|
raise RDF.Namespace.InvalidVocabBaseIRIError, "invalid base IRI: #{inspect(base_uri)}"
|
||||||
end
|
end
|
||||||
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
|
@doc false
|
||||||
@spec vocabulary_namespace?(module) :: boolean
|
@spec vocabulary_namespace?(module) :: boolean
|
||||||
def vocabulary_namespace?(name) do
|
def vocabulary_namespace?(name) do
|
||||||
|
|
|
@ -42,6 +42,15 @@ defmodule RDF.Vocabulary.NamespaceTest do
|
||||||
base_iri: "http://example.com/strict#",
|
base_iri: "http://example.com/strict#",
|
||||||
terms: ~w[foo bar]
|
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,
|
defvocab ExampleFromGraph,
|
||||||
base_iri: "http://example.com/from_graph#",
|
base_iri: "http://example.com/from_graph#",
|
||||||
data:
|
data:
|
||||||
|
@ -139,18 +148,6 @@ defmodule RDF.Vocabulary.NamespaceTest do
|
||||||
end
|
end
|
||||||
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
|
test "when the base_iri isn't a valid IRI, an error is raised" do
|
||||||
assert_raise RDF.Namespace.InvalidVocabBaseIRIError, fn ->
|
assert_raise RDF.Namespace.InvalidVocabBaseIRIError, fn ->
|
||||||
defmodule NSWithInvalidBaseIRI2 do
|
defmodule NSWithInvalidBaseIRI2 do
|
||||||
|
@ -957,9 +954,13 @@ defmodule RDF.Vocabulary.NamespaceTest do
|
||||||
test "__base_iri__ returns the base_iri" do
|
test "__base_iri__ returns the base_iri" do
|
||||||
alias TestNS.ExampleFromGraph, as: HashVocab
|
alias TestNS.ExampleFromGraph, as: HashVocab
|
||||||
alias TestNS.ExampleFromNTriplesFile, as: SlashVocab
|
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 HashVocab.__base_iri__() == "http://example.com/from_graph#"
|
||||||
assert SlashVocab.__base_iri__() == "http://example.com/from_ntriples/"
|
assert SlashVocab.__base_iri__() == "http://example.com/from_ntriples/"
|
||||||
|
assert BaseFromModuleAttribute.__base_iri__() == "http://example.com/"
|
||||||
|
assert BaseFromIRI.__base_iri__() == "http://example.com/"
|
||||||
end
|
end
|
||||||
|
|
||||||
test "__iris__ returns all IRIs of the vocabulary" do
|
test "__iris__ returns all IRIs of the vocabulary" do
|
||||||
|
@ -1040,7 +1041,9 @@ defmodule RDF.Vocabulary.NamespaceTest do
|
||||||
EXS,
|
EXS,
|
||||||
ExampleFromGraph,
|
ExampleFromGraph,
|
||||||
ExampleFromNTriplesFile,
|
ExampleFromNTriplesFile,
|
||||||
StrictExampleFromTerms
|
StrictExampleFromTerms,
|
||||||
|
ExampleWithBaseFromIRI,
|
||||||
|
ExampleWithBaseFromModuleAttribute
|
||||||
}
|
}
|
||||||
|
|
||||||
test "undefined terms" do
|
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 StrictExampleFromTerms.foo() == ~I<http://example.com/strict_from_terms#foo>
|
||||||
assert RDF.iri(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
|
end
|
||||||
|
|
||||||
test "capitalized terms" do
|
test "capitalized terms" do
|
||||||
assert RDF.iri(ExampleFromGraph.Bar) == ~I<http://example.com/from_graph#Bar>
|
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(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(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
|
end
|
||||||
|
|
||||||
test "terms starting with an underscore" do
|
test "terms starting with an underscore" do
|
||||||
|
|
Loading…
Reference in a new issue