From 9655d6388522ce9f3e1a6eff7eafa297d6684aee Mon Sep 17 00:00:00 2001 From: Marcel Otto Date: Fri, 22 Apr 2022 02:47:44 +0200 Subject: [PATCH] Allow atom keys in context maps --- CHANGELOG.md | 8 ++++++- lib/json_ld.ex | 22 +++++++++++++---- test/unit/context_test.exs | 38 +++++++++++++++++++++++++++++ test/unit/encoder_test.exs | 49 +++++++++++++++++++++++++------------- test/unit/json_ld_test.exs | 5 ++++ 5 files changed, 100 insertions(+), 22 deletions(-) create mode 100644 test/unit/json_ld_test.exs diff --git a/CHANGELOG.md b/CHANGELOG.md index d7f0351..72aa2bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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) diff --git a/lib/json_ld.ex b/lib/json_ld.ex index b2cba86..64b1bba 100644 --- a/lib/json_ld.ex +++ b/lib/json_ld.ex @@ -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. diff --git a/test/unit/context_test.exs b/test/unit/context_test.exs index d0b91fc..7ea935b 100644 --- a/test/unit/context_test.exs +++ b/test/unit/context_test.exs @@ -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" => %{ diff --git a/test/unit/encoder_test.exs b/test/unit/encoder_test.exs index 0b2f3f4..fd4d72f 100644 --- a/test/unit/encoder_test.exs +++ b/test/unit/encoder_test.exs @@ -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 diff --git a/test/unit/json_ld_test.exs b/test/unit/json_ld_test.exs new file mode 100644 index 0000000..e4aa36e --- /dev/null +++ b/test/unit/json_ld_test.exs @@ -0,0 +1,5 @@ +defmodule JSON.LDTest do + use ExUnit.Case + + doctest JSON.LD +end