From 54abc0973889d9643be91e0cc1d4c5801a6e131a Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Wed, 5 May 2021 13:50:28 -0700 Subject: [PATCH 01/20] Check for dot segments finding base and parents. --- lib/json/ld/context.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/json/ld/context.rb b/lib/json/ld/context.rb index 67ec566..1b831de 100644 --- a/lib/json/ld/context.rb +++ b/lib/json/ld/context.rb @@ -1884,7 +1884,7 @@ def remove_base(base, iri) @base_and_parents ||= begin u = base iri_set = u.to_s.end_with?('/') ? [u.to_s] : [] - iri_set << u.to_s while (u = u.parent) + iri_set << u.to_s while (u != './' && u = u.parent) iri_set end b = base.to_s From 060bf55c432c1cb02c32a32f106bcbaa2e7ba5e6 Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Wed, 5 May 2021 13:50:42 -0700 Subject: [PATCH 02/20] Add some omitGraphs tests. --- spec/frame_spec.rb | 96 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 93 insertions(+), 3 deletions(-) diff --git a/spec/frame_spec.rb b/spec/frame_spec.rb index d85d2b4..fdecfb9 100644 --- a/spec/frame_spec.rb +++ b/spec/frame_spec.rb @@ -992,6 +992,95 @@ end end + context "omitGraph option" do + { + "Defaults to false in 1.0": { + input: %([{ + "http://example.org/prop": [{"@value": "value"}], + "http://example.org/foo": [{"@value": "bar"}] + }]), + frame: %({ + "@context": { + "@vocab": "http://example.org/" + } + }), + output: %({ + "@context": { + "@vocab": "http://example.org/" + }, + "@graph": [{ + "foo": "bar", + "prop": "value" + }] + }), + processingMode: "json-ld-1.0" + }, + "Set with option in 1.0": { + input: %([{ + "http://example.org/prop": [{"@value": "value"}], + "http://example.org/foo": [{"@value": "bar"}] + }]), + frame: %({ + "@context": { + "@vocab": "http://example.org/" + } + }), + output: %({ + "@context": { + "@vocab": "http://example.org/" + }, + "foo": "bar", + "prop": "value" + }), + processingMode: "json-ld-1.0", + omitGraph: true + }, + "Defaults to true in 1.1": { + input: %([{ + "http://example.org/prop": [{"@value": "value"}], + "http://example.org/foo": [{"@value": "bar"}] + }]), + frame: %({ + "@context": { + "@vocab": "http://example.org/" + } + }), + output: %({ + "@context": { + "@vocab": "http://example.org/" + }, + "foo": "bar", + "prop": "value" + }), + processingMode: "json-ld-1.1" + }, + "Set with option in 1.1": { + input: %([{ + "http://example.org/prop": [{"@value": "value"}], + "http://example.org/foo": [{"@value": "bar"}] + }]), + frame: %({ + "@context": { + "@vocab": "http://example.org/" + } + }), + output: %({ + "@context": { + "@vocab": "http://example.org/" + }, + "@graph": [{ + "foo": "bar", + "prop": "value" + }] + }), + processingMode: "json-ld-1.1", + omitGraph: false + }, + }.each do |title, params| + it(title) {do_frame(params.merge(pruneBlankNodeIdentifiers: true))} + end + end + context "@included" do { "Basic Included array": { @@ -2359,15 +2448,16 @@ def do_frame(params) begin - input, frame, output, processingMode = params[:input], params[:frame], params[:output], params.fetch(:processingMode, 'json-ld-1.0') + input, frame, output = params[:input], params[:frame], params[:output] + params = {processingMode: 'json-ld-1.0'}.merge(params) input = ::JSON.parse(input) if input.is_a?(String) frame = ::JSON.parse(frame) if frame.is_a?(String) output = ::JSON.parse(output) if output.is_a?(String) jld = nil if params[:write] - expect{jld = JSON::LD::API.frame(input, frame, logger: logger, processingMode: processingMode)}.to write(params[:write]).to(:error) + expect{jld = JSON::LD::API.frame(input, frame, logger: logger, **params)}.to write(params[:write]).to(:error) else - expect{jld = JSON::LD::API.frame(input, frame, logger: logger, processingMode: processingMode)}.not_to write.to(:error) + expect{jld = JSON::LD::API.frame(input, frame, logger: logger, **params)}.not_to write.to(:error) end expect(jld).to produce_jsonld(output, logger) From 97d0daa4ff8f9497de683bd4cee902f9e5cf2131 Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Sat, 15 May 2021 12:12:50 -0700 Subject: [PATCH 03/20] Add minor change to compaction algorith to expand property index before compacting it. --- lib/json/ld/compact.rb | 1 + spec/compact_spec.rb | 70 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/lib/json/ld/compact.rb b/lib/json/ld/compact.rb index deee309..e5fb177 100644 --- a/lib/json/ld/compact.rb +++ b/lib/json/ld/compact.rb @@ -297,6 +297,7 @@ def compact(element, if index_key == '@index' map_key = expanded_item['@index'] else + index_key = context.expand_iri(index_key, vocab: true) container_key = context.compact_iri(index_key, vocab: true) map_key, *others = Array(compacted_item[container_key]) if map_key.is_a?(String) diff --git a/spec/compact_spec.rb b/spec/compact_spec.rb index cedbc07..717ce72 100644 --- a/spec/compact_spec.rb +++ b/spec/compact_spec.rb @@ -954,6 +954,76 @@ }), processingMode: 'json-ld-1.1' }, + "issue-514": { + input: %({ + "http://example.org/ns/prop": [{ + "@id": "http://example.org/ns/bar", + "http://example.org/ns/name": "bar" + }, { + "@id": "http://example.org/ns/foo", + "http://example.org/ns/name": "foo" + }] + }), + context: %({ + "@context": { + "ex": "http://example.org/ns/", + "prop": { + "@id": "ex:prop", + "@container": "@index", + "@index": "ex:name" + } + } + }), + output: %({ + "@context": { + "ex": "http://example.org/ns/", + "prop": { + "@id": "ex:prop", + "@container": "@index", + "@index": "ex:name" + } + }, + "prop": { + "foo": { "@id": "ex:foo"}, + "bar": { "@id": "ex:bar"} + } + }) + }, + "issue-514b": { + input: %({ + "http://example.org/ns/prop": [{ + "@id": "http://example.org/ns/bar", + "http://example.org/ns/name": "bar" + }, { + "@id": "http://example.org/ns/foo", + "http://example.org/ns/name": "foo" + }] + }), + context: %({ + "@context": { + "ex": "http://example.org/ns/", + "prop": { + "@id": "ex:prop", + "@container": "@index", + "@index": "http://example.org/ns/name" + } + } + }), + output: %({ + "@context": { + "ex": "http://example.org/ns/", + "prop": { + "@id": "ex:prop", + "@container": "@index", + "@index": "http://example.org/ns/name" + } + }, + "prop": { + "foo": { "@id": "ex:foo"}, + "bar": { "@id": "ex:bar"} + } + }) + }, }.each_pair do |title, params| it(title) {run_compact(params)} end From eef56214ed44b553be896ab3f1ab8be4fcbff2df Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Sat, 7 Aug 2021 13:06:15 -0700 Subject: [PATCH 04/20] Remove obsolete travis config. --- .travis.yml | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 20af913..0000000 --- a/.travis.yml +++ /dev/null @@ -1,16 +0,0 @@ -language: ruby -script: "bundle exec rspec spec" -env: - global: - - CI=true -rvm: - - 2.4 - - 2.5 - - 2.6 - - 2.7 - - jruby -#cache: bundler -sudo: false -matrix: - allow_failures: - - rvm: jruby From 620e9e1761e6f33ebed4ca5fb16d6708509b5d2a Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Sat, 7 Aug 2021 13:29:54 -0700 Subject: [PATCH 05/20] Nokogumbo is now included in Nokogiri. --- Gemfile | 1 - README.md | 2 +- lib/json/ld/html/nokogiri.rb | 5 ++--- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index b597cb6..ed2bd01 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,5 @@ source "https://rubygems.org" gem "nokogiri", '~> 1.10' -gem "nokogumbo", platforms: :mri gemspec gem 'rdf', git: "https://github.com/ruby-rdf/rdf", branch: "develop" diff --git a/README.md b/README.md index ece1fbc..ec03bc8 100755 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ JSON::LD parses and serializes [JSON-LD][] into [RDF][] and implements expansion JSON::LD can now be used to create a _context_ from an RDFS/OWL definition, and optionally include a JSON-LD representation of the ontology itself. This is currently accessed through the `script/gen_context` script. * If the [jsonlint][] gem is installed, it will be used when validating an input document. -* If available, uses [Nokogiri][] and/or [Nokogumbo][] for parsing HTML, falls back to REXML otherwise. +* If available, uses [Nokogiri][] for parsing HTML, falls back to REXML otherwise. * Provisional support for [JSON-LD-star][JSON-LD-star]. [Implementation Report](https://ruby-rdf.github.io/json-ld/etc/earl.html) diff --git a/lib/json/ld/html/nokogiri.rb b/lib/json/ld/html/nokogiri.rb index d5ca7f8..5ba7b9d 100644 --- a/lib/json/ld/html/nokogiri.rb +++ b/lib/json/ld/html/nokogiri.rb @@ -136,11 +136,10 @@ def initialize_html_nokogiri(input, options = {}) input else begin - require 'nokogumbo' unless defined?(::Nokogumbo) input = input.read if input.respond_to?(:read) - ::Nokogiri::HTML5(input.dup.force_encoding('utf-8'), max_parse_errors: 1000) + ::Nokogiri::HTML5(input.force_encoding('utf-8'), max_parse_errors: 1000) rescue LoadError - ::Nokogiri::HTML.parse(input, 'utf-8') + ::Nokogiri::HTML.parse(input, base_uri.to_s, 'utf-8') end end From 1eeb97dbb3c36bea11c6e9bac00488af69248044 Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Sat, 7 Aug 2021 13:30:12 -0700 Subject: [PATCH 06/20] Update CI for coveralls. --- .github/workflows/ci.yml | 7 +++++-- Gemfile | 5 +++-- spec/spec_helper.rb | 11 +++++++++-- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9fda18f..d245a26 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,7 +27,6 @@ jobs: fail-fast: false matrix: ruby: - - 2.4 - 2.5 - 2.6 - 2.7 @@ -45,4 +44,8 @@ jobs: run: bundle install --jobs 4 --retry 3 - name: Run tests run: bundle exec rspec spec || $ALLOW_FAILURES - + - name: Coveralls GitHub Action + uses: coverallsapp/github-action@v1.1.2 + if: "matrix.ruby == '3.0'" + with: + github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/Gemfile b/Gemfile index ed2bd01..e3d44e1 100644 --- a/Gemfile +++ b/Gemfile @@ -37,8 +37,9 @@ group :development do end group :development, :test do - gem 'simplecov', platforms: :mri - gem 'coveralls', '~> 0.8', platforms: :mri + gem 'simplecov', '~> 0.21', platforms: :mri + gem 'simplecov-lcov', '~> 0.8', platforms: :mri + gem 'coveralls', platforms: :mri gem 'psych', platforms: [:mri, :rbx] gem 'benchmark-ips' gem 'rake' diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 2500bc7..4f4693a 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -15,10 +15,17 @@ require 'yaml' begin require 'simplecov' - require 'coveralls' unless ENV['NOCOVERALLS'] + require 'simplecov-lcov' + require 'coveralls' + SimpleCov::Formatter::LcovFormatter.config do |config| + #Coveralls is coverage by default/lcov. Send info results + config.report_with_single_file = true + config.single_report_path = 'coverage/lcov.info' + end + SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([ SimpleCov::Formatter::HTMLFormatter, - (Coveralls::SimpleCov::Formatter unless ENV['NOCOVERALLS']) + SimpleCov::Formatter::LcovFormatter ]) SimpleCov.start do add_filter "/spec/" From 75a4e04e9aafe85ceb526fcd1327379c9fbef1ac Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Sat, 7 Aug 2021 13:36:38 -0700 Subject: [PATCH 07/20] Handle Nokogiri::HTML5 undefined error. --- lib/json/ld/html/nokogiri.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/json/ld/html/nokogiri.rb b/lib/json/ld/html/nokogiri.rb index 5ba7b9d..d709ae4 100644 --- a/lib/json/ld/html/nokogiri.rb +++ b/lib/json/ld/html/nokogiri.rb @@ -138,7 +138,7 @@ def initialize_html_nokogiri(input, options = {}) begin input = input.read if input.respond_to?(:read) ::Nokogiri::HTML5(input.force_encoding('utf-8'), max_parse_errors: 1000) - rescue LoadError + rescue LoadError, NoMethodError ::Nokogiri::HTML.parse(input, base_uri.to_s, 'utf-8') end end From 729099ea9022509df0b3d445355463445a8a2152 Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Sat, 7 Aug 2021 13:41:11 -0700 Subject: [PATCH 08/20] Allow failures on JRuby. --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d245a26..e466d79 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: runs-on: ubuntu-latest env: CI: true - ALLOW_FAILURES: false ${{ endsWith(matrix.ruby, 'head') }} + ALLOW_FAILURES: {{ endsWith(matrix.ruby, 'head') || matrix.ruby == 'jruby' }} strategy: fail-fast: false matrix: From 438ef10617fee2a56712f15c618353b487335dd1 Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Sat, 7 Aug 2021 13:48:24 -0700 Subject: [PATCH 09/20] Workflow syntax. --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e466d79..898f023 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: runs-on: ubuntu-latest env: CI: true - ALLOW_FAILURES: {{ endsWith(matrix.ruby, 'head') || matrix.ruby == 'jruby' }} + ALLOW_FAILURES: ${{ endsWith(matrix.ruby, 'head') || matrix.ruby == 'jruby' }} strategy: fail-fast: false matrix: From 894cf395e8ea31bcda805eeb3283287ccb34191e Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Wed, 11 Aug 2021 12:25:10 -0700 Subject: [PATCH 10/20] Remove explicit dependency on coveralls gem. --- Gemfile | 1 - spec/spec_helper.rb | 1 - 2 files changed, 2 deletions(-) diff --git a/Gemfile b/Gemfile index e3d44e1..728aca4 100644 --- a/Gemfile +++ b/Gemfile @@ -39,7 +39,6 @@ end group :development, :test do gem 'simplecov', '~> 0.21', platforms: :mri gem 'simplecov-lcov', '~> 0.8', platforms: :mri - gem 'coveralls', platforms: :mri gem 'psych', platforms: [:mri, :rbx] gem 'benchmark-ips' gem 'rake' diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 4f4693a..541b2ff 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -16,7 +16,6 @@ begin require 'simplecov' require 'simplecov-lcov' - require 'coveralls' SimpleCov::Formatter::LcovFormatter.config do |config| #Coveralls is coverage by default/lcov. Send info results config.report_with_single_file = true From c10a69fae246d74724826acbbc6bfde67e37edda Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Sun, 26 Sep 2021 15:46:16 -0400 Subject: [PATCH 11/20] Better account for context_base when loading a scoped context. Add back some debug output, including depth. --- lib/json/ld/context.rb | 26 +++++++++++++++----------- lib/json/ld/expand.rb | 22 +++++++++++----------- spec/context_spec.rb | 9 ++++++++- 3 files changed, 34 insertions(+), 23 deletions(-) diff --git a/lib/json/ld/context.rb b/lib/json/ld/context.rb index 1b831de..013e4fa 100644 --- a/lib/json/ld/context.rb +++ b/lib/json/ld/context.rb @@ -253,6 +253,7 @@ def parse(local_context, local_context = as_array(local_context) + log_depth do local_context.each do |context| case context when nil,false @@ -266,22 +267,22 @@ def parse(local_context, "Attempt to clear a context with protected terms" end when Context - #log_debug("parse") {"context: #{context.inspect}"} + log_debug("parse") {"context: #{context.inspect}"} result = result.merge(context) when IO, StringIO - #log_debug("parse") {"io: #{context}"} + log_debug("parse") {"io: #{context}"} # Load context document, if it is an open file begin ctx = JSON.load(context) raise JSON::LD::JsonLdError::InvalidRemoteContext, "Context missing @context key" if @options[:validate] && ctx['@context'].nil? result = result.parse(ctx["@context"] ? ctx["@context"] : {}) rescue JSON::ParserError => e - #log_debug("parse") {"Failed to parse @context from remote document at #{context}: #{e.message}"} + log_info("parse") {"Failed to parse @context from remote document at #{context}: #{e.message}"} raise JSON::LD::JsonLdError::InvalidRemoteContext, "Failed to parse remote context at #{context}: #{e.message}" if @options[:validate] self end when String, RDF::URI - #log_debug("parse") {"remote: #{context}, base: #{result.context_base || result.base}"} + log_debug("parse") {"remote: #{context}, base: #{result.context_base || result.base}"} # 3.2.1) Set context to the result of resolving value against the base IRI which is established as specified in section 5.1 Establishing a Base URI of [RFC3986]. Only the basic algorithm in section 5.2 of [RFC3986] is used; neither Syntax-Based Normalization nor Scheme-Based Normalization are performed. Characters additionally allowed in IRI references are treated in the same way that unreserved characters are treated in URI references, per section 6.5 of [RFC3987]. context = RDF::URI(result.context_base || base).join(context) @@ -296,11 +297,11 @@ def parse(local_context, cached_context = if PRELOADED[context_canon.to_s] # If we have a cached context, merge it into the current context (result) and use as the new context - #log_debug("parse") {"=> cached_context: #{context_canon.to_s.inspect}"} + log_debug("parse") {"=> cached_context: #{context_canon.to_s.inspect}"} # If this is a Proc, then replace the entry with the result of running the Proc if PRELOADED[context_canon.to_s].respond_to?(:call) - #log_debug("parse") {"=> (call)"} + log_debug("parse") {"=> (call)"} PRELOADED[context_canon.to_s] = PRELOADED[context_canon.to_s].call end PRELOADED[context_canon.to_s] @@ -320,16 +321,17 @@ def parse(local_context, ctx = Context.new(unfrozen: true, **options).dup ctx.context_base = context.to_s ctx = ctx.parse(remote_doc.document['@context'], remote_contexts: remote_contexts.dup) + ctx.context_base = context.to_s # In case it was altered ctx.instance_variable_set(:@base, nil) ctx end rescue JsonLdError::LoadingDocumentFailed => e - #log_debug("parse") {"Failed to retrieve @context from remote document at #{context_no_base.context_base.inspect}: #{e.message}"} + log_info("parse") {"Failed to retrieve @context from remote document at #{context_canon.inspect}: #{e.message}"} raise JsonLdError::LoadingRemoteContextFailed, "#{context}: #{e.message}", e.backtrace rescue JsonLdError raise rescue StandardError => e - #log_debug("parse") {"Failed to retrieve @context from remote document at #{context_no_base.context_base.inspect}: #{e.message}"} + log_info("parse") {"Failed to retrieve @context from remote document at #{context_canon.inspect}: #{e.message}"} raise JsonLdError::LoadingRemoteContextFailed, "#{context}: #{e.message}", e.backtrace end end @@ -406,6 +408,7 @@ def parse(local_context, raise JsonLdError::InvalidLocalContext, "must be a URL, JSON object or array of same: #{context.inspect}" end end + end result end @@ -475,7 +478,7 @@ def create_term_definition(local_context, term, defined, remote_contexts: [], validate_scoped: true) # Expand a string value, unless it matches a keyword - #log_debug("create_term_definition") {"term = #{term.inspect}"} + log_debug("create_term_definition") {"term = #{term.inspect}"} # If defined contains the key term, then the associated value must be true, indicating that the term definition has already been created, so return. Otherwise, a cyclical term definition has been detected, which is an error. case defined[term] @@ -646,7 +649,7 @@ def create_term_definition(local_context, term, defined, # Otherwise, term is an absolute IRI. Set the IRI mapping for definition to term term end - #log_debug("") {"=> #{definition.id}"} + log_debug("") {"=> #{definition.id}"} elsif term.include?('/') # If term is a relative IRI definition.id = expand_iri(term, vocab: true) @@ -659,7 +662,7 @@ def create_term_definition(local_context, term, defined, # Otherwise, active context must have a vocabulary mapping, otherwise an invalid value has been detected, which is an error. Set the IRI mapping for definition to the result of concatenating the value associated with the vocabulary mapping and term. raise JsonLdError::InvalidIRIMapping, "relative term definition without vocab: #{term} on term #{term.inspect}" unless vocab definition.id = vocab + term - #log_debug("") {"=> #{definition.id}"} + log_debug("") {"=> #{definition.id}"} end @iri_to_term[definition.id] = term if simple_term && definition.id @@ -699,6 +702,7 @@ def create_term_definition(local_context, term, defined, when nil then [nil] else value['@context'] end + log_debug("") {"context: #{definition.context.inspect}"} rescue JsonLdError => e raise JsonLdError::InvalidScopedContext, "Term definition for #{term.inspect} contains illegal value for @context: #{e.message}" end diff --git a/lib/json/ld/expand.rb b/lib/json/ld/expand.rb index 76b56f6..3956349 100644 --- a/lib/json/ld/expand.rb +++ b/lib/json/ld/expand.rb @@ -107,7 +107,7 @@ def expand(input, active_property, context, Array(input[tk]).sort.each do |term| term_context = type_scoped_context.term_definitions[term].context if type_scoped_context.term_definitions[term] unless term_context.nil? - log_debug("expand", depth: log_depth.to_i) {"term_context: #{term_context.inspect}"} + log_debug("expand", depth: log_depth.to_i) {"term_context[#{term}]: #{term_context.inspect}"} context = context.parse(term_context, base: @options[:base], propagate: false) end end @@ -258,10 +258,10 @@ def expand_object(input, active_property, context, output_object, expanded_property.to_s.start_with?("_:") && context.processingMode('json-ld-1.1') - #log_debug("expand property", depth: log_depth.to_i) {"ap: #{active_property.inspect}, expanded: #{expanded_property.inspect}, value: #{value.inspect}"} + log_debug("expand property", depth: log_depth.to_i) {"ap: #{active_property.inspect}, expanded: #{expanded_property.inspect}, value: #{value.inspect}"} if expanded_property.nil? - #log_debug(" => ", depth: log_depth.to_i) {"skip nil property"} + log_debug(" => ", depth: log_depth.to_i) {"skip nil property"} next end @@ -341,7 +341,7 @@ def expand_object(input, active_property, context, output_object, Array(output_object['@included']) + included_result when '@type' # If expanded property is @type and value is neither a string nor an array of strings, an invalid type value error has been detected and processing is aborted. Otherwise, set expanded value to the result of using the IRI Expansion algorithm, passing active context, true for vocab, and true for document relative to expand the value or each of its items. - #log_debug("@type", depth: log_depth.to_i) {"value: #{value.inspect}"} + log_debug("@type", depth: log_depth.to_i) {"value: #{value.inspect}"} e_type = case value when Array value.map do |v| @@ -516,7 +516,7 @@ def expand_object(input, active_property, context, output_object, # If expanded value contains an @reverse member, i.e., properties that are reversed twice, execute for each of its property and item the following steps: if value.key?('@reverse') - #log_debug("@reverse", depth: log_depth.to_i) {"double reverse: #{value.inspect}"} + log_debug("@reverse", depth: log_depth.to_i) {"double reverse: #{value.inspect}"} value['@reverse'].each do |property, item| # If result does not have a property member, create one and set its value to an empty array. # Append item to the value of the property member of result. @@ -566,7 +566,7 @@ def expand_object(input, active_property, context, output_object, end # Unless expanded value is null, set the expanded property member of result to expanded value. - #log_debug("expand #{expanded_property}", depth: log_depth.to_i) { expanded_value.inspect} + log_debug("expand #{expanded_property}", depth: log_depth.to_i) { expanded_value.inspect} output_object[expanded_property] = expanded_value unless expanded_value.nil? && expanded_property == '@value' && input_type != '@json' next end @@ -688,21 +688,21 @@ def expand_object(input, active_property, context, output_object, # If expanded value is null, ignore key by continuing to the next key from element. if expanded_value.nil? - #log_debug(" => skip nil value", depth: log_depth.to_i) + log_debug(" => skip nil value", depth: log_depth.to_i) next end - #log_debug(depth: log_depth.to_i) {" => #{expanded_value.inspect}"} + log_debug(depth: log_depth.to_i) {" => #{expanded_value.inspect}"} # If the container mapping associated to key in active context is @list and expanded value is not already a list object, convert expanded value to a list object by first setting it to an array containing only expanded value if it is not already an array, and then by setting it to a JSON object containing the key-value pair @list-expanded value. if container.first == '@list' && container.length == 1 && !list?(expanded_value) - #log_debug(" => ", depth: log_depth.to_i) { "convert #{expanded_value.inspect} to list"} + log_debug(" => ", depth: log_depth.to_i) { "convert #{expanded_value.inspect} to list"} expanded_value = {'@list' => as_array(expanded_value)} end - #log_debug(depth: log_depth.to_i) {" => #{expanded_value.inspect}"} + log_debug(depth: log_depth.to_i) {" => #{expanded_value.inspect}"} # convert expanded value to @graph if container specifies it if container.first == '@graph' && container.length == 1 - #log_debug(" => ", depth: log_depth.to_i) { "convert #{expanded_value.inspect} to list"} + log_debug(" => ", depth: log_depth.to_i) { "convert #{expanded_value.inspect} to list"} expanded_value = as_array(expanded_value).map do |v| {'@graph' => as_array(v)} end diff --git a/spec/context_spec.rb b/spec/context_spec.rb index ae83c98..1cb9dc5 100644 --- a/spec/context_spec.rb +++ b/spec/context_spec.rb @@ -181,7 +181,14 @@ def containers before {JSON::LD::Context.instance_variable_set(:@cache, nil)} it "retrieves and parses a remote context document" do expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", anything).and_yield(remote_doc) - subject.parse(ctx) + ec = subject.parse(ctx) + expect(ec.send(:mappings)).to produce({ + "xsd" => "http://www.w3.org/2001/XMLSchema#", + "name" => "http://xmlns.com/foaf/0.1/name", + "homepage" => "http://xmlns.com/foaf/0.1/homepage", + "avatar" => "http://xmlns.com/foaf/0.1/avatar", + "integer" => "http://www.w3.org/2001/XMLSchema#integer" + }, logger) end end From a714a5af903627b087dcfeea13509d2c8e4488bc Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Sun, 26 Sep 2021 15:53:24 -0400 Subject: [PATCH 12/20] Announce Ruby version. --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 898f023..486471f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,6 +40,7 @@ jobs: uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} + run: ruby --version - name: Install dependencies run: bundle install --jobs 4 --retry 3 - name: Run tests From 11d69260427f343dd8234ed22c7e4177565c3e82 Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Sun, 26 Sep 2021 15:55:19 -0400 Subject: [PATCH 13/20] Announce Ruby version. --- .github/workflows/ci.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 486471f..b69b382 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,11 +40,10 @@ jobs: uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} - run: ruby --version - name: Install dependencies run: bundle install --jobs 4 --retry 3 - name: Run tests - run: bundle exec rspec spec || $ALLOW_FAILURES + run: ruby --version; bundle exec rspec spec || $ALLOW_FAILURES - name: Coveralls GitHub Action uses: coverallsapp/github-action@v1.1.2 if: "matrix.ruby == '3.0'" From 7d02c9c8b97572027003b2e40f68e4e04d0e708a Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Sun, 26 Sep 2021 15:59:23 -0400 Subject: [PATCH 14/20] Version 3.1.10. --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 7148b0a..c7a2498 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.1.9 +3.1.10 From 9c699e3d804bf676b368577e985572ef2a2e8f52 Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Tue, 26 Oct 2021 11:27:58 -0700 Subject: [PATCH 15/20] Update CI. --- .github/workflows/ci.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b69b382..0a4430c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,21 +1,14 @@ # This workflow runs continuous CI across different versions of ruby on all branches and pull requests to develop. name: CI - -# Controls when the action will run. on: - # Triggers the workflow on push or pull request events but only for the develop branch push: branches: [ '**' ] pull_request: branches: [ develop ] - - # Allows you to run this workflow manually from the Actions tab workflow_dispatch: -# A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: - # This workflow contains a single job called "build" tests: name: Ruby ${{ matrix.ruby }} if: "contains(github.event.commits[0].message, '[ci skip]') == false" From 6135f465fdb24f93386924f1dcb840999e006ef8 Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Sun, 12 Dec 2021 16:52:32 -0800 Subject: [PATCH 16/20] Update documentation, dependencies, and version sync for 3.2. --- .github/workflows/ci.yml | 1 - Gemfile | 1 + README.md | 6 +++--- VERSION | 2 +- json-ld.gemspec | 22 +++++++++++----------- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0a4430c..7326117 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,6 @@ jobs: fail-fast: false matrix: ruby: - - 2.5 - 2.6 - 2.7 - 3.0 diff --git a/Gemfile b/Gemfile index 728aca4..d5473b9 100644 --- a/Gemfile +++ b/Gemfile @@ -3,6 +3,7 @@ gem "nokogiri", '~> 1.10' gemspec gem 'rdf', git: "https://github.com/ruby-rdf/rdf", branch: "develop" +gem 'json-canonicalization',git: "https://github.com/dryruby/json-canonicalization",branch: "develop" group :development do gem 'ebnf', git: "https://github.com/dryruby/ebnf", branch: "develop" diff --git a/README.md b/README.md index ec03bc8..4cfcc23 100755 --- a/README.md +++ b/README.md @@ -588,9 +588,9 @@ Note, the API method signatures differed in versions before 1.0, in that they al * {JSON::LD::Writer} ## Dependencies -* [Ruby](https://ruby-lang.org/) (>= 2.4) -* [RDF.rb](https://rubygems.org/gems/rdf) (~> 3.1) -* [JSON](https://rubygems.org/gems/json) (>= 2.2) +* [Ruby](https://ruby-lang.org/) (>= 2.6) +* [RDF.rb](https://rubygems.org/gems/rdf) (~> 3.2) +* [JSON](https://rubygems.org/gems/json) (>= 2.6) ## Installation The recommended installation method is via [RubyGems](https://rubygems.org/). diff --git a/VERSION b/VERSION index c7a2498..944880f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.1.10 +3.2.0 diff --git a/json-ld.gemspec b/json-ld.gemspec index db704ef..cd1aaef 100755 --- a/json-ld.gemspec +++ b/json-ld.gemspec @@ -23,26 +23,26 @@ Gem::Specification.new do |gem| gem.require_paths = %w(lib) gem.test_files = Dir.glob('spec/**/*.rb') + Dir.glob('spec/test-files/*') - gem.required_ruby_version = '>= 2.4' + gem.required_ruby_version = '>= 2.6' gem.requirements = [] - gem.add_runtime_dependency 'rdf', '~> 3.1' - gem.add_runtime_dependency 'multi_json', '~> 1.14' + gem.add_runtime_dependency 'rdf', '~> 3.2' + gem.add_runtime_dependency 'multi_json', '~> 1.15' gem.add_runtime_dependency 'link_header', '~> 0.0', '>= 0.0.8' - gem.add_runtime_dependency 'json-canonicalization', '~> 0.2' + gem.add_runtime_dependency 'json-canonicalization', '~> 0.3' gem.add_runtime_dependency 'htmlentities', '~> 4.3' - gem.add_runtime_dependency 'rack', '~> 2.0' + gem.add_runtime_dependency 'rack', '~> 2.2' gem.add_development_dependency 'sinatra-linkeddata','~> 3.1' gem.add_development_dependency 'jsonlint', '~> 0.3' unless is_java - gem.add_development_dependency 'oj', '~> 3.9' unless is_java + gem.add_development_dependency 'oj', '~> 3.13' unless is_java gem.add_development_dependency 'yajl-ruby', '~> 1.4' unless is_java gem.add_development_dependency 'rack-test', '~> 1.1' - gem.add_development_dependency 'rdf-isomorphic', '~> 3.1' - gem.add_development_dependency 'rdf-spec', '~> 3.1' + gem.add_development_dependency 'rdf-isomorphic', '~> 3.2' + gem.add_development_dependency 'rdf-spec', '~> 3.2' gem.add_development_dependency 'rdf-trig', '~> 3.1' gem.add_development_dependency 'rdf-turtle', '~> 3.1' - gem.add_development_dependency 'rdf-vocab', '~> 3.1' - gem.add_development_dependency 'rdf-xsd', '~> 3.1' - gem.add_development_dependency 'rspec', '~> 3.9' + gem.add_development_dependency 'rdf-vocab', '~> 3.2' + gem.add_development_dependency 'rdf-xsd', '~> 3.2' + gem.add_development_dependency 'rspec', '~> 3.10' gem.add_development_dependency 'rspec-its', '~> 1.3' gem.add_development_dependency 'yard' , '~> 0.9' From 61c48929005bcb835216c38a1c98b7ce6f0eada2 Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Mon, 13 Dec 2021 14:43:32 -0800 Subject: [PATCH 17/20] Sync more gem versions. --- json-ld.gemspec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/json-ld.gemspec b/json-ld.gemspec index cd1aaef..296a827 100755 --- a/json-ld.gemspec +++ b/json-ld.gemspec @@ -38,8 +38,8 @@ Gem::Specification.new do |gem| gem.add_development_dependency 'rack-test', '~> 1.1' gem.add_development_dependency 'rdf-isomorphic', '~> 3.2' gem.add_development_dependency 'rdf-spec', '~> 3.2' - gem.add_development_dependency 'rdf-trig', '~> 3.1' - gem.add_development_dependency 'rdf-turtle', '~> 3.1' + gem.add_development_dependency 'rdf-trig', '~> 3.2' + gem.add_development_dependency 'rdf-turtle', '~> 3.2' gem.add_development_dependency 'rdf-vocab', '~> 3.2' gem.add_development_dependency 'rdf-xsd', '~> 3.2' gem.add_development_dependency 'rspec', '~> 3.10' From 42e7f2778e1ae7e60cbebdf9f9c287aae5677538 Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Sun, 26 Dec 2021 22:44:52 -0800 Subject: [PATCH 18/20] CI on Ruby 3.1. --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7326117..9827680 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,6 +23,7 @@ jobs: - 2.6 - 2.7 - 3.0 + - 3.1 - ruby-head - jruby steps: From 9798d9f9b617e17cc3e4f7d4f080033731804061 Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Wed, 29 Dec 2021 13:13:27 -0800 Subject: [PATCH 19/20] Fix reading `@processingMode` in context. --- lib/json/ld/context.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/json/ld/context.rb b/lib/json/ld/context.rb index 013e4fa..6fdb2b9 100644 --- a/lib/json/ld/context.rb +++ b/lib/json/ld/context.rb @@ -1688,7 +1688,7 @@ def dup ec.default_direction = that.default_direction ec.default_language = that.default_language ec.previous_context = that.previous_context - ec.processingMode = that.processingMode if that.instance_variable_get(:@processingModee) + ec.processingMode = that.processingMode if that.instance_variable_get(:@processingMode) ec.vocab = that.vocab if that.vocab ec.instance_eval do From 9dbf716b63545821f9bfee7ed6ead8efad81e0f9 Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Wed, 29 Dec 2021 13:13:37 -0800 Subject: [PATCH 20/20] Update yard docs. --- example-files/frame-title-frame.jsonld | 16 ++++++++++++++++ example-files/frame-title.jsonld | 17 +++++++++++++++++ lib/json/ld/flatten.rb | 2 +- 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 example-files/frame-title-frame.jsonld create mode 100644 example-files/frame-title.jsonld diff --git a/example-files/frame-title-frame.jsonld b/example-files/frame-title-frame.jsonld new file mode 100644 index 0000000..e1c1d91 --- /dev/null +++ b/example-files/frame-title-frame.jsonld @@ -0,0 +1,16 @@ +{ + "@context": [ + { + "@language": "en" + }, + { + "title": { + "@id": "dct:title" + }, + "titles": { + "@id": "dct:title", + "@container": "@language" + } + } + ] +} diff --git a/example-files/frame-title.jsonld b/example-files/frame-title.jsonld new file mode 100644 index 0000000..b9ded19 --- /dev/null +++ b/example-files/frame-title.jsonld @@ -0,0 +1,17 @@ +{ + "@context": [ + { + "@language": "en" + }, + { + "title": { + "@id": "dct:title" + }, + "titles": { + "@id": "dct:title", + "@container": "@language" + } + } + ], + "title": "myTitle" +} diff --git a/lib/json/ld/flatten.rb b/lib/json/ld/flatten.rb index 2790046..5a348c4 100644 --- a/lib/json/ld/flatten.rb +++ b/lib/json/ld/flatten.rb @@ -202,7 +202,7 @@ def create_node_map(element, graph_map, # * Deserialize the key into a map, and re-serialize the value of `@id`. # * If the map contains an entry with that value (after re-canonicalizing, as appropriate), and the associated antry has a item which matches the non-`@id` item from the map, the node is used to create an `@annotation` entry within that value. # - # @param [Hash{String => Hash}] input + # @param [Hash{String => Hash}] node_map # @return [Hash{String => Hash}] def create_annotations(node_map) node_map.keys.