Add :auto_fix for :case_validation option on defvocab

This commit is contained in:
Marcel Otto 2022-06-27 00:21:03 +02:00
parent 370a3a3568
commit 0b0b42e2a1
3 changed files with 36 additions and 2 deletions

View file

@ -19,8 +19,10 @@ The generated namespaces are much more flexible now and compile faster.
- `RDF.IRI.starts_with?/2` and `RDF.IRI.ends_with?/2` - `RDF.IRI.starts_with?/2` and `RDF.IRI.ends_with?/2`
- `RDF.Graph.build/2` now supports the creation of ad-hoc vocabulary namespaces - `RDF.Graph.build/2` now supports the creation of ad-hoc vocabulary namespaces
with a `@prefix` declaration providing the URI of the namespace as a string with a `@prefix` declaration providing the URI of the namespace as a string
- the `case_violations` option of `defvocab` now supports custom handler functions, - The `case_violations` option of `defvocab` now supports an `:auto_fix` option
either as an inline function or as a function on a separate module which adapts the first letter of violating term accordingly. It also supports
custom handler functions, either as an inline function or as a function on a
separate module.
### Changed ### Changed

View file

@ -145,6 +145,10 @@ defmodule RDF.Vocabulary.Namespace.CaseValidation do
terms_and_ignored terms_and_ignored
end end
defp do_handle_case_violations(terms_and_ignored, violation_groups, :auto_fix, base_iri) do
do_handle_case_violations(terms_and_ignored, violation_groups, &auto_fix_term/2, base_iri)
end
defp do_handle_case_violations(terms_and_ignored, violation_groups, fun, base_iri) defp do_handle_case_violations(terms_and_ignored, violation_groups, fun, base_iri)
when is_function(fun) do when is_function(fun) do
{alias_violations, term_violations} = {alias_violations, term_violations} =
@ -209,4 +213,11 @@ defmodule RDF.Vocabulary.Namespace.CaseValidation do
defp case_violation_warning(:lowercased_alias, term, _, _) do defp case_violation_warning(:lowercased_alias, term, _, _) do
IO.warn("lowercased alias '#{term}' for a non-property resource") IO.warn("lowercased alias '#{term}' for a non-property resource")
end end
defp auto_fix_term(:property, term) do
{first, rest} = String.next_grapheme(term)
{:ok, String.downcase(first) <> rest}
end
defp auto_fix_term(:resource, term), do: {:ok, :string.titlecase(term)}
end end

View file

@ -139,6 +139,18 @@ defmodule RDF.Vocabulary.NamespaceTest do
base_iri: "http://example.com/ex#", base_iri: "http://example.com/ex#",
terms: [foo: "bar", baz: "bar", Foo: "Bar", Baz: "Bar"] terms: [foo: "bar", baz: "bar", Foo: "Bar", Baz: "Bar"]
defvocab ExampleWithAutoFixedCaseViolations,
base_iri: "http://example.com/ex#",
case_violations: :auto_fix,
data:
RDF.Graph.new([
{~I<http://example.com/ex#FooTest>, RDF.type(), RDF.Property},
{~I<http://example.com/ex#barTest>, RDF.type(), RDF.Property},
{~I<http://example.com/ex#bazTest>, RDF.type(), RDFS.Resource},
{~I<http://example.com/ex#baazTest>, RDF.type(), RDFS.Resource}
]),
alias: [BaazAlias: :baazTest]
defvocab ExampleWithCustomInlineCaseViolationFunction, defvocab ExampleWithCustomInlineCaseViolationFunction,
base_iri: "http://example.com/ex#", base_iri: "http://example.com/ex#",
case_violations: fn case_violations: fn
@ -799,6 +811,15 @@ defmodule RDF.Vocabulary.NamespaceTest do
end end
end end
test "auto_fix case violations" do
alias TestNS.ExampleWithAutoFixedCaseViolations, as: Example
assert Example.fooTest() == RDF.iri(Example.__base_iri__() <> "FooTest")
assert Example.barTest() == RDF.iri(Example.__base_iri__() <> "barTest")
assert RDF.iri(Example.BazTest) == RDF.iri(Example.__base_iri__() <> "bazTest")
assert RDF.iri(Example.BaazAlias) == RDF.iri(Example.__base_iri__() <> "baazTest")
end
test "case violation function (inline)" do test "case violation function (inline)" do
alias TestNS.ExampleWithCustomInlineCaseViolationFunction, as: Example alias TestNS.ExampleWithCustomInlineCaseViolationFunction, as: Example