Allow atom keys in context maps

This commit is contained in:
Marcel Otto 2022-04-22 02:47:44 +02:00
parent 01974543a0
commit 9655d63885
5 changed files with 100 additions and 22 deletions

View file

@ -11,7 +11,13 @@ This project adheres to [Semantic Versioning](http://semver.org/) and
- the `JSON.LD.Encoder` now supports implicit compaction by providing a context
as a map or a URL string for a remote context with the new `:context` option
### Changed
- context maps can be given now with atom keys to `JSON.LD.context/2` and
`JSON.LD.compact/3`
[Compare v0.3.4...HEAD](https://github.com/rdf-elixir/jsonld-ex/compare/v0.3.4...HEAD)

View file

@ -95,13 +95,27 @@ defmodule JSON.LD do
object its value, or the JSON-LD context object directly.
"""
@spec context(map, Options.t()) :: Context.t()
def context(args, opts \\ %Options{})
def context(context, options \\ %Options{}) do
context
|> stringify_keys()
|> do_context(options)
end
def context(%{"@context" => _} = object, options),
defp do_context(%{"@context" => _} = object, options),
do: Context.create(object, options)
def context(context, options),
do: Context.create(%{"@context" => context}, options)
defp do_context(context, options),
do: Context.create(%{"@context" => stringify_keys(context)}, options)
defp stringify_keys(map) when is_map(map) do
Map.new(map, fn
{key, value} when is_map(value) -> {to_string(key), stringify_keys(value)}
{key, value} -> {to_string(key), value}
end)
end
defp stringify_keys(list) when is_list(list), do: Enum.map(list, &stringify_keys/1)
defp stringify_keys(value), do: value
@doc """
Generator function for JSON-LD node maps.

View file

@ -173,6 +173,44 @@ defmodule JSON.LD.ContextTest do
end
end
describe "JSON.LD.context/2" do
@example_context_map %{
"@context" => %{
"givenName" => "http://schema.org/givenName",
"familyName" => "http://schema.org/familyName",
"homepage" => %{
"@id" => "http://schema.org/url",
"@type" => "@id"
}
}
}
test "wraps everything under a @context" do
assert JSON.LD.context(@example_context_map["@context"]) ==
JSON.LD.context(@example_context_map)
end
test "with atom keys" do
context_with_atom_keys = %{
givenName: "http://schema.org/givenName",
familyName: "http://schema.org/familyName",
homepage: %{
"@id": "http://schema.org/url",
"@type": "@id"
}
}
assert JSON.LD.context(context_with_atom_keys) ==
JSON.LD.context(@example_context_map)
assert JSON.LD.context(%{"@context": context_with_atom_keys}) ==
JSON.LD.context(@example_context_map)
assert JSON.LD.context(%{"@context" => context_with_atom_keys}) ==
JSON.LD.context(@example_context_map)
end
end
describe "errors" do
%{
"no @id, @type, or @container" => %{

View file

@ -590,24 +590,39 @@ defmodule JSON.LD.EncoderTest do
}
}
expected_result =
"""
{
"@context": {
"familyName": "http://schema.org/familyName",
"givenName": "http://schema.org/givenName",
"homepage": {
"@id": "http://schema.org/url",
"@type": "@id"
}
},
"@id": "http://manu.sporny.org/about#manu",
"familyName": "Sporny",
"givenName": "Manu",
"homepage": "http://manu.sporny.org/"
}
"""
|> String.trim()
assert JSON.LD.Encoder.encode!(graph, context: context, pretty: true) ==
"""
{
"@context": {
"familyName": "http://schema.org/familyName",
"givenName": "http://schema.org/givenName",
"homepage": {
"@id": "http://schema.org/url",
"@type": "@id"
}
},
"@id": "http://manu.sporny.org/about#manu",
"familyName": "Sporny",
"givenName": "Manu",
"homepage": "http://manu.sporny.org/"
}
"""
|> String.trim()
expected_result
context_with_atom_keys = %{
givenName: "http://schema.org/givenName",
familyName: "http://schema.org/familyName",
homepage: %{
"@id": "http://schema.org/url",
"@type": "@id"
}
}
assert JSON.LD.Encoder.encode!(graph, context: context_with_atom_keys, pretty: true) ==
expected_result
end
test ":context with a remote context" do

View file

@ -0,0 +1,5 @@
defmodule JSON.LDTest do
use ExUnit.Case
doctest JSON.LD
end